对于令人困惑的标题感到抱歉,这个有点难以描述。基本上,我有两个看起来类似的数据表:
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
函数选择多个列名,而不只是单个列名。如何解决这个问题的建议将非常感激 - 或者如果你有一个更简单的方法,那也会很棒。
答案 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)...)
可能不是此处的最佳选择,因为您要做的就是选择df2
或df1[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是两个给出相应组的级别的因子