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
相关产品推荐
相关产品推荐

