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.
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
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)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With