如何在R中多值透视时保留统一年份列并提取变量名中年份
解决方案
1. 用正则提取年份(替代固定位置的str_sub)
别再用str_sub按固定位置截取年份了,改用正则表达式匹配变量名里的4位数字(年份),不管变量名长短都能精准提取。而且可以直接在pivot_longer操作里完成提取,不用额外写处理步骤。
核心正则逻辑:用\\d{4}匹配4位连续数字(年份),如果变量名里年份前有下划线(比如cost_2020)或没有(比如revenue2020),可以用更灵活的规则:(.*?)(?:_)?(\\d{4}),各部分作用:
(.*?):非贪婪匹配年份前的所有字符,避免把下划线误算进前缀(?:_)?:匹配可选的下划线(非捕获组,不会生成多余列)(\\d{4}):捕获4位数字作为年份
2. 统一生成单个年份列(解决year/year2分栏问题)
你出现两个年份列,是因为pivot_longer的参数设置不对,导致年份被错误拆分。调整参数,让所有变量的年份都提取到同一个year列,同一ea_no下的相同年份自然会归到一起。
示例代码
假设你的宽格式数据是这样:
df_wide <- tibble( ea_no = c(1, 2), sales2020 = c(120, 230), profit_2020 = c(25, 48), sales2021 = c(160, 270) )
执行正确的透视代码:
library(dplyr) library(tidyr) df_long <- df_wide %>% pivot_longer( cols = -ea_no, # 排除ea_no列,透视其他所有列 names_to = c("indicator", "year"), # 拆分变量名为指标名和年份 names_pattern = "(.*?)(?:_)?(\\d{4})", # 用正则提取年份 values_to = "value" # 存储数值的列名 )
处理重复的ea_no+year记录
如果同一ea_no+year下有多条不同指标的记录,可按需聚合:
# 按ea_no和year分组,求和所有数值 df_summary <- df_long %>% group_by(ea_no, year) %>% summarise(total_value = sum(value), .groups = "drop")
关键提示
- 正则可以根据你的变量名实际规则调整,比如年份在变量名开头的话,就把
\\d{4}放在正则前面 - 确保
pivot_longer的names_to只指定一个和年份相关的列,避免拆分出多个年份列
内容的提问来源于stack exchange,提问作者Rstudyer
相关产品推荐
相关产品推荐

