如果事先不知道最终结果的数量,在 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/