Comment forcer R à utiliser un niveau de facteur spécifié comme référence dans une régression?


112

Comment puis-je dire à R d'utiliser un certain niveau comme référence si j'utilise des variables explicatives binaires dans une régression?

Il utilise simplement un niveau par défaut.

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

avec b {0, 1, 2, 3, 4}. Disons que je veux utiliser 3 au lieu du zéro qui est utilisé par R.


9
Vous devez effectuer l'étape de traitement des données en dehors de la formule / ajustement du modèle. Lors de la création du facteur à partir de, bvous pouvez spécifier l'ordre des niveaux à l'aide de factor(b, levels = c(3,1,2,4,5)). Faites cela dans une étape de traitement des données en dehors de l' lm()appel. Ma réponse ci-dessous utilise la relevel()fonction afin que vous puissiez créer un facteur, puis décaler le niveau de référence en fonction de vos besoins.
Gavin Simpson

1
J'ai reformulé votre question. Vous êtes en fait après avoir changé le niveau de référence, sans en oublier un.
Joris Meys

merci d'avoir reformulé ma question. En effet, relevel () était ce que je recherchais. Merci pour la réponse détaillée et l'exemple. Je ne suis pas sûr que la balise de régression linéaire soit un peu trompeuse car elle s'applique à toutes sortes de régression utilisant des explications factices ...
Matt Bannert

Réponses:


152

Voir la relevel()fonction. Voici un exemple:

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)

Modifiez maintenant le facteur ben DFutilisant la relevel()fonction:

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

Les modèles ont estimé différents niveaux de référence.

> 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
Pour présélectionner la variable d'origine, n'utilisez simplement pas le within, mais df$bR = relevel(df$b, ref=3).
BurninLeo

1
Vous pouvez utiliser relevel () dans votre formule, cela n'affecterait pas l'ensemble de données d'origine ...
Mehdi Zare

36

D'autres ont mentionné la relevelcommande qui est la meilleure solution si vous souhaitez changer le niveau de base pour toutes les analyses sur vos données (ou êtes prêt à vivre avec la modification des données).

Si vous ne souhaitez pas modifier les données (il s'agit d'un changement unique, mais à l'avenir, vous souhaitez à nouveau le comportement par défaut), vous pouvez utiliser une combinaison de la fonction C(notez en majuscules) pour définir les contrastes et la contr.treatmentsfonction avec l'argument de base pour choisir le niveau que vous voulez être la ligne de base.

Par exemple:

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

33

La relevel()commande est une méthode abrégée pour votre question. Ce qu'il fait, c'est réorganiser le facteur afin que le niveau de référence soit le premier. Par conséquent, réorganiser vos niveaux de facteur aura également le même effet mais vous donnera plus de contrôle. Peut-être que vous vouliez avoir des niveaux 3,4,0,1,2. Dans ce cas...

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

Je préfère cette méthode car il est plus facile pour moi de voir dans mon code non seulement quelle était la référence mais aussi la position des autres valeurs (plutôt que d'avoir à regarder les résultats pour cela).

REMARQUE: NE PAS en faire un facteur ordonné. Un facteur avec un ordre spécifié et un facteur ordonné ne sont pas la même chose. lm()peut commencer à penser que vous voulez des contrastes polynomiaux si vous faites cela.


2
Contrastes polynomiaux, pas une régression polynomiale.
hadley

Existe-t-il un moyen de définir le niveau de référence en même temps que vous définissez le facteur, plutôt que dans un appel ultérieur à relevel?
David Bruce Borenstein

31

Je sais que c'est une vieille question, mais j'ai eu un problème similaire et j'ai trouvé que:

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

fait exactement ce que vous avez demandé.


3
C'était une grande aide! Seule solution qui comprenait un moyen de le faire dans la commande lm () qui était exactement ce dont j'avais besoin. Merci!
cparmstrong

3
C'est une manière très flexible de travailler avec les facteurs. J'aime le fait que je puisse le combiner avec as.factor()si nécessaire, par exemple en utilisant...+relevel(as.factor(mycol), ref = "myref")+...
Peter

12

Vous pouvez également baliser manuellement la colonne avec un contrastsattribut, qui semble être respecté par les fonctions de régression:

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

1

Pour ceux qui recherchent une version dplyr / tidyverse. S'appuyant sur la solution 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)

Je ne comprends pas pourquoi vous mettez "Si la variable est un facteur" là où vous l'avez fait ... c'est nécessaire que vous utilisiez relevel()ouforcats::fct_relevel()
Gregor Thomas

Vous avez raison, merci! J'ai ajouté "vous pouvez également utiliser", car, afaik, fct_relevel ne fonctionne qu'avec des facteurs.
Gorka

2
relevelne fonctionne qu'avec des facteurs. fct_relevelne fonctionne qu'avec des facteurs. Il n'y a aucune différence entre les fonctions sauf le nom, AFAIK. Dire "Si la variable est un facteur que vous pouvez également utiliser fct_relevel" implique que si la variable n'est pas un facteur, vous pouvez utiliser relevel, mais ce n'est pas vrai.
Gregor Thomas
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.