注意到您的数据实际上是从 1 到 5 的 5 个级别,编码为“a”、“b”、“a”、“c”和“d”,我开始寻找方法来获取数字 1-5,然后将它们重新映射到您使用的级别。
让我们从输入数据开始:
my_vec <- c("a","b","a","c","d") # the character
my_vec_ind <- seq(1,length(my_vec),1) # their identifier
为了得到排列,我应用了Generating all distinct permutations of a list in R 给出的函数:
permutations <- function(n){
if(n==1){
return(matrix(1))
} else {
sp <- permutations(n-1)
p <- nrow(sp)
A <- matrix(nrow=n*p,ncol=n)
for(i in 1:n){
A[(i-1)*p+1:p,] <- cbind(i,sp+(sp>=i))
}
return(A)
}
}
首先,使用排列创建一个 data.frame:
tmp <- data.frame(permutations(length(my_vec)))
您现在有一个包含 120 行的数据框 tmp,其中每一行都是数字 1-5 的唯一排列:
>tmp
X1 X2 X3 X4 X5
1 1 2 3 4 5
2 1 2 3 5 4
3 1 2 4 3 5
...
119 5 4 3 1 2
120 5 4 3 2 1
现在您需要将它们重新映射到您拥有的字符串。您可以使用gsub() 主题的变体重新映射它们,此处建议:R: replace characters using gsub, how to create a function?
gsub2 <- function(pattern, replacement, x, ...) {
for(i in 1:length(pattern))
x <- gsub(pattern[i], replacement[i], x, ...)
x
}
gsub() 不起作用,因为替换数组中有多个值。
您还需要一个可以使用lapply() 调用的函数,以便在tmp data.frame 的每个元素上使用gsub2() 函数。
remap <- function(x,
old,
new){
return(gsub2(pattern = old,
replacement = new,
fixed = TRUE,
x = as.character(x)))
}
差不多了。我们像这样进行映射:
shuffled_vec <- as.data.frame(lapply(tmp,
remap,
old = as.character(my_vec_ind),
new = my_vec))
可以简化为...
shuffled_vec <- as.data.frame(lapply(data.frame(permutations(length(my_vec))),
remap,
old = as.character(my_vec_ind),
new = my_vec))
.. 如果你觉得有必要。
这给了你所需的答案:
> shuffled_vec
X1 X2 X3 X4 X5
1 a b a c d
2 a b a d c
3 a b c a d
...
119 d c a a b
120 d c a b a