如何在R中合并按county和district分组且分散在多列的信息
问题描述
观测数据嵌套在county*district分组中,单个候选人的信息分散在多行(每个字段的有效信息分别位于不同行),原始数据集包含500+非分组变量且均存在该问题;同时candidate字段值无效,需要重新按每个district内的顺序生成候选人标识。
当前数据集示例:
current_df <- data.frame( county = c("E100", "E100", "E100", "E101", "E101", "E101", "E202", "E202", "E202", "E204", "E204", "E204"), district = c(1,1,1,2,2,2,1,1,1,3,3,3), candidate = c(1,2,3,4,5,6,7,8,9,10,11,12), name = c("john", NA, NA, "maria", NA, NA, "tom", NA, NA, "jose", NA, NA), votes = c(NA, 100, NA, NA, 200, NA, NA,78,NA,NA,120,NA), party = c(NA, NA, "D", NA, NA, "I", NA, NA, "R", NA, NA, NA) )
期望目标数据集:
target_df <- data.frame( county = c("E100", "E101","E202", "E204"), district= c(1, 2, 1, 3), candidate = c(1, 1, 2, 1), name = c("john","maria","tom", "jose"), votes = c(100,200,78,120), party = c( "D","I","R",NA) )
解决方案
使用tidyverse工具集即可实现,核心逻辑是分组后提取各字段的有效非NA值,再重新生成候选人标识:
library(tidyverse) cleaned_df <- current_df %>% # 按county+district分组,锁定单个候选人的分散行 group_by(county, district) %>% # 对所有列提取唯一非NA值(每个字段在组内仅一个有效数据) summarise(across(everything(), ~ first(na.omit(.))), .groups = "drop") %>% # 按district分组,生成区内候选人序号 group_by(district) %>% mutate(candidate = row_number()) %>% ungroup()
代码说明
- 分组聚合:先通过
county和district分组,确保每组对应同一个候选人的分散数据;summarise配合across(everything())自动处理所有字段,无需手动指定500+变量,直接提取每个字段的非NA值完成合并。 - 重置候选人标识:按
district分组后用row_number()生成区内的有序候选人编号,替代原有无效的candidate值。 - 多候选人场景兼容:若单个
county*district内存在多个候选人(比如每组占固定N行),可先添加候选人组标识再聚合,示例如下:
# 假设每个候选人占3行的场景 cleaned_df_multi <- current_df %>% group_by(county, district) %>% mutate(candidate_group = ceiling(row_number()/3)) %>% group_by(county, district, candidate_group) %>% summarise(across(everything(), ~ first(na.omit(.))), .groups = "drop") %>% group_by(district) %>% mutate(candidate = row_number()) %>% ungroup() %>% select(-candidate_group)
验证结果:运行代码后cleaned_df与目标数据集完全匹配:
> all.equal(cleaned_df, target_df, check.attributes = FALSE) [1] TRUE
内容的提问来源于stack exchange,提问作者AntVal
相关产品推荐
相关产品推荐

