R语言多列名数据框宽转长:pivot_longer使用难题求解
解决宽格式答题数据转长格式的问题
针对你的宽格式答题数据,用tidyverse的pivot_longer就能完成转换,核心是通过正则表达式提取题目前缀,同时匹配对应的四类字段。以下是具体步骤:
1. 模拟你的数据结构
先模拟一份和你描述一致的宽格式数据(假设包含用户ID列):
library(tidyverse) set.seed(123) df_wide <- tibble( id = 1:30, # 心血管题的四类列 cardiology_timestamp = sample(seq(as.POSIXct("2024-01-01"), as.POSIXct("2024-01-30"), by = "hour"), 30), cardiology = sample(c("A", "B", "C", "D"), 30, replace = TRUE), cardiology_key = rep("B", 30), cardiology_complete = rep(TRUE, 30), # 营养学题的四类列 nutrition_timestamp = sample(seq(as.POSIXct("2024-01-01"), as.POSIXct("2024-01-30"), by = "hour"), 30), nutrition = sample(c("True", "False"), 30, replace = TRUE), nutrition_key = rep("True", 30), nutrition_complete = rep(TRUE, 30), # 药理学题的四类列 pharmacology_timestamp = sample(seq(as.POSIXct("2024-01-01"), as.POSIXct("2024-01-30"), by = "hour"), 30), pharmacology = sample(c(1,2,3), 30, replace = TRUE), pharmacology_key = rep(2, 30), pharmacology_complete = sample(c(TRUE, FALSE), 30, replace = TRUE) )
2. 转换为长格式
用pivot_longer配合正则表达式提取题目信息:
df_long <- df_wide %>% pivot_longer( cols = -id, # 保留不需要转换的列(比如用户ID) names_to = c("Question", ".value"), # 正则表达式:提取前缀 + 匹配四类后缀(空后缀对应作答答案列) names_pattern = "^(.*?)(_timestamp|_key|_complete)?$", values_drop_na = TRUE # 可选:移除缺失值 ) %>% # 重命名列到你需要的字段名 rename( Timestamp = `_timestamp`, Response = ``, # 空字符串对应原作答答案列(无后缀的列) Key = `_key`, Complete = `_complete` ) %>% # 调整列顺序(可选) relocate(Question, Timestamp, Response, Key, Complete, .after = id)
关键参数解释
names_to = c("Question", ".value"):把列名拆成两部分,第一部分存为Question字段,第二部分作为新的列名(对应Timestamp/Response/Key/Complete)。names_pattern的正则逻辑:^(.*?):非贪婪匹配列名的前缀(比如cardiology、nutrition),作为题目标识。(_timestamp|_key|_complete)?:可选匹配三类后缀,空后缀对应原作答答案列(无后缀的列)。
注意事项
- 如果你的数据里有其他不需要转换的列(比如用户基本信息),在
cols参数里用-列名排除即可。 - 如果前缀里包含下划线,需要调整正则表达式(比如把
.*?改成[^_]+,但你描述的前缀是无下划线的,所以当前正则足够)。
内容的提问来源于stack exchange,提问作者Blair W
相关产品推荐
相关产品推荐

