通过替换按组生成随机数
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 的倍数成员时,才能做到完全均匀)。
** 编辑是因为我是个傻瓜 - 有替换,不是没有 **
我有一个大型(> 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 的倍数成员时,才能做到完全均匀)。