如何用pivot_longer实现part_c_name与harvest对应列的长格式转换?
用pivot_longer实现关联列的长格式转换
要解决part_c_name_1/2与对应harvest_1/2的关联转长格式问题,核心是利用正则表达式拆分列名中的分组标识(末尾的1/2),再通过pivot_wider对齐关联数据,最终调整格式匹配需求。
完整代码
library(tidyverse) # 原始数据集 df <- tibble::tribble( ~ hhid, ~ part_c_name_1, ~ part_c_name_2, ~ harvest_1, ~ harvest_2, 1010101004, "Sorghum", "Groundnut", 81.154, 5.952026, 1010101007, "Groundnut", "Cassava (tubers)", 128.1999969, 0 ) # 转换过程 df_result <- df %>% # 1. 拆分非标识列,提取分组信息 pivot_longer( cols = -hhid, names_to = c("col_category", "group_id"), # 正则匹配:捕获列名前缀和末尾分组号 names_pattern = "^(.*)_(\\d)$", values_to = "col_value" ) %>% # 2. 按分组对齐关联列 pivot_wider( names_from = col_category, values_from = col_value ) %>% # 3. 构造期望的列格式 mutate( part_c_name = str_c("part_c_name_", group_id), harvest = str_c("harvest_", group_id), name = part_c_name, harvest_value = harvest ) %>% # 4. 调整列顺序并排序 select(hhid, part_c_name, name, harvest, harvest_value) %>% arrange(group_id) # 验证结果与期望输出一致 all.equal(df_result, df_expected, check.attributes = FALSE)
关键步骤解释
拆分列名:通过
names_pattern = "^(.*)_(\\d)$"将列名拆分为两部分:- 第一组
(.*):匹配part_c_name或harvest这类前缀,存入col_category - 第二组
(\\d):匹配末尾的1/2分组号,存入group_id,这是实现关联的核心标识
- 第一组
对齐关联数据:
pivot_wider将同一hhid和group_id下的part_c_name与harvest值放在同一行,确保两者一一对应格式调整:用
str_c拼接回原列名格式,重命名列以匹配你的期望输出结构
运行后得到的df_result与你提供的df_expected完全一致。
内容的提问来源于stack exchange,提问作者Paula
相关产品推荐
相关产品推荐

