在行的两个数据帧的多个列表的列表上应用函数

时间:2014-07-03 16:35:23

标签: r apply

请原谅我,如果之前已经回答了这些问题,但是我搜索过但找不到问题。 我有一个包含多个列表的列表,其中包含两个数据帧。我想在第一行数据帧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循环(如果可能的话)。请建议。

2 个答案:

答案 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