Das Löschen einer Variablen in der lm-Formel löst immer noch einen Kontrastfehler aus

9

Ich versuche, lm () nur für eine Teilmenge meiner Daten auszuführen und stoße auf ein Problem.

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)

Dies funktioniert nicht, da der Datensatz nur noch Männer enthält und wir daher x3, die Geschlechtsvariable, nicht in das Modell aufnehmen können. ABER...

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

Dies ist ein Problem mit der "Minuszeichen" -Notation in der Formel? Bitte beraten. Hinweis: Natürlich kann ich es auch anders machen. Zum Beispiel könnte ich die Variablen ausschließen, bevor ich sie in lm () setze. Aber ich unterrichte eine Klasse über dieses Zeug, und ich möchte die Schüler nicht verwirren, da ich ihnen bereits gesagt habe, dass sie Variablen mit einem Minuszeichen in der Formel ausschließen können.

Zhaochen He
quelle
3
Es ist interessant, dass beide model.matrix(y ~ . - x3, data = dt[x3 == "men"])und model.matrix(y ~ x1 + x2, data = dt[x3 == "men"])arbeiten ( lmAnrufe model.matrixintern). Der einzige Unterschied zwischen beiden Modellmatrizen besteht in einem "contrasts"Attribut (das noch enthält x3), das später in der lmRoutine erfasst wird und wahrscheinlich den angezeigten Fehler verursacht. Mein Gefühl ist also, dass das Problem damit zu tun hat, wie model.matrixdie Designmatrix beim Entfernen von Begriffen erstellt und gespeichert wird.
Maurits Evers
Ich habe versucht, das zu "erweitern" ., um eine vereinfachte Formel zu erhalten, terms(y ~ . -x3, data=dt, simplify=TRUE)aber seltsamerweise bleibt es immer noch x3im Variablenattribut, das lm
ausgelöst wird
1
@ MrFlick - Es sieht so aus, als ob die neg.out=Option " Nicht implementiert in R" verwandt sein könnte. Aus den S-Hilfedateien für terms, wo neg.out=implementiert: Flag, das die Behandlung von Begriffen steuert, die mit dem Zeichen "-" eingegeben werden. Wenn TRUE, werden die Bedingungen auf Stornierung überprüft und ansonsten ignoriert. Bei FALSE bleiben negative Begriffe erhalten (mit negativer Reihenfolge).
E-Mail vom
1
@MauritsEvers: lmAnrufe model.matrixauf einer modifizierten Version der Daten. lmVerfasst und bewertet zu Beginn den folgenden Ausdruck : mf <- stats::model.frame( y ~ . -x3, dt[x3=="men"], drop.unused.levels=TRUE ). Dies führt x3zu einem einstufigen Faktor. model.matrix()wird dann aufgerufen mf, nicht die Originaldaten, was zu dem Fehler führt, den wir beobachten.
Artem Sokolov

Antworten:

2

Der Fehler, den Sie erhalten, ist, dass x3 im Modell mit nur einem Wert = ist "men"(siehe Kommentar unten von @Artem Sokolov)

Eine Möglichkeit, dies zu lösen, besteht darin, im Voraus eine Teilmenge zu erstellen:

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)

Oder Sie können beides im selben Schritt tun:

lm( y ~ ., dt[x3 == 'men',-"x3"])
Dylan_Gomes
quelle
Insgesamt ist dies eine schöne Lösung. Eine Sache, die korrigiert werden muss, ist, dass -x3in einer Formel nicht der Eindruck entsteht lm, dass Sie versuchen, die Spalte zu subtrahieren. Die Absicht "x3 nicht im Modell verwenden" wird korrekt kommuniziert, aber das Problem ist, dass lmAnrufe, die model.frame( ..., drop.unused.levels=TRUE )dazu führen x3, dass sie zu einem einstufigen Faktor werden, zu Downstream-Problemen führen model.matrix().
Artem Sokolov
Vielen Dank für die Klarstellung Artem Sokolov, ich habe diese falsche Erklärung aus meiner Antwort genommen.
Dylan_Gomes