Как заставить R использовать указанный факторный уровень в качестве ссылки в регрессии?

112

Как я могу сказать R использовать определенный уровень в качестве эталона, если я использую двоичные независимые переменные в регрессии?

Просто по умолчанию используется какой-то уровень.

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

с b {0, 1, 2, 3, 4}. Скажем, я хочу использовать 3 вместо нуля, который используется R.

Мэтт Баннерт
источник
9
Вы должны выполнить этап обработки данных вне формулы / подбора модели. При создании коэффициента из bвы можете указать порядок уровней с помощью factor(b, levels = c(3,1,2,4,5)). Однако сделайте это на этапе обработки данных вне lm()вызова. В моем ответе ниже используется relevel()функция, поэтому вы можете создать коэффициент, а затем сместить опорный уровень в соответствии с вашими потребностями.
Гэвин Симпсон
1
Я перефразировал ваш вопрос. Фактически вы меняете контрольный уровень, а не упускаете ни одного.
Джорис Мейс
спасибо за переформулировку моего вопроса. Действительно, я искал relvel (). Спасибо за подробный ответ и пример. Я не уверен, вводит ли тег линейной регрессии в заблуждение, потому что он применим ко всем видам регрессии с использованием фиктивных пояснений ...
Мэтт Баннерт

Ответы:

152

Смотрите relevel()функцию. Вот пример:

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)

Теперь изменим фактор bв DFпри использовании relevel()функции:

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

Модели оценили различные референтные уровни.

> 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
Чтобы сохранить исходную переменную, просто не используйте within, но df$bR = relevel(df$b, ref=3).
BurninLeo
1
Вы можете использовать relvel () внутри своей формулы, это не повлияет на исходный набор данных ...
Мехди Заре
36

Другие упомянули relevelкоманду, которая является лучшим решением, если вы хотите изменить базовый уровень для всех анализов ваших данных (или готовы жить с изменением данных).

Если вы не хотите изменять данные (это однократное изменение, но в будущем вам снова понадобится поведение по умолчанию), вы можете использовать комбинацию функции C(обратите внимание на верхний регистр) для установки контрастов и contr.treatmentsфункции с базовый аргумент для выбора, какой уровень вы хотите использовать в качестве базового.

Например:

lm( Sepal.Width ~ C(Species,contr.treatment(3, base=2)), data=iris )
Грег Сноу
источник
33

Команда relevel()- это сокращенный метод ответа на ваш вопрос. Что он делает, так это переупорядочивает множитель так, чтобы первым был уровень ссылки. Следовательно, изменение порядка уровней факторов также будет иметь тот же эффект, но даст вам больше контроля. Возможно, вы хотели иметь уровни 3,4,0,1,2. В таком случае...

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

Я предпочитаю этот метод, потому что мне легче увидеть в моем коде не только ссылку, но и положение других значений (вместо того, чтобы смотреть на результаты для этого).

ПРИМЕЧАНИЕ: НЕ делайте это упорядоченным фактором. Фактор с указанным порядком и упорядоченный коэффициент - это не одно и то же. lm()может начать думать, что вам нужны полиномиальные контрасты, если вы это сделаете.

Джон
источник
2
Полиномиальные контрасты, а не полиномиальная регрессия.
Хэдли 06
Есть ли способ установить контрольный уровень одновременно с определением фактора, а не при последующем вызове повторного выравнивания?
Дэвид Брюс Боренштейн
31

Я знаю, что это старый вопрос, но у меня была аналогичная проблема, и я обнаружил, что:

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

делает именно то, что вы просили.

Ян Альперович
источник
3
Это было большим подспорьем! Единственное решение, которое включало способ сделать это с помощью команды lm (), что было именно тем, что мне было нужно. Спасибо!
cparmstrong
3
Это очень гибкий способ работы с факторами. Мне нравится тот факт, что я могу комбинировать его, as.factor()если нужно, например, используя...+relevel(as.factor(mycol), ref = "myref")+...
Питер
12

Вы также можете вручную пометить столбец contrastsатрибутом, который, похоже, соблюдается функциями регрессии:

contrasts(df$factorcol) <- contr.treatment(levels(df$factorcol),
   base=which(levels(df$factorcol) == 'RefLevel'))
Харлан
источник
1

Для тех, кто ищет версию dplyr / tidyverse. Основываясь на решении Гэвина Симпсона:

# 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)
Горка
источник
Я не понимаю, почему вы указали «Если переменная является фактором» там, где вы это сделали ... это необходимо независимо от того, используете ли вы relevel()илиforcats::fct_relevel()
Грегор Томас
Вы правы, спасибо! Я добавил «вы также можете использовать», потому что afaik, fct_relevel работает только с факторами.
Горка
2
relevelработает только с факторами. fct_relevelработает только с факторами. Между функциями нет никакой разницы, кроме названия, AFAIK. Высказывание «Если переменная является фактором, который вы также можете использовать fct_relevel» подразумевает, что если переменная не является фактором, который вы можете использовать relevel, но это неверно.
Грегор Томас