如何使用R将长格式dataframe转换为宽格式并合并值
R语言长表转宽表实现方案
你之前使用cast/dcast未得到预期结果,核心原因是缺少两个前置处理:一是没有先把同一ID同一日期下的多条操作做拼接,直接转宽会触发多值冲突;二是没有给每个ID的日期按顺序生成编号,无法生成你要的「第N次」格式列。
以下方案基于tidyverse生态的dplyr和tidyr包实现,逻辑清晰适合新手理解:
前置准备
首先安装加载所需包(已安装可跳过安装步骤):
# 安装包 install.packages("tidyverse") # 加载包 library(tidyverse)
实现步骤
步骤1:预处理数据,保证日期格式正确
首先将你的Date列转换为R可识别的日期格式,避免后续排序出错,需根据你实际的日期格式调整format参数:
# 替换df为你的实际数据框名 df <- df %>% mutate(Date = as.Date(Date, format = "%Y-%m-%d"))
步骤2:同ID同日期下的操作拼接+日期排序编号
df_processed <- df %>% # 按ID和日期分组,拼接同日期的多条操作 group_by(ID, Date) %>% summarise(Procedure = paste(Procedure, collapse = ","), .groups = "drop") %>% # 按ID分组,给每个ID的日期按先后顺序编号 group_by(ID) %>% arrange(Date, .by_group = TRUE) %>% mutate(date_rank = row_number(), # 提前统计每个ID的日期总数 date_count = n()) %>% ungroup()
步骤3:转换为宽格式
df_wide <- df_processed %>% pivot_wider( id_cols = c(ID, date_count), names_from = date_rank, values_from = c(Date, Procedure), names_glue = "第{date_rank}次日期_{.value}" ) %>% # 调整列名符合需求 rename_with(~gsub("_Date", "", .x), starts_with("第")) %>% rename_with(~gsub("_Procedure", "_对应操作", .x), starts_with("第"))
结果说明
- 最终输出的
df_wide每一行对应唯一ID - 自动生成
第1次日期、第1次对应操作、第2次日期、第2次对应操作等列,最多到第3次 date_count列即为每个ID对应的日期总数- 没有对应第N次日期的ID,对应列会自动填充为NA,可根据需要用
replace_na处理为空值
内容的提问来源于stack exchange,提问作者Becky
相关产品推荐
相关产品推荐

