将宽格式DataFrame转换为长格式以开展时变分析
宽表转长表解决方案(适配时变分析需求)
你遇到的问题核心是将成对的列(SGLT_v1_xxx和SGLT_time_xxx)按时间维度合并为长表,pivot_longer完全可以解决,关键是用正则表达式匹配列名的结构。
完整代码实现
library(tidyverse) # 加载原始数据 df <- structure(list(ID = 1:2, Age = c(45L, 60L), SGLT_v1_0_3 = 1:0, SGLT_time_0_3 = c(92L, 92L), SGLT_v1_3_6 = 0:1, SGLT_time_3_6 = c(183L, 183L), SGLT_v1_6_9 = 1:0, SGLT_time_6_9 = c(285L, 285L)), class = "data.frame", row.names = c(NA, -2L)) # 转换为目标长表格式 df_long <- df %>% pivot_longer( cols = starts_with("SGLT_"), # 选中所有需要转换的SGLT相关列 names_to = c(".value", "time_interval"), # .value保留原列前缀作为新列名,time_interval存时间区间后缀 names_pattern = "SGLT_(.*)_(.*)" # 正则拆分列名:SGLT_前缀 + 指标类型(v1/time) + 时间区间 ) %>% rename(SGLT_time = time, SGLT_v1 = v1) %>% # 重命名为你需要的列名 select(ID, Age, SGLT_time, SGLT_v1) %>% # 调整列顺序 arrange(SGLT_time, ID) # 按时间和ID排序 # 查看结果 print(df_long)
转换后输出
ID Age SGLT_time SGLT_v1 1 1 45 92 1 2 2 60 92 0 3 1 45 183 0 4 2 60 183 1 5 1 45 285 1 6 2 60 285 0
关键参数说明
names_pattern = "SGLT_(.*)_(.*)":用正则表达式把列名拆成三部分,其中(.*)分别匹配指标类型(v1/time)和时间区间(0_3/3_6/6_9)。names_to = c(".value", "time_interval"):.value是特殊占位符,告诉pivot_longer把匹配到的第一组(v1/time)作为新的列名,自动将同一时间区间的v1和time值对应到同一行。starts_with("SGLT_"):精准选中需要转换的列,避免误操作ID、Age等固定属性列。
内容的提问来源于stack exchange,提问作者Sharon Macwan
相关产品推荐
相关产品推荐

