在R中使用循环按条件合并多CSV数据时遇到的问题
问题分析与解决方案
问题背景
主数据集HIP2_SPOR包含48134条唯一观测值、35个变量(覆盖2015-2020年手术人群),其中LopNr为唯一病例标识符,YearOfSurgery(字符型)记录患者手术年份。需要将6个独立年度CSV文件中的社会经济数据(如Raks_SummaInk)按手术年份匹配合并到主数据集,且合并后变量需统一为单个列。
原运行代码后出现两个问题:
- 新增的
Raks_SummaInk变量带有不同后缀(如Raks_SummaInk.x、Raks_SummaInk.y) - 所有新增变量的值均为
NA
原代码的核心问题
- 错误使用
summarize:将每个年份的SES数据聚合为一个总和值,丢失了单个病例的匹配键LopNr,导致后续合并无法对应到具体病例 - 循环中
merge无明确匹配键:R自动尝试用同名列匹配,但聚合后的数据无LopNr,最终填充为NA;且每次循环新增同名变量,R自动添加后缀区分 - 管道操作符拼写错误:使用了
%>而非正确的%>%
修正后的解决方案
方案一:批量读取+一次性匹配(推荐)
利用purrr批量读取所有年度SES数据,统一添加年份标识后,与主数据集按病例ID和手术年份匹配:
library(tidyverse) # 定义目标年份 years <- 2015:2020 # 批量读取所有年度SES数据,添加年份列并合并为一个数据集 ses_combined <- map_dfr(years, function(year) { read_csv(paste0("MC_Lev_LISA_", year, ".csv")) %>% select(Lopnr, Raks_SummaInk) %>% mutate(YearOfSurgery = as.character(year)) }) # 主数据集与合并后的SES数据匹配 HIP2_SPOR_SES <- HIP2_SPOR %>% left_join(ses_combined, by = c("LopNr" = "Lopnr", "YearOfSurgery" = "YearOfSurgery"))
方案二:改进循环填充
先初始化目标变量,循环中针对每个年份的病例匹配对应SES数据并填充:
library(tidyverse) years <- 2015:2020 # 复制主数据集并初始化目标变量 HIP2_SPOR_SES <- HIP2_SPOR %>% mutate(Raks_SummaInk = NA_real_) for (year in years) { # 读取对应年份的SES数据 socioeco_data <- read_csv(paste0("MC_Lev_LISA_", year, ".csv")) %>% select(Lopnr, Raks_SummaInk) # 定位主数据中当前年份的病例,匹配并填充SES变量 year_mask <- HIP2_SPOR_SES$YearOfSurgery == as.character(year) matched_data <- HIP2_SPOR_SES[year_mask, ] %>% select(LopNr) %>% left_join(socioeco_data, by = c("LopNr" = "Lopnr")) HIP2_SPOR_SES[year_mask, "Raks_SummaInk"] <- matched_data$Raks_SummaInk }
关键修正说明
- 移除错误的
summarize操作,保留单个病例的LopNr用于匹配 - 明确匹配键(
LopNr和YearOfSurgery),确保SES数据精准对应到手术年份匹配的病例 - 统一维护单个
Raks_SummaInk变量,避免重复新增列
内容的提问来源于stack exchange,提问作者Rasmus Åhman
相关产品推荐
相关产品推荐

