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

列名包含两部分的tibble如何转长格式?可通过dplyr实现吗?

你要的效果用pivot_longer可以一行核心代码实现,你之前调试没成功大概率是没配好列名拆分和排序规则,具体实现如下:
你已经加载了tidyverse,其中pivot_longer属于tidyr包,和dplyr同属tidyverse生态,可以直接调用,完整代码:

library(tidyverse)

df = tribble(
  ~id, ~a1, ~a2, ~a3, ~b1, ~b2, ~b3, ~c1, ~c2, ~c3,
    1,   1,   4,   7,  11,  14,  17,  21,  24,  27,
    2,   2,   5,   8,  12,  15,  18,  22,  25,  28,
    3,   3,   6,   8,  13,  16,  19,  23,  26,  29,
)

df_long <- df %>%
  pivot_longer(
    cols = -id, # 除了id列,其余所有列都转长格式
    names_to = c("name", "nr"), # 原列名拆分后存为name和nr两列
    names_sep = 1, # 拆分规则:在第1个字符后切割,刚好把a1拆为"a"和"1"
    values_to = "data", # 原单元格的值存在data列
    cols_vary = "slowest" # 控制排序规则,优先按name、nr排序,再按id排序,和你给的示例输出顺序完全一致
  ) %>%
  mutate(nr = as.integer(nr)) # 把nr列从字符串转为整数,和示例格式匹配

运行后得到的df_long和你给出的预期输出完全一致。
如果你确实需要仅用dplyr原生函数实现(不依赖tidyr),也可以用如下写法,不过逻辑会繁琐很多:

df_long <- df %>%
  rowwise() %>%
  reframe(
    id = id,
    name = rep(c("a","b","c"), each = 3),
    nr = rep(1:3, 3),
    data = c(a1,a2,a3,b1,b2,b3,c1,c2,c3)
  )

两种方法都可以得到你要的结果,优先推荐第一种更简洁的pivot_longer写法。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.28 07:09:03