使用切换 rows/columns 在两个不同的数据帧上执行 t-test?
Conducting a t-test across two different data frames with switched rows/columns?
抱歉,标题有点乱,这个有点难以描述。基本上,我有两个类似于此的数据表:
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-test 中的 p-values 填充 df1$pval。对于 df1 中的每一行,我想做一个 t-test 比较与 df1$SNP 的值匹配的 df2 列,并将其与与 df1$Gene.ID 的值匹配的 df2 列进行比较。
例如,对于 df1 中的第一行,我想比较 df2$W 与 df2$A,然后 return df1[1, 3 中的结果 p-value ].对于第二行,我将比较 df2$X 与 df2$B 以及 df1[2, 3] 中的 return 和 p-value。换句话说,像这样:
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
函数 select 多个列名,而不仅仅是单个列名。非常感谢有关如何解决此问题的建议——或者如果您有更简单的方法,那也很好。
我不明白为什么您认为这行不通 - 我认为您的代码中存在语法错误。下面的代码似乎工作正常(注意使用 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
})
这里使用 which(colnames(df2)...)
可能不是最佳选择,因为您要做的只是 select df2
中具有 df1[i,1]
或df1[i,2]
作为名字。
在 R 中,通过名称 select 列的一种方法是使用双括号:例如df2[["A"]]
将检索 df2
的列 A
,这似乎是你想要的,并且比 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]
,因为 t.test
的文档指出二进制变量必须在右侧。
a formula of the form lhs ~ rhs where lhs is a numeric variable giving the data values and rhs a factor with two levels giving the corresponding groups
抱歉,标题有点乱,这个有点难以描述。基本上,我有两个类似于此的数据表:
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-test 中的 p-values 填充 df1$pval。对于 df1 中的每一行,我想做一个 t-test 比较与 df1$SNP 的值匹配的 df2 列,并将其与与 df1$Gene.ID 的值匹配的 df2 列进行比较。
例如,对于 df1 中的第一行,我想比较 df2$W 与 df2$A,然后 return df1[1, 3 中的结果 p-value ].对于第二行,我将比较 df2$X 与 df2$B 以及 df1[2, 3] 中的 return 和 p-value。换句话说,像这样:
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
函数 select 多个列名,而不仅仅是单个列名。非常感谢有关如何解决此问题的建议——或者如果您有更简单的方法,那也很好。
我不明白为什么您认为这行不通 - 我认为您的代码中存在语法错误。下面的代码似乎工作正常(注意使用 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
})
这里使用 which(colnames(df2)...)
可能不是最佳选择,因为您要做的只是 select df2
中具有 df1[i,1]
或df1[i,2]
作为名字。
在 R 中,通过名称 select 列的一种方法是使用双括号:例如df2[["A"]]
将检索 df2
的列 A
,这似乎是你想要的,并且比 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]
,因为 t.test
的文档指出二进制变量必须在右侧。
a formula of the form lhs ~ rhs where lhs is a numeric variable giving the data values and rhs a factor with two levels giving the corresponding groups