R语言无有效时间变量时如何实现长格式转宽格式
R语言药物处方数据长转宽实现方案
你不需要强行适配reshape函数的参数要求,以下两种方案都可以完成处理,同时匹配你后续构建诊断规则的需求。
核心注意点
- 你之前尝试生成每个id下的处方序号失败,核心是没有按患者id分组后独立生成序列,全表统一生成的行号无法匹配每个患者的独立就诊顺序。
- 原始数据里的
prescription_date是字符格式,必须先转成标准日期类型再排序,否则字符串排序会出现时间先后顺序错误(比如示例中id=2的两条处方,7月5日的字符串排序会早于4月10日,和实际时间相反)。
方案1:tidyverse 实现(推荐,适配后续分析需求)
步骤1:加载包并构造示例数据
library(tidyverse) id <- c(1, 1, 1, 2, 2, 3, 3, 3) prescription_date <- c("17JAN2009", "02MAR2009", "20MAR2009", "05JUL2009", "10APR2009", "09MAY2009", "13JUN2009", "29MAY2009") med <- c("A", "B", "A", "B", "A", "B", "A", "B") df <- data.frame(id, prescription_date, med)
步骤2:生成每个患者的处方次序号(替代reshape要求的时间变量)
按患者id分组,按处方时间排序后生成的次序号,完全可以作为长转宽函数需要的时间变量使用:
df_processed <- df %>% # 字符转日期格式,%d%b%Y对应“日-月缩写-年”的格式 mutate(prescription_date = as.Date(prescription_date, format = "%d%b%Y")) %>% # 按患者id、处方时间排序 arrange(id, prescription_date) %>% group_by(id) %>% # 生成每个患者自己的处方顺序号 mutate(presc_seq = row_number()) %>% ungroup()
步骤3:按需转成宽格式
如果你需要把每条处方展开为单独列,直接用pivot_wider即可:
df_wide_detail <- df_processed %>% pivot_wider( id_cols = id, names_from = presc_seq, values_from = c(med, prescription_date), names_prefix = "presc_" )
结合你要统计药物处方数、构建诊断规则、后续和其他数据集合并的需求,不需要展开逐次处方的明细,直接聚合得到每个患者的各类药物处方数即可,这种宽表后续关联和计算效率更高:
df_wide_count <- df %>% mutate(prescription_date = as.Date(prescription_date, format = "%d%b%Y")) %>% # 统计每个患者每类药物的处方数 count(id, med, name = "presc_count") %>% pivot_wider( id_cols = id, names_from = med, values_from = presc_count, # 没有开具的药物计数填充为0 values_fill = 0 ) %>% # 直接生成诊断判定列 mutate(diag_pos = ifelse(A > 1, 1, 0))
方案2:base R 实现(无需安装额外包)
如果不想依赖第三方包,可以用基础R函数完成序号生成和格式转换:
# 转换日期格式 df$prescription_date <- as.Date(df$prescription_date, format = "%d%b%Y") # 按患者id、处方时间排序 df <- df[order(df$id, df$prescription_date), ] # 按id分组生成处方次序号 df$presc_seq <- ave(df$id, df$id, FUN = seq_along) # 调用reshape转宽格式 df_wide_base <- reshape( df, idvar = "id", timevar = "presc_seq", direction = "wide" )
内容的提问来源于stack exchange,提问作者theblackbox
相关产品推荐
相关产品推荐

