作者:杜亮亮喜欢2602936263 | 来源:互联网 | 2023-08-19 18:55
博客来源于我的语雀专栏: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语言写多核的麻烦)。
步骤:
- 查看电脑核数:
parallel::detectCores()
- 多线程计算
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&#61;1
result_data<-read.csv("发券方案.csv",stringsAsFactors&#61;FALSE)
total_coupon_solution_data<-read.csv("结果表框架.csv",stringsAsFactors&#61;FALSE)
coupon_solution_data<-subset(result_data,solution&#61;&#61; paste(&#39;方案&#39;,n,sep&#61;""))
for (i in 1:11){#i&#61;3
coupon_solution_data$channel_ad_cost[3]<-5000*(i-1)
for (j in 1:11){#j&#61;5
coupon_solution_data$channel_ad_cost[4]<-10000*(j-1)
solution_mark<-paste(&#39;方案&#39;,n,i,j,sep&#61;"-")
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(&#39;rbind&#39;,results) # 整合结果
stopCluster(cl) # 关闭集群
})
df&#61;as.data.frame(res.df)
报错1&#xff1a;Error in checkForRemoteErrors(val) :
3 nodes produced errors; first error: object &#39;tvp.var&#39; not found
r - Error in check for remote errors (val): 5 nodes produced an error: object not found - Stack Overflow
![](https://img8.php1.cn/3cdc5/18b49/a6e/b24257a07a956f3b.png)
方法三&#xff1a;使用 foreach 包
除了parallel包以外&#xff0c;还有针对并行for循环的foreach包&#xff0c;foreach()的使用也与parLapply()类似&#xff0c;两个功能也类似&#xff0c;其中遇到的问题也类似。
#定义计算幂函数
square <- function(x)
{
return(x^2)
}
# 参数中的combine就是整合结果的函数&#xff0c;可以是c&#xff0c;可以是rbind&#xff0c;也可以是&#43;等
results &#61; foreach(x &#61; c(1:3),.combine &#61; &#39;c&#39;) %do% square(x)
#结果
> results
[1] 1,4,9
# 注意并行情况的时候&#xff0c;需要与parallel包进行配合&#xff0c;引入library(doParallel)。同时%do%需要改成%dopar%。另外与parallel包不一样的是&#xff0c;需要多加一句registerDoParallel(cl)来注册核进行使用。
#定义计算幂函数
square <- function(x)
{
return(x^2)
}
# 参数中的combine就是整合结果的函数&#xff0c;可以是c&#xff0c;可以是rbind&#xff0c;也可以是&#43;等
cl <- makeCluster(4)
registerDoParallel(cl)
results &#61; foreach(x &#61; c(1:100000),.combine &#61; &#39;c&#39;) %dopar% square(x)
stopCluster(cl)
# 上一级环境中变量的引入
# 同parallel包并行计算前需要clusterExport()来引入全局变量一样&#xff0c;foreach也同样需要声明&#xff0c;不同的是&#xff0c;foreach声明方式直接写在foreach()的参数export里边。
#定义计算幂函数
base &#61; 2
square <- function(x)
{
return(x^base)
}
cl <- makeCluster(4)
registerDoParallel(cl)
results &#61; foreach(x &#61; c(1:100000),.combine &#61; &#39;c&#39;,.export &#61;&#39;base&#39; ) %dopar% square(x)
stopCluster(cl)
经测发现&#xff1a;
- makecluster的核数与耗时的关系&#xff0c;在迭代次数较少时&#xff0c;成正比&#xff1b;次数较多时&#xff0c;成反比&#xff08;待验证&#xff09;