Come forzare R a utilizzare un livello di fattore specificato come riferimento in una regressione?


112

Come posso dire a R di utilizzare un certo livello come riferimento se utilizzo variabili esplicative binarie in una regressione?

Sta solo usando un certo livello per impostazione predefinita.

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

con b {0, 1, 2, 3, 4}. Diciamo che voglio usare 3 invece dello zero usato da R.


9
È necessario eseguire la fase di elaborazione dei dati al di fuori della formula / adattamento del modello. Quando si crea il fattore da bè possibile specificare l'ordine dei livelli utilizzando factor(b, levels = c(3,1,2,4,5)). Fallo in una fase di elaborazione dei dati al di fuori della lm()chiamata. La mia risposta di seguito utilizza la relevel()funzione in modo da poter creare un fattore e quindi spostare il livello di riferimento in base alle esigenze.
Gavin Simpson

1
Ho riformulato la tua domanda. In realtà stai dopo aver cambiato il livello di riferimento, non tralasciandone uno.
Joris Meys

grazie per aver riformulato la mia domanda. In effetti, rilevel () era quello che stavo cercando. Grazie per la risposta dettagliata e l'esempio però. Non sono sicuro che il tag di regressione lineare sia un po 'fuorviante perché si applica a tutti i tipi di regressione che utilizzano spiegatori fittizi ...
Matt Bannert

Risposte:


152

Vedi la relevel()funzione. Ecco un esempio:

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)

Ora modificare il fattore bin DFmediante la relevel()funzione di:

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

I modelli hanno stimato diversi livelli di riferimento.

> 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

9
Per conservare la variabile originale, non usare semplicemente within, ma df$bR = relevel(df$b, ref=3).
BurninLeo

1
Puoi usare rilevel () all'interno della tua formula, non influenzerebbe il set di dati originale ...
Mehdi Zare

36

Altri hanno menzionato il relevel comando che è la soluzione migliore se vuoi cambiare il livello di base per tutte le analisi sui tuoi dati (o sei disposto a convivere con la modifica dei dati).

Se non si desidera modificare i dati (si tratta di una modifica una tantum, ma in futuro si desidera di nuovo il comportamento predefinito), è possibile utilizzare una combinazione della funzione C(nota maiuscola) per impostare i contrasti e la contr.treatmentsfunzione con l'argomento di base per la scelta del livello che si desidera essere la linea di base.

Per esempio:

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

33

Il relevel()comando è un metodo abbreviato per la tua domanda. Quello che fa è riordinare il fattore in modo che qualunque sia il livello di riferimento è il primo. Pertanto, anche il riordino dei livelli dei fattori avrà lo stesso effetto ma offre un maggiore controllo. Forse volevi avere i livelli 3,4,0,1,2. In quel caso...

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

Preferisco questo metodo perché è più facile per me vedere nel mio codice non solo quale fosse il riferimento ma anche la posizione degli altri valori (piuttosto che dover guardare i risultati per quello).

NOTA: NON renderlo un fattore ordinato. Un fattore con un ordine specificato e un fattore ordinato non sono la stessa cosa. lm()potrebbe iniziare a pensare che tu voglia contrasti polinomiali se lo fai.


2
Contrasti polinomiali, non regressione polinomiale.
Hadley

Esiste un modo per impostare il livello di riferimento nello stesso momento in cui si definisce il fattore, piuttosto che in una successiva chiamata di rilocalizzazione?
David Bruce Borenstein

31

So che questa è una vecchia domanda, ma ho avuto un problema simile e ho scoperto che:

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

fa esattamente quello che hai chiesto.


3
Questo è stato di grande aiuto! L'unica soluzione che includeva un modo per farlo all'interno del comando lm () che era esattamente ciò di cui avevo bisogno. Grazie!
cparmstrong

3
Questo è un modo molto flessibile di lavorare con i fattori. Mi piace il fatto di poterlo combinare con as.factor()se necessario, ad esempio utilizzando...+relevel(as.factor(mycol), ref = "myref")+...
Peter

12

Puoi anche taggare manualmente la colonna con un contrastsattributo, che sembra essere rispettato dalle funzioni di regressione:

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

1

Per chi cerca una versione dplyr / tidyverse. Basandosi sulla soluzione 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)

Sono confuso perché hai messo "Se la variabile è un fattore" dove l'hai fatto ... questo è necessario se usi relevel()oforcats::fct_relevel()
Gregor Thomas

Hai ragione, grazie! Ho aggiunto "puoi anche usare", perché, afaik, fct_relevel funziona solo con i fattori.
Gorka

2
relevelfunziona solo con i fattori. fct_relevelfunziona solo con i fattori. Non c'è alcuna differenza tra le funzioni tranne il nome, AFAIK. Dire "Se la variabile è un fattore puoi anche usare fct_relevel" implica che se la variabile non è un fattore potresti usare relevel, ma non è vero.
Gregor Thomas
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.