在R中使用pivot_longer实现多变量宽表转长表的语法问题
用pivot_longer实现宽格式转长格式(多分类+多值列)
针对你的需求,使用tidyr::pivot_longer时核心是通过正则表达式解析列名结构,一次性拆分出分类列并对应值列。以下是完整实现:
完整代码
library(tidyr) library(dplyr) # 加载原始数据 df <- data.frame( stringsAsFactors = FALSE, Testing.Date = c("5/25/23","5/30/23","5/31/23", "6/1/23","6/27/23","6/20/23"), ID = c(101L, 103L, 106L, 109L, 110L, 201L), Condition = c("Lab", "Nature", "Nature", "Lab", "Nature", "Lab"), Age = c(21L, 22L, 22L, 21L, 29L, 56L), Pre.Time.A = c(22.78, 15.75, 30.33, 18.43, 26.99, 24.94), Pre.Error.A = c(0L, 0L, 1L, 0L, 0L, 0L), Pre.Time.B = c(60.38, 61.65, 65.6, 65.73, 58.63, 60.97), Pre.Error.B = c(0L, 0L, 1L, 2L, 0L, 0L), Post.Time.A = c(21.48, 14.65, 20.66, 24.55, 23.87, 35.7), Post.Error.A = c(0L, 0L, 0L, 0L, 0L, 0L), Post.Time.B = c(45.88, 48.58, 56.45, 48.95, 53, 64.3), Post.Error.B = c(0L, 0L, 0L, 0L, 0L, 0L) ) # 宽转长转换 TMT_long <- df %>% pivot_longer( cols = starts_with(c("Pre", "Post")), # 选中所有需要转换的宽格式列 names_pattern = "(Pre|Post)\\.(Time|Error)\\.(A|B)", # 正则匹配列名的三段结构 names_to = c("Assessment", ".value", "Test") # 分配匹配结果到对应列:.value表示此处匹配值作为新值列的名称 ) %>% rename(Errors = Error) # 将原Error列名调整为你期望的Errors # 查看ID=101的结果(与目标格式一致) TMT_long %>% filter(ID == 101)
参数说明
cols: 用starts_with快速筛选所有以"Pre"/"Post"开头的列,避免手动列举。names_pattern: 正则表达式(Pre|Post)\\.(Time|Error)\\.(A|B)精准匹配列名的三段结构:- 第一段
(Pre|Post)对应Assessment列的取值 - 第二段
(Time|Error)对应值列的名称(通过.value关键字实现) - 第三段
(A|B)对应Test列的取值
- 第一段
names_to: 这里的.value是pivot_longer的特殊参数,告诉函数将该位置的匹配结果作为值列的名称,因此会自动生成Time和Error列,后续用rename统一调整为Errors。
内容的提问来源于stack exchange,提问作者SBL
相关产品推荐
相关产品推荐

