列联表表

时间:2013-09-12 17:09:18

标签: r lapply contingency

我有一张包含以下数据的表格:

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。

是否有任何内置函数可以执行此类操作?

希望我的问题不要太模糊,干杯。

2 个答案:

答案 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