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

R语言:将日期为列名的数据框从宽格式重塑为长格式

宽格式转长格式并将日期转换为R序列值

原始数据与目标需求

原始宽格式数据:

HAVE = data.frame('STUDENT'= c(1,2,3,4),
'1/1/2019' = c(1, NA, 8, 4),
'2/1/2019' = c(1, 3, NA, 6),
'1/15/2020' = c(NA, 7, NA, 10))

需要转换为长格式数据WANT,要求:

  • 保留STUDENT列
  • 原日期列名转为DATE列,且为R的日期序列数值(即从1970-01-01开始的天数)
  • 原日期列的内容转为SCORE列

方法一:使用tidyverse包(推荐)

利用pivot_longer快速实现宽转长,再处理日期格式:

library(tidyverse)

WANT_tidy <- HAVE %>%
  # 宽转长:除STUDENT外的列转为DATE和SCORE
  pivot_longer(cols = -STUDENT, names_to = "DATE", values_to = "SCORE") %>%
  # 将字符日期转为R Date类型,再转成数值序列
  mutate(DATE = as.numeric(as.Date(DATE, format = "%m/%d/%Y")))

# 查看结果
WANT_tidy

方法二:使用base R

通过reshape函数实现转换:

WANT_base <- reshape(HAVE, 
                     idvar = "STUDENT",          # 分组变量
                     varying = colnames(HAVE)[-1],# 需要转换的列
                     v.names = "SCORE",          # 值列名
                     timevar = "DATE",           # 时间列名
                     times = colnames(HAVE)[-1], # 时间列的原始值
                     direction = "long") %>%     # 转长格式
  mutate(DATE = as.numeric(as.Date(DATE, format = "%m/%d/%Y"))) %>%
  arrange(STUDENT, DATE) %>%                    # 按学生和日期排序
  select(-rownames(.))                          # 移除自动生成的行名

# 查看结果
WANT_base

验证结果

可以通过以下代码验证转换后的结果与目标WANT是否一致:

all.equal(WANT_tidy, WANT)
all.equal(WANT_base, WANT)

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.31 01:57:37