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.