使用R中的apply family并行化用户定义的函数

时间:2017-08-03 03:52:52

标签: r parallel-processing lapply sapply mapply

我有一个脚本,计算时间太长,而且我试图将其执行并行化。

脚本基本上循环遍历数据框的每一行并执行一些计算,如下所示:

my.df = data.frame(id=1:9,value=11:19)

sumPrevious <- function(df,df.id){
    sum(df[df$id<=df.id,"value"])
}

for(i in 1:nrow(my.df)){
    print(sumPrevious(my.df,my.df[i,"id"]))
}

我开始学习在R中并行化代码,这就是为什么我首先想要了解如何使用类似应用的函数(例如,sapply,lapply,mapply)来实现这一点。

我尝试了很多东西但到目前为止没有任何工作:

mapply(sumPrevious,my.df,my.df$id) # Error in df$id : $ operator is invalid for atomic vectors

2 个答案:

答案 0 :(得分:3)

使用R中的parallel包,您可以使用mclapply()功能。您需要稍微调整一下代码才能使其并行运行。

library(parallel)
my.df = data.frame(id=1:9,value=11:19)

sumPrevious <- function(i,df){df.id = df$id[i]
    sum(df[df$id<=df.id,"value"])
}

mclapply(X = 1:nrow(my.df),FUN = sumPrevious,my.df,mc.preschedule = T,mc.cores = no.of.cores)

此代码将在您计算机的no.of.cores上并行运行sumPrevious。

答案 1 :(得分:1)

嗯,这很有趣。你需要的东西如下:

 mapply(sumPrevious,list(my.df),my.df$id)

对于供应,由于第一个输入是数据帧,因此您必须定义一个给定的函数才能识别它:

  sapply(my.df$id,function(x,y) sumPrevious(y,x),my.df)

我更喜欢mapply,因为我们可以将第一个值设置为直接作为数据帧。但整个数据帧。这就是你必须使用函数list的原因。

Map我是mapply的包装器,因此只会以列表格式呈现解决方案。试试吧。此外,lapplysapply类似,只有sapply必须将结果简化为数组格式,而lapply会提供与列表相同的结果。

虽然看起来无论你想做什么都可以通过cumsum函数完成。

 cumsum(df$values)