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

如何使用pivot_longer直接提取前缀实现宽表转长表

问题

我的数据常以宽表格式呈现,列名包含"Left/Right"或"Pre/Post"前缀但无分隔符,需要按这些前缀合并变量转成长表。目前我通过gsub()在列名中插入分隔符,再用pivot_longer的names_sep参数实现转换,但想知道是否可以直接使用pivot_longer的names_prefix、names_pattern、names_to语法完成。

示例宽表:

HW <- tribble(
  ~Subject,  ~LeftV1,  ~RightV1, ~LeftV2, ~RightV2,  ~LeftV3, ~RightV3,
  "A", 0, 1, 10, 11, 100, 101,
  "B", 2, 3, 12, 13, 102, 103,
  "C", 4, 5, 14, 15, 104, 105)

期望得到的长表结构:

HWT <- tribble(
  ~Subject,  ~Side, ~V1,  ~V2,  ~V3,
  "A", "Left", 0, 10, 100,
  "A", "Right", 1, 11, 101, 
  "B", "Left", 2, 12, 102,
  "B", "Right", 3, 13, 103,
  "C", "Left", 4, 14, 104,
  "C", "Right", 5, 15, 105)

我尝试了如下语法,但均出现语法错误:

HWT <- HW %>% pivot_longer(
  cols = contains(c("Left", "Right")),
  names_pattern = "/^(Left|Right)",
  names_to =  c('Side', '.value') )

或:

HWT <- HW %>% pivot_longer(
  cols = contains(c("Left", "Right")),
  names_prefix = "/^(Left|Right)",
  names_to =  c('Side', '.value') )
解决方案

你之前的写法问题出在正则表达式格式和参数使用逻辑上:

  • names_pattern不需要额外添加开头的/,且必须完整匹配列名的两个组成部分(前缀+变量名),通过捕获组分别对应names_to中的元素;
  • names_prefix仅用于移除指定前缀,无法同时提取分组信息,不适合当前场景。

正确的写法是用names_pattern分别捕获前缀(Left/Right)和后续变量名(V1/V2/V3),再通过names_to指定第一个捕获组映射到Side列,第二个捕获组对应.value(即保留变量名作为新的列名):

library(tidyr)
library(dplyr)

HWT <- HW %>% 
  pivot_longer(
    cols = -Subject,  # 排除Subject列,用contains(c("Left", "Right"))也可
    names_pattern = "(Left|Right)(V\\d+)",
    names_to = c("Side", ".value")
  )

运行这段代码即可得到期望的长表结构。如果处理"Pre/Post"前缀的场景,只需将正则中的(Left|Right)替换为(Pre|Post)即可。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.19 00:20:16