You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何利用分隔符将多变量宽格式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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.27 18:23:19