如何在R中重塑数据集并提取日期、HbA1c及月份用于分析?
R语言宽格式医疗数据转长格式解决方案
核心思路:用tidyverse包的pivot_longer实现向量化转换(替代低效的for循环)
针对你的宽格式医疗数据,我们可以通过分组提取字段前缀和编号,自动将同一随访时间点的days_*、HbA1c_Date_*、HbA1c_*字段对应到同一行,再匹配对应月份信息。
步骤1:安装并加载依赖包
# 第一次使用先安装 install.packages("tidyverse") # 加载包 library(tidyverse)
步骤2:核心转长操作(处理days、HbA1c相关字段)
假设你的数据集名为df,执行以下代码将重复的时间点字段转成长格式:
# 将days_*、HbA1c_Date_*、HbA1c_*转成长格式,保留Pat_ID、study_group等非重复字段 long_core <- df %>% pivot_longer( # 指定要转长的列:所有以days_、HbA1c_Date_、HbA1c_开头的列 cols = starts_with("days_") | starts_with("HbA1c_Date_") | starts_with("HbA1c_"), # 将列名拆分为「字段前缀」和「时间点编号」,前缀作为新列名,编号作为分组标识 names_to = c(".value", "time_point"), # 正则表达式:匹配「前缀_数字」的格式,(.*)捕获前缀,(\\d+)捕获数字编号 names_pattern = "(.*)_(\\d+)" )
执行后,你会得到包含Pat_ID、study_group、days、HbA1c_Date、HbA1c、time_point的长格式表,同一time_point对应同一随访时间的所有数据。
步骤3:匹配月份信息(处理X*_month字段)
如果你的X1_month、X2_month等字段对应time_point的1、2,执行以下代码转换并合并:
# 将X*_month转成长格式,提取时间点编号 month_data <- df %>% select(Pat_ID, starts_with("X") & ends_with("_month")) %>% pivot_longer( cols = -Pat_ID, names_to = "time_point", values_to = "visit_month", # 正则表达式:提取X和_month之间的数字作为time_point names_pattern = "X(\\d+)_month" ) # 合并核心长表和月份表,按患者ID和时间点匹配 final_df <- long_core %>% left_join(month_data, by = c("Pat_ID", "time_point"))
步骤4:处理followup_*字段(可选)
如果followup_1、followup_2等字段对应各时间点的随访信息,只需在第一步的cols参数中加入starts_with("followup_")即可:
long_core <- df %>% pivot_longer( cols = starts_with("days_") | starts_with("HbA1c_Date_") | starts_with("HbA1c_") | starts_with("followup_"), names_to = c(".value", "time_point"), names_pattern = "(.*)_(\\d+)" )
关键说明
- 为什么不用for循环?R的循环是逐行处理,效率极低,且容易因字段名不规范、空值等问题出错;
pivot_longer是向量化操作,一次处理所有列,简洁高效。 - 正则表达式
names_pattern是核心:如果你的字段命名规则不同(比如days1而非days_1),只需调整正则表达式即可,比如改成"(.*)(\\d+)"。
内容的提问来源于stack exchange,提问作者Ray
相关产品推荐
相关产品推荐

