如何用tidyr单次pivot操作高效整理多列非整洁数据
高效实现宽格式到整洁长格式的转换
问题背景
现有宽格式数据df_have,包含患者ID、两个阶段(ip/cp)的多组药物编码和剂量,需要转换为包含id/phase/drug/dose的长格式df_want。原多步骤转换代码在大数据集上速度较慢,希望用更高效的方式,最好通过单次pivot操作完成。
可行的高效方案
方法1:单次pivot_longer配合列名拆分
可以直接用**单次pivot_longer**完成转换,无需后续的pivot_wider操作。利用names_sep拆分列名,同时指定names_to的结构来自动匹配drug和dose的对应关系:
library(tidyr) library(dplyr) df_have %>% pivot_longer( cols = -id, names_to = c("phase", ".value", "drug_num"), names_sep = "_", values_drop_na = FALSE # 保留NA行,匹配目标格式 ) %>% select(-drug_num) # 移除临时的药物序号列
方法2:正则匹配列名(更灵活)
如果列名规则需要更精准的匹配,可改用names_pattern实现相同效果:
df_have %>% pivot_longer( cols = -id, names_to = c("phase", ".value", "drug_num"), names_pattern = "(ip|cp)_(drug|dose)(\\d+)", values_drop_na = FALSE ) %>% select(-drug_num)
效率优势说明
- 避免了
pivot_longer→mutate→pivot_wider的多步骤数据重组,减少内存操作次数 - 直接通过一次列名拆分完成
drug/dose的对应映射,无需临时辅助列
运行上述代码后,输出结果与目标df_want完全一致,且在大规模数据集上的运行速度远优于原多步骤方案。
内容的提问来源于stack exchange,提问作者jpsmith
相关产品推荐
相关产品推荐

