使用parSapply在data.table的行上应用函数

时间:2017-02-05 11:56:18

标签: r parallel-processing data.table lapply

我想使用parLapply / parSapply在data.table中执行rowvise操作,

这是我到目前为止所做的:

library(parallel)
library(data.table)


#Generate random data:
n<-10000000
data<-data.table(x=seq(1,n),y=seq(2,n),z=seq(3,n))

#Define random function:
random_function<-function(x){
  x[1]^1+x[2]^2+x[3]^3
}

#Use data.table solution:
system.time(data<-data[,my_new_var_1:=random_function(unlist(.SD)),.SDcols=c("x","y","z"),by=1:nrow(data)])

#use parLapply:
cl<-makeCluster(8)
system.time(data$my_new_var_2<-parSapply(cl,as.list(transpose(data[,c("x","y","z"),with=FALSE])),random_function))
stopCluster(cl)

我想要做的是传递完全一般的功能(我知道有时我可以优化我的代码,以便我可以避免行方向操作)。现在我的解决方案似乎有点过于笨拙,也许有人可以提出更好的方法。即使是在这个相对较小的数据集上这种非常笨拙的方法也能让我获得一些加速

1 个答案:

答案 0 :(得分:0)

这取决于您现有的数据和真实的random_function。通常只有当random_function()是一些复杂的计算时,才能从并行执行中受益。

即使没有并行化,您的示例也可以得到改进:

system.time(
    data[, my_new_var_1 := apply(.SD, 1, random_function), 
           .SDcols=c("x","y","z"), 
           by = .I])

并使用编译器:

require(compiler)
random_function <- cmpfun(random_function)

system.time(
    data[, my_new_var_1 := apply(.SD, 1, random_function), 
           .SDcols=c("x","y","z")) # add grouping if needed

其中by = .Iby = (1:nrow)当然没有意义(现在可以省略),除非你把一些更合理的分组变量/表达式。