R语言:对重复列标题的数据集进行逆透视(Unpivot)处理
解决复合表头数据的长格式转换问题
你的问题核心在于原始数据是复合表头结构(第一行是月份,第二行是对应的指标类型),直接用gather会把不同指标的数据混在一起,我们需要先处理复合表头,再用更灵活的pivot_longer来重塑数据。
完整解决方案步骤:
加载依赖包
我们需要tidyverse(包含dplyr和tidyr用于数据处理)和readxl读取Excel文件:library(tidyverse) library(readxl)读取原始数据并处理复合表头
先把Excel里的所有内容读入(不设置表头),然后将前两行合并为复合列名:# 读取数据,不自动设置表头 df_raw <- read_excel("df.xlsx", col_names = FALSE) # 将前两行(月份+指标)合并为复合列名,用下划线分隔 col_names <- paste(df_raw[1, ], df_raw[2, ], sep = "_") # 第一列的复合列名改为"Firm"(因为前两行第一列都是Firm) col_names[1] <- "Firm" # 提取第三行及以后的实际数据,并设置新列名 df_clean <- df_raw[-c(1, 2), ] %>% set_names(col_names)转换为目标长格式
使用pivot_longer的.value参数,自动拆分复合列名,将月份提取为单独列,同时保留On-time和Pieces作为独立的数值列:df_long <- df_clean %>% pivot_longer( cols = -Firm, # 排除Firm列,处理所有月份相关列 names_to = c("Month", ".value"), # 拆分列名:第一部分是Month,第二部分是值的列名 names_sep = "_" # 用下划线作为拆分符 ) %>% arrange(Firm, desc(Month)) # 按照Firm分组,月份倒序排列(和你的示例顺序一致)
结果说明
运行后你会得到完全符合需求的长格式数据:
| Firm | Month | On-time | Pieces |
|---|---|---|---|
| A | December | 50% | 10 |
| A | November | 37% | 60 |
| B | December | 10% | 55 |
| B | November | 60% | 50 |
为什么之前的gather无效?
gather是比较基础的宽转长工具,它只能将所有非指定列合并成一个“键”列和一个“值”列,无法区分复合列名里的指标类型(On-time/Pieces)。而pivot_longer的.value参数可以指定列名的某一部分作为最终的数值列名,完美适配这种复合表头的场景。
内容的提问来源于stack exchange,提问作者Christian R. Houen
相关产品推荐
相关产品推荐

