単調な(増加または減少する)順列を作成するためのR関数[重複]

Nov 26 2020

大きなベクトルの単調に増加するすべての順列を生成する効率的な関数を作成しようとしています。明らかに、expand.gridまたはからの出力を減らすことは機能しますgtools::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またはこの機能を備えた既存のパッケージを使用した提案はありますか?

編集:理想的な解決策は、サブセット化するための順列の完全なセットの生成を回避することです。

回答

3 AbdessabourMtk Nov 26 2020 at 04:56

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>=V1&V3>=V2同じように式を作成し、その式V#を評価した結果によってサブセット化することに基づいて魔法が発生する場所です。

parse(text=paste0("V", 2:len, ">=", "V", 1:(len-1), collapse="&") )
# expression(V2>=V1&V3>=V2)
2 stevec Nov 26 2020 at 05:03

これは、例のように繰り返しが許可された順列を作成し、各順列が単調であるかどうかを検出するコードです。

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
# ....