基于新tax-unit分组重构家庭关系矩阵的技术求助
解决方案
可以通过dplyr和tidyr的组合操作实现需求,核心思路是先建立原人员编号到纳税单元内新编号的映射,再筛选同单元内的关系并重构矩阵:
library(dplyr) library(tidyr) # 加载示例数据 df <- data.frame(household = c(1,1,1,1,2,2,2,3,3,4,5,5), person = c(1,2,3,4,1,2,3,1,2,1,1,2), r01 = c(NA, 1, 3, 3, NA, 3, 15, NA, 18, NA, NA, 5), r02 = c(1, NA, 3, 3, 7, NA, 3, 18, NA, NA, 9, NA), r03 = c(7, 7, NA, 11, 16, 7, rep(NA,6)), r04 = c(7, 7, 11, rep(NA, 9)), r05 = rep(NA, 12), r06 = rep(NA, 12), household.tu = c("1a", "1a", "1b", "1a", "2a", "2b", "2b", "3a", "3b", "4a", "5a", "5b")) # 1. 生成纳税单元内的人员序号person.tu,并创建原人员到新序号的映射表 df <- df %>% group_by(household.tu) %>% mutate(person.tu = row_number()) %>% ungroup() person_map <- df %>% select(household, person, household.tu, person.tu) # 2. 将原关系列转为长格式,提取原目标人员编号 df_long <- df %>% pivot_longer(cols = starts_with("r0"), names_to = "original_col", values_to = "rel_value", values_drop_na = FALSE) %>% mutate(original_person = as.integer(sub("r0", "", original_col))) # 3. 关联映射表,筛选出同纳税单元内的关系,生成新关系列名 df_long <- df_long %>% left_join(person_map, by = c("household", "original_person" = "person"), suffix = c("", "_target")) %>% filter(household.tu == household.tu_target) %>% mutate(new_rel_col = paste0("r0", person.tu_target, ".tu")) # 4. 转回宽格式,得到重构后的关系矩阵 df_wide <- df_long %>% select(-original_col, -original_person, -household.tu_target, -person.tu_target) %>% pivot_wider(names_from = new_rel_col, values_from = rel_value, values_fill = NA) # 5. 合并原数据与新关系列,补充缺失的关系列并调整顺序 result <- df %>% left_join(df_wide, by = names(df)) %>% mutate(across(paste0("r0", 1:6, ".tu"), ~replace_na(.x, NA))) %>% select(household, person, r01, r02, r03, r04, r05, r06, household.tu, person.tu, starts_with("r0")) # 查看结果 print(result, row.names = FALSE)
代码说明
- 生成person.tu与映射表:按
household.tu分组,为每个纳税单元内的人员分配连续序号,同时建立(家庭编号, 原人员编号)到(纳税单元, 新人员序号)的映射,方便后续关系匹配。 - 长格式转换:将原有的宽格式关系列(
r01-r06)转为长格式,便于逐个处理每个人员的关系记录。 - 筛选同单元关系:通过映射表找到原关系目标人员所属的纳税单元,仅保留与当前人员同单元的关系,并生成对应新关系列的名称(如
r02.tu对应单元内第2位人员)。 - 重构宽格式矩阵:将处理后的长格式关系数据转回宽格式,得到以新人员序号为基础的关系矩阵。
- 合并与整理:将新关系矩阵合并到原数据中,补充缺失的关系列(设为
NA),并调整列顺序与期望输出一致。
内容的提问来源于stack exchange,提问作者ravinglooper
相关产品推荐
相关产品推荐

