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

基于聚合值透视列:实现流感疫苗数据单患者一行的宽表转换

患者疫苗接种数据宽表转换解决方案

问题描述

现有患者疫苗接种数据集,包含变量:

  • ptid:患者ID
  • time:时间(0=RCT前,1=RCT后)
  • type:流感疫苗类型(有效值为0、1、3,注意原数据中type因子水平为"0"、"1"、"2",实际值需对应转换)
  • num:接种次数(因子型)
  • volume:接种剂量(连续变量)

需将数据转换为每个患者一行的宽表,包含以下衍生变量:

  1. 剂量汇总变量:
    • totalvol:患者总接种剂量(不计疫苗类型)
    • voltype0、voltype1、voltype3:按患者+疫苗类型汇总的总剂量
  2. 接种指示变量:
    • totalyn:患者是否接种过任意疫苗(是=1,否=0)
    • type0yn、type1yn、type3yn:患者是否接种过对应类型疫苗(是=1,否=0)

原尝试代码存在问题:多次pivot_wider导致生成值列表,且无法重复利用type变量透视,无法得到每行对应单个患者的结果。


解决方案代码

library(dplyr)
library(tidyr)

# 加载原始数据集
df <- structure(list(ptid = c("30000", "30000", "30000", "30000", "30000", 
"30001", "30002", "30002", "30002", "30003", "30003", "30003", 
"30004", "30004", "30004", "30005", "30005", "30005", "30006", 
"30006", "30006", "30007", "30007", "30007", "30007", "30008", 
"30008", "30008", "30008", "30008"), num = structure(c(1L, 2L, 
3L, 4L, 5L, 1L, 1L, 2L, 3L, 1L, 2L, 3L, 1L, 2L, 3L, 1L, 2L, 3L, 
1L, 2L, 3L, 1L, 2L, 3L, 4L, 1L, 2L, 3L, 4L, 5L), levels = c("1", 
"2", "3", "4", "5", "6", "7"), class = "factor"), type = structure(c(3L, 
3L, 3L, 1L, 1L, 3L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 
1L, 3L, 1L, 1L, 3L, 3L, 3L, 1L, 1L, 1L, 1L, 1L), levels = c("0", 
"1", "2"), class = "factor"), time = structure(c(2L, 2L, 2L, 
2L, 2L, 2L, 1L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 1L, 
2L, 2L, 1L, 2L, 2L, 2L, 1L, 1L, 2L, 2L, 2L), levels = c("0", 
"1"), class = "factor"), volume = c(694L, 745L, 415L, 201L, 446L, 
589L, 99L, 887L, 266L, 261L, 188L, 391L, 240L, 221L, 578L, 296L, 596L, 204L, 703L, 113L, 370L, 922L, 419L, 168L, 879L, 856L, 800L, 736L, 386L, 912L)), row.names = c(NA, 30L), class = "data.frame")

# 核心转换代码
wide_data <- df %>%
  # 修正疫苗类型值:原因子水平"2"对应业务中的类型3
  mutate(type = case_when(
    type == "0" ~ "0",
    type == "1" ~ "1",
    type == "2" ~ "3"
  )) %>%
  # 按患者+疫苗类型分组,计算各类型总剂量、标记接种状态
  group_by(ptid, type) %>%
  summarise(
    vol_type = sum(volume),
    type_yn = 1,
    .groups = "drop"
  ) %>%
  # 按患者分组,计算总剂量和整体接种状态
  group_by(ptid) %>%
  mutate(
    totalvol = sum(vol_type),
    totalyn = 1
  ) %>%
  ungroup() %>%
  # 一次透视完成宽表转换,未接种类型填充0
  pivot_wider(
    id_cols = ptid,
    names_from = type,
    values_from = c(vol_type, type_yn),
    names_glue = "{.value}{type}",
    values_fill = list(vol_type = 0, type_yn = 0)
  ) %>%
  # 重命名变量匹配需求
  rename(
    voltype0 = vol_type0,
    voltype1 = vol_type1,
    voltype3 = vol_type3,
    type0yn = type_yn0,
    type1yn = type_yn1,
    type3yn = type_yn3
  ) %>%
  # 补全总剂量和总接种状态(兼容无接种记录的患者)
  mutate(
    totalvol = rowSums(select(., starts_with("voltype"))),
    totalyn = ifelse(totalvol > 0, 1, 0)
  ) %>%
  # 按患者ID排序
  arrange(ptid)

代码说明

  1. 修正类型值:解决原数据中因子水平与实际业务类型不匹配的问题,避免后续命名混乱。
  2. 分组汇总:先按ptid+type分组,计算单患者单类型的剂量总和与接种标记,减少后续透视的冗余数据。
  3. 单次透视成型:用pivot_wider一次性完成剂量和指示变量的宽表转换,通过names_glue自动生成规范变量名,values_fill对未接种类型填充0,避免NA值。
  4. 变量补全:通过行求和确保totalvol的准确性,同时兼容无接种记录的患者场景。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.22 03:32:14