【问题标题】:R function for creating monotonic (increasing or decreasing) permutations [duplicate]用于创建单调(增加或减少)排列的R函数[重复]
【发布时间】:2021-03-08 18:49:42
【问题描述】:

我正在尝试创建一个有效的函数来生成一个大向量的所有单调递增排列。显然,减少 expand.gridgtools::permutations 的输出是可行的,但仅适用于较小的向量。

例子:

x = 1:3

期望的输出:

1, 1, 1
1, 1, 2
1, 1, 3
1, 2, 2
1, 2, 3
1, 3, 3
2, 2, 2
2, 2, 3
2, 3, 3
3, 3, 3

对使用基本 R 或具有此功能的现有软件包有任何建议吗?

编辑:理想的解决方案是避免将完整的排列集生成到子集。

【问题讨论】:

  • 您能否调整您的示例所需输出以显示长度为 2 的排列(它们当前都是长度为 3)
  • 排列必须是length(x),但是排列长度的附加参数会有所改进!
  • 在处理不同长度的向量时,您需要(仔细)考虑如何存储它们。例如,在上面您想要的输出中,是否会显示长度为 2 的向量 1, 2, NA
  • 谢谢史蒂夫,根据函数参数,所有输出向量的长度都相同,所以我不确定为什么“NA”填充会成为问题。
  • arrangements 包对此很有用,谢谢。

标签: r permutation


【解决方案1】:

使用data.table 这很容易:

expand.monotonic <- function(x, len=length(x)){
    do.call(CJ, lapply(integer(len), function(...) x ))[
        eval(parse(text=paste0("V", 2:len, ">=", "V", 1:(len-1), collapse="&") )), ]
}
expand.monotonic(1:3)
   V1 V2 V3
 1:  1  1  1
 2:  1  1  2
 3:  1  1  3
 4:  1  2  2
 5:  1  2  3
 6:  1  3  3
 7:  2  2  2
 8:  2  2  3
 9:  2  3  3
10:  3  3  3

解释:

首先创建一个包含复制向量len 次的列表,使用data.table::CJ 交叉连接所有向量。这就是基于len 创建一个表达式的神奇之处,基本上V2&gt;=V1&amp;V3&gt;=V2 因为V# 是未命名列的默认名称,并且是评估所述表达式的结果的子集。

parse(text=paste0("V", 2:len, ">=", "V", 1:(len-1), collapse="&") )
# expression(V2>=V1&V3>=V2)

【讨论】:

  • 这是一个非常好的解决方案,使用data.table
  • 感谢 Abdessabour,我已经编辑了问题以反映内存方面的考虑。 data.table 解决方案的 object.sizegtools::permutations 的结果更大,并且两者都比最终输出大得多。
  • @FredViole 我在尝试进行基准测试时遇到了这些错误,交叉连接会占用大量内存
【解决方案2】:

这里有一些代码可以像您的示例一样创建允许重复的排列,并检测每个排列是否是单调的

x <- 1:3

# Generate permutations of length x
out <- gtools::permutations(length(x), length(x), v = x, repeats.allowed=TRUE)

# Detect if they're monotonic
mono <- apply(out, 1, function(x) { all(x == cummax(x)) })


output_with_monotonic_label <- cbind(out, mono)

# output_with_monotonic_label
#             mono
#  [1,] 1 1 1    1
#  [2,] 1 1 2    1
#  [3,] 1 1 3    1
#  [4,] 1 2 1    0
#  [5,] 1 2 2    1
#  [6,] 1 2 3    1
#  [7,] 1 3 1    0
#  [8,] 1 3 2    0
#  [9,] 1 3 3    1
# [10,] 2 1 1    0
# ....

【讨论】:

  • 谢谢,这是我之前遇到的问题,它很快就变得非常低效。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-11-04
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多