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

如何将宽格式DataFrame转换为按月份分组的长格式数据?

解决DataFrame宽格式转长格式的问题

你现在遇到的问题是把按年份行存储、每月3个数据列(X1-X3对应1月,X4-X6对应2月…)的宽格式DataFrame,转换成包含Year、Month、Value的长格式,之前的gather代码没达到预期,对吧?

问题分析

你之前的代码把每个Xn列单独当成了一个月份,但实际上每3个X列对应同一个月份,所以需要先把X的编号映射到对应的月份分组,再转换成月份名称。

完整解决方案

这里用dplyr、tidyr和stringr包来实现,代码如下:

library(dplyr)
library(tidyr)
library(stringr)

df_L <- df %>%
  # 可选:过滤掉1970年全为NA的行,如果你需要保留这行可以删除此句
  filter(!is.na(X1)) %>%
  # 将X1-X36列转为长格式,生成X_col(列名)和Value(对应数值)两列
  gather(key = "X_col", value = "Value", X1:X36) %>%
  # 提取X_col中的数字部分,转为数值类型
  mutate(Month_num = as.numeric(str_replace(X_col, "X", ""))) %>%
  # 每3个X对应一个月份,计算对应的月份序号(1-12)
  mutate(Month_idx = ceiling(Month_num / 3)) %>%
  # 将月份序号转为缩写名称(Jan/Feb/.../Dec),用month.name可得到全称
  mutate(Month = month.abb[Month_idx]) %>%
  # 保留需要的三列,并按年份和月份排序
  select(Year, Month, Value) %>%
  arrange(Year, Month_idx)

代码解释

  • filter(!is.na(X1)):因为1970年所有X列都是NA,如果你不需要这一行可以过滤掉;如果需要保留,直接删除这一行即可,结果中1970年的Value会是NA。
  • gather:把宽格式的X1-X36列转换为长格式的键值对,X_col存储原列名(如X1、X2),Value存储对应的数据。
  • str_replace(X_col, "X", ""):提取X后面的数字,得到1到36的连续编号,用于后续分组月份。
  • ceiling(Month_num / 3):通过向上取整,把1-3映射为1(1月),4-6映射为2(2月),以此类推,完美匹配你每月3个数据的规则。
  • month.abb[Month_idx]:调用R内置的月份缩写向量,把1-12的序号转为Jan、Feb这种格式;如果需要全称(如January),替换成month.name即可。
  • select和arrange:最后只保留需要的三列,并按年份和月份排序,让结果和你期望的格式完全一致。

运行这段代码后,你就能得到和示例中一样的长格式数据啦!

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.27 06:35:02