R语言中基于虚拟变量的控制月份随机抽取需求
问题描述
我有一个带唯一id的数据集,结构如下:
structure(list(id = c(1, 2, 3, 4), control_1_2017 = c(1, 0, 1, 0), control_2_2017 = c(1, 0, 1, 0), control_3_2017 = c(1, 1, 1, 0), control_4_2017 = c(1, 0, 1, 1), control_5_2017 = c(0, 1, 1, 0), `Ex of desired output` = c("1_2017", "5_2017", "2_2017", "4_2017")), class = c("tbl_df", "tbl", "data.frame"), row.names = c(NA, -4L))
每列是虚拟变量(dummy),用于标识对应id是否可在该月份作为控制组。需求如下:
- 每个
id若存在多个取值为1的符合条件月份,随机抽取一个 - 若仅存在一个符合条件的月份,直接选择该月份
- 输出的月份格式需与列名中的格式一致(如
1_2017) - 数据集可能包含跨多年的大量月份及多个
id
解决方案
使用tidyverse工具包可高效处理这类需求,代码如下:
# 加载工具包 library(tidyverse) # 定义数据集(实际使用时替换为你的数据集) df <- structure(list(id = c(1, 2, 3, 4), control_1_2017 = c(1, 0, 1, 0), control_2_2017 = c(1, 0, 1, 0), control_3_2017 = c(1, 1, 1, 0), control_4_2017 = c(1, 0, 1, 1), control_5_2017 = c(0, 1, 1, 0), `Ex of desired output` = c("1_2017", "5_2017", "2_2017", "4_2017")), class = c("tbl_df", "tbl", "data.frame"), row.names = c(NA, -4L)) # 核心处理流程 result <- df %>% # 移除示例输出列(实际数据无此列可删除该行) select(-`Ex of desired output`) %>% # 宽格式转长格式,拆分月份列与 eligibility 值 pivot_longer( cols = starts_with("control_"), names_to = "month", values_to = "is_eligible" ) %>% # 筛选符合条件的行(虚拟变量为1) filter(is_eligible == 1) %>% # 提取目标月份格式(去掉control_前缀) mutate(month = str_remove(month, "^control_")) %>% # 按id分组,随机抽取1行(组内仅1行时直接保留) group_by(id) %>% slice_sample(n = 1) %>% ungroup() %>% # 整理结果列 select(id, selected_month = month) # 查看结果 print(result)
代码说明
pivot_longer:将宽格式的多月份列转换为长格式,便于后续过滤与抽样操作str_remove:剔除列名中的control_前缀,生成要求的数字_年份格式slice_sample(n=1):按id分组后随机抽取1行,自动适配组内仅1行的场景- 代码可兼容大规模数据集,处理效率稳定
内容的提问来源于stack exchange,提问作者R novice
相关产品推荐
相关产品推荐

