A friend of mine asked me recently if I could make in R a list of N
numbers separated by step
that sum up to 1. For example, all the possible combinations of 3 numbers in the vector seq(0.1,1,0.1)
that sum 1. The order is not important.
I've been working with expand.grid
but as the number increases, the memory requirement explodes. Since the order is unimportant we thought to reduce the matrix by only considering some of the combinations. If we make it so 111 represents the values c(0.1,0.1,0.1)
, and 123 represents c(0.1,0.2,0.3)
, we only considered 111, 112, 113 ... 119, 122, 123, ... 129, 133 ... etc.
Note that we excluded 121, 131 and 132 because they are equivalent to 112, 113 and 123. This considerably reduces the number of combinations to test. To do this, we used nested for loops as follows:
step=.1
lst=list()
for(i in seq(step,1,step)){
for(j in seq(i,1,step)){
for(k in seq(j,1,step)){
print(c(i,j,k));if(sum(c(i,j,k))==1){lst=append(lst,list(c(i,j,k)))}
}
}
}
do.call("rbind",lst)
This works but I want to make it more flexible. As it is now, to compare 4 numbers instead of 3 I'd need to write a new for loop. I was thinking of a function like all_comb(vector, N)
that is equivalent to the nested loops above but I can't find it nor I know how to implement it elegantly.
Thank you!