2

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

模拟示例:

基本功能:

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))
}

所以通过参数的方法是执行以下操作......

for(i in 1:10){
    for(j in 1:2){
       for(k in seq(100,500,by=100)){
         ff(k,i,j)
       }
    }
}

加快速度的最快方法是什么?我假设它可能需要类似expand.grid(x=c(1:10),y=c(1:2),z=seq(100,500,by=100))的东西和使用mclapply来遍历每一行......以某种并行方式?(我有 4 个内核可用于此)。请根据可以最大程度提高速度的方法,随意从基本功能中提取一些内容或将内容放入基本功能中。如果您增加每个参数的范围,该过程显然会花费更长的时间,但是对此没有什么可以做的......或者如果拆分更多核心或其他东西,也可以以某种方式改变......?

并且对于奖励积分...是否有任何东西可以保存输出图像并创建像包manipulate中一样的滑块以交互方式遍历所有参数...它所做的只是拉出相关图像,而不是而不是每次都重新计算。

注意请随意使用/建议foreach您认为可能对您的解决方案有用的任何其他软件包(如 )

4

2 回答 2

1

如果使用mclapply,将参数组合成一个列表并将其传递给函数,而不是使用 for 循环。

例如

df <- expand.grid(i = 1:10, j = 1:2 , k = seq(100, 500, 100))
params <- mapply(list, n = df[, 3], mu = df[, 1], stdev = df[,2], SIMPLIFY = F)

ff <- function(tlist) {
    n <- tlist$n 
    mu <- tlist$mu 
    stdev <- tlist$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))
}

results <- llply(params, ff, .progress='text')

如果使用mclapply

results <- mclapply(params, ff, mc.cores = 4, mc.preschedule = TRUE)
于 2012-10-08T22:59:05.973 回答
1

保存输出图像非常容易。只需调用ggsave()您的ff()函数。

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"))
}

您对使用expand.grid(). 这是我要做的:

x <- expand.grid(i = 1:10, j = 1:2, k = seq(100,500,100))

然后调用它,我会使用lapply()或者mclapply()如果你在 Linux 上并且有多个内核可用:

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 来使其变得简单。尽管恕我直言,这确实是一个单独的问题。

于 2012-10-08T23:00:41.670 回答