R语言:多重for循环的加速问题

博客来源于我的语雀专栏:R 语言 · 语雀

更多内容同步更新请关注我的语雀:令平子 · 语雀

R多重for循环的加速问题? - COS论坛 | 统计之都 | 统计与数据科学论坛

使用多核并行运行:如何解决R语言循环慢的问题 - 开发技术 - 亿速云

R语言如何多线程 - 简书

方法一:参数整合成数据框或使用“apply”

不必要多重循环,可以像楼上一样将所有参数的组合构成一个参数的数据框(参考expand.grid())。这样对参数数据框做一层循环或者apply一次就够了,然后就可以并行了

a = rep(1:3,each=2)
b = rep(5:6,times=3)
dataframe = data.frame('a'=a,'b'=b)
dataframe
apply(dataframe, 1, function(x){
a1 = x[[1]]
b1 =x[[2]]
return(c(a1,b1))
})

方法二:使用多核

至于速度可以网上找找提速的小技巧,我推荐别用原生r,用Microsoft r可以默认使用多核(避免原生r语言写多核的麻烦)。

步骤:

  1. 查看电脑核数:parallel::detectCores()
  2. 多线程计算
setwd("C:\\Users\\siyuanmao\\Documents\\imdada\\0-渠道投放和新人券联动模型\\测算")
options(scipen=3)  ##取消科学计数法
channel_ad_ios_data<-seq(0,50000,5000)
channel_ad_android_data<-seq(0,100000,10000)
library(parallel)
func <- function(n){#n=1
  result_data<-read.csv("发券方案.csv",stringsAsFactors=FALSE)
  total_coupon_solution_data<-read.csv("结果表框架.csv",stringsAsFactors=FALSE)
  coupon_solution_data<-subset(result_data,solution== paste('方案',n,sep=""))
  
  for (i in 1:11){#i=3
    coupon_solution_data$channel_ad_cost[3]<-5000*(i-1)
    
    for (j in 1:11){#j=5
      coupon_solution_data$channel_ad_cost[4]<-10000*(j-1)
      solution_mark<-paste('方案',n,i,j,sep="-")
      coupon_solution_data$solution<-solution_mark
      
      total_coupon_solution_data<-rbind(total_coupon_solution_data,coupon_solution_data)
    }
  }
  print(solution_mark)
  return(total_coupon_solution_data)
}
#func(10)
system.time({
x <- 1:7776
cl <- makeCluster(4) # 初始化四核心集群
results <- parLapply(cl,x,func) # lapply的并行版本
res.df <- do.call('rbind',results) # 整合结果
stopCluster(cl) # 关闭集群
})
df=as.data.frame(res.df)

报错1:Error in checkForRemoteErrors(val) :

3 nodes produced errors; first error: object 'tvp.var' not found

r - Error in check for remote errors (val): 5 nodes produced an error: object not found - Stack Overflow

方法三:使用 foreach 包

除了parallel包以外,还有针对并行for循环的foreach包,foreach()的使用也与parLapply()类似,两个功能也类似,其中遇到的问题也类似。

#定义计算幂函数
square <- function(x)
{
    return(x^2)
}

# 参数中的combine就是整合结果的函数,可以是c,可以是rbind,也可以是+等
results = foreach(x = c(1:3),.combine = 'c') %do% square(x)
#结果
> results
[1] 1,4,9
# 注意并行情况的时候,需要与parallel包进行配合,引入library(doParallel)。同时%do%需要改成%dopar%。另外与parallel包不一样的是,需要多加一句registerDoParallel(cl)来注册核进行使用。

#定义计算幂函数
square <- function(x)
{
    return(x^2)
}

# 参数中的combine就是整合结果的函数,可以是c,可以是rbind,也可以是+等
cl <- makeCluster(4)
registerDoParallel(cl)
results = foreach(x = c(1:100000),.combine = 'c') %dopar% square(x)
stopCluster(cl)

# 上一级环境中变量的引入
# 同parallel包并行计算前需要clusterExport()来引入全局变量一样,foreach也同样需要声明,不同的是,foreach声明方式直接写在foreach()的参数export里边。
#定义计算幂函数
base = 2
square <- function(x)
{
    return(x^base)
}
cl <- makeCluster(4)
registerDoParallel(cl)
results = foreach(x = c(1:100000),.combine = 'c',.export ='base' ) %dopar% square(x)
stopCluster(cl)

经测发现:

  • makecluster的核数与耗时的关系,在迭代次数较少时,成正比;次数较多时,成反比(待验证)

 

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值