#r #linear-regression
Вопрос:
Почему значения тестовой статистики имеют обратные знаки при использовании lm()
сравнения t.test()
для одной 2-факторной переменной для линейного мореля? Например, ниже:
sim_data = data.frame(
groups = c(rep("A", n / 2), rep("B", n / 2)),
values = rep(0, n))
sim_data$values = rnorm(n, mean = 42, sd = 3.5)
summary(lm(values ~ groups, data = sim_data))
t.test(values ~ groups, data = sim_data, var.equal = TRUE)
Оба t.test()
и lm()
дают одну и ту же тестовую статистику, но с разными знаками: 0,02 и -0,02. Это потому, что, например, здесь R использует группу A в качестве опорного уровня, lm()
но использует группу B в качестве опорного уровня t.test()
? Пожалуйста, просвети меня.
Комментарии:
1. Да, просто эти две функции используют разную параметризацию.
lm
Принимает A в качестве элемента управления.t.test
смотрит на разницу «между группой А и группой В» — то есть В является контролем. Статистика теста идентична, как и выводы, которые вы можете сделать.
Ответ №1:
Поскольку в справке по t.test это не обсуждается, давайте выпишем различные возможности, чтобы мы могли эмпирически определить, как он действует (или посмотрите ссылки на исходный код в комментариях).
Короткий ответ заключается в том, что мы можем заставить lm дать тот же результат, если мы используем contr.Контрасты SAS в lm (как в № 4 в разделе сравнения), которые совпадают с контрастами обработки по умолчанию, за исключением того, что последний уровень используется в качестве эталонного уровня вместо первого.
метод по умолчанию
Без метода формулы t.test
можно записать как t.test(x, y, ...)
, и статистика t, полученная в результате, представляет собой среднее значение x минус среднее значение y, деленное на стандартную ошибку, поэтому знак статистики определяется порядком, в котором x и y передаются в качестве аргументов.
# the standard error does not depend on which level is reference level
# so just get it in most convenient way
out <- t.test(values ~ groups, sim_data, var.equal = TRUE)
out$statistic
t
1.118583
stderr <- out$stderr
x <- with(sim_data, values[groups == "A"])
y <- with(sim_data, values[groups == "B"])
(mean(x) - mean(y)) / stderr
## [1] 1.118583
(mean(y) - mean(x)) / stderr
## [1] -1.118583
способ получения формулы
Если мы используем интерфейс формулы с символьным столбцом для групп, он эффективно преобразует группы в фактор с первой группой в алфавитном порядке в качестве первого аргумента и второй группой в алфавитном порядке в качестве второго аргумента.
# A is passed as the first argument to t.test.default
gA <- factor(sim_data$groups, levels = c("A", "B"))
t.test(values ~ gA, sim_data, var.equal = TRUE)$statistic
## t
## 1.118583
# B is passed as the first argument to t.test.default
gB <- factor(sim_data$groups, levels = c("B", "A"))
t.test(values ~ gB, sim_data, var.equal = TRUE)$statistic
## t
## -1.118583
лм
С помощью lm очевидно, что первый уровень эффективно передается в t.test.default в качестве второго аргумента и называется базовым или эталонным уровнем.
# A is reference level
coef(summary(lm(values ~ gA, data = sim_data)))
## Estimate Std. Error t value Pr(>|t|)
## (Intercept) 42.533345 0.8827383 48.183414 1.750263e-28
## gAB -1.396417 1.2483805 -1.118583 2.728234e-01
# B is reference level
coef(summary(lm(values ~ gB, data = sim_data)))
## Estimate Std. Error t value Pr(>|t|)
## (Intercept) 41.136929 0.8827383 46.601500 4.407622e-28
## gBA 1.396417 1.2483805 1.118583 2.728234e-01
или мы можем управлять базовым уровнем, также известным как базовый уровень, в lm, используя аргумент контрастов (или используя релевантность, как в другом ответе).:
# A is reference level (default is first level)
coef(summary(lm(values ~ groups, data = sim_data)))
## Estimate Std. Error t value Pr(>|t|)
## (Intercept) 42.533345 0.8827383 48.183414 1.750263e-28
## groupsB -1.396417 1.2483805 -1.118583 2.728234e-01
# same - groups2 in output is groups with the first level, A, as base
coef(summary(lm(values ~ groups, data = sim_data,
contrasts = list(groups = contr.treatment(2, base = 1)))))
## Estimate Std. Error t value Pr(>|t|)
## (Intercept) 42.533345 0.8827383 48.183414 1.750263e-28
## groups2 -1.396417 1.2483805 -1.118583 2.728234e-01
# change reference level - groups1 in output is groups with 2nd level, B, as base
coef(summary(lm(values ~ groups, data = sim_data,
contrasts = list(groups = contr.treatment(2, base = 2)))))
## Estimate Std. Error t value Pr(>|t|)
## (Intercept) 41.136929 0.8827383 46.601500 4.407622e-28
## groups1 1.396417 1.2483805 1.118583 2.728234e-01
# contr.SAS is like contr.treatment except last level is reference
coef(summary(lm(values ~ groups, data = sim_data,
contrasts = list(groups = contr.SAS))))
## Estimate Std. Error t value Pr(>|t|)
## (Intercept) 41.136929 0.8827383 46.601500 4.407622e-28
## groups1 1.396417 1.2483805 1.118583 2.728234e-01
Сравнение
Возможно, будет легче сравнивать, если мы напишем похожие выражения вместе. Все они дают одну и ту же статистику t.
attach(sim_data)
out <- t.test(values ~ groups, var.equal = TRUE)
stderr <- out$stderr
x <- values[groups == "A"]
y <- values[groups == "B"]
# 1
(mean(x) - mean(y)) / stderr
## 1.118583
# 2
t.test(x, y, var.equal = TRUE)$statistic
## t
## 1.118583
# 3
coef(summary(lm(values ~ groups,
contrasts = list(groups = contr.treatment(2, base = 2)))))
## Estimate Std. Error t value Pr(>|t|)
## (Intercept) 41.136929 0.8827383 46.601500 4.407622e-28
## groups1 1.396417 1.2483805 1.118583 2.728234e-01
# 4 - contr.SAS is like contr.treatment except reference level
# defaults to last, rather than first, level
coef(summary(lm(values ~ groups,
contrasts = list(groups = contr.SAS))))
## Estimate Std. Error t value Pr(>|t|)
## (Intercept) 41.136929 0.8827383 46.601500 4.407622e-28
## groups1 1.396417 1.2483805 1.118583 2.728234e-01
и все они дают одну и ту же статистику t.
# 1
(mean(y) - mean(x)) / stderr
## [1] -1.118583
# 2
t.test(y, x, var.equal = TRUE)$statistic
## t
## -1.118583
# 3
coef(summary(lm(values ~ groups,
contrasts = list(groups = contr.treatment(2, base = 1)))))
## Estimate Std. Error t value Pr(>|t|)
## (Intercept) 42.533345 0.8827383 48.183414 1.750263e-28
## groups2 -1.396417 1.2483805 -1.118583 2.728234e-01
# 4
coef(summary(lm(values ~ groups)))
## Estimate Std. Error t value Pr(>|t|)
## (Intercept) 42.533345 0.8827383 48.183414 1.750263e-28
## groupsB -1.396417 1.2483805 -1.118583 2.728234e-01
Примечание
Для воспроизводимости входных данных необходимо определить n и выдать set.seed из-за использования случайных чисел. Мы использовали:
set.seed(123)
n <- 30
sim_data <- data.frame(
groups = c(rep("A", n / 2), rep("B", n / 2)),
values = rnorm(n, mean = 42, sd = 3.5))
Комментарии:
1. Исправили предыдущую версию ответа.
2. Большое спасибо за ваш обстоятельный ответ! Возможно , подумайте о добавлении указателя на соответствующий код: например , t in
t.test.default
иsplit
int.test.formula
, где порядок результата будет зависеть от уровней факторов, которые затем передаютсяt.test.default
. Просто мысль, чтобы дополнить вашу превосходную эмпирическую демонстрацию.
Ответ №2:
вы можете задать справочную группу
sim_data$groups <- relevel(factor(sim_data$groups), ref = "B")