Bagaimana cara memaksa R menggunakan tingkat faktor tertentu sebagai referensi dalam regresi?

112

Bagaimana cara memberi tahu R untuk menggunakan level tertentu sebagai referensi jika saya menggunakan variabel penjelas biner dalam regresi?

Ini hanya menggunakan beberapa level secara default.

lm(x ~ y + as.factor(b)) 

dengan b {0, 1, 2, 3, 4}. Katakanlah saya ingin menggunakan 3 alih-alih nol yang digunakan oleh R.

Matt Bannert
sumber
9
Anda harus melakukan langkah pemrosesan data di luar formula / fitting model. Saat membuat faktor dari bAnda dapat menentukan urutan level menggunakan factor(b, levels = c(3,1,2,4,5)). Lakukan ini dalam langkah pemrosesan data di luar lm()panggilan. Jawaban saya di bawah ini menggunakan relevel()fungsi tersebut sehingga Anda dapat membuat faktor dan kemudian menggeser tingkat referensi agar sesuai sesuai kebutuhan.
Gavin Simpson
1
Saya menulis ulang pertanyaan Anda. Anda sebenarnya setelah mengubah tingkat referensi, tidak meninggalkan satu pun.
Joris Meys
terima kasih untuk menulis ulang pertanyaan saya. Memang, relevel () adalah yang saya cari. Terima kasih untuk jawaban rinci dan contohnya. Saya tidak yakin apakah tag regresi linier agak menyesatkan karena ini berlaku untuk semua jenis regresi yang menggunakan penjelasan tiruan ...
Matt Bannert

Jawaban:

152

Lihat relevel()fungsinya. Berikut ini contohnya:

set.seed(123)
x <- rnorm(100)
DF <- data.frame(x = x,
                 y = 4 + (1.5*x) + rnorm(100, sd = 2),
                 b = gl(5, 20))
head(DF)
str(DF)

m1 <- lm(y ~ x + b, data = DF)
summary(m1)

Sekarang mengubah faktor bdi DFoleh penggunaan relevel()fungsi:

DF <- within(DF, b <- relevel(b, ref = 3))
m2 <- lm(y ~ x + b, data = DF)
summary(m2)

Model tersebut memperkirakan tingkat referensi yang berbeda.

> coef(m1)
(Intercept)           x          b2          b3          b4          b5 
  3.2903239   1.4358520   0.6296896   0.3698343   1.0357633   0.4666219 
> coef(m2)
(Intercept)           x          b1          b2          b4          b5 
 3.66015826  1.43585196 -0.36983433  0.25985529  0.66592898  0.09678759
Gavin Simpson
sumber
9
Untuk preseve variabel asli, jangan gunakan within, tapi df$bR = relevel(df$b, ref=3).
BurninLeo
1
Anda dapat menggunakan relevel () di dalam rumus Anda, tidak akan memengaruhi kumpulan data asli ...
Mehdi Zare
36

Orang lain telah menyebutkan relevelperintah yang merupakan solusi terbaik jika Anda ingin mengubah level dasar untuk semua analisis pada data Anda (atau bersedia untuk hidup dengan mengubah data).

Jika Anda tidak ingin mengubah data (ini adalah perubahan satu kali, tetapi di masa mendatang Anda menginginkan perilaku default lagi), maka Anda dapat menggunakan kombinasi fungsi C(huruf besar catatan) untuk mengatur kontras dan contr.treatmentsfungsi dengan argumen dasar untuk memilih level mana yang ingin Anda jadikan baseline.

Sebagai contoh:

lm( Sepal.Width ~ C(Species,contr.treatment(3, base=2)), data=iris )
Greg Snow
sumber
33

The relevel()perintah adalah metode singkat untuk pertanyaan Anda. Apa yang dilakukannya adalah menyusun ulang faktor sehingga apa pun yang menjadi tingkat referensi adalah yang pertama. Oleh karena itu, menyusun ulang tingkat faktor Anda juga akan memiliki efek yang sama tetapi memberi Anda lebih banyak kendali. Mungkin Anda ingin memiliki level 3,4,0,1,2. Dalam hal itu...

bFactor <- factor(b, levels = c(3,4,0,1,2))

Saya lebih suka metode ini karena lebih mudah bagi saya untuk melihat dalam kode saya tidak hanya apa referensinya tetapi juga posisi nilai-nilai lainnya (daripada harus melihat hasil untuk itu).

CATATAN: JANGAN menjadikannya faktor yang dipesan. Faktor dengan urutan tertentu dan faktor urutan bukanlah hal yang sama. lm()mungkin mulai berpikir Anda menginginkan kontras polinomial jika Anda melakukannya.

John
sumber
2
Kontras polinomial, bukan regresi polinomial.
hadley
Apakah ada cara untuk menyetel tingkat referensi pada saat yang sama saat Anda menentukan faktor, daripada dalam panggilan berikutnya ke relevel?
David Bruce Borenstein
31

Saya tahu ini adalah pertanyaan lama, tetapi saya memiliki masalah serupa dan menemukan bahwa:

lm(x ~ y + relevel(b, ref = "3")) 

melakukan apa yang Anda minta.

Yan Alperovych
sumber
3
Ini sangat membantu! Hanya solusi yang menyertakan cara untuk melakukannya dalam perintah lm () yang persis seperti yang saya butuhkan. Terima kasih!
cparmstrong
3
Ini adalah cara yang sangat fleksibel untuk menangani faktor. Saya suka fakta bahwa saya dapat menggabungkannya as.factor()jika diperlukan, misalnya dengan menggunakan...+relevel(as.factor(mycol), ref = "myref")+...
Peter
12

Anda juga dapat memberi tag kolom secara manual dengan contrastsatribut, yang tampaknya diterapkan oleh fungsi regresi:

contrasts(df$factorcol) <- contr.treatment(levels(df$factorcol),
   base=which(levels(df$factorcol) == 'RefLevel'))
Harlan
sumber
1

Untuk mereka yang mencari versi dplyr / tidyverse. Membangun solusi Gavin Simpson:

# Create DF
set.seed(123)
x <- rnorm(100)
DF <- data.frame(x = x,
                 y = 4 + (1.5*x) + rnorm(100, sd = 2),
                 b = gl(5, 20))

# Change reference level
DF = DF %>% mutate(b = relevel(b, 3))

m2 <- lm(y ~ x + b, data = DF)
summary(m2)
Gorka
sumber
Saya bingung mengapa Anda meletakkan "Jika variabel adalah faktor" di mana Anda melakukannya ... ini perlu apakah Anda menggunakan relevel()atauforcats::fct_relevel()
Gregor Thomas
Anda benar, terima kasih! Saya menambahkan "Anda juga dapat menggunakan", karena, afaik, fct_relevel hanya berfungsi dengan faktor.
Gorka
2
relevelhanya bekerja dengan faktor-faktor. fct_relevelhanya bekerja dengan faktor-faktor. Tidak ada perbedaan apapun diantara fungsinya kecuali namanya, AFAIK. Mengatakan "Jika variabel adalah faktor, Anda juga dapat menggunakan fct_relevel" menyiratkan bahwa jika variabel tersebut bukan faktor yang dapat Anda gunakan relevel, tetapi itu tidak benar.
Gregor Thomas