在R中使用data.table进行多线程处理

8

有没有办法在R中使用data.table来利用多个线程进行计算?例如,假设我有以下的data.table

dtb <- data.table(id=rep(1:10000, 1000), x=1:1e7)
setkey(dtb, id)
f <- function(m) { #some really complicated function }
res <- dtb[,f(x), by=id]

如果f需要一段时间来计算,有没有办法让R进行多线程处理?如果f很快,那么使用多线程会有帮助吗?还是大部分时间都会被data.table用于将事物分组?

1个回答

5
我不确定这是否属于“多线程”,但也许你是想包括一个多核解决方案?如果是这样,那么看一下之前的答案:Performing calculations by subsets of data in R,通过搜索“[r] [data.table] parallel”找到。
编辑:(在4核机器上速度提高了一倍,但我的系统监视器表明在mclapply调用期间只使用了2个核。)代码从这个帖子复制:http://r.789695.n4.nabble.com/Access-to-local-variables-in-quot-j-quot-expressions-tt2315330.html#a2315337
 calc.fake.dt.mclapply <- function (dt) {
     mclapply(6*c(1000,1:4,6,8,10),
              function(critical.age) {
                  dt$tmp <-  pmax((dt$age <  critical.age) * dt$x, 0)
                  dt[, cumsum.lag(tmp), by = grp]$V1})
 } 
 mk.fake.df <- function (n.groups=10000, n.per.group=70) {
    data.frame(grp=rep(1:n.groups, each=n.per.group),
               age=rep(0:(n.per.group-1), n.groups),
               x=rnorm(n.groups * n.per.group),
               ## These don't do anything, but only exist to give
               ## the table a similar size to the real data.
               y1=rnorm(n.groups * n.per.group),
               y2=rnorm(n.groups * n.per.group),
               y3=rnorm(n.groups * n.per.group),
               y4=rnorm(n.groups * n.per.group)) } 
 df <- mk.fake.df 
 df <- mk.fake.df()
 calc.fake.dt.lapply <- function (dt) { # use base lapply for testing
     lapply(6*c(1000,1:4,6,8,10),
            function(critical.age) {
                dt$tmp <-  pmax((dt$age <  critical.age) * dt$x, 0)
                dt[, cumsum.lag(tmp), by = grp]$V1})
 } 
 mk.fake.dt <- function (fake.df) {
    fake.dt <- as.data.table(fake.df)
    setkey(fake.dt, grp, age)
    fake.dt
  } 
 dt <- mk.fake.dt()

require(data.table)
dt <- mk.fake.dt(df)

 cumsum.lag <- function (x) {
    x.prev <- c(0, x[-length(x)])
    cumsum(x.prev)
  } 
 system.time(res.dt.mclapply <- calc.fake.dt.mclapply(dt))
  user  system elapsed 
 1.896   4.413   1.210 

system.time(res.dt.lapply   <- calc.fake.dt.lapply(dt))
   user  system elapsed 
  1.391   0.793   2.175 

1
你是在看第一个答案还是第二个答案?第一个答案没有使用'plyr',而是使用了foreach(这是一个多核函数)。 - IRTFM
1
如果您对非并行化方法的速度感到满意,那么为什么要问这个问题呢? - IRTFM
我不是:根据他们的回答,听起来他们说data.tableforeach方法一样快。 - Alex
1
我发现这也很有帮助:http://r.789695.n4.nabble.com/Parallelize-data-table-s-operations-td2537545.html - Alex
显示剩余4条评论

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