如何在R中基于特定变量匹配数据:构建女性生育史
问题
我有一份2016年伊朗人口普查的抽样数据,样本量150万,占总人口7500万的2%。以下是22条个体示例数据:
sample <- structure(list(household.ID = c(16523634, 16523634, 16523634, 16523634,16525912, 16525912, 16540127,16540127, 16598050, 16598050, 16611764,16611764, 16611764, 16643309, 16643309, 16652356, 16652356,16652356, 16672105, 16672105, 16672105,16672105 ),Member.ID= c(16527193, 16529443, 16532250, 16534992,16527527, 16529230, 16542499,16545263, 16616975, 16620223, 16633984,16642611, 16650837, 16646986, 16650210, 16660335, 16665128,16668381, 16676674, 16681528, 16685073,16687491 ),Relatshinship= c(1,2,3,3,1,2,1,2,1,3,1,2,3,1,2,1,2,3,1,2,3,3),birth.year= c(1346,1348,1376,1377,1357,1367,1316,1319,1329,1374,1339,1342,1367,1343,1336 ,1321 ,1326,1367,1338,1352,1372,1381),Gender = c(1,2 ,1,2,1,2,1 ,2,1 ,1,1 ,2,1 ,1 ,2 ,1,2 ,2,1 ,2,1,1),age = c(49,47,19 ,18,38,28,78,75,66 ,21,56 ,52 ,28,51 ,58 ,74 ,68 ,27 ,56 ,43,23 ,13),marriage.stuatus= c(1,1 ,4 ,4 ,1,1,1,1,2,4,1,1 ,1,1 ,1,1,1 ,4,1 ,1,4 ,4), number.of.children.ever.born= c(NA,2,NA,NA,NA,NA,NA,6,NA,NA,NA,2,NA,NA,3,NA,3,NA,NA,2,NA,NA), number.of.living.children = c(NA,2,NA,NA,NA,NA,NA,4,NA,NA,NA,2,NA,NA,3,NA,3,NA,NA,2,NA, NA)), row.names = c(NA, -22L),class = "data.frame")
需要为女性构建生育史,将家庭中的儿童匹配到对应的母亲。字段说明:
Relatshinship:1=户主,2=户主配偶(妻子),3=子女,4=女婿/儿媳等- 示例:家庭ID16523634包含户主(男,Gender=1)、妻子及两名子女(19岁儿子、18岁女儿)
最终需要生成每位母亲的记录,包含各子女年龄,格式如下:
| H.ID | M.ID | B.year | Gender | age | First child | second child | Third child |
|---|---|---|---|---|---|---|---|
| 16523634 | 16529443 | 1348 | 2 | 47 | 19 | 18 | NA |
请提供R语言实现方法。
解决方案
可以通过分组处理家庭数据,匹配母亲与子女,再将子女年龄按长表转宽表实现,步骤如下:
- 加载必要包(未安装先运行
install.packages(c("dplyr", "tidyr"))):
library(dplyr) library(tidyr)
- 核心处理代码:
# 按家庭分组,匹配母亲与子女并整理成目标格式 mother_child_data <- sample %>% # 按家庭ID分组处理 group_by(household.ID) %>% # 筛选出母亲(户主配偶)和子女 filter(Relatshinship %in% c(2, 3)) %>% # 为同家庭子女按年龄从大到小排序,标记出生顺序 mutate(child_order = ifelse(Relatshinship == 3, row_number(desc(age)), NA)) %>% # 提取母亲的核心信息字段 mutate( M.ID = ifelse(Relatshinship == 2, Member.ID, NA), B.year = ifelse(Relatshinship == 2, birth.year, NA), Gender = ifelse(Relatshinship == 2, Gender, NA), age = ifelse(Relatshinship == 2, age, NA) ) %>% # 将母亲信息填充到同家庭的所有行,确保子女与母亲关联 fill(M.ID, B.year, Gender, age, .direction = "downup") %>% # 把子女年龄从长表转为宽表,生成对应出生顺序的列 pivot_wider( id_cols = c(household.ID, M.ID, B.year, Gender, age), names_from = child_order, names_prefix = "child_", values_from = age, values_fill = NA ) %>% # 重命名列以匹配示例格式 rename( H.ID = household.ID, `First child` = child_1, `second child` = child_2, `Third child` = child_3 ) %>% # 去重,每个母亲只保留一条记录 distinct(H.ID, M.ID, .keep_all = TRUE) %>% ungroup() # 查看最终结果 print(mother_child_data)
- 代码逻辑说明:
- 按家庭分组后,只保留母亲和子女的记录,减少无效数据;
- 为子女按年龄降序编号,确定老大、老二等出生顺序;
- 用
fill函数将母亲的信息同步到同家庭的子女行,确保母子关联; - 通过
pivot_wider将子女年龄从纵向转为横向,生成对应顺序的列; - 最后去重得到每位母亲的唯一记录,自动补全无对应子女的NA值。
内容的提问来源于stack exchange,提问作者Mohammad Haddadi
相关产品推荐
相关产品推荐

