gpt4 book ai didi

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

转载 作者:行者123 更新时间:2023-12-03 15:01:21 24 4
gpt4 key购买 nike

对于二变量问题,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/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com