McLappy vs for循环打印:速度和可伸缩性重点
我在R中运行一个函数,该函数可能需要很长时间才能运行,因为它执行多个命令来转换和子集某些数据,然后将其推入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
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))和usingmclappy
以某种并行方式运行每一行?(我有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]))