r - 如何避免为大型数据集编写嵌套的 for 循环?

标签 r nested-loops

对于二变量问题,outer很可能是最好的解决方案,如果循环的空间足够小,那么我们可以有 expand.grid做我们的跑腿工作。然而,如果我们有两个以上的变量和一个大的空间来循环,这些就被排除了。 outer不能处理两个以上的变量和 expand.grid占用的内存比我见过的机器能够占用的内存还多。

我最近发现自己在写这样的代码:

n<-1000
for(c in 1:n){
    for(b in 1:c){
        for(a in 1:b){
            if(foo(a,b,c))
            {
                bar(a,b,c)
            }
        }
    }
}

在这些情况下,嵌套循环似乎是自然的解决方案(例如 mapply 不会做,并且 tapply 没有好的因素可以使用),但是有更好的方法吗?这似乎是通往错误代码的道路。

我怀疑 combn也许能够以某种方式做到这一点,但根据我的经验,它很快就会陷入与 expand.grid 相同的内存陷阱中。 .如果没记错的话,我也知道它采取了不明智的步骤,告诉我更改递归限制的全局设置。

最佳答案

这是与重复的组合。 可能是您开箱即用的最佳选择,但在 n = 1000L ,这只是超过 5 亿个组合,将占用 ~ 2GB 的内存。

library(RcppAlgos)
n = 1000L
mat <- comboGeneral(n, 3L, repetition = TRUE)

现在有两条路要走。如果您有 RAM 并且您的函数能够被矢量化,那么您可以非常快速地完成上述操作。假设组合的总和大于 1000,您需要组合的均值,否则您需要组合的总和。
res <- if (rowSums(mat) > 1000L) 
  rowMeans(mat)
else
  rowSums(mat)

## Error: cannot allocate vector of size 1.2 Gb

不好了!我得到了可怕的分配向量错误。 允许您返回函数的结果。但请注意,它返回一个列表并且速度要慢得多,因为它将不得不评估您的 R 函数,而不是停留在 C++ 中。为此,我改成了n = 100L因为我没有一整天...
comboGeneral(100L, 3L, repetition = TRUE,
                        FUN = function(x) { 
                          if (sum(x) > 100L)
                            mean(x)
                          else
                            sum(x)
                        }
)

如果我有一个静态集合,我总是从 n 中选择 3 个组合,我可能会使用 Rcpp代码直接取决于什么foo(a,b,c)bar(a,b,c)是,但首先我想了解更多有关这些功能的信息。

关于r - 如何避免为大型数据集编写嵌套的 for 循环?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/62225190/

相关文章:

python - 使用嵌套循环的 Windchill 表

PHP MySQL 循环遍历?我是 "overlooped"

Tibble 数据类型的行求和

r - 在 RStudio 中构建并重新加载会生成 'Save File' 错误

R - 如何进行跨年日期操作?

javascript - 正则表达式:嵌套标签

cuda - 嵌套循环中数组的二维累积和——CUDA 实现?

r - 为什么 mapply 不返回日期对象?

通过全局变量选择R数据框

java - 在双(或多)循环内部或外部声明/初始化变量