如何在R中处理含年度与月度数据的pivot_longer转换?
处理混合年度/月度宽格式数据的pivot_longer解决方案
先构造一份和你描述匹配的示例宽格式数据,方便演示:
library(tidyverse) wide_data <- tibble( region_name = c("北京", "上海"), total_population_2019 = c(2154, 2428), total_population_2020 = c(2189, 2487), mean_temperature_2019_1 = c(-3.1, 3.2), mean_temperature_2019_2 = c(-0.7, 5.6), mean_temperature_2020_1 = c(-2.5, 4.1), mean_temperature_2020_2 = c(0.3, 6.2) )
下面提供两种可行的实现方式:
方法一:拆分处理后合并
这种方式逻辑直观,适合新手理解:
- 单独提取年度人口列,转成长格式并提取年份
- 单独提取月度气温列,转成长格式并提取年份、月份
- 按地区和年份将两个数据集合并,自动匹配对应年份的总人口到每个月度行
# 处理年度人口数据 pop_long <- wide_data %>% select(region_name, starts_with("total_population")) %>% pivot_longer( cols = starts_with("total_population"), names_to = "year", names_prefix = "total_population_", values_to = "total_population" ) %>% mutate(year = as.integer(year)) # 处理月度气温数据 temp_long <- wide_data %>% select(region_name, starts_with("mean_temperature")) %>% pivot_longer( cols = starts_with("mean_temperature"), names_to = c("year", "month"), names_pattern = "mean_temperature_(\\d{4})_(\\d{1,2})", values_to = "mean_temperature" ) %>% mutate(year = as.integer(year), month = as.integer(month)) # 合并得到最终长格式数据 final_long <- temp_long %>% left_join(pop_long, by = c("region_name", "year"))
方法二:一次性pivot处理(更简洁)
利用正则表达式匹配不同类型的列名,一次性完成格式转换,再通过分组填充匹配总人口:
final_long <- wide_data %>% # 所有列转长格式,提取变量类型、年份、月份 pivot_longer( cols = -region_name, names_to = c("variable_type", "year", "month"), # 正则匹配:区分人口/气温前缀,提取四位年份,可选提取月份 names_pattern = "(total_population|mean_temperature)_(\\d{4})(?:_(\\d{1,2}))?", values_to = "value" ) %>% # 把人口和气温转回宽格式列 pivot_wider( names_from = variable_type, values_from = value ) %>% # 按地区+年份分组,填充该组内的总人口值 group_by(region_name, year) %>% fill(total_population, .direction = "downup") %>% ungroup() %>% # 移除只有人口的空气温行 drop_na(mean_temperature)
两种方法最终都会得到目标长格式:每行对应一个地区-年份-月份的组合,同时包含当月气温和当年总人口。
内容的提问来源于stack exchange,提问作者markpc
相关产品推荐
相关产品推荐

