Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/performance/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
有效地在R中创建向量的无序_R_Performance_Vector_Permutation - Fatal编程技术网

有效地在R中创建向量的无序

有效地在R中创建向量的无序,r,performance,vector,permutation,R,Performance,Vector,Permutation,我正在寻找一种有效的方法,在R中创建一个向量的错乱(和相反的特定排列)。 就我所见,没有基函数能做到这一点,这里也没有太多关于它的内容 一个明显的开始是sample,它创建了向量的排列。但我需要这个排列没有固定点,所以是向量的错乱。有关此主题的详细说明,请参阅 这是我的第一个方法: derangr <- function(x){ while(TRUE){ xp <- sample(x) if(sum(xp == x) == 0) break }

我正在寻找一种有效的方法,在R中创建一个向量的错乱(和相反的特定排列)。 就我所见,没有基函数能做到这一点,这里也没有太多关于它的内容

一个明显的开始是
sample
,它创建了向量的排列。但我需要这个排列没有固定点,所以是向量的错乱。有关此主题的详细说明,请参阅

这是我的第一个方法:

derangr <- function(x){

  while(TRUE){

    xp <- sample(x)

     if(sum(xp == x) == 0) break

  }

  return(xp)

}
所以我想知道是否有更好的方法可以做到这一点,可能是用某种向量化来代替
,而
。我还想关注可伸缩性

以下是两个示例的
microbenchmark

library(microbenchmark)

> microbenchmark(derangr(1:10),times = 10000)
Unit: microseconds
          expr   min     lq    mean  median      uq      max neval
 derangr(1:10) 8.359 15.492 40.1807 28.3195 49.4435 6866.453 10000

> microbenchmark(derangr(LETTERS),times = 10000)
Unit: microseconds
             expr    min     lq     mean  median      uq      max neval
 derangr(LETTERS) 24.385 31.123 34.75819 32.4475 34.3225 10200.17 10000
同样的问题也适用于相反的情况,即产生具有给定数量的固定点的排列
n

arrangr <- function(x,n){

  while(TRUE){

    xp <- sample(x)

     if(sum(xp == x) == n) break
  }

  return(xp)

}

arrangr如果您没有唯一的值,您可以重新排列一个索引,如,并使用它以新的顺序对输入向量进行子集设置。在这种情况下,如果您有例如
rep(字母,2)
第一个
A
和第二个
A
可以互换。Q中提出的
derangr()
函数也将重新排列这些

derangr2 <- function(x){
  ind <- seq_along(x)
  while(TRUE){
    indp <- sample(ind)
    if(sum(indp == ind) == 0) break

  }
  return(x[indp])
}
然而,如果您只面对唯一的值,那么这种方法不会有太多的改进

microbenchmark(derangr(1:1000), derangr2(1:1000), times = 1000)
# Unit: microseconds
#             expr    min     lq     mean median      uq      max neval
#  derangr(1:1000) 19.341 21.333 61.55154 40.959 78.0775 2770.382  1000
# derangr2(1:1000) 23.608 25.884 72.76647 46.079 84.1930 2674.243  1000

向量中的某些值是否像在
rep(字母,2)
中那样多次出现?如果是这样的话,第一个“A”和第二个“A”互换有关系吗?我在寻找一个通用的解决方案,所以你提出了一个很好的观点。我的函数采用唯一的值。如果您有重复的值,那么第一个“A”与第二个“A”互换也没关系,只要没有元素(或者相反地,
n
)元素停留在它们以前的位置。+1一旦我读了您的评论,我就有了类似的想法。这绝对是一个进步。只是回顾一下我的部分问题,没有办法替代
while
或其他循环?如果是这样,我认为这是一个解决方案。而且,
derangr2
是否应该返回
x[indp]
?我刚刚尝试了只重新排列
indp==ind
的值。然而,理论上,如果只剩下一个符合此条件的值,则这可能会创建一个无限循环。。。所以没有改进。我可能弄错了,但我认为
derangr3
无法执行。在定义indp之前,您正在对其进行评估。我承认我确实兴奋了一会儿,直到我意识到这也是我的感受,因此我接受了您的解决方案。谢谢你的努力!
microbenchmark(derangr(rep(LETTERS, 4)), 
               derangr2(rep(LETTERS, 4)), times = 1000)

# Unit: microseconds
#                      expr   min       lq       mean  median      uq      max neval
#  derangr(rep(LETTERS, 4)) 6.258 113.4895 441.831094 251.724 549.384 5837.143  1000
# derangr2(rep(LETTERS, 4)) 6.542   7.3960  23.173800  12.800  22.755 4645.936  1000
microbenchmark(derangr(1:1000), derangr2(1:1000), times = 1000)
# Unit: microseconds
#             expr    min     lq     mean median      uq      max neval
#  derangr(1:1000) 19.341 21.333 61.55154 40.959 78.0775 2770.382  1000
# derangr2(1:1000) 23.608 25.884 72.76647 46.079 84.1930 2674.243  1000