如何利用分隔符将多变量宽格式DataFrame转换为长格式
解决R中宽格式DataFrame转指定长格式的问题
你的问题核心是要将带有_1/_2后缀的宽列,按前缀分组转换为长格式列。使用tidyr::pivot_longer时,关键是通过names_pattern正确匹配列名的结构,而非单纯依赖分隔符。
宽格式DataFrame回顾
先确认你的原始数据结构:
FID <- c(1,2,3,4) d <- c(1,1,2,2) IID_1 <- c("1A","2A","NA","4A") IID_2 <- c("1B","2B","3B","4B") PS_1 <- c(0.5,0.8, NA, 0.3) PS_2 <- c(0.3,0.4, 0.1, 0.4) EA_1 <- c(0.2,0.8, NA, 0.3) EA_2 <- c(0.5,0.5, 0.1, 0.2) df <- data.frame (FID,d,IID_1,IID_2, PS_1, PS_2, EA_1, EA_2)
正确的pivot_longer转换代码
使用正则表达式匹配列名的前缀(如IID、PS、EA)和后缀(1/2),通过.value参数指定前缀作为长格式的列名:
library(tidyr) library(dplyr) # 可选,用于后续清理 df2 <- df %>% pivot_longer( cols = -c(FID, d), # 保留FID和d作为id列,其余列转长格式 names_to = c(".value", "group"), # .value对应列名前缀,group暂存后缀数字 names_pattern = "(.*)_(\\d+)" # 正则捕获前缀与后缀部分 ) %>% select(-group) # 不需要后缀分组则删除该列
验证结果
运行上述代码后,df2的结构与你要求的完全一致:
> df2 # A tibble: 8 × 4 FID d IID PS EA <dbl> <dbl> <chr> <dbl> <dbl> 1 1 1 1A 0.5 0.2 2 1 1 1B 0.3 0.5 3 2 1 2A 0.8 0.8 4 2 1 2B 0.4 0.5 5 3 2 NA NA NA 6 3 2 3B 0.1 0.1 7 4 2 4A 0.3 0.3 8 4 2 4B 0.4 0.2
关键参数说明
cols = -c(FID, d):明确指定不需要转换的标识列,剩余列全部参与转长格式names_to = c(".value", "group"):.value是pivot_longer的特殊关键字,用于将正则捕获的前缀作为新列名;group用来临时存储后缀的数字标识names_pattern = "(.*)_(\\d+)":正则表达式规则,(.*)匹配下划线前的列名前缀,(\\d+)匹配下划线后的数字后缀
内容的提问来源于stack exchange,提问作者JuanJMV
相关产品推荐
相关产品推荐

