基于日期创建列:使用pivot_wider实现按日期排序的宽表转换
按日期排序后将长表转换为宽表的解决方案
原始数据
你提供的创建数据框的R代码:
case <- c("A","A","A","B","B","C","C","C","C") date <- c("2022-01-01","2022-01-08","2022-06-07","2022-05-08","2022-03-06","2022-09-08","2022-09-23","2022-12-08","2022-06-05") df <- data.frame(case,date)
数据框结构如下:
# A tibble: 9 x 2 case date <chr> <chr> 1 A 2022-01-01 2 A 2022-01-08 3 A 2022-06-07 4 B 2022-05-08 5 B 2022-03-06 6 C 2022-09-08 7 C 2022-09-23 8 C 2022-12-08 9 C 2022-06-05
需求说明
按每个case下的日期从早到晚排序,将最早的日期设为instance_1,次早为instance_2,以此类推,把长表转换为宽表。
解决方案
需要先对每个case内的日期排序并生成对应序号,再使用pivot_wider完成转换,步骤如下:
1. 加载依赖包
用到dplyr处理数据、tidyr转换表结构:
library(dplyr) library(tidyr)
2. 预处理数据
将日期转为日期类型(保证排序逻辑正确),按case分组后对日期升序排序,生成instance序号列:
df_processed <- df %>% mutate(date = as.Date(date)) %>% # 转换为日期类型,避免字符串排序错误 group_by(case) %>% arrange(date, .by_group = TRUE) %>% # 按case分组,组内日期升序排列 mutate(instance = paste0("instance_", row_number())) %>% # 生成instance_1、instance_2...序号 ungroup()
3. 转换为宽表
用pivot_wider完成长表转宽表:
df_wide <- df_processed %>% pivot_wider( id_cols = case, # 保留作为行标识的列 names_from = instance, # 将instance列的取值作为新列名 values_from = date # 将date列的取值作为新列对应的值 )
最终结果
执行后得到的宽表如下:
# A tibble: 3 x 5 case instance_1 instance_2 instance_3 instance_4 <chr> <date> <date> <date> <date> 1 A 2022-01-01 2022-01-08 2022-06-07 NA 2 B 2022-03-06 2022-05-08 NA NA 3 C 2022-06-05 2022-09-08 2022-09-23 2022-12-08
关键说明
- 必须转换日期类型:若直接用字符串排序,会出现逻辑错误(比如字符串"2022-12-08"会被误判为比"2022-06-05"小)
- 分组排序后生成序号:确保每个
case下的日期按从早到晚顺序对应instance_1到instance_n pivot_wider参数设置:id_cols指定行的唯一标识,names_from和values_from分别对应新列名和值的来源
内容的提问来源于stack exchange,提问作者a nony mouse
相关产品推荐
相关产品推荐

