I'm looking to permute (or combine) c("a","b","c") within six positions under the condition to have always sequences with alternate elements, e.g abcbab.
Permutations could easily get with:
abc<-c("a","b","c")
permutations(n=3,r=6,v=abc,repeats.allowed=T)
I think is not possible to do that with gtools, and I've been trying to design a function for that -even though I think it may already exist.
Since you're looking for permutations,
expand.gridcan work as well aspermutations. But since you don't want like-neighbors, we can shorten the dimensionality of it considerably. I think this is legitimate random-wise!Up front:
Walk-through:
gtools::permutations, or we can useexpand.grid... I'll use the latter, I don't know if it's much faster, but it does a short-cut I need (more later)however, since we don't want neighbors to be the same, I thought that instead of each row of values being the straight index, we
cumsumthem; by using this, we can control the ability of the cumulative sum to re-reach the same value ... by removing0andlength(abc)from the list of possible values, we remove the possibility of (a) never staying the same, and (b) never increasing actually one vector-length (repeating the same value); as a walk-through:Since the first value can be all three values, it's
1:3, but each additional is intended to be 1 or 2 away from it.okay, that doesn't seem that useful (since it goes beyond the length of the vector), so we can invoke the modulus operator and a shift (since modulus returns 0-based, we want 1-based):
To verify this works, we can do a
diffacross each row and look for0:to automate this to an arbitrary vector, we enlist the help of
replicateto generate the list of possible vectors:and then
do.callto expand it.one you have the matrix of indices,
and then replace each index with the vector's value:
and then we
cbindthe united string (viaapplyandpaste)Performance:
I tried the infix (non-
%>%) tidy2 version just for kicks, and though I was confident it would theoretically be faster, I didn't realize it would shave over 7% off the run-times. (The 50163 is likely R garbage-collecting, not "real".) The price we pay for readability/maintainability.