1

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

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)得到这些对,然后写了一个经过组合结果的 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。

有没有做这种事情的内置函数?

希望我的问题不是太含糊,干杯。

4

2 回答 2

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最后一行替换它。

于 2013-09-12T17:34:32.127 回答
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参数 forcombn从 中获取“p.values”向量chisq.test。这将产生一个 2 行 x 15 列的矩阵。

csTest <- combn(rownames(ex), 2, FUN=function(y) {
  sapply(A, function(z) {
    chisq.test(ex[y, z])$p.value
  })
})

第 3 步:用于将两行中的 alapply创建为. 利用来自动填充矩阵。listmatrixlower.tri

setNames(lapply(sequence(nrow(csTest)), function(y) {
  myMat[lower.tri(myMat)] <- csTest[y, ]
  myMat
}), A2)
# $AvsB
#            E          F         G         H          I  J
# E         NA         NA        NA        NA         NA NA
# F 0.91819969         NA        NA        NA         NA NA
# G 0.43257210 0.42498245        NA        NA         NA NA
# H 0.35865125 0.36295550 0.9986592        NA         NA NA
# I 0.96056413 0.96863115 0.3549964 0.2848266         NA NA
# J 0.01440299 0.01958004 0.1070303 0.1230579 0.00951511 NA
# 
# $CvsD
#             E           F           G           H          I  J
# E          NA          NA          NA          NA         NA NA
# F 0.608649273          NA          NA          NA         NA NA
# G 0.790459437 0.932706790          NA          NA         NA NA
# H 0.723319426 0.982958067 1.000000000          NA         NA NA
# I 0.089684835 0.068473490 0.102779772 0.080105009         NA NA
# J 0.002829232 0.003022993 0.004604047 0.003324808 0.05598334 NA
于 2013-09-12T18:50:30.760 回答