【问题标题】:How to facilitate nested for loops in R?如何促进 R 中的嵌套 for 循环?
【发布时间】:2012-09-01 01:08:32
【问题描述】:

我已经嵌套了如下的 for 循环。我需要 p:q=1:300 和 n=20。函数“mark”是我感兴趣的模型(Package RMark)。我知道 rbind 可能很慢,但我不知道应该用什么来替换它。否则我还能做些什么来使这个功能更快?谢谢。

foo<-function(data, p, q, n){
results.frame <- data.frame()
for (i in 1:n){
    for (i in p:q) {
        run.model<-mark(data[sample(nrow(data), i),], model="Occupancy")       
        results<-data.frame(summary(run.model)$real$p, Occupancy=summary(run.model)$real$Psi, se.p=t(as.matrix(summary(run.model, se=T)$real$p$se)), se.Psi=summary(run.model, se=T)$real$Psi$se, stations=i)
        results.frame<-rbind(results.frame, results)
        } 
    }
write.table(results.frame, "C:\\RWorkspace\\simulation_results.txt")
return(results.frame)
}

【问题讨论】:

  • 1)你应该预先分配results.frame的维度,然后通过索引填充它。 2) 你真的需要data.frame() 还是matrix() 就足够了?您的所有结果看起来都是数字,因此矩阵可能就足够了。 3) cmpfun() 你的函数通过compiler 包查看是否可以让你获得任何免费的减速带。 4) 告诉我们函数mark() 来自哪里,因为它不在基础中,而且您的问题不是reproducible,所以人们会发现很难提供真正的建议。
  • 1) 听起来很合理,我会试试的。 2) 是的,我所有的输出都是数字的,所以我将切换到 matrix()。 3) 我会看看cmpfun()complier。 4)函数mark()来自“RMark”包,用于动物种群动态。感谢您的建议。
  • 另外,你在两个循环中都使用了i;最好使用不同的变量,这样你就可以确定你在循环中使用了你想要的i

标签: r loops for-loop nested


【解决方案1】:

是的,rbind 可能很慢;更快的方法通常是使矩阵开始时具有正确的大小并适当地填充它。填充矩阵而不是数据框通常也更快。

但是,根据您指定的大小,我怀疑 mark 会减慢该功能的速度,这样做您不会获得太多明显的加速。通过将单个结果存储在 run.model 中,然后在循环中注释掉该行,可以很容易地测试它;这将告诉您仅存储结果花费了多少时间。 (您也可以“分析”该函数,但这会更简单。)

编辑:我实际上错了;您指示的大小足够大,rbind 很可能会导致问题。在我的系统上,它相当快并且具有相当大的内存量,使用带有n=20 的数据帧需要7.73 秒到rbind,而使用n=1 只需0.09 秒,所以很明显正在发生一些内存搅动。至于加速,n=20 只需 1.00 秒即可完成rbind 矩阵和 0.033 秒的填充。

foo <- function(data, p, q, n){
  # make a single results line; remove this line when you put in your code 
  results <- c(1, Occupancy=2, se.p=3, se.Psi=4, stations=5)
  # make the matrix the right size to start with
  results.frame <- matrix(ncol=5, nrow=(q-p+1)*n)
  for (i in 1:n){
    for (j in p:q) {
      # get results here; commented out to show loop speed only
      # put in your actual code here instead
      results.frame[ 1+(i-1)*(q-p+1)+(j-p), ] <- results
    } 
  }
  # get the names right by taking the names from the last time through the loop
  colnames(results.frame) <- names(results)
  results.frame
}

【讨论】:

  • 感谢您的建议。我第一次尝试p:q=1:200,没有n,只用了8分钟就完成了。然后我为n添加了另一个for循环并运行p:q=1:300, n=20,然后花了将近5个小时才完成。所以我认为它可能是嵌套循环而不是mark()commenting that line out of my loop 是什么意思?如果这是一个愚蠢的问题,我先道歉。我不是专业程序员,还在学习。
  • 迫不及待地想试试你修改的代码。但我必须等到我当前的模拟结束。 T_T
猜你喜欢
  • 1970-01-01
  • 2023-03-02
  • 1970-01-01
  • 1970-01-01
  • 2017-04-30
  • 1970-01-01
  • 1970-01-01
  • 2021-08-09
  • 2021-09-15
相关资源
最近更新 更多