这实际上是其他答案的后续行动 - 对他们两个都投赞成票,而不是这个。
如果您要做的只是随机排列观察向量,sample()
则从基本 R 安装可以正常工作(如@tf 在他们的回答中所示):
a <- c("Ar","Ba","Bl","Bu","Ca")
x <- list(a)
sample(a)
sample(x[[1]])
> sample(a)
[1] "Ca" "Bu" "Ba" "Ar" "Bl"
> sample(x[[1]])
[1] "Bl" "Ba" "Bu" "Ar" "Ca"
请注意,您不需要sample(1:length(a))
或使用它来索引x[[1]]
; sample()
如果你给它一个向量作为输入,它会做正确的事情,如上所示。
shuffle()
并被shuffleSet()
设计为受限排列的接口,但它们需要将完全随机化作为特殊情况处理,因此如果您深入挖掘,您会看到shuffle
或shuffleSet
调用shuffleFree
内部使用sample.int()
(出于效率原因,但出于所有意图和目的,这是sample()
对设置所有参数的更明确的调用。)
因为这两个函数是为更一般的问题而设计的,所以我们只需要知道要迭代的观察次数;因此,两者的第一个论点应该是观察的数量。如果你向他们传递一个向量,那么作为一点糖,我只是n
根据对象的大小(向量的长度,矩阵的 nrow 等)来计算。
@RHertel 指出shuffleSet()
,在这个例子中,生成了 set 的所有排列a
。这是由于在排列集较小时尝试提供更好的随机排列的启发式方法。生成所有排列集的更直接的方法是通过allPerms()
:
> head(allPerms(seq_along(a)))
[,1] [,2] [,3] [,4] [,5]
[1,] 1 2 3 5 4
[2,] 1 2 4 3 5
[3,] 1 2 4 5 3
[4,] 1 2 5 3 4
[5,] 1 2 5 4 3
[6,] 1 3 2 4 5
请注意,这allPerms(a)
不起作用,因为a
它属于类"character"
并且没有nobs()
方法(但我会在permute中修复它,以便将来可以使用。)
shuffle
并shuffleSet
返回要排列的事物的索引排列,而不是排列后的元素本身;事实上,他们从未真正了解您想要置换的实际元素/事物。因此,@RHertel 使用sapply
调用将置换索引应用于a
. 一种更快的方法是存储排列,然后将 的元素重新插入到这个排列矩阵中a
,由排列矩阵索引:
perms <- allPerms(seq_along(a)) # store all permutations
perms[] <- a[perms] # replace elements of perms with shuffled elements of a
> perms <- allPerms(seq_along(a))
> perms[] <- a[perms]
> head(perms)
[,1] [,2] [,3] [,4] [,5]
[1,] "Ar" "Ba" "Bl" "Ca" "Bu"
[2,] "Ar" "Ba" "Bu" "Bl" "Ca"
[3,] "Ar" "Ba" "Bu" "Ca" "Bl"
[4,] "Ar" "Ba" "Ca" "Bl" "Bu"
[5,] "Ar" "Ba" "Ca" "Bu" "Bl"
[6,] "Ar" "Bl" "Ba" "Bu" "Ca"
此处的效率在于,替换是在对 的单个函数调用中完成的<-.[()
,而不是对 的单独调用[()
。你需要[]
onperms
否则你会覆盖perms
而不是替换原地。