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

如何使用pivot_longer将宽格式DataFrame转为含x、y列的长格式?

解决pivot_longer转换宽格式到长格式的问题

首先先构造你的示例DataFrame:

df <- data.frame(
  col = c("red", "blue"),
  x1 = c(23, 12),
  y1 = c(0.5, 8),
  x2 = c(25, 45),
  y2 = c(0.7, 0.1),
  x3 = c(30, 31),
  y3 = c(0.8, 0.5)
)

你需要把x1/y1、x2/y2、x3/y3这类成对列转成x和y的长格式,这里有两种简单的实现方式:

方法1:使用正则匹配列名模式

利用names_pattern捕获列名里的前缀(x/y)和数字后缀,通过.value指定用前缀作为新列的列名:

library(tidyr)

df1 <- df %>%
  pivot_longer(
    cols = !col,  # 选中除col外的所有列
    names_to = c(".value", "group"),  # .value表示用捕获的第一部分作为新列名,group是临时分组列
    names_pattern = "([xy])(\\d)"     # 正则匹配:第一个分组是x或y,第二个是数字
  ) %>%
  select(-group)  # 移除不需要的临时分组列

方法2:按字符位置分割列名

因为x/y都是单个字符,直接在第1个字符后分割列名,更简洁:

df1 <- df %>%
  pivot_longer(
    cols = !col,
    names_to = c(".value", "group"),
    names_sep = 1  # 在第1个字符后分割列名
  ) %>%
  select(-group)

两种方法最终都会得到你需要的结果:

col     x     y
1  red    23   0.5
2  red    25   0.7
3  red    30   0.8
4 blue    12   8.0
5 blue    45   0.1
6 blue    31   0.5

你之前代码的问题

你用names_sep = "(.)(.)"是错误的,这个语法会尝试按两个任意字符分割列名,但你的列名是x1、y1这类长度为2的字符串,分割后会得到空值和完整列名,完全不符合需求。正确的思路是把列名拆分成「类型(x/y)」和「组号」两部分,用.value让类型部分成为新的列名,组号作为临时分组依据。

内容的提问来源于stack exchange,提问作者user22178063

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.08 11:46:21