基于年龄与亲属关系规则的家庭收入列值重分配问题
家庭收入按规则重分配的优雅dplyr实现方案
问题背景
现有记录个人信息的DataFrame,包含家庭组、亲属关系、年龄、家庭总收入字段(hy040g至hy050g存储完整家庭总收入,每个家庭成员字段值一致)。需按规则将总收入分配到个人,尤其需适配多已婚夫妇的复杂家庭场景,此前用dplyr结合ifelse的方案因嵌套逻辑复杂,在多婚姻场景下出现问题,寻求更简洁的实现方式。
示例数据
library(dplyr) # 模拟家庭数据:包含双夫妇家庭(A组)和核心家庭+老人(B组) sample_df <- tibble( 家庭组 = c("A", "A", "A", "A", "B", "B", "B"), 亲属关系 = c("户主", "配偶", "儿子", "儿媳", "户主", "配偶", "父亲"), 年龄 = c(50, 48, 25, 23, 60, 58, 82), hy040g = c(100000, 100000, 100000, 100000, 80000, 80000, 80000) )
分配规则(示例)
假设规则如下(可根据实际需求调整):
- 识别家庭内所有已婚夫妇单元(如户主-配偶、儿子-儿媳)
- 家庭总收入按已婚单元数量平分,每个单元获得总金额的
1/N(N为已婚单元数) - 每个已婚单元内的成员平分该单元的金额
- 无配偶的家庭成员(如单身老人)按家庭总人数平分总收入
优雅实现方案
利用dplyr的分组、窗口函数和case_when替代多层ifelse,逻辑更清晰且扩展性强:
result_df <- sample_df %>% group_by(家庭组) %>% mutate( # 标记每个已婚夫妇单元:给同属一个夫妇的成员分配相同单元ID 单元ID = case_when( 亲属关系 %in% c("户主", "配偶") ~ 1, 亲属关系 %in% c("儿子", "儿媳") ~ 2, TRUE ~ 0 # 无配偶成员归为0号单元 ), # 计算家庭内有效已婚单元总数 单元总数 = n_distinct(单元ID[单元ID != 0]), # 单个单元应分配的总金额 单元分配额 = hy040g / ifelse(单元总数 == 0, n(), 单元总数), # 计算当前单元的成员数量 单元人数 = sum(单元ID == cur_data()$单元ID), # 计算个人最终分配收入 个人分配收入 = case_when( 单元ID != 0 ~ 单元分配额 / 单元人数, TRUE ~ hy040g / n() # 无单元成员按家庭总人数平分 ) ) %>% ungroup() %>% # 清理辅助列(按需保留) select(家庭组, 亲属关系, 年龄, hy040g, 个人分配收入)
期望输出
# # A tibble: 7 × 5 # 家庭组 亲属关系 年龄 hy040g 个人分配收入 # <chr> <chr> <dbl> <dbl> <dbl> # 1 A 户主 50 100000 25000 # 2 A 配偶 48 100000 25000 # 3 A 儿子 25 100000 25000 # 4 A 儿媳 23 100000 25000 # 5 B 户主 60 80000 26667. # 6 B 配偶 58 80000 26667. # 7 B 父亲 82 80000 26667.
方案优势
- 避免多层
ifelse嵌套,用case_when实现多条件分支,代码可读性更强 - 基于分组和窗口函数动态计算单元数、人数,适配不同家庭结构
- 扩展性高:新增亲属关系(如女儿、女婿)时,仅需在
单元ID的case_when中补充规则即可
内容的提问来源于stack exchange,提问作者ravinglooper
相关产品推荐
相关产品推荐

