R语言如何将含年龄性别合并列的数据集转换为指定格式
问题说明
当前需要处理的数据集列名同时编码了年龄分组、性别两类维度信息,典型列名格式如Y_0_13_Males、Y_0_13_Females、Y_0_13_Unknown,本次测试用的示例数据集如下:
structure(list(Y_O_13_Males = c(5, 0, 0, 0, 0), Y_O_13_Females = c(4, 0, 0, 0, 0), Y_O_13_Unknown = c(1, 0, 0, 0, 0), Y65_And_Over_Males = c(0, 0, 0, 0, 0), Y65_And_Over_Females = c(0, 0, 0, 0, 0), Y65_And_Over_Unknown = c(0, 0, 0, 0, 0), Unknown_And_Over_Males = c(0, 0, 0, 0, 0), Unknown_And_Over_Females = c(0, 0, 0, 0, 0), Unknown_And_Over_Unknown = c(0, 0, 0, 0, 0)), row.names = c(NA, -5L), class = c("tbl_df", "tbl", "data.frame"))
需要将上述宽格式数据转换为如下目标长表结构:
高效实现方案
使用R语言tidyverse生态的工具可以快速完成转换,不需要手动写循环处理列名,适配所有同规则的列名格式:
- 先给原始数据的每一行添加唯一行标识,避免宽转长时数据错位
- 调用
pivot_longer将所有编码了维度的列转为长格式,暂存列名和对应统计值 - 用正则拆分列名:所有列名最后一个下划线后的固定为性别值(Males/Females/Unknown),下划线前的所有内容为年龄分组,拆分后直接得到结构化字段
完整可运行代码:
# 加载依赖,首次使用需先运行 install.packages("tidyverse") library(tidyverse) # 读取示例数据 raw_df <- structure(list(Y_O_13_Males = c(5, 0, 0, 0, 0), Y_O_13_Females = c(4, 0, 0, 0, 0), Y_O_13_Unknown = c(1, 0, 0, 0, 0), Y65_And_Over_Males = c(0, 0, 0, 0, 0), Y65_And_Over_Females = c(0, 0, 0, 0, 0), Y65_And_Over_Unknown = c(0, 0, 0, 0, 0), Unknown_And_Over_Males = c(0, 0, 0, 0, 0), Unknown_And_Over_Females = c(0, 0, 0, 0, 0), Unknown_And_Over_Unknown = c(0, 0, 0, 0, 0)), row.names = c(NA, -5L), class = c("tbl_df", "tbl", "data.frame")) # 执行转换 long_df <- raw_df %>% mutate(row_seq = row_number()) %>% pivot_longer(cols = -row_seq, names_to = "raw_colname", values_to = "count") %>% separate_wider_regex( raw_colname, patterns = c( age_group = ".*(?=_(Males|Females|Unknown)$)", "_", sex = ".*" ) ) %>% select(-row_seq)
转换后输出的long_df包含age_group(年龄分组)、sex(性别)、count(统计值)三个字段,和目标结构完全匹配,即使后续新增同规则的年龄/性别列,代码也不需要修改可以直接运行。
内容的提问来源于stack exchange,提问作者silent_hunter
相关产品推荐
相关产品推荐

