Wie kann man R zwingen, eine bestimmte Faktorstufe als Referenz in einer Regression zu verwenden?

112

Wie kann ich R anweisen, eine bestimmte Ebene als Referenz zu verwenden, wenn ich binäre erklärende Variablen in einer Regression verwende?

Standardmäßig wird nur ein Level verwendet.

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

mit b {0, 1, 2, 3, 4}. Angenommen, ich möchte 3 anstelle der von R verwendeten Null verwenden.

Matt Bannert
quelle
9
Sie sollten den Datenverarbeitungsschritt außerhalb der Modellformel / -anpassung ausführen. Beim Erstellen des Faktors aus können bSie die Reihenfolge der Ebenen mit festlegen factor(b, levels = c(3,1,2,4,5)). Tun Sie dies jedoch in einem Datenverarbeitungsschritt außerhalb des lm()Anrufs. Meine Antwort unten verwendet die relevel()Funktion, damit Sie einen Faktor erstellen und dann den Referenzpegel nach Bedarf verschieben können.
Gavin Simpson
1
Ich habe Ihre Frage umformuliert. Sie sind tatsächlich nach dem Ändern des Referenzpegels und lassen keinen aus.
Joris Meys
Danke, dass du meine Frage umformuliert hast. In der Tat war relevel () das, wonach ich gesucht habe. Vielen Dank für die ausführliche Antwort und das Beispiel. Ich bin nicht sicher, ob das lineare Regressions-Tag etwas irreführend ist, da dies für alle Arten von Regression mit Dummy-Erklärungen gilt ...
Matt Bannert

Antworten:

152

Siehe die relevel()Funktion. Hier ist ein Beispiel:

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)

Nun ändern Sie den Faktor bin DFdurch die Verwendung der relevel()Funktion:

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

Die Modelle haben unterschiedliche Referenzwerte geschätzt.

> 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
quelle
9
Um die ursprüngliche Variable zu erhalten, verwenden Sie einfach nicht das within, aber df$bR = relevel(df$b, ref=3).
BurninLeo
1
Sie können relevel () in Ihrer Formel verwenden, ohne den ursprünglichen Datensatz zu beeinflussen ...
Mehdi Zare
36

Andere haben den relevelBefehl erwähnt, der die beste Lösung ist, wenn Sie die Basisebene für alle Analysen Ihrer Daten ändern möchten (oder bereit sind, mit dem Ändern der Daten zu leben).

Wenn Sie die Daten nicht ändern möchten (dies ist eine einmalige Änderung, aber in Zukunft möchten Sie wieder das Standardverhalten), können Sie eine Kombination der CFunktion (Großbuchstaben beachten) verwenden, um Kontraste und die contr.treatmentsFunktion mit festzulegen Das Basisargument für die Auswahl der Ebene, die Sie als Basis verwenden möchten.

Beispielsweise:

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

Der relevel()Befehl ist eine Kurzmethode für Ihre Frage. Was es tut, ist den Faktor neu zu ordnen, so dass, was auch immer die Ref-Stufe ist, zuerst ist. Daher hat die Neuordnung Ihrer Faktorstufen ebenfalls den gleichen Effekt, bietet Ihnen jedoch mehr Kontrolle. Vielleicht wollten Sie Level 3,4,0,1,2 haben. In diesem Fall...

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

Ich bevorzuge diese Methode, weil ich in meinem Code nicht nur die Referenz, sondern auch die Position der anderen Werte leichter erkennen kann (anstatt mir die Ergebnisse dafür ansehen zu müssen).

HINWEIS: Machen Sie es NICHT zu einem geordneten Faktor. Ein Faktor mit einer bestimmten Reihenfolge und ein geordneter Faktor sind nicht dasselbe. lm()Vielleicht denken Sie, Sie wollen Polynomkontraste, wenn Sie das tun.

John
quelle
2
Polynomkontraste, keine Polynomregression.
Hadley
Gibt es eine Möglichkeit, den Referenzpegel zur gleichen Zeit festzulegen, zu der Sie den Faktor definieren, anstatt in einem nachfolgenden Aufruf zum erneuten Leveln?
David Bruce Borenstein
31

Ich weiß, dass dies eine alte Frage ist, aber ich hatte ein ähnliches Problem und stellte fest, dass:

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

macht genau das, was du gefragt hast.

Yan Alperovych
quelle
3
Das war eine große Hilfe! Einzige Lösung, die eine Möglichkeit enthielt, dies innerhalb des Befehls lm () zu tun, was genau das war, was ich brauchte. Vielen Dank!
cparmstrong
3
Dies ist eine sehr flexible Art, mit Faktoren zu arbeiten. Ich mag die Tatsache, dass ich es bei as.factor()Bedarf mit kombinieren kann , zum Beispiel mit...+relevel(as.factor(mycol), ref = "myref")+...
Peter
12

Sie können die Spalte auch manuell mit einem contrastsAttribut versehen, das von den Regressionsfunktionen berücksichtigt zu werden scheint:

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

Für diejenigen, die eine dplyr / tidyverse Version suchen. Aufbauend auf der Lösung von 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
quelle
Ich bin verwirrt, warum Sie "Wenn die Variable ein Faktor ist" dort setzen, wo Sie es getan haben ... dies ist notwendig, ob Sie relevel()oderforcats::fct_relevel()
Gregor Thomas
Sie haben Recht, danke! Ich habe "Sie können auch verwenden" hinzugefügt, da fct_relevel afaik nur mit Faktoren funktioniert.
Gorka
2
relevelfunktioniert nur mit Faktoren. fct_relevelfunktioniert nur mit Faktoren. Es gibt keinen Unterschied zwischen den Funktionen außer dem Namen AFAIK. Sagen : „Wenn die Variable ein Faktor ist , können Sie auch fct_relevel“ impliziert , dass , wenn die Variable ist kein Faktor könnte man verwenden relevel, aber das ist nicht wahr.
Gregor Thomas