如何在R的回归分析中设置变量的对比?

时间:2016-10-01 02:28:52

标签: r regression linear-regression glm lm

在编码期间,我需要更改分配给因子的虚拟值。但是,以下代码不起作用。有什么建议吗?

test_mx= data.frame(a= c(T,T,T,F,F,F), b= c(1,1,1,0,0,0))
test_mx
      a b
1  TRUE 1
2  TRUE 1
3  TRUE 1
4 FALSE 0
5 FALSE 0
6 FALSE 0

model= glm(b ~ a, data= test_mx, family= "binomial")
summary(model)

model= glm(a ~ b, data= test_mx, family= "binomial")
summary(model)

这里我将得到b的coef为47.现在,如果我交换虚拟值,那么它应该是-47。然而,这种情况并非如此。

test_mx2= test_mx
contrasts(test_mx2$a)
      TRUE
FALSE    0
TRUE     1
contrasts(test_mx2$a) = c(1,0)
contrasts(test_mx2$a)
      [,1]
FALSE    1
TRUE     0
model= glm(a ~ b, data= test_mx2, family= "binomial")
summary(model)

对于b的系数仍然相同。到底是怎么回事?感谢。

2 个答案:

答案 0 :(得分:4)

关于你的问题有几个令人困惑的事情。您已经同时使用了taglib uria ~ b,那么您到底在想什么呢?

  • 对比仅适用于协变量/自变量,因为它与模型矩阵的构建有关;因此,对于b ~ a,对比应该应用于a ~ b,而对于b,对比应该应用于b ~ a;
  • 对比仅适用于因子/逻辑变量,而不适用于数值变量。因此,除非您将a作为一个因素,否则您无法与之形成对比。

在不更改数据类型的情况下,很明显只有模型b才能进一步讨论。在下文中,我将展示如何设置b ~ a的对比度。

方法1:使用acontrasts的{​​{1}}参数

我们可以通过glm的{​​{1}}参数来控制对比度处理(lm也是如此):

contrasts

此处,glm正在生成对比矩阵:

lm

并将它们传递给## dropping the first factor level (default) coef(glm(b ~ a, data = test_mx, family = binomial(), contrasts = list(a = contr.treatment(n = 2, base = 1)))) #(Intercept) a2 # -24.56607 49.13214 ## dropping the second factor level coef(glm(b ~ a, data = test_mx, family = binomial(), contrasts = list(a = contr.treatment(n = 2, base = 2)))) #(Intercept) a1 # 24.56607 -49.13214 以有效地更改contr.treatment的行为。让我们比较两种情况的模型矩阵:

contr.treatment(n = 2, base = 1)
#  2
#1 0
#2 1

contr.treatment(n = 2, base = 2)
#  1
#1 1
#2 0

glm的第二列只是model.matrix.defaultmodel.matrix.default( ~ a, test_mx, contrasts.arg = list(a = contr.treatment(n = 2, base = 1))) # (Intercept) a2 #1 1 1 #2 1 1 #3 1 1 #4 1 0 #5 1 0 #6 1 0 model.matrix.default( ~ a, test_mx, contrasts.arg = list(a = contr.treatment(n = 2, base = 2))) # (Intercept) a1 #1 1 0 #2 1 0 #3 1 0 #4 1 1 #5 1 1 #6 1 1 之间的翻转,这是您对虚拟变量的期望。

方法2:直接将“对比”属性设置为数据框

我们可以使用a0设置“对比”属性(1仅用于设置,但C也可用于查看):< / p>

contrasts

现在我们可以在不使用C参数的情况下使用contrasts

test_mx2 <- test_mx
contrasts(test_mx2$a) <- contr.treatment(n = 2, base = 1)
str(test_mx2)
#'data.frame':  6 obs. of  2 variables:
# $ a: Factor w/ 2 levels "FALSE","TRUE": 2 2 2 1 1 1
#  ..- attr(*, "contrasts")= num [1:2, 1] 0 1
#  .. ..- attr(*, "dimnames")=List of 2
#  .. .. ..$ : chr  "FALSE" "TRUE"
#  .. .. ..$ : chr "2"
# $ b: num  1 1 1 0 0 0

test_mx3 <- test_mx
contrasts(test_mx3$a) <- contr.treatment(n = 2, base = 2)
str(test_mx3)
#'data.frame':  6 obs. of  2 variables:
# $ a: Factor w/ 2 levels "FALSE","TRUE": 2 2 2 1 1 1
#  ..- attr(*, "contrasts")= num [1:2, 1] 1 0
#  .. ..- attr(*, "dimnames")=List of 2
#  .. .. ..$ : chr  "FALSE" "TRUE"
#  .. .. ..$ : chr "1"
# $ b: num  1 1 1 0 0 0

方法3:为全局变更设置glm

Hahaha,@ BenBolker还提到了另一种选择,即通过设置R的全局选项。对于具有仅涉及两个级别的因子的具体示例,我们可以使用contrasts

coef(glm(b ~ a, data = test_mx2, family = "binomial"))
#(Intercept)          a2 
#  -24.56607    49.13214 

coef(glm(b ~ a, data = test_mx3, family = "binomial"))
#(Intercept)          a1 
#   24.56607   -49.13214 

但我相信Ben只是提到了这一点来完成图片;他不会在实际中采用这种方式,因为改变全局选项不利于获得可重现的R代码。

另一个问题是options("contrasts")只会将最后一个因素级别视为参考。在你的特殊情况下只有2个级别,这实际上是“翻转”。

方法4:手动重新编码因子级别

我无意提及这一点,因为它是如此微不足道,但由于我添加了“方法3”,我最好也添加这个。

?contr.SAS

答案 1 :(得分:0)

正如哲源所指出的,对比度仅控制分类预测值(x值)的虚拟值赋值,而不控制glm建模中的分类响应(y值)。我已将此问题报告给R核心团队。

要为预测变量手动分配虚拟值,另一种方法可以是矢量/矩阵直接分配,例如

contrasts(test_mx$a) = c(1,0)

但是,存在这样的风险:如果在代码中稍后您尝试使用test_mx$a作为建模中的响应值,则虚拟值赋值可能会令人困惑,因为那里的赋值将不匹配 contrasts(test_mx$a)