R语言:如何按pof后数字对多列透视,实现宽表转长表
问题描述
现有一份宽格式数据集,包含母亲ID列Patient_ID,以及对应多胎新生儿的分组列(如双胞胎、三胞胎对应不同后缀编号)。列名规则如下:
pofid_n:第n个婴儿的唯一ID(唯一不遵循pofnvarname格式的列)pofncompleteddate、pofnpregendweeks:第n个婴儿的对应属性列(每个婴儿对应约50列,示例仅展示3列)
初始数据集代码:
df <- data.frame( Patient_ID = c(1, 2, 3, 4), pofid_1 = c(1, 2, 3, 4), pof1completeddate = as.Date(c("2022-11-12", "2022-12-11", "2022-10-10", "2022-01-01")), pof1pregendweeks = c(40, 39, 41, 40), pofid_2 = c(NA, NA, 5, 6), pof2completeddate = as.Date(c(NA, NA, "2022-10-10", "2022-01-01")), pof2pregendweeks = c(NA, NA, 41, 40) )
初始数据展示:
Patient_ID pofid_1 pof1completeddate pof1pregendweeks pofid_2 pof2completeddate pof2pregendweeks 1 1 1 2022-11-12 40 NA <NA> NA 2 2 2 2022-12-11 39 NA <NA> NA 3 3 3 2022-10-10 41 5 2022-10-10 41 4 4 4 2022-01-01 40 6 2022-01-01 40
需要将其转换为长格式,每个婴儿对应一行,最终列名如下:Patient_ID、babynumber、pofid、pofcompleteddate、pofpregendweeks
期望结果:
Patient_ID pofid babynumber pofcompleteddate pofpregendweeks 1 1 1 1 2022-11-12 40 2 2 2 1 2022-12-11 39 3 3 3 1 2022-10-10 41 4 3 5 2 2022-10-10 41 5 4 4 1 2022-01-01 40 6 4 6 2 2022-01-01 40
解决方案
使用R语言的tidyverse工具包可以高效完成宽转长的转换,步骤如下:
- 加载
tidyverse包(未安装先执行install.packages("tidyverse")):
library(tidyverse)
- 执行数据转换:
result <- df %>% # 将所有婴儿相关列转为长格式,提取婴儿编号和统一变量名 pivot_longer( cols = -Patient_ID, names_to = c("babynumber", "variable"), # 正则匹配两种列名格式,提取婴儿编号和变量名前缀 names_pattern = "^pof(?:id_)?(\\d+)(.*)$", # 统一变量名格式:空字符串对应pofid,其余补全pof前缀 names_transform = list( babynumber = as.integer, variable = ~ ifelse(.x == "", "pofid", paste0("pof", .x)) ), # 过滤掉无婴儿数据的NA行 values_drop_na = TRUE ) %>% # 将长格式转回宽格式,每个婴儿一行 pivot_wider( names_from = variable, values_from = value ) %>% # 调整列顺序为期望格式 select(Patient_ID, pofid, babynumber, pofcompleteddate, pofpregendweeks)
运行上述代码后,result即为所需的长格式数据集。
内容的提问来源于stack exchange,提问作者jackahall
相关产品推荐
相关产品推荐

