You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

R语言pivot_longer实现重名列宽表转为带单位列的规范长表

R实现混乱宽表转规范长表

问题说明

现有数据集存在三类格式问题:

  • 存在重复列名:Real_GDP、Unemployment各出现2次,分别对应不同年份的指标值
  • 元数据未结构化存储:指标单位存于第一行指标列、年份存于第二行指标列
  • 有效预测数据从第三行才开始

原始数据样例:

Forecaster                   Real_GDP         Real_GDP   Unemployment       Unemployment   Country 

NA                        Variation in %         NA      % of active pop.      NA         USA
Individual Forecasts           2022             2023        2022               2023       USA
Forecaster_1                    3.3              4.1        1.3                1.6        USA 
Forecaster_2                    2.5              3.9        0.9                1.3        USA

目标输出结构:

Forecaster       Unit             Indicator     2022    2023  Country

Forecaster_1     Variation in %   Real_GDP      3.3     4.1   USA
Forecaster_2     Variation in %   Real_GDP      2.5     3.9   USA
Forecaster_1     % of active pop. Unemployment  1.3     1.6   USA
Forecaster_2     % of active pop. Unemployment  0.9     1.3   USA

测试数据构造代码:

test2 <- data.frame(Forecaster=c(NA,"Individual Forecasts", "Forecaster_1", "Forecaster_2"),
                   Real_GDP=c("Variation in %", "2022", 3.3, 2.5),
                   Real_GDP=c(NA, "2023", 4.1, 3.9),
                   Unemployment=c("% of active pop.", "2022", 1.3, 0.9),
                   Unemployment=c(NA, "2023", 1.6, 1.3),
                   Country=c("USA","USA", "USA", "USA"))
colnames(test2) <- c("Forecaster", "Real_GDP", "Real_GDP", "Unemployment", "Unemployment", "Country")

处理逻辑

  • 先为重复列名添加唯一后缀,避免列索引错误
  • 分别提取存储在行中的元数据:指标单位、对应年份,生成列名和元数据的映射表
  • 过滤掉存储元数据的前两行,保留有效预测数据
  • 先转长表关联元数据,再将年份维度转回宽表,调整列顺序得到最终结果

完整实现代码

依赖dplyr和tidyr(tidyverse生态包):

library(dplyr)
library(tidyr)

# 1. 为重复列名添加唯一后缀
colnames(test2) <- make.unique(colnames(test2), sep = "_")

# 2. 提取各列对应指标单位
unit_map <- test2 |> 
  slice(1) |> 
  select(starts_with(c("Real_GDP", "Unemployment"))) |> 
  pivot_longer(cols = everything(), names_to = "col_name", values_to = "Unit") |> 
  mutate(Indicator = sub("_\\d+$", "", col_name)) |> 
  fill(Unit, .direction = "down")

# 3. 提取各列对应年份
year_map <- test2 |> 
  slice(2) |> 
  select(starts_with(c("Real_GDP", "Unemployment"))) |> 
  pivot_longer(cols = everything(), names_to = "col_name", values_to = "Year")

# 4. 合并列元数据映射表
col_meta <- unit_map |> 
  left_join(year_map, by = "col_name") |> 
  select(col_name, Unit, Indicator, Year)

# 5. 提取有效预测数据
valid_data <- test2 |> 
  slice(-c(1,2))

# 6. 长宽转换+结构整理
final_result <- valid_data |> 
  pivot_longer(
    cols = starts_with(c("Real_GDP", "Unemployment")),
    names_to = "col_name",
    values_to = "value"
  ) |> 
  left_join(col_meta, by = "col_name") |> 
  mutate(value = as.numeric(value)) |> 
  pivot_wider(
    names_from = Year,
    values_from = value
  ) |> 
  select(Forecaster, Unit, Indicator, `2022`, `2023`, Country)

输出结果

运行后final_result输出完全匹配目标结构:

# A tibble: 4 × 6
  Forecaster  Unit             Indicator   `2022` `2023` Country
  <chr>       <chr>            <chr>        <dbl>  <dbl> <chr>  
1 Forecaster_1 Variation in %   Real_GDP      3.3    4.1 USA    
2 Forecaster_1 % of active pop. Unemployment  1.3    1.6 USA    
3 Forecaster_2 Variation in %   Real_GDP      2.5    3.9 USA    
4 Forecaster_2 % of active pop. Unemployment  0.9    1.3 USA

内容的提问来源于stack exchange,提问作者Erazijus

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.02 23:15:58