通过替换按组生成随机数

Generate random numbers by group with replacement

** 编辑是因为我是个傻瓜 - 有替换,不是没有 **

我有一个大型(> 500k 行)数据集,其中包含 421 个组,由两个分组变量定义。样本数据如下:

df<-data.frame(group_one=rep((0:9),26), group_two=rep((letters),10))

head(df)

  group_one group_two
1         0         a
2         1         b
3         2         c
4         3         d
5         4         e
6         5         f

...等等。

我想要的是按 (group_one x group_two) 中的成员划分的一些分层样本(目前 k = 12,但该数字可能会有所不同)。每个组中的成员资格应由一个新列 sample_membership 表示,该列的值为 1 到 k(此时再次为 12)。我应该能够按 sample_membership 进行子集化并获得最多 12 个不同的样本,在考虑 group_one 和 group_two.

时每个样本都具有代表性

最终数据集将如下所示:

  group_one group_two sample_membership
1         0         a                 1  
2         0         a                12
3         0         a                 5
4         1         a                 5
5         1         a                 7
6         1         a                 9

想法?非常感谢!

未经测试的示例使用 dplyr,如果它不起作用,它可能会为您指明正确的方向。

library( dplyr )
set.seed(123)
df <- data.frame(
  group_one = as.integer( runif( 1000, 1, 6) ),
  group_two = sample( LETTERS[1:6], 1000, TRUE)
) %>%
  group_by( group_one, group_two ) %>%
  mutate(
    sample_membership = sample( seq(1, length(group_one) ), length(group_one), FALSE)
  )

祝你好运!

也许是这样的?:

library(dplyr)
  df %>% 
    group_by(group_one, group_two) %>% 
    mutate(sample_membership = sample(1:12, n(), replace = FALSE))

这是一个基本的 R 方法,假设您的 data.frame 按组排序:

# get number of observations for each group
groupCnt <- with(df, aggregate(group_one, list(group_one, group_two), FUN=length))$x

# for reproducibility, set the seed
set.seed(1234)    
# get sample by group
df$sample <- c(sapply(groupCnt, function(i) sample(12, i, replace=TRUE)))

这是一种单行 data.table 方法,如果您的 data.frame.

很长,您绝对应该考虑这种方法
library(data.table)

setDT(df)

df[, sample_membership := sample.int(12, .N, replace=TRUE), keyby = .(group_one, group_two)]

df
#    group_one group_two sample_membership
#   1:         0         a                 9
#   2:         0         a                 8
#   3:         0         c                10
#   4:         0         c                 4
#   5:         0         e                 9
# ---                                      
# 256:         9         v                 4
# 257:         9         x                 7
# 258:         9         x                11
# 259:         9         z                 3
# 260:         9         z                 8

对于无放回抽样,请使用 replace=FALSE,但如其他地方所述,请确保每个组的成员少于 k或:

如果你想使用 "sampling without unnecessary replacement"(编造这个 - 不确定这里的正确术语是什么)因为你每个组有超过 k 个成员但是仍然希望保持组的大小尽可能均匀,你可以这样做:

# example with bigger groups
k <- 12L
big_df <- data.frame(group_one=rep((0:9),260), group_two=rep((letters),100))
setDT(big_df)

big_df[, sample_round := rep(1:.N, each=k, length.out=.N), keyby = .(group_one, group_two)]
big_df[, sample_membership := sample.int(k, .N, replace=FALSE), keyby = .(group_one, group_two, sample_round)]
head(big_df, 15) # you can see first repeat does not occur until row k+1 

在每个 "sampling round" 中(组中的前 k 个观察值,组中的第二个 k 个观察值,等等)有无放回抽样。然后,如有必要,下一轮采样使所有 k 分配再次可用。

这种方法可以真正均匀地对样本进行分层(但只有当每个组中有 k 的倍数成员时,才能做到完全均匀)。