如何无需生成两个数据框再合并,实现两次同时Pivoting longer?
解决方案
可以通过一次pivot_longer结合正则表达式匹配列名实现配对转换,无需拆分后合并数据框,直接得到列顺序符合要求的结果:
library(tidyverse) dat_long_test <- dat %>% pivot_longer( # 指定所有需要转换的结果和协变量列 cols = c(glucose_mmol, trig_mmol, col_total_mmol, glucose_mmol_cov, trig_mmol_cov, col_total_mmol_cov), # 拆分列名为两部分:指标名称 + 数值类型(结果/协变量) names_to = c("outcomes_names", ".value"), # 正则表达式捕获:第一组是指标核心名称,第二组标记是否为协变量 names_pattern = "^(.*)_mmol(_cov)?$", # 可选:自动丢弃全NA的行,按需调整 values_drop_na = TRUE ) %>% # 重命名列到目标名称 rename( outcomes_values = ``, covariate_values = `_cov` ) %>% # 调整列顺序,确保协变量列紧邻结果列 select(ID, time, group, outcomes_names, outcomes_values, covariate_values)
代码说明:
names_pattern = "^(.*)_mmol(_cov)?$":用正则将列名拆分为两部分:- 第一组
(.*)捕获指标核心名称(比如glucose、trig) - 第二组
(_cov)?标记是否为协变量列(匹配_cov或空字符串)
- 第一组
.value作为names_to的一部分,会将对应类型的数值自动填充到新列:无_cov的列值进入空名字段,带_cov的进入_cov字段- 最后通过
rename和select调整列名与顺序,得到目标结构:outcomes_names|outcomes_values|covariate_values
替代方案(分步转换更直观)
如果觉得正则表达式难理解,也可以用两次pivot操作实现,同样无需额外合并数据框:
dat_long_test <- dat %>% # 第一步:将所有相关列转成长格式,拆分指标名和数值类型 pivot_longer( cols = starts_with(c("glucose", "trig", "col_total")), names_to = c("outcomes_names", "type"), names_pattern = "^(.*)_(.*)$", values_to = "value" ) %>% # 第二步:将类型(mmol/mmol_cov)转成列,实现配对 pivot_wider( names_from = type, values_from = value ) %>% # 重命名为目标列名 rename( outcomes_values = mmol, covariate_values = mmol_cov ) %>% # 调整列顺序 select(ID, time, group, outcomes_names, outcomes_values, covariate_values)
内容的提问来源于stack exchange,提问作者jtjtjtjt
相关产品推荐
相关产品推荐

