Jak zmusić R do używania określonego poziomu czynnika jako odniesienia w regresji?

112

Jak mogę powiedzieć R, aby używał określonego poziomu jako odniesienia, jeśli używam binarnych zmiennych objaśniających w regresji?

Po prostu domyślnie używa jakiegoś poziomu.

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

z b {0, 1, 2, 3, 4} . Powiedzmy, że chcę użyć 3 zamiast zera używanego przez R.

Matt Bannert
źródło
9
Krok przetwarzania danych należy wykonać poza formułą / dopasowaniem modelu. Podczas tworzenia współczynnika z bmożesz określić kolejność poziomów za pomocą factor(b, levels = c(3,1,2,4,5)). Zrób to jednak na etapie przetwarzania danych poza lm()wywołaniem. Moja odpowiedź poniżej wykorzystuje relevel()funkcję, dzięki czemu możesz utworzyć współczynnik, a następnie zmienić poziom odniesienia, aby dopasować go do potrzeb.
Gavin Simpson
1
Przeformułowałem twoje pytanie. W rzeczywistości zmieniasz poziom odniesienia, nie pomijając go.
Joris Meys
dzięki za przeformułowanie mojego pytania. Rzeczywiście, szukałem reportel (). Dzięki za szczegółową odpowiedź i przykład. Nie jestem pewien, czy tag regresji liniowej jest trochę mylący, ponieważ dotyczy to wszystkich rodzajów regresji z użyciem fałszywych wyjaśnień ...
Matt Bannert,

Odpowiedzi:

152

Zobacz relevel()funkcję. Oto przykład:

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)

Teraz zmienia współczynnik bw DFprzy korzystaniu z relevel()funkcji:

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

W modelach oszacowano różne poziomy odniesienia.

> 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
źródło
9
Aby wstępnie ustawić oryginalną zmienną, po prostu nie używaj within, ale df$bR = relevel(df$b, ref=3).
BurninLeo
1
W formule można użyć funkcji relevel (), która nie wpłynie na oryginalny zestaw danych ...
Mehdi Zare
36

Inni wspominali o relevelpoleceniu, które jest najlepszym rozwiązaniem, jeśli chcesz zmienić poziom podstawowy dla wszystkich analiz na swoich danych (lub chcesz żyć ze zmianą danych).

Jeśli nie chcesz zmieniać danych (jest to jednorazowa zmiana, ale w przyszłości chcesz ponownie zachować domyślne zachowanie), możesz użyć kombinacji funkcji C(uwaga wielkie litery), aby ustawić kontrast icontr.treatments funkcji z podstawowy argument do wyboru poziomu, który ma być linią bazową.

Na przykład:

lm( Sepal.Width ~ C(Species,contr.treatment(3, base=2)), data=iris )
Greg Snow
źródło
33

relevel()Komenda jest metodą skróconą do Twojego pytania. To, co robi, to zmiana kolejności współczynnika, tak aby poziom odniesienia był pierwszy. Dlatego zmiana kolejności poziomów współczynników również będzie miała ten sam efekt, ale zapewnia większą kontrolę. Być może chciałeś mieć poziomy 3,4,0,1,2. W tym wypadku...

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

Wolę tę metodę, ponieważ łatwiej jest mi zobaczyć w kodzie nie tylko, jakie było odniesienie, ale także położenie innych wartości (zamiast patrzeć na wyniki).

UWAGA: NIE czyń tego zamówionym czynnikiem. Czynnik o określonej kolejności i zamówiony czynnik to nie to samo. lm()możesz zacząć myśleć, że chcesz kontrastów wielomianowych, jeśli to zrobisz.

Jan
źródło
2
Kontrasty wielomianowe, a nie regresja wielomianowa.
hadley
Czy istnieje sposób na ustawienie poziomu odniesienia w tym samym czasie, w którym definiujesz współczynnik, a nie w kolejnym wywołaniu reglamentowania?
David Bruce Borenstein
31

Wiem, że to stare pytanie, ale miałem podobny problem i stwierdziłem, że:

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

robi dokładnie to, o co prosiłeś.

Yan Alperovych
źródło
3
To była duża pomoc! Jedyne rozwiązanie, które zawierało sposób na zrobienie tego za pomocą polecenia lm (), czego dokładnie potrzebowałem. Dzięki!
cparmstrong
3
To bardzo elastyczny sposób pracy z czynnikami. Podoba mi się to, że mogę to połączyć w as.factor()razie potrzeby, na przykład używając...+relevel(as.factor(mycol), ref = "myref")+...
Peter
12

Możesz również ręcznie oznaczyć kolumnę contrastsatrybutem, który wydaje się być uwzględniany przez funkcje regresji:

contrasts(df$factorcol) <- contr.treatment(levels(df$factorcol),
   base=which(levels(df$factorcol) == 'RefLevel'))
Harlan
źródło
1

Dla tych, którzy szukają wersji dplyr / tidyverse. Opierając się na rozwiązaniu Gavina Simpsona:

# 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
źródło
Jestem zdezorientowany, dlaczego umieściłeś „Jeśli zmienna jest czynnikiem” tam, gdzie zrobiłeś ... jest to konieczne, niezależnie od tego, czy używasz, relevel()czyforcats::fct_relevel()
Gregor Thomas
Masz rację, dzięki! Dodałem „możesz też użyć”, ponieważ afaik, fct_relevel działa tylko z czynnikami.
Gorka
2
releveldziała tylko z czynnikami. fct_releveldziała tylko z czynnikami. Nie ma żadnej różnicy między funkcjami poza nazwą AFAIK. Powiedzenie „Jeśli zmienna jest czynnikiem, którego możesz również użyć fct_relevel” oznacza, że ​​jeśli zmienna nie jest czynnikiem , którego możesz użyć relevel, ale to nieprawda.
Gregor Thomas