有没有一种方法可以在不使用 R 中的 sample() 函数的情况下创建向量的排列?

Is there a way to create a permutation of a vector without using the sample() function in R?

希望您今天过得愉快。我想知道是否有办法在 R 中创建向量中值的排列(重新排列)?

我的教授提供了一项作业,其中我们应该为随机化测试创建函数,一个是使用 sample() 创建排列,另一个是不使用 sample() 函数。到目前为止,我所有的努力都没有结果,因为我能找到的任何答案总是使用 sample() 函数。我尝试了其他几种方法,例如使用 runif() 建立索引和编写自己的函数,但都无济于事。唉,认输来救赎了

使用 sample() 函数时,代码如下所示:

#create the groups
a <- c(2,5,5,6,6,7,8,9)
b <- c(1,1,2,3,3,4,5,7,7,8)

#create a permutation of the combined vector without replacement using the sample function()
permsample <-sample(c(a,b),replace=FALSE)

permsample
[1] 2 5 6 1 7 7 3 8 6 3 5 9 2 7 4 8 1 5

而且,作为参考,我函数的整个代码如下所示:

PermutationTtest <- function(a, b, P){
  sample.t.value <- t.test(a, b)$statistic
  perm.t.values<-matrix(rep(0,P),P,1)
  N <-length(a)
  M <-length(b)
  for (i in 1:P)
  {
    permsample <-sample(c(a,b),replace=FALSE)
    pgroup1 <- permsample[1:N]
    pgroup2 <- permsample[(N+1) : (N+M)]
    perm.t.values[i]<-  t.test(pgroup1, pgroup2)$statistic
  }
  return(mean(perm.t.values))
}

如果不使用 sample() 函数并且在 base R 的范围内,我将如何实现同样的目标?我的教授给出的唯一提示是“使用索引”。非常感谢您的帮助,祝您有愉快的一天。

您可以使用 runif() 生成介于 1.0 和最终数组长度之间的值。 floor() 函数 returns 该数字的整数部分。在每次迭代中,我减小要选择的随机数的范围,将原始数组第 rn 位置的元素附加到新数组并将其删除。

a <- c(2,5,5,6,6,7,8,9)
b <- c(1,1,2,3,3,4,5,7,7,8)

c<-c(a,b)

index<-length(c)
perm<-c()

for(i in 1:length(c)){
  rn = floor(runif(1, min=1, max=index))
  perm<-append(perm,c[rn])
  c=c[-rn]
  index=index-1
}


如果我们使用连续的数字,更容易看出发生了什么:

a <- 1:8
b <- 9:17
ab <- c(a, b)
ab
# [1]  1  2  3  4  5  6  7  8  9 10 11 12 13 14 15 16 17

现在抽取17(length(ab))个随机数并用它们来排序ab:

rnd <- runif(length(ab))
ab[order(rnd)]
#  [1]  5 13 11 12  6  1 17  3 10  2  8 16  7  4  9 15 14
rnd <- runif(length(ab))
ab[order(rnd)]
#  [1] 14 11  5 15 10  7 13  9 17  8  2  6  1  4 16 12  3

对于每个排列,只需再抽取 17 个随机数。