McLappy vs for循环打印:速度和可伸缩性重点

McLappy vs for循环打印:速度和可伸缩性重点,r,for-loop,foreach,ggplot2,mclapply,R,For Loop,Foreach,Ggplot2,Mclapply,我在R中运行一个函数,该函数可能需要很长时间才能运行,因为它执行多个命令来转换和子集某些数据,然后将其推入ggplot进行绘图。我需要多次运行此函数来调整参数值。我将提供一个简单的例子…但我想知道如何加快它?如果按比例放大,即获得每个单一组合的最快方法是什么…是否有一种通用方法将for循环转换为mclappy,假设它们更快…请随时提供其他模拟示例,演示对特定方法的偏好 模拟示例: 基本功能: ff <- function(n, mu, stdev){ x1 <- c(1:n

我在R中运行一个函数,该函数可能需要很长时间才能运行,因为它执行多个命令来转换和子集某些数据,然后将其推入
ggplot
进行绘图。我需要多次运行此函数来调整参数值。我将提供一个简单的例子…但我想知道如何加快它?如果按比例放大,即获得每个单一组合的最快方法是什么…是否有一种通用方法将
for
循环转换为
mclappy
,假设它们更快…请随时提供其他模拟示例,演示对特定方法的偏好

模拟示例:

基本功能:

ff <- function(n, mu, stdev){
     x1 <- c(1:n)
     y1 <- rnorm(n,mu,stdev)
     z1 <- data.frame(cbind(x1,y1))
     ggplot(z1, aes(x=x1,y=y1))+
       geom_point()+
       labs(title=paste("n=",n,"mu=",mu, "stdev=",stdev))
}
加快速度的最快方法是什么?我假设它可能需要像expand.grid(x=c(1:10),y=c(1:2),z=seq(100500,by=100))和using
mclappy
以某种并行方式运行每一行?(我有4个内核可用于此)。请随意从基本函数中提取一些位,或者根据能够最大程度提高速度的方法将一些内容放入基本函数中。如果您增加每个参数的范围,这个过程显然会花费更长的时间,但是否对此无能为力……或者,如果拆分到多个内核或其他什么东西,是否也可以以某种方式进行更改

对于额外的积分…是否有任何东西可以保存输出图像并创建类似于包中的滑块
操纵
以交互方式浏览所有参数…它所做的只是拉出相关图像,而不是每次重新计算它


注意:如果使用
mclappy
,请随意使用/建议您认为可能对您的解决方案有用的任何其他包(如
foreach
),将参数组合到一个列表中,并将其传递给函数,而不是使用for循环

e、 g


以非常简单的方式保存输出图像。只需在
ff()
函数中调用
ggsave()

ff <- function(n, mu, stdev){
  x1 <- c(1:n)
  y1 <- rnorm(n,mu,stdev)
  z1 <- data.frame(cbind(x1,y1))
  ggplot(z1, aes(x=x1,y=y1))+
    geom_point()+
    labs(title=paste("n=",n,"mu=",mu, "stdev=",stdev))
  ggsave(paste0(n,"_", mu, "_", stdev, ".jpeg"))
}
然后,如果您在Linux上并且有多个可用的内核,我将使用
lappy()
mclappy()

lapply(seq(nrow(x)), function(i) ff(x[i,2], x[i,1], x[i,3]))

这将创建100个命名约定为“n_mu_stdev.jpeg”的jpeg。至于访问这些内容并在屏幕上呈现它们的有效方法,我将研究web浏览器和一些简单的CSS和jQuery,使其更加简洁。这确实是一个单独的问题,尽管如此,IMHO。

感谢您的快速响应…所以…我对McLappy位有困难…但是仅仅使用
Lappy
并不能真正提高速度…这是我的基准案例
system.time(for(i in 1:10){for(j in 1:2){for(k in seq(100500,by=100)){print(ff)(k,i,j))}}}}{/code>花了21.4秒,使用
lappy
我做了以下
system.time(lappy(seq(nrow(x)),函数(i)打印(ff(x[i,3],x[i,1],x[i,2]))
这花费了21.7秒…用mc.cores=4替换
lappy
mclappy
产生了这个错误:
ATSFontGetFileReference失败:错误-3182。
@h.l.m-我不希望
lappy
比for循环快多少。我还敢打赌你的大部分时间都花在
gg上plot2
位,它不能通过多核来加速。尝试修改一些基本图形,使其不那么难看,几乎可以肯定地将计算时间减少很多倍。我以前从未见过这种错误,因此遗憾的是,我在这方面没有太多帮助。你能从
?McLappy
获得一个小例子吗?使用帮助页上的代码e对于mclappy,以下代码运行良好
mclappy(1:30,rnorm,mc.cores=4)
@Chase您是对的,
ggplot
本身不会被拆分为多个内核,但每个作业都会被拆分,因此根据传输和计算时间之间的权衡,它可能会更快,因为每个内核处理该列表的1/4(因为他有4个内核)。但是对于这个简单的例子,
llply
足以在单个内核上运行。感谢您的回复,但我似乎不断收到错误,说
“Error in 1:n:NA/NaN argument\n”
并且无法解决如何修复它…要排除
mclappy
的问题,请先使用
llply
执行操作(删除
mc.cores
mc.preschedule
)并查看是否出现相同的错误。如果出现错误,则函数无法正确读取每个列表项。请参阅
params[1]
以确保所有3个都在每个列表项中。这就是我的params[1]看起来的样子100
因此,当我将最后一行更改为
llply(params,ff)时,我不太确定要调整什么
并得到相同的错误…因此解决方案现在似乎可以工作了…但只有在两种情况下键入
结果
时(这两种情况似乎花费了大致相同的时间),在对手头数据进行预处理时会有什么不同?此外,如果试图将其放入
系统中。time()
函数检查哪一个打印速度更快结果不打印,所以用h调整函数为什么要键入
结果
?它只会将所有300个结果打印到屏幕上。相反,在
结果
对象上运行
llply
,并将其推过
ggsave
,这样你就可以得到一个图像文件夹,然后用幻灯片放映粗糙的。
results <- mclapply(params, ff, mc.cores = 4, mc.preschedule = TRUE)
ff <- function(n, mu, stdev){
  x1 <- c(1:n)
  y1 <- rnorm(n,mu,stdev)
  z1 <- data.frame(cbind(x1,y1))
  ggplot(z1, aes(x=x1,y=y1))+
    geom_point()+
    labs(title=paste("n=",n,"mu=",mu, "stdev=",stdev))
  ggsave(paste0(n,"_", mu, "_", stdev, ".jpeg"))
}
x <- expand.grid(i = 1:10, j = 1:2, k = seq(100,500,100))
lapply(seq(nrow(x)), function(i) ff(x[i,2], x[i,1], x[i,3]))