r - 在循环中收集未知数量的结果

标签 r loops append

如果事先不知道最终结果的数量,在 R 中的循环中收集结果的惯用方法是什么?这是一个玩具示例:

results = vector('integer')
i=1L
while (i < bigBigBIGNumber)  {
    if (someCondition(i)) results = c(results, i)
    i = i+1
}
results

这个例子的问题是(我假设)它将具有二次复杂性,因为向量需要在每次追加时重新分配。 (这是正确的吗?)我正在寻找避免这种情况的解决方案。

我找到了 Filter ,但它需要预先生成 1:bigBigBIGNumber我想避免以节省内存。 (问题:for (i in 1:N) 是否也预先生成 1:N 并将其保存在内存中?)

我可以做一个像这样的链表:
results = list()
i=1L
while (i < bigBigBIGNumber)  {
    if (someCondition(i)) results = list(results, i)
    i = i+1
}
unlist(results)

(请注意,这不是串联。它正在构建一个类似 list(list(list(1),2),3) 的结构,然后用 unlist 展平。)

还有比这更好的方法吗?通常使用的惯用方式是什么? (我对 R 很陌生。)我正在寻找有关如何解决此类问题的建议。非常欢迎关于紧凑(易于编写)和快速代码的建议! (但我想专注于快速和内存效率。)

最佳答案

这是一种算法,它在输出列表填满时将其大小加倍,从而实现一些线性计算时间,如基准测试所示:

test <- function(bigBigBIGNumber = 1000) {

  n <- 10L
  results <- vector("list", n)
  m <- 0L
  i <- 1L
  while (i < bigBigBIGNumber)  {
    if (runif(1) > 0.5) {
      m <- m + 1L
      results[[m]] <- i
      if (m == n) {
        results <- c(results, vector("list", n))
        n <- n * 2L
      }
    }
    i = i + 1L
  }
  unlist(results)
}

system.time(test(1000))
#    user  system elapsed 
#   0.008   0.000   0.008 
system.time(test(10000))
#    user  system elapsed 
#   0.090   0.002   0.093 
system.time(test(100000))
#    user  system elapsed 
#   0.885   0.051   0.936 
system.time(test(1000000))
#    user  system elapsed 
#   9.428   0.339   9.776 

关于r - 在循环中收集未知数量的结果,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16512371/

相关文章:

r - mgcv_1.8-24 : "fREML" or "REML" method of bam() gives wrong explained deviance

r - 迭代数据框并为每一列创建一个图

arrays - 在 pngs 上循环运行 ffmpeg 以提高效率?

mysql 选择更新

python - 如何在 kubernetes 集群内使用脚本语言连接数据库

R - 如何使 2 个邻接矩阵相互兼容

php - 确定哪些对象链接或不链接到主根对象

java - 将 for 循环转换为 while 循环会产生与预期不同的结果

c# - 如何将一组属性 append 到现有的 xml 文件

jquery - 使用jquery追加重复克隆隐藏的html