使用R语言的apply函数族并行化用户自定义函数

4

我有一个脚本需要计算的时间太长,我正在尝试并行化它的执行。

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

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中并行化代码,因此我首先想了解如何使用类似于apply的函数(例如sapply、lapply、mapply)来实现。

我尝试了多种方法,但目前为止都没有成功:

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

1
lapplysapplymapply不会并行执行操作,它们会按顺序运行函数。您是想将for loop替换为lapply,还是想要并行运行代码? - tushaR
你需要并行处理这个吗?对我来说,你想要实现的只是 cumsum(my.df$value),假设 my.df$id 已经排序。 - F. Privé
2个回答

5

在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函数。


2
太棒了!非常感谢 :) - Victor

2

好吧,这很有趣。你需要像下面这样的东西:

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

对于供应,由于第一个输入是数据框,因此您将不得不为其定义一个给定的函数,以便它能够识别它:

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

我更喜欢使用mapply,因为我们可以直接将要填充的第一个值设置为数据框。但是需要整个数据框。这就是为什么你必须使用函数listMapmapply的包装器,因此只会以列表格式呈现解决方案。试一下。另外,lapply类似于sapply,只是sapply需要将结果简化为数组格式,而lapply会将结果作为列表给出。
虽然似乎可以通过cumsum函数轻松完成你想做的任何操作。
 cumsum(df$values)

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接