【问题标题】:r - combinations from elements in vector [duplicate]r - 向量中元素的组合[重复]
【发布时间】:2019-02-23 20:37:51
【问题描述】:

给定向量:

a <- c(1,2,3)

我正在尝试计算包含a中元素组合的所有向量,即:

list(
    a[c(1,2,3)],
    a[c(1,3,2)],
    a[c(2,1,3)],
    a[c(2,3,1)],
    a[c(3,1,2)],
    a[c(3,2,1)])

这可以通过以下方式复制:

df <- expand.grid(rep(list(a), length(a)))
nunique <- apply(df, 1, function(x) length(unique(x)))
df <- df[nunique == ncol(df), ]
as.list(as.data.frame(t(df)))

我尝试使用 expand.grid 执行此操作,但此函数提供了可以重复元素的排列,这会导致数据集过大并从下面给出错误。

我已经看到了与此类似的问题,但未能找到不会产生错误的快速解决方案:

Error: cannot allocate vector of size 37.3 Gb

错误可以重现:

a <- c(1,2,3,4,5,6,7,8,9,10)

【问题讨论】:

  • 对于大型数据集,组合会太大。您可能需要在内存更大的系统上执行操作
  • 您似乎想要排列而不是组合(所有 6 个输出向量仅对应一个组合,但形​​成 3! = 6 个排列的列表)。请参阅this question 获取一些提示。
  • arrangements 包含排列的生成器和迭代器(因此,如果您只想循环它们,则不必一次将它们全部保存在内存中)。 Benchmarks 建议它比 combinat 等一些替代方案快得多。

标签: r combinations permutation large-data


【解决方案1】:

您似乎想要排列,而不是组合。试试 permn() 包中的函数 combinat:

# Your first example:
combinat::permn(c(1, 2, 3))
#> [[1]]
#> [1] 1 2 3
#> 
#> [[2]]
#> [1] 1 3 2
#> 
#> [[3]]
#> [1] 3 1 2
#> 
#> [[4]]
#> [1] 3 2 1
#> 
#> [[5]]
#> [1] 2 3 1
#> 
#> [[6]]
#> [1] 2 1 3

# Your second example
res <- combinat::permn(c(1,2,3,4,5,6,7,8,9,10))

不过,这确实需要一段时间。当然,对象本身会很大:

system.time(res <- combinat::permn(c(1,2,3,4,5,6,7,8,9,10)))
#>   user  system elapsed 
#>  14.661   0.448  15.346 
pryr::object_size(res)
#> 639 MB

【讨论】:

  • 正如@JohnColeman 指出的那样,对于此类任务,有更高效的软件包。例如,包arrangements 在大约十分之一秒内返回1:10 的所有排列。试试system.time(arrangements::permutations(10, 10))
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-09-19
  • 1970-01-01
  • 1970-01-01
  • 2016-10-22
  • 2021-01-24
  • 1970-01-01
相关资源
最近更新 更多