Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

R function for creating monotonic (increasing or decreasing) permutations [duplicate]

Tags:

r

permutation

I'm trying to create an efficient function to generate all monotonically increasing permutations of a large vector. Obviously, reducing the outputs from expand.grid or gtools::permutations works, but only for smaller vectors.

Example:

x = 1:3

Desired output:

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

Any suggestions using base R or, existing packages with this capability?

EDIT: An ideal solution would avoid generating the complete set of permutations to then subset.

like image 265
Fred Viole Avatar asked Mar 07 '26 10:03

Fred Viole


1 Answers

Using data.table this is fairly easy:

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

explanation:

First create a list containing the replicated vector len times, Use data.table::CJ to cross join all the vectors. And this is where the magic happens based on the len create an expression basically V2>=V1&V3>=V2 as V# is the default name for unnamed columns, and subset by the result of evaluating said expression.

parse(text=paste0("V", 2:len, ">=", "V", 1:(len-1), collapse="&") )
# expression(V2>=V1&V3>=V2)
like image 107
Abdessabour Mtk Avatar answered Mar 09 '26 01:03

Abdessabour Mtk