1

我想使用permute::shuffle/shuffleSet()或任何其他函数对 R 中的单词列表进行洗牌。

代码:

require(permute)
a <- c("Ar","Ba","Bl","Bu","Ca")
x <- list(a)
x
shuffleSet(x)
shuffle(x)

但是当我尝试这段代码时,我得到了错误

shuffleSet : Error in seq_len(n) : argument must be coercible to non-negative integer

shuffle : Error in factor(rep(1, n)) : 
  (list) object cannot be coerced to type 'integer'

应该permute::shuffle/shuffleSet()只用于整数吗?如何对上述列表执行随机播放?有没有其他功能可以做到这一点?

4

3 回答 3

3

为什么不使用样本?

     > a <- c("Ar","Ba","Bl","Bu","Ca")
     > a
     [1] "Ar" "Ba" "Bl" "Bu" "Ca"
     > x <- list(a)
     > x
     [[1]]
     [1] "Ar" "Ba" "Bl" "Bu" "Ca"
     > x[[1]][sample(1:length(a))]
     [1] "Ba" "Bu" "Ar" "Bl" "Ca"
于 2016-02-19T10:47:29.043 回答
2

如果要生成整个 shuffle 集,而不是随机排列,可以尝试以下操作:

require(permute)
a <- c("Ar","Ba","Bl","Bu","Ca")
x <- list(a)
y <- shuffleSet(as.factor(x[[1]]), quietly=TRUE)
y[] <- sapply(y, function(x) a[x])
y <- as.data.frame(y)
> head(y)
#  V1 V2 V3 V4 V5
#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

希望这可以帮助。

于 2016-02-19T10:55:51.480 回答
2

这实际上是其他答案的后续行动 - 对他们两个都投赞成票,而不是这个。

如果您要做的只是随机排列观察向量,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()设计为受限排列的接口,但它们需要将完全随机化作为特殊情况处理,因此如果您深入挖掘,您会看到shuffleshuffleSet调用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中修复它,以便将来可以使用。)

shuffleshuffleSet返回要排列的事物的索引排列,而不是排列后的元素本身;事实上,他们从未真正了解您想要置换的实际元素/事物。因此,@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而不是替换原地

于 2016-02-19T20:04:20.633 回答