Menjatuhkan variabel dalam rumus lm masih memicu kesalahan kontras

9

Saya mencoba menjalankan lm () hanya pada sebagian dari data saya, dan mengalami masalah.

dt = data.table(y = rnorm(100), x1 = rnorm(100), x2 = rnorm(100), x3 = as.factor(c(rep('men',50), rep('women',50)))) # sample data

lm( y ~ ., dt) # Use all x: Works
lm( y ~ ., dt[x3 == 'men']) # Use all x, limit to men: doesn't work (as expected)

Di atas tidak berfungsi karena dataset sekarang hanya memiliki laki-laki, dan oleh karena itu kami tidak dapat memasukkan x3, variabel gender, ke dalam model. TAPI...

lm( y ~ . -x3, dt[x3 == 'men']) # Exclude x3, limit to men: STILL doesn't work
lm( y ~ x1 + x2, dt[x3 == 'men']) # Exclude x3, with different notation: works great

Ini adalah masalah dengan notasi "tanda minus" dalam rumus? Tolong saran. Catatan: Tentu saja saya bisa melakukannya dengan cara yang berbeda; misalnya, saya bisa mengecualikan variabel sebelum memasukkannya ke lm (). Tapi saya mengajar kelas tentang hal ini, dan saya tidak ingin membingungkan para siswa, setelah mengatakan kepada mereka bahwa mereka dapat mengecualikan variabel menggunakan tanda minus dalam rumus.

Zhaochen He
sumber
3
Sangat menarik bahwa keduanya model.matrix(y ~ . - x3, data = dt[x3 == "men"])dan model.matrix(y ~ x1 + x2, data = dt[x3 == "men"])bekerja ( lmpanggilan model.matrixinternal). Satu-satunya perbedaan antara kedua model matriks adalah "contrasts"atribut (yang masih berisi x3) dan yang diambil kemudian dalam lmrutinitas, kemungkinan menyebabkan kesalahan yang Anda lihat. Jadi perasaan saya adalah bahwa masalah ini berkaitan dengan bagaimana model.matrixmembuat dan menyimpan matriks desain ketika menghapus persyaratan.
Maurits Evers
Saya mencoba untuk "memperluas" .untuk mendapatkan formula yang disederhanakan dengan terms(y ~ . -x3, data=dt, simplify=TRUE)tetapi anehnya masih tetap x3dalam atribut variabel yang naiklm
MrFlick
1
@MrFlick - sepertinya opsi unimplemented-in-R neg.out=mungkin terkait. Dari file bantuan S untuk terms, di mana neg.out=diimplementasikan: flag mengendalikan perlakuan istilah yang masuk dengan tanda "-". Jika BENAR, syarat akan diperiksa untuk pembatalan dan jika tidak diabaikan. Jika SALAH, istilah negatif akan dipertahankan (dengan urutan negatif).
thelatemail
1
@MauritsEvers: lmpanggilan model.matrixpada versi data yang dimodifikasi. Pada awal mula, lmmenyusun dan mengevaluasi berikut ekspresi: mf <- stats::model.frame( y ~ . -x3, dt[x3=="men"], drop.unused.levels=TRUE ). Ini menyebabkan x3menjadi faktor level tunggal. model.matrix()kemudian dipanggil mf, bukan data asli, menghasilkan kesalahan yang kami amati.
Artem Sokolov

Jawaban:

2

Kesalahan yang Anda dapatkan adalah karena x3 ada dalam model dengan hanya satu nilai = "men"(lihat komentar di bawah dari @Artem Sokolov)

Salah satu cara untuk mengatasinya adalah dengan subset sebelumnya:

dt = data.table(y = rnorm(100), x1 = rnorm(100), x2 = rnorm(100), x3 = as.factor(c(rep('men',50), rep('women',50)))) # sample data

dmen<-dt[x3 == 'men'] # create a new subsetted dataset with just men

lm( y ~ ., dmen[,-"x3"]) # now drop the x3 column from the dataset (just for the model)

Atau Anda bisa melakukan keduanya dalam langkah yang sama:

lm( y ~ ., dt[x3 == 'men',-"x3"])
Dylan_Gomes
sumber
Secara keseluruhan, ini adalah solusi yang bagus. Satu hal yang perlu diperbaiki adalah bahwa -x3dalam sebuah rumus tidak menyebabkan Anda lmberpikir bahwa Anda mencoba mengurangi kolom. Maksud "jangan gunakan x3 dalam model" dikomunikasikan dengan benar, tetapi masalahnya adalah bahwa lmpanggilan model.frame( ..., drop.unused.levels=TRUE )menyebabkan x3menjadi faktor tingkat tunggal, yang mengarah ke masalah hilir di model.matrix().
Artem Sokolov
Terima kasih atas klarifikasi Artem Sokolov, saya telah mengambil penjelasan yang salah dari jawaban saya.
Dylan_Gomes