La caduta di una variabile nella formula lm innesca ancora l'errore di contrasto


9

Sto provando a eseguire lm () solo su un sottoinsieme dei miei dati e ho riscontrato un problema.

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)

Quanto sopra non funziona perché il set di dati ora ha solo uomini e quindi non possiamo includere x3, la variabile di genere, nel modello. MA...

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

Questo è un problema con la notazione "segno meno" nella formula? Per favore, consiglio. Nota: certo che posso farlo in un modo diverso; per esempio, potrei escludere le variabili prima di metterle in lm (). Ma sto insegnando un corso su queste cose e non voglio confondere gli studenti, avendo già detto loro che possono escludere le variabili usando un segno meno nella formula.


3
E 'interessante che sia model.matrix(y ~ . - x3, data = dt[x3 == "men"])e model.matrix(y ~ x1 + x2, data = dt[x3 == "men"])di lavoro ( lmchiamate model.matrixinternamente). L'unica differenza tra le due matrici del modello è un "contrasts"attributo (che contiene ancora x3) e che viene raccolto più avanti nella lmroutine, probabilmente causando l'errore che stai vedendo. Quindi la mia sensazione è che il problema abbia a che fare con il modo in cui model.matrixcrea e memorizza la matrice del design quando si rimuovono i termini.
Maurits Evers,

Stavo cercando di "espandere" il .per ottenere una formula semplificata, terms(y ~ . -x3, data=dt, simplify=TRUE)ma stranamente mantiene ancora x3l'attributo variabili che inciampalm
MrFlick

1
@MrFlick - sembra che l' neg.out=opzione non implementata in R potrebbe essere correlata. Dai file della guida S per terms, dove neg.out=è implementato: flag che controlla il trattamento dei termini che entrano con il segno "-". Se TRUE, i termini verranno controllati per la cancellazione e altrimenti ignorati. Se FALSO, i termini negativi verranno mantenuti (con ordine negativo).
thelatemail

1
@MauritsEvers: lmchiama model.matrixuna versione modificata dei dati. All'inizio, lmcompone e valuta l'espressione seguenti: mf <- stats::model.frame( y ~ . -x3, dt[x3=="men"], drop.unused.levels=TRUE ). Questo fa x3diventare un fattore a livello singolo. model.matrix()viene quindi chiamato mf, non i dati originali, causando l'errore che stiamo osservando.
Artem Sokolov,

Risposte:


2

L'errore che stai ricevendo è perché x3 è nel modello con un solo valore = "men"(vedi commento sotto da @Artem Sokolov)

Un modo per risolverlo è sottoinsediare in anticipo:

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)

Oppure puoi fare entrambi nello stesso passaggio:

lm( y ~ ., dt[x3 == 'men',-"x3"])

Nel complesso, questa è una buona soluzione. Una cosa da corretta è che -x3in una formula non non provoca lma pensare che si sta cercando di sottrarre la colonna. Il "non usare x3 nel modello" intento è comunicato correttamente, ma il problema è che lmle chiamate model.frame( ..., drop.unused.levels=TRUE )causando x3a diventare un fattore singolo livello, con conseguenti problemi a valle model.matrix().
Artem Sokolov,

Grazie per il chiarimento Artem Sokolov, ho preso quella spiegazione errata dalla mia risposta.
Dylan_Gomes
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.