如何快速从R中的组中取样

如何快速从R中的组中取样,r,sample,dplyr,R,Sample,Dplyr,我有一个大型数据集,x,其中包含复制的值, 其中一些在其变量中重复: set.seed(40) x <- data.frame(matrix(round(runif(1000)), ncol = 10)) x_unique <- x[!duplicated(x),] set.seed(40) x您可以使用rep()创建索引向量,然后使用此索引向量对数据进行子集设置 试试这个: idx <- rep(1:length(s), times=s) 然后进行子集设置。请注意,新副本

我有一个大型数据集,
x
,其中包含复制的值, 其中一些在其变量中重复:

set.seed(40)
x <- data.frame(matrix(round(runif(1000)), ncol = 10))
x_unique <- x[!duplicated(x),]
set.seed(40)
x您可以使用
rep()
创建索引向量,然后使用此索引向量对数据进行子集设置

试试这个:

idx <- rep(1:length(s), times=s)
然后进行子集设置。请注意,新副本的行名称如何指示复制

x_unique[idx, ]

     X1 X2 X3 X4 X5 X6 X7 X8 X9 X10
1     1  1  0  0  0  1  0  0  1   0
2     1  0  1  0  0  1  0  0  0   0
2.1   1  0  1  0  0  1  0  0  0   0
3     1  1  0  0  1  0  0  0  1   0
6     0  0  0  0  1  1  0  0  0   0
7     0  1  1  0  1  1  0  1  1   1
8     1  1  0  1  0  0  1  1  0   0
10    0  0  1  0  1  1  1  1  0   0
....

有效地做到这一点的关键是找出如何使用 索引,以及如何尽可能多地进行矢量化。对于你的问题, 如果找到每个重复行的索引,事情就会变得容易得多:

set.seed(40)
x <- data.frame(matrix(round(runif(1000)), ncol = 10))

index <- 1:nrow(x)
grouped_index <- split(index, x, drop = TRUE)
names(grouped_index) <- NULL
如果要保持原始顺序,请使用
sort()

我认为这段代码中的瓶颈将是
split()
:base R不是 有一种高效的散列数据帧的方法,因此依赖于粘贴
列放在一起。

只是一个小问题,它意味着每次迭代
for
循环,都会覆盖
sel
对象。这可能不是你想要做的。它没有完全覆盖sel:前面的信息被c(sel,…)连接起来。啊,是的,我错过了。最好(从速度的角度)初始化所需长度的向量,然后使用
[
提取而不是重复
c
向量。好的,谢谢你的提示-在这种情况下,速度非常重要。但是我看不出你的建议在这种情况下会起什么作用。请提供你的意思的示例代码。可能类似于:
sel谢谢你的回答,但这不是我想要的…我会我喜欢从x中随机抽样,而不是从x中唯一抽样。原因是x中还有其他变量没有显示。因此,请考虑上面示例中的x唯一[32],这与x[32,],x[34,]和x[84,]相同。我想要样本(c(32,34,84),s[32])对于这个例子,每种可能性都有1/3的几率被选中。另外,我相信你的答案会有所帮助,Andrie@RobinLovelace这是否正好回答了你的问题?它是重复的吗?取决于你的出发点,我想-我从许多不同的列开始,然后我将它们转换成一个变量x_代码,这是类比的我们可以在另一个问题中分类。我也在寻找一种快速分类的方法,所以这也不一样。但是有没有一种
dplyr
ish的方法来做这件事(它会散列数据。帧)?感谢Hadley方法-以前没有使用过Map,而且似乎工作得很好,速度快了大约3倍:
microbenchmark(MapMethod(),original_method())单位:毫秒expr min lq MENTARY uq max neval映射方法()106.0149 109.2071 111.8960 116.2424 195.7272 100原始方法()293.9523 301.0262 305.6481 311.8210 355.2843 100
是赢家,如果有dplyr方法……而且,结果也不完全相同:
s
对象是有序的,因此
sel
必须在与
x
@Arun的顺序相同的数据上生成,这不是真正的-它是
sample\n()的变体
,具有不同的
n
。dplyr还不太支持按索引选择行。下一个版本可能支持
切片(x,sample(n(),rpois(1,0.8))
@RobinLovelace我不确定我是否遵循:我的代码没有
s
对象。
idx <- rep(1:length(s), times=s)
idx
 [1]  1  2  2  3  6  7  8 10 11 13 14 14 ......
x_unique[idx, ]

     X1 X2 X3 X4 X5 X6 X7 X8 X9 X10
1     1  1  0  0  0  1  0  0  1   0
2     1  0  1  0  0  1  0  0  0   0
2.1   1  0  1  0  0  1  0  0  0   0
3     1  1  0  0  1  0  0  0  1   0
6     0  0  0  0  1  1  0  0  0   0
7     0  1  1  0  1  1  0  1  1   1
8     1  1  0  1  0  0  1  1  0   0
10    0  0  1  0  1  1  1  1  0   0
....
set.seed(40)
x <- data.frame(matrix(round(runif(1000)), ncol = 10))

index <- 1:nrow(x)
grouped_index <- split(index, x, drop = TRUE)
names(grouped_index) <- NULL
sample2 <- function(x, n, ...) {
  if (length(x) == 1) return(rep(x, n))
  sample(x, n, ...)
}

samples <- rpois(n = length(grouped_index), lambda = 0.9)
sel <- unlist(Map(sample2, grouped_index, samples, replace = TRUE))
sel
#>  [1]  66  99  99   2   6  31  90  25  42  57  14  14   8   8  12  77  60
#> [18]  17  17  92  76  76  76  70  95  36  36  36 100  91  41  41  28  69
#> [35]  69  54  54  54  54  81  64  96  35  39  29  11  74  93  82  82  24
#> [52]  46  48  48  48  51  51  73  20  37  71  71  58  16  68  94  94  94
#> [69]  80  80  80  13  13  87  87  67  67  86  49  49  88  88  52  75  47
#> [86]  89   7  79  63  78  72  72  19
sort(sel)
#>  [1]   2   6   7   8   8  11  12  13  13  14  14  16  17  17  19  20  24
#> [18]  25  28  29  31  35  36  36  36  37  39  41  41  42  46  47  48  48
#> [35]  48  49  49  51  51  52  54  54  54  54  57  58  60  63  64  66  67
#> [52]  67  68  69  69  70  71  71  72  72  73  74  75  76  76  76  77  78
#> [69]  79  80  80  80  81  82  82  86  87  87  88  88  89  90  91  92  93
#> [86]  94  94  94  95  96  99  99 100