比R中的mappy函数更快的方法

比R中的mappy函数更快的方法,r,mapply,R,Mapply,我最近问了一个问题,我得到了一个有用的答案,但是考虑到我的大数据集(14K行),下面的代码运行得非常慢 我如何使用MCM使其更快 代码如下: within(df, count <- mapply(function(x, y) { in5year <- paste(animals.2[year %in% (x-4):x], collapse = "; ") sum(strsplit(in5year, "; ")[[1]] %in% strsplit(y, "; ")

我最近问了一个问题,我得到了一个有用的答案,但是考虑到我的大数据集(14K行),下面的代码运行得非常慢

我如何使用MCM使其更快

代码如下:

within(df,
  count <- mapply(function(x, y) {
    in5year <- paste(animals.2[year %in% (x-4):x], collapse = "; ")
    sum(strsplit(in5year, "; ")[[1]] %in% strsplit(y, "; ")[[1]])
  }, year, animals.1)
)
在(df,

使用并行计算一个解决方案。使用
mclappy
而不是
mcapply
,因为它稍微快一点

library(parallel)
library(dplyr)
library(microbenchmark)

df = data.frame(animals.1 = c("cat; dog; bird", "dog; bird", "bird", "dog"), 
                animals.2 = c("cat; dog; bird","dog; bird; seal", "bird", ""), 
                stringsAsFactors = F)

df <- replicate(10000,{df}, simplify=F) %>% do.call(rbind, .)
df$year <- seq(2000,2000 + nrow(df) - 1)

st_func <- function(df) {
  within(df,
         count <- mapply(function(x, y) {
           in5year <- paste(animals.2[year %in% (x-4):x], collapse = "; ")
           sum(strsplit(in5year, "; ")[[1]] %in% strsplit(y, "; ")[[1]])
         }, year, animals.1)
  )
}

mc_func <- function(df) {
  df$count <- mclapply(1:nrow(df), function(i) {
    x <- df$year[i]
    y <- df$animals.1[i]
    in5year <- paste(df$animals.2[df$year %in% (x-4):x], collapse = "; ")
    sum(strsplit(in5year, "; ")[[1]] %in% strsplit(y, "; ")[[1]])
  }, mc.cores=4) %>% unlist
  return(df)
}

identical(mc_func(df), st_func(df)) # TRUE

microbenchmark(mc_func(df), st_func(df), times=5)

Unit: seconds
        expr       min        lq      mean   median        uq      max neval cld
 mc_func(df)  8.588759  8.637135  9.101409  8.91779  8.924929 10.43843     5  a 
 st_func(df) 30.090307 30.107282 30.440877 30.45653 30.696706 30.85356     5   b
库(并行)
图书馆(dplyr)
图书馆(微基准)
df=data.frame(动物1=c(“猫;狗;鸟”,“狗;鸟”,“鸟”,“狗”),
动物.2=c(“猫;狗;鸟”,“狗;鸟;海豹”,“鸟”,“鸟”),
(系数=F)
df%do.呼叫(rbind,.)

df$year有很多东西。首先,为什么你要将值粘贴在一起,然后在下一行中将它们分割开来?@thc,显示了连接已经嵌入分号的字符串,因此有效地粘贴(c(“cat;dog”,“bird”),collapse=“;”)。它看起来确实很傻,但有它的实用性。也许有更好的方法。@r2evans我明白了。一个小优化是在循环之前对整个向量执行strsplit;但这并没有我想象的那么多,所以不值得作为答案发布。多线程(
mclappy
)正如预期的那样,它可以加快速度,但我在R中找不到明显更好的基线方法。我认为需要Rcpp来显著加快速度。我尝试使用
mcmapply
,但无法真正编写工作代码。你能分享一下你与mcmapply一起开发的代码吗?你今天只问了第一个问题?W等待人们在开始一个新的线程之前回答该线程。