R 中的自定义对比:对比系数矩阵或对比矩阵/编码方案?以及如何到达那里?
Custom contrasts in R: contrast coefficient matrix or contrast matrix / coding scheme? And how to get there?
自定义对比在分析中使用非常广泛,例如:"Do DV values at level 1 and level 3 of this three-level factor differ significantly?"
直观上,这种对比用单元格均值表示为:
c(1,0,-1)
这些对比中的一个或多个,绑定为列,形成对比系数矩阵,例如
mat = matrix(ncol = 2, byrow = TRUE, data = c(
1, 0,
0, 1,
-1, -1)
)
[,1] [,2]
[1,] 1 0
[2,] 0 1
[3,] -1 -1
然而,当涉及到运行系数矩阵指定的这些对比时,网络和书籍中有很多(显然是矛盾的)信息。我的问题是哪些信息是正确的?
声明 1:contrasts(factor) 采用系数矩阵
在某些示例中,向用户展示了可以通过 contrasts()
或 C()
函数直接使用直观的对比系数矩阵。所以它很简单:
contrasts(myFactor) <- mat
声明 2:变换系数以创建编码方案
在其他地方(例如 UCLA stats)我们被告知系数矩阵(或基矩阵)在使用前必须从系数矩阵转换为对比矩阵。这涉及对系数矩阵进行逆变换:(mat')⁻¹
,或者,在 Rish 中:
contrasts(myFactor) = solve(t(mat))
此方法需要使用截距均值的初始列填充矩阵。为了避免这种情况,一些网站建议使用可以处理非方矩阵的广义逆函数,即 MASS::ginv()
contrasts(myFactor) = ginv(t(mat))
第三个选项:预乘变换,取逆,post乘变换
再次在其他地方(例如 SPSS support 的注释),我们了解到正确的代数是:(mat'mat)-¹ mat'
暗示我创建对比矩阵的正确方法应该是:
x = solve(t(mat)%*% mat)%*% t(mat)
[,1] [,2] [,3]
[1,] 0 0 1
[2,] 1 0 -1
[3,] 0 1 -1
contrasts(myFactor) = x
我的问题是,哪个是对的? (如果我准确地解释和描述每条建议)。如何在 R 中为 lm
、lme
等指定自定义对比度?
参考文献
我可能遗漏了一些东西,但在你的三个例子中,你都以相同的方式指定了对比矩阵,即
## Note it should plural of contrast
contrasts(myFactor) = x
唯一不同的是 x
的值。
以加州大学洛杉矶分校网站的数据为例
hsb2 = read.table('http://www.ats.ucla.edu/stat/data/hsb2.csv', header=T, sep=",")
#creating the factor variable race.f
hsb2$race.f = factor(hsb2$race, labels=c("Hispanic", "Asian", "African-Am", "Caucasian"))
我们可以指定 treatment
版本的对比
contrasts(hsb2$race.f) = contr.treatment(4)
summary(lm(write ~ race.f, hsb2))
或sum
版本
contrasts(hsb2$race.f) = contr.sum(4)
summary(lm(write ~ race.f, hsb2))
或者,我们可以指定一个定制的对比度矩阵。
有关其他标准对比度,请参阅 ?contr.sum
。
物有所值....
如果您有一个具有 3 个级别(级别 A、B 和 C)的因素,并且您想要测试以下正交对比:A 与 B,以及平均值。 A 和 B vs C,你的对比代码是:
Cont1<- c(1,-1, 0)
Cont2<- c(.5,.5, -1)
如果您按照 UCLA 网站上的指示进行操作(变换系数以制定编码方案),则:
Contrasts(Variable)<- solve(t(cbind(c(1,1,1), Cont1, Cont2)))[,2:3]
那么如果您创建了两个虚拟变量,那么您的结果是相同的(例如:
Dummy1<- ifelse(Variable=="A", 1, ifelse(Variable=="B", -1, 0))
Dummy2<- ifelse(Variable=="A", .5, ifelse(Variable=="B", .5, -1))
并将它们都输入回归方程而不是你的因子,这让我倾向于认为这是正确的方法。
PS 我没有写出最优雅的 R 代码,但它完成了工作。抱歉,我相信有更简单的方法来重新编码变量,但你明白了要点。
声明 2 是正确的(参见答案 here and here),有时声明 1 也是正确的。这是因为在某些情况下(转置)系数矩阵的广义逆等于矩阵本身。
自定义对比在分析中使用非常广泛,例如:"Do DV values at level 1 and level 3 of this three-level factor differ significantly?"
直观上,这种对比用单元格均值表示为:
c(1,0,-1)
这些对比中的一个或多个,绑定为列,形成对比系数矩阵,例如
mat = matrix(ncol = 2, byrow = TRUE, data = c(
1, 0,
0, 1,
-1, -1)
)
[,1] [,2]
[1,] 1 0
[2,] 0 1
[3,] -1 -1
然而,当涉及到运行系数矩阵指定的这些对比时,网络和书籍中有很多(显然是矛盾的)信息。我的问题是哪些信息是正确的?
声明 1:contrasts(factor) 采用系数矩阵
在某些示例中,向用户展示了可以通过 contrasts()
或 C()
函数直接使用直观的对比系数矩阵。所以它很简单:
contrasts(myFactor) <- mat
声明 2:变换系数以创建编码方案
在其他地方(例如 UCLA stats)我们被告知系数矩阵(或基矩阵)在使用前必须从系数矩阵转换为对比矩阵。这涉及对系数矩阵进行逆变换:(mat')⁻¹
,或者,在 Rish 中:
contrasts(myFactor) = solve(t(mat))
此方法需要使用截距均值的初始列填充矩阵。为了避免这种情况,一些网站建议使用可以处理非方矩阵的广义逆函数,即 MASS::ginv()
contrasts(myFactor) = ginv(t(mat))
第三个选项:预乘变换,取逆,post乘变换
再次在其他地方(例如 SPSS support 的注释),我们了解到正确的代数是:(mat'mat)-¹ mat'
暗示我创建对比矩阵的正确方法应该是:
x = solve(t(mat)%*% mat)%*% t(mat)
[,1] [,2] [,3]
[1,] 0 0 1
[2,] 1 0 -1
[3,] 0 1 -1
contrasts(myFactor) = x
我的问题是,哪个是对的? (如果我准确地解释和描述每条建议)。如何在 R 中为 lm
、lme
等指定自定义对比度?
参考文献
我可能遗漏了一些东西,但在你的三个例子中,你都以相同的方式指定了对比矩阵,即
## Note it should plural of contrast
contrasts(myFactor) = x
唯一不同的是 x
的值。
以加州大学洛杉矶分校网站的数据为例
hsb2 = read.table('http://www.ats.ucla.edu/stat/data/hsb2.csv', header=T, sep=",")
#creating the factor variable race.f
hsb2$race.f = factor(hsb2$race, labels=c("Hispanic", "Asian", "African-Am", "Caucasian"))
我们可以指定 treatment
版本的对比
contrasts(hsb2$race.f) = contr.treatment(4)
summary(lm(write ~ race.f, hsb2))
或sum
版本
contrasts(hsb2$race.f) = contr.sum(4)
summary(lm(write ~ race.f, hsb2))
或者,我们可以指定一个定制的对比度矩阵。
有关其他标准对比度,请参阅 ?contr.sum
。
物有所值....
如果您有一个具有 3 个级别(级别 A、B 和 C)的因素,并且您想要测试以下正交对比:A 与 B,以及平均值。 A 和 B vs C,你的对比代码是:
Cont1<- c(1,-1, 0)
Cont2<- c(.5,.5, -1)
如果您按照 UCLA 网站上的指示进行操作(变换系数以制定编码方案),则:
Contrasts(Variable)<- solve(t(cbind(c(1,1,1), Cont1, Cont2)))[,2:3]
那么如果您创建了两个虚拟变量,那么您的结果是相同的(例如:
Dummy1<- ifelse(Variable=="A", 1, ifelse(Variable=="B", -1, 0))
Dummy2<- ifelse(Variable=="A", .5, ifelse(Variable=="B", .5, -1))
并将它们都输入回归方程而不是你的因子,这让我倾向于认为这是正确的方法。
PS 我没有写出最优雅的 R 代码,但它完成了工作。抱歉,我相信有更简单的方法来重新编码变量,但你明白了要点。
声明 2 是正确的(参见答案 here and here),有时声明 1 也是正确的。这是因为在某些情况下(转置)系数矩阵的广义逆等于矩阵本身。