我希望有一个通用函数,可以使用以下示例数据对数据框中的数据执行多个t.tests:
dat <- data.frame(ID=c(1:100),
DRUG= rep(c("D1","D2","D2","D3","D3","D3","D5","D1","D4","D2"),10),
ADR=rep(c("A1","A2","A3","A6","A7","A8","A4","A2","A1","A2"),10),
X= sample(1:250, 100, replace=F))
基本上,我想为DRUG-ADR的每个唯一组合运行两个t.tests,用于X的值。如果我以D1-A1为例,我想测试D1-A1与D1-A&lt; 1的X值和D1-A1与D&lt; 1-A1的X值。下面是我这个例子的语法,但我的问题是如何制作一个通用的循环/函数来为DRUG-ADR的每个独特组合执行两个测试。
x <- ifelse (dat$DRUG == "D1" & dat$ADR == "A1",dat$X, NA)
x <- x[!is.na(x)]
y <- ifelse (dat$DRUG != "D1" & dat$ADR == "A1",dat$X, NA)
y <- y[!is.na(y)]
z <- ifelse (dat$DRUG == "D1" & dat$ADR != "A1",dat$X, NA)
z <- z[!is.na(z)]
t.test(x,y)
t.test(x,z)
因此,对于记录号4(D3-A6),语法将是:
x <- ifelse (dat$DRUG == "D3" & dat$ADR == "A6",dat$X, NA)
x <- x[!is.na(x)]
y <- ifelse (dat$DRUG != "D3" & dat$ADR == "A6",dat$X, NA)
y <- y[!is.na(y)]
z <- ifelse (dat$DRUG == "D3" & dat$ADR != "A6",dat$X, NA)
z <- z[!is.na(z)]
t.test(x,y)
t.test(x,z)
任何人对一般功能都有好主意吗?
编辑:我理想的结果如下表所示:
Drug ADR pvalue1 pvalue2
1 D1 A1 pval11 pval21
2 D2 A2 pval12 pval22
3 D.. A.. pval1.. pval2..
答案 0 :(得分:1)
与每个编程问题一样,解决方案分为两个步骤:
你可以继续
然而,首先:由于数据不足,t检验有时会失败;所以让我们替换t.test
来电:
t_test = function (x, y, ...) {
tryCatch(t.test(x, y, ...)$p.value, error = function (err) NA)
}
然后,所有这些都在一起,这给了我们:
library(dplyr) # Makes data manipulation easier.
test_combination = function (data, id) {
drug = data[id, ]$DRUG
adr = data[id, ]$ADR
match = filter(data, DRUG == drug, ADR == adr)$X
mismatch1 = filter(data, DRUG != drug, ADR == adr)$X
mismatch2 = filter(data, DRUG == drug, ADR != adr)$X
list(pval1 = t_test(match, mismatch1), pval2 = t_test(match, mismatch2))
}
哪种测试单一组合。现在我们测试所有这些:
result = lapply(dat$ID, test_combination, data = dat) %>%
bind_rows() %>%
bind_cols(dat, .) %>%
select(-X)
或者,使用更像dplyr(但在我看来有点模糊)的方法:
result = dat %>%
rowwise() %>%
do(bind_rows(test_combination(dat, .$ID))) %>%
bind_cols(dat, .) %>%
select(-X)
请注意此代码如何不使用显式for
循环。这是您在R中处理数据的方式:将函数应用于表或列表中的项目,而不是手动迭代。
请注意,从统计学角度来看,上述内容非常值得怀疑。至少你需要执行严格的multiple testing correction。