如何在R中基于样本量与百分比还原二进制原始数据集?
基于dplyr实现百分比到二进制列的数据集展开
需求说明
现有数据集包含year、location、ID、sample_size、percent字段,每个year/location/ID组合对应固定样本量和“是”的占比。需要生成包含二进制Y_N列(1=是,0=否)的完整展开数据集,使每个组合的Y_N分布匹配对应的percent数值,且希望通过dplyr实现分组展开。
示例输入数据集
table <- "year location ID sample_size percent 1 2000 A 1a 10 40 2 2001 A 1a 10 30 3 2000 B 2a 10 70 4 2001 B 2a 10 90 5 2005 C 1a 20 10 6 2006 C 1a 20 50" # 创建数据框 df <- read.table(text=table, header = TRUE)
实现方案
可以用dplyr结合tidyr的unnest()实现,核心思路是分组后生成对应数量的1和0,再展开成多行数据:
library(dplyr) library(tidyr) expanded_df <- df %>% # 按唯一组合分组 group_by(year, location, ID) %>% # 生成Y_N列表:先计算1的数量,再补0到样本量 mutate(Y_N = list(c(rep(1, round(sample_size * percent / 100)), rep(0, sample_size - round(sample_size * percent / 100))))) %>% # 展开列表列为多行 unnest(Y_N) %>% # 移除原sample_size和percent字段(可选操作) select(-sample_size, -percent) %>% ungroup() # 查看结果 head(expanded_df, 20)
补充说明
round(sample_size * percent / 100)用于计算每个组中1的数量,确保百分比匹配;若需要更精确处理小数百分比,可替换为floor或ceiling函数。- 若希望1和0随机分布(而非示例中前n个为1),可在
list()内添加sample()打乱顺序:
mutate(Y_N = list(sample(c(rep(1, round(sample_size * percent / 100)), rep(0, sample_size - round(sample_size * percent / 100))))))
示例输出(前20行)
对应输入的前两个组合,展开后结果如下:
# year location ID Y_N # 1 2000 A 1a 1 # 2 2000 A 1a 1 # 3 2000 A 1a 1 # 4 2000 A 1a 1 # 5 2000 A 1a 0 # 6 2000 A 1a 0 # 7 2000 A 1a 0 # 8 2000 A 1a 0 # 9 2000 A 1a 0 # 10 2000 A 1a 0 # 11 2001 A 1a 1 # 12 2001 A 1a 1 # 13 2001 A 1a 1 # 14 2001 A 1a 0 # 15 2001 A 1a 0 # 16 2001 A 1a 0 # 17 2001 A 1a 0 # 18 2001 A 1a 0 # 19 2001 A 1a 0 # 20 2001 A 1a 0
内容的提问来源于stack exchange,提问作者cgxytf
相关产品推荐
相关产品推荐

