请原谅我,如果之前已经回答了这些问题,但是我搜索过但找不到问题。 我有一个包含多个列表的列表,其中包含两个数据帧。我想在第一行数据帧1和第一行数据帧2之间应用t.test,依此类推。
我试过了:
list1 <- list(set1 = data.frame(rnorm(100), rexp(100)), set2 = data.frame(rnorm(100, mean = 5, sd = 3), rexp(100, rate = 4)))
list2 <- list(set1 = data.frame(rnorm(100), rexp(100)), set2 = data.frame(rnorm(100, mean = 6, sd = 4), rexp(100, rate = 2)))
mylist <- list(list1, list2)
ttest<-function(list){
df1 <- list$set1
df2 <- list$set2
testresults<-rep(NA,nrow(df1))
for (j in seq(nrow(df1))){
testresults[j] <- t.test(df1[j,], df2[j,])$p.value
}
return(as.matrix(testresults))}
lapply(mylist,ttest)
这样可以正常工作,但由于这个for循环需要花费很多时间,因为实际数据要大得多。我想用apply函数替换for循环(如果可能的话)。请建议。
答案 0 :(得分:3)
您基本上希望lapply
使用带有多个参数的函数,即Map
。因此,您可以使用
ttest
ttest2 <- function(list) {
df1 <- list$set1
df2 <- list$set2
l1 <- unlist(apply(df1, 1, list), recursive = FALSE)
l2 <- unlist(apply(df2, 1, list), recursive = FALSE)
testresults <- unlist(Map(function(x,y) t.test(x,y)$p.value, x=l1, y=l2))
return(as.matrix(testresults))
}
这似乎更快。我将您的数据框扩展为10000行(它运行速度非常快,只有100行,并且不能看到差异很大)并得到了
system.time(lapply(mylist,ttest))
# user system elapsed
# 12.736 0.000 12.760
system.time(lapply(mylist,ttest2))
# user system elapsed
# 3.825 0.000 3.833
答案 1 :(得分:0)
尝试:
res1 <- sapply(mylist, function(x) {
x1 <- do.call(`cbind`,x)
apply(x1, 1, function(y) t.test(y[1:2], y[3:4])$p.value)
})
使用您的功能
res2 <- sapply(mylist, ttest)
identical(res1, res2)
#[1] TRUE