问题描述
请考虑以下名为mydata
的数据框。
id s1 s2 s3 t1 t2 t3
1 1 0 0 0 1 0
2 0 0 1 0 0 1
3 1 0 0 1 0 0
4 0 1 0 0 1 0
5 0 1 0 1 0 0
6 0 0 1 0 0 1
7 0 0 1 0 1 0
8 1 0 0 0 0 1
9 0 1 0 0 0 1
10 0 0 1 0 0 1
我的意图是获取给定t_i
的每个s_i
的条件比例。例如,给定t1
的{{1}}的条件比例计算为:s1
。因此,我想使用(no of s1==1 & t1==1)/(no of s1==1) = 1/3
中的for循环对所有可能的组合重复此操作。
我们非常感谢您的帮助。 Tnx!
解决方法
我们展示了如何通过使用矩阵数学而不循环的方式做到这一点,并且在特殊情况下确实使用了回归方法解决了问题中显示的示例输入。
将s列作为矩阵矩阵,将t列作为矩阵矩阵。然后使用显示的矩阵表达式,并可选地添加行名。
nms <- names(mydata)
is <- startsWith(nms,"s")
it <- startsWith(nms,"t")
mats <- as.matrix(mydata[is])
matt <- as.matrix(mydata[it])
crossprod(mats,matt) / colSums(mats)
给予:
t1 t2 t3
s1 0.3333333 0.3333333 0.3333333
s2 0.3333333 0.3333333 0.3333333
s3 0.0000000 0.2500000 0.7500000
仔细检查一下,上述矩阵中的s1 / t1单元格是问题中的1/3。
正交垫子
在这个问题中,s列的每一行中恰好有一个1,如果这是一般情况(通常我们只需要使mats的列正交),则可以将结果作为的回归系数来获得以下回归:
coef( lm(cbind(t1,t2,t3) ~ s1 + s2 + s3 + 0,mydata))
给予:
t1 t2 t3
s1 3.333333e-01 0.3333333 0.3333333
s2 3.333333e-01 0.3333333 0.3333333
s3 5.551115e-17 0.2500000 0.7500000
或等效方式(行名稍有不同除外):
coef(lm(matt ~ mats + 0))
或
solve(crossprod(mats),crossprod(mats,matt))
注意
以可复制形式输入的mydata假定为:
Lines <- "
id s1 s2 s3 t1 t2 t3
1 1 0 0 0 1 0
2 0 0 1 0 0 1
3 1 0 0 1 0 0
4 0 1 0 0 1 0
5 0 1 0 1 0 0
6 0 0 1 0 0 1
7 0 0 1 0 1 0
8 1 0 0 0 0 1
9 0 1 0 0 0 1
10 0 0 1 0 0 1"
mydata <- read.table(text = Lines,header = TRUE)
,
我们可以使用Map
Map(function(x,y) (x & y)/sum(y),mydata[startsWith(names(mydata),'t')],'s')])