在具有交换行/列的两个不同数据帧上进行t检验?

时间:2018-04-18 20:56:19

标签: r subset t-test

对于令人困惑的标题感到抱歉,这个有点难以描述。基本上,我有两个看起来类似的数据表:

df1 <- data.frame(SNP=c("W", "X", "Y", "Z"),
                  Gene.ID=c("A", "B", "C", "B"), pval=NA)
df2 <- data.frame(W=c(1, 0, 1), X=c(1, 1, 0), Y=c(0, 0, 1), Z=c(1, 0, 1),
                  A=c(3.5, 2.5, 3.5), C=c(4.5, 2.5, 1.5), B=c(1.5, 2.5, 1.5))

因此df1中的所有条目都对应于df2中的列名。我的目标是用t检验中的p值填充df1 $ pval。对于df1中的每一行,我想进行t检验,比较与df1 $ SNP的值匹配的df2列,并将其与df2列匹配df1 $ Gene.ID的值。

例如,对于df1中的第一行,我想比较df2 $ W与df2 $ A,然后在df1 [1,3]内返回得到的p值。对于第二行,我将比较df2 $ X与df2 $ B并返回df1 [2,3]中的p值。换句话说,就像这样:

for (i in 1:nrow(df1)){
  test <- t.test(df2[,which(colnames(df2)==df1[i, 1]] ~ df2[,which(colnames(df2)==df1[i, 2]])
  df1[i, 3] <- test$p.value
}

但这不起作用,因为您只能使用colnames函数选择多个列名,而不只是单个列名。如何解决这个问题的建议将非常感激 - 或者如果你有一个更简单的方法,那也会很棒。

2 个答案:

答案 0 :(得分:1)

我不明白为什么你认为这不起作用 - 我认为你的代码中只有语法错误。以下代码似乎工作正常(请注意使用sapply的更改,这在R中略微更常规):

df1[, 3] <- sapply(seq_len(nrow(df1)), 
  function(i) {
    test <- t.test(
      df2[, which(colnames(df2) == df1[i, 1])],
      df2[, which(colnames(df2) == df1[i, 2])])
    test$p.value
  })

答案 1 :(得分:1)

使用which(colnames(df2)...)可能不是此处的最佳选择,因为您要做的就是选择df2df1[i,1]df1[i,2]的列名。

在R中,按名称选择列的一种方法是使用双括号:例如df2[["A"]]会检索A的{​​{1}}列,这似乎是您想要的,而且不如df2麻烦。

考虑到这一点,您可以像这样重写代码:

df2[, which(colnames(df2) == "A")]

请注意,由于for (i in 1:nrow(df1)){ test <- t.test(df2[[df1[i, 2]]] ~ df2[[df1[i, 1]]]) df1[i, 3] <- test$p.value } 的文档声明二进制变量必须位于右侧,因此我切换了df1[i, 1]df1[i, 2]

  

形式为lhs~rhs的公式,其中lhs是给出数据值的数值变量,rhs是两个给出相应组的级别的因子