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

在R中实现事件级数据集转患者级数据:生成事件及最早时间列

解决方案

核心需求拆解

要把事件级长格式数据转成以deidnum为唯一标识的患者级宽格式,需满足:

  • 每个事件对应两列:发生标记(1=发生/0=未发生)、最早发生时间
  • 同一患者多次触发同一事件时,仅保留最早的EVENTDT
  • 保留MI_COMPLICATED字段,对应MI事件的并发症状态(多次MI时取存在并发症的记录值)

方法一:tidyverse工具链(推荐,逻辑清晰)

用dplyr做数据预处理,tidyr做宽格式转换:

library(tidyverse)

# 第一步:分组预处理,提取每个患者-事件的最早时间,处理MI并发症字段
processed_data <- df %>%
  group_by(deidnum, eventc) %>%
  summarise(
    earliest_dt = min(EVENTDT, na.rm = TRUE),
    # MI事件单独提取并发症状态,取该患者的最大值(优先保留有并发症的记录)
    mi_complication = ifelse(eventc == "MI", max(MI_COMPLICATED, na.rm = TRUE), NA),
    .groups = "drop"
  ) %>%
  # 每个患者只保留一个MI并发症值
  group_by(deidnum) %>%
  mutate(MI_COMPLICATED = max(mi_complication, na.rm = TRUE)) %>%
  select(-mi_complication) %>%
  ungroup()

# 第二步:分两次转宽格式,分别生成事件标记和时间列,再合并
wide_data <- processed_data %>%
  # 生成事件发生标记列
  mutate(event_occurred = 1) %>%
  pivot_wider(
    id_cols = c(deidnum, MI_COMPLICATED),
    names_from = eventc,
    values_from = event_occurred,
    values_fill = 0  # 未发生的事件填0
  ) %>%
  # 合并事件最早时间列
  left_join(
    processed_data %>%
      pivot_wider(
        id_cols = deidnum,
        names_from = eventc,
        values_from = earliest_dt,
        names_glue = "{eventc}_DT"  # 时间列命名规则:事件名_DT
      ),
    by = "deidnum"
  )

# 查看最终结果
print(wide_data)

方法二:reshape2 + base R

如果习惯用reshape2,可按以下步骤实现:

library(reshape2)

# 1. 提取每个患者-事件的最早时间,并重命名时间列
event_time_df <- dcast(df, deidnum ~ eventc, value.var = "EVENTDT", fun.aggregate = min)
names(event_time_df)[-1] <- paste0(names(event_time_df)[-1], "_DT")

# 2. 生成事件发生标记列(1=发生过,0=未发生)
event_flag_df <- dcast(df, deidnum ~ eventc, fun.aggregate = function(x) as.integer(length(x) > 0))

# 3. 提取MI并发症状态:每个患者取最大值(优先保留有并发症的记录)
mi_complication_df <- df %>%
  filter(eventc == "MI") %>%
  aggregate(MI_COMPLICATED ~ deidnum, data = ., FUN = max, na.rm = TRUE)

# 4. 合并所有数据框,补全未发生MI患者的并发症值为NA
wide_data <- event_flag_df %>%
  merge(event_time_df, by = "deidnum") %>%
  merge(mi_complication_df, by = "deidnum", all.x = TRUE) %>%
  mutate(MI_COMPLICATED = ifelse(MI == 0, NA, MI_COMPLICATED))

# 查看结果
print(wide_data)

最终输出示例

生成的宽格式数据结构如下(对应你的期望输出):

deidnumMIDEATHNew Rose Dyspnea Scale 2 or moreMI_DTDEATH_DTNew Rose Dyspnea Scale 2 or more_DTMI_COMPLICATED
32510710121NA14681
418351001NANA207NA
839172001NANA1060NA
14874221109901113NA0
1511165101424NA7211

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.15 03:09:54