置换10,000次矢量元素 - 有效吗? (R)

时间:2014-07-07 02:04:38

标签: r vector sequence permutation sequential

这个问题很简单。但是,我发现它的解决方案非常耗费内存和时间。我想知道这是否可以在R中完成而不会将一台机器磨成灰尘。

拿一个矢量:

x<-c("A", "B", "B", "E", "C", "C", "D", "E", "A', "C")

这个有10个元素。有五个独特的元素。因此,重要的是,重复一些元素,并且任何排列应包含每种类型元素的相同总数。我希望将这个序列/向量置换10,000次,每个序列是一个随机生成的唯一序列。根据我的真实数据,我可以为多达1000个元素进行这些排列。这可能很难有效地完成。

要获得一个排列,您可以这样做:

sample(x)

或者,从gtools包中:

permute(x)

我可以写一些代码来做10,000次,但很可能有重复。有没有办法做到这一点并删除重复,直到达到10,000?

关于stackoverflow和statsoverflow的其他类似问题已经提出了关于生成序列的所有唯一排列的问题。这些问题在这里:

Shuffling a vector - all possible outcomes of sample()?

Generating all distinct permutations of a list in R

https://stats.stackexchange.com/questions/24300/how-to-resample-in-r-without-repeating-permutations

这些都是好的,并且产生所有独特排列的建议非常好,并且运行它们并从每个样本中抽取10,000个随机样本以获得10,000个非常容易。但是,如果你超过了向量中的大约10个元素,那么它会占用大量内存。

有关如何有效地执行此操作的任何评论,最多可支持1000个元素。这让我头晕目眩。

3 个答案:

答案 0 :(得分:2)

我不认为计算应该像你实现的那样昂贵。对于小的“x”向量,您可能希望略微过冲(这里,我有点过头了),然后使用duplicated检查重复项。如果所需数量与重复行数之间的差异太大,无法获得所需的10,000,请重复此过程以填补差异,使用rbind将要保留的数据添加到矩阵中来自replicate。这可以在while循环中实现。

x <- c("A", "B", "B", "E", "C", "C", "D", "E", "A", "C")
set.seed(1)
N <- t(replicate(15000, sample(x)))
sum(duplicated(N))
# [1] 1389
out <- N[!(duplicated(N)), ][1:10000, ]
head(out)
#      [,1] [,2] [,3] [,4] [,5] [,6] [,7] [,8] [,9] [,10]
# [1,] "B"  "E"  "C"  "D"  "B"  "E"  "A"  "C"  "C"  "A"  
# [2,] "B"  "B"  "C"  "C"  "C"  "D"  "E"  "E"  "A"  "A"  
# [3,] "C"  "B"  "C"  "A"  "A"  "E"  "D"  "C"  "B"  "E"  
# [4,] "C"  "C"  "E"  "B"  "C"  "E"  "A"  "A"  "D"  "B"  
# [5,] "A"  "C"  "D"  "E"  "E"  "C"  "A"  "B"  "B"  "C"  
# [6,] "C"  "E"  "E"  "B"  "A"  "C"  "D"  "A"  "B"  "C"

duplicated步骤实际上是最贵的,据我所知:

y <- sample(500, 1000, TRUE)
system.time(N <- t(replicate(12000, sample(y))))
# user  system elapsed 
# 2.35    0.08    2.43 
system.time(D <- sum(duplicated(N)))
#  user  system elapsed 
# 14.82    0.01   14.84 
D
# [1] 0

^^在那里,我们的12,000个样本中没有重复项。

答案 1 :(得分:0)

如果您只对前10000个排列感兴趣(按字典顺序排列),则可以使用iterpc库。

library(iterpc)
x <- c("A", "B", "B", "E", "C", "C", "D", "E", "A", "C")
I <- iterpc(table(x), ordered=TRUE)
# first 10000 permutations
result <- getnext(I, d=10000)

获得它们的速度非常快。

> system.time(getnext(I, d=10000))
   user  system elapsed 
  0.004   0.000   0.005 

答案 2 :(得分:-1)

这是一个想法。这不一定是答案,但它对于评论来说太大了。

以有序的方式获取排列,并将它们添加到集合中。例如,如果元素是A,B,C和D:

A B C D
A B D C
A D B C
... so on

一旦您获得了所需的排列数(在您的情况下为10000),就

如果随机化的成本是瓶颈,这种方法应该解决它。