【问题标题】:Nested loops in R, all the possibilitiesR中的嵌套循环,所有可能性
【发布时间】:2016-09-03 13:02:01
【问题描述】:

我需要制作一个包含所有可能性的数据框,其中七个变量的总和为 100,每个变量都可以是 0 到 100。 我实现了以下代码,但需要很长时间。

combina <- function(U){
          d<- NULL
          for (i in 0:U) {
            for (j in 0:U) {
              for (k in 0:U) {
                for (l in 0:U) {
                  for (m in 0:U) {
                    for (n in 0:U) {
                      for (o in 0:U) {
                        if (i+j+k+l+m+n+o == U){
                          d <- rbind(d,c(i,j,k,l,m,n,o))
                        }
                      }
                    }
                  }
                }
              }
            }
          }
        return(d)
        }

如你所见,我使用 U 变量进行测试,在 15 之后它需要永远......

【问题讨论】:

  • 当总和超过 100 时,您应该看到每个 for 循环的中断...
  • 似乎expand.gridcombn 会提供一种更简单的方法......虽然这样的问题对于大型U 来说非常困难。
  • 这似乎是一项简单的任务,但您要求 R 创建和评估 100^7(即 100 万亿)个不同的数字组合,每个组合包含 7 个数字。这是一项艰巨的任务。我同意@Laurel 的建议,即在总和超过目标值时打破循环,这至少会减少任务的大小。
  • 您应该查看partitions package。根据该包中的 P() 函数,“只有”大约 1.9 亿个分区,但计算它们仍然是一个很大的挑战。
  • The answers to this SO question 可能会有所帮助。

标签: r for-loop nested


【解决方案1】:

这是我能想到的解决问题的一种方法(规模要小得多,因为我不想创建 100^7 数据)。 :)

例如,如果您有四个变量,范围从 0 到 10,并且您想找到它们的所有组合加起来为 10,您可以这样做:

df <- expand.grid(a = 1:10, b = 1:10, c = 1:10, d = 1:10)
df[rowSums(df) == 10, ]

输出具有 10,000 (10^4) 个可传递值中的 84 个值组合。

当然,这个解决方案看起来很简单,因为它首先创建并存储了 10,000 x 4 的数据框。随着尺寸的增加,这将成为一个大问题。

  • 根据下面的评论进行了编辑。同意,它比apply 要好得多,也许也更有效。

【讨论】:

  • 100^7 似乎有点高。具体数字可能取决于这些是否需要唯一以及是否需要为正数。我认为您应该在寻求解决方案之前要求澄清问题。
  • 您可以稍微简化子集:df[rowSums(df) == 10, ]
  • 这个解决方案的问题是我无法分配向量,因为在我的情况下它的大小是 372529 GB
  • 就像我说的,我发布这个是为了展示排列如何与 expand.grid 一起工作。仅 100 万亿个总和就是问题,更不用说在内存中预存了。
  • 对不起我之前的帖子,我很粗鲁,首先,@Gopala 感谢您的回复。我不明白“更不用说预先存储在内存中”是什么意思,提前感谢所有帮助
【解决方案2】:

这是一个 R 函数,它产生所有 k 个非负整数的序列,总和为 n。

sum_to_N <- function (n, k) {
  combos <- combn(seq(0, n+k-2), k-1)
  as.data.frame(t(rbind(combos, as.integer(n+k-1)) - rbind(0L, combos+1L)))
}

让我们看一个数字较小的例子。找到所有解决方案 A + B + C + D = 10 在非负整数中,我们首先找到 0 到 12 之间不同数字 a

解的数量是 (n+k-1) 选择 (k-1)。在这种情况下,n = 100 和 k = 7,因此解决方案的数量是(106 选择 6)= 1,705,904,746。这可能太多行无法放入数据框中,因此您应该尝试找到一种不涉及存储所有组合的方法来解决您的问题。

【讨论】:

  • 数据帧需要 48 GB(每行 28 个字节)。这不在可能的范围之外,但几乎不实用。
  • 戴夫感谢您的回复,您是对的,我想我必须采取另一种方法。就像您说的那样,这几乎不实用,特别是如果以后我必须计算到它的距离向量。无论如何,您的解决方案就是答案,因为我只是运行它,并且运行良好!!谢谢!!
猜你喜欢
  • 2020-11-08
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-11-13
  • 2013-01-29
相关资源
最近更新 更多