我有一张包含以下数据的表格:
ex = structure(list(A = c(482, 208, 227, 239, 783, 141), B = c(155,
69, 63, 65, 255, 25), C = c(64, 24, 28, 29, 134, 34), D = c(408,
180, 196, 207, 638, 104)), .Names = c("A", "B", "C", "D"), class = "data.frame", row.names = c("E",
"F", "G", "H", "I", "J"))
>ex
A B C D
E 482 155 64 408
F 208 69 24 180
G 227 63 28 196
H 239 65 29 207
I 783 255 134 638
J 141 25 34 104
我想为A vs B和C vs D计算所有行对的chisq.test()。这听起来很模糊,所以这里有一个具体的例子:
A B C D
E 482 155 E 64 408
F 208 69 F 24 180
A B C D
E 482 155 E 64 408
G 227 63 G 28 196
...对所有E,F,G,H,I和J对重复
使用chisq.tests()为每个表计算P值。
我已经这样做了,但它的输出是一种恼人的格式。基本上我使用combn(rownames(ex),2)
来获取对,然后写了一个经历了combn结果的lapply,从表中构造了矩阵,然后给了我矩阵的chisq。
tests = combn(rownames(ex), 2)
tests = apply(tests,2,list)
testResults = lapply(tests, function(cat){
test = unlist(cat)
AvsBm = matrix(c(ex[test[1],'A'],ex[test[2],'A'],ex[test[1],'B'],ex[test[2],'B']),nrow=2, ncol=2)
AvsBp = chisq.test(AvsBm)$p.value
CvsDm = matrix(c(ex[test[1],'C'],ex[test[2],'C'],ex[test[1],'D'],ex[test[2],'D']),nrow=2, ncol=2)
CvsDp = chisq.test(CvsDm)$p.value
a = c(test[1], test[2], AvsBp, CvsDp)
})
testResults = data.frame(do.call(rbind, testResults))
names(testResults) = c('Var1', 'Var2', 'AvsB', 'CvsD')
结果如下:
> testResults
Var1 Var2 AvsB CvsD
1 E F 0.918199692198075 0.608649272659481
2 E G 0.432572099792864 0.790459437339736
3 E H 0.358651246275942 0.723319426118104
4 E I 0.960564133271506 0.0896848347203047
5 E J 0.0144029906033956 0.0028292317888333
6 F G 0.424982446036333 0.932706790402674
7 F H 0.36295549985099 0.982958067120215
8 F I 0.968631154321032 0.0684734899837275
9 F J 0.0195800439529193 0.00302299304015596
10 G H 0.998659183486833 0.999999999999997
11 G I 0.354996420259763 0.102779771508206
12 G J 0.107030315095613 0.00460404677366423
13 H I 0.284826573788384 0.0801050087692166
14 H J 0.123057932646613 0.00332480813135708
15 I J 0.00951511015485216 0.0559833381301495
这项工作正常,但感觉它应该更容易。之后我必须对表格进行大量重新格式化,以使其成为一个漂亮的表格。 理想的格式是两个三角形表,一个用于A-vs-B,另一个用于C-vs-D。
是否有任何内置函数可以执行此类操作?
希望我的问题不要太模糊,干杯。
答案 0 :(得分:2)
您可以改用:
within(as.data.frame(t(combn(rownames(ex), 2)), stringsAsFactors=FALSE), {
CvsDp <- mapply(function(i,j)chisq.test(ex[c(i,j),c("C","D")])$p.value,V1,V2)
AvsBp <- mapply(function(i,j)chisq.test(ex[c(i,j),c("A","B")])$p.value,V1,V2)
})
结果
V1 V2 AvsBp CvsDp
1 E F 0.91819969 0.608649273
2 E G 0.43257210 0.790459437
3 E H 0.35865125 0.723319426
4 E I 0.96056413 0.089684835
5 E J 0.01440299 0.002829232
6 F G 0.42498245 0.932706790
7 F H 0.36295550 0.982958067
8 F I 0.96863115 0.068473490
9 F J 0.01958004 0.003022993
10 G H 0.99865918 1.000000000
11 G I 0.35499642 0.102779772
12 G J 0.10703032 0.004604047
13 H I 0.28482657 0.080105009
14 H J 0.12305793 0.003324808
15 I J 0.00951511 0.055983338
编辑:作为三角表,给定x
=以上结果:
m <- matrix(nrow=nrow(ex), ncol=nrow(ex))
rownames(m) <- colnames(m) <- rownames(ex)
m[cbind(x$V1,x$V2)] <- x$AvsBp
结果
E F G H I J
E NA 0.9181997 0.4325721 0.3586512 0.9605641 0.01440299
F NA NA 0.4249824 0.3629555 0.9686312 0.01958004
G NA NA NA 0.9986592 0.3549964 0.10703032
H NA NA NA NA 0.2848266 0.12305793
I NA NA NA NA NA 0.00951511
J NA NA NA NA NA NA
对于CvsDp
,只需在最后一行替换它。
答案 1 :(得分:1)
这是另一种选择:
步骤1:创建一个空矩阵和您正在查看的列组合的list
A <- list(c("A", "B"), c("C", "D"))
A2 <- sapply(A, paste, collapse = "vs")
myMat <- matrix(NA, nrow = nrow(ex), ncol = nrow(ex),
dimnames = list(rownames(ex), rownames(ex)))
第2步:使用FUN
的{{1}}参数从combn
获取“p.values”的向量。这将导致2行乘15列矩阵。
chisq.test
第3步:使用csTest <- combn(rownames(ex), 2, FUN=function(y) {
sapply(A, function(z) {
chisq.test(ex[y, z])$p.value
})
})
将lapply
两行创建为list
。利用matrix
自动填写矩阵。
lower.tri