R语言如何实现不等样本量分组的组内有放回抽样
问题说明
现有如下结构的R数据框df:
set.seed(123) n1 <- 5 n2 <- 8 DVm <- rnorm(n1, 180, 10) DVf <- rnorm(n2, 175, 6) df <- data.frame(DV=c(DVm, DVf), IV=factor(rep(c("m", "f"), c(n1, n2)))) df
运行后输出的原始数据内容:
DV IV 1 174.3952 m 2 177.6982 m 3 195.5871 m 4 180.7051 m 5 181.2929 m 6 185.2904 f 7 177.7655 f 8 167.4096 f 9 170.8789 f 10 172.3260 f 11 182.3445 f 12 177.1589 f 13 177.4046 f
需求为生成新数据框,满足:
- 对
IV=="m"的分组,在组内对DV做有放回抽样,抽取数量为n1=5 - 对
IV=="f"的分组,在组内对DV做有放回抽样,抽取数量为n2=8 - 新数据框和原数据框维度、结构完全一致,抽样全程在各自分组内部完成
需要确认是否存在可直接实现该操作的单个函数/简洁实现流程。
实现方法
存在非常简洁的直接实现方式,不需要手动写分组循环拆分合并数据,最常用的方案是使用dplyr包的分组抽样函数,单流程即可输出符合要求的结果:
# 加载dplyr包 library(dplyr) # 固定随机种子方便结果复现 set.seed(1234) df_resampled <- df %>% group_by(IV) %>% slice_sample(prop = 1, replace = TRUE) %>% ungroup()
参数说明:
group_by(IV):指定按IV列的分组类别拆分数据,后续所有操作会按组独立执行slice_sample(prop = 1, replace = TRUE):prop = 1表示每组抽取原组100%数量的样本(自动匹配m组抽5个、f组抽8个的要求),replace = TRUE指定抽样方式为有放回抽样ungroup():移除结果的分组属性,返回和原数据框结构完全一致的普通数据框。
如果不想加载第三方包,基础R也可以通过一行代码实现相同效果:
set.seed(1234) df_resampled_base <- df[as.logical(ave(as.numeric(row.names(df)), df$IV, FUN = function(x) sample(x, replace = TRUE))), ]
两种方式输出的结果都完全符合要求:和原数据维度一致,抽样仅在对应分组内部完成。
内容的提问来源于stack exchange,提问作者David Z
相关产品推荐
相关产品推荐

