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

如何使用pivot_longer处理两组序列列实现宽表转长表

解决方案:将两组序列列从宽格式转换为长格式

正确转换代码

library(tidyr)
library(dplyr)

test_pivot <- df %>%
  # 仅筛选start_date_*和end_date_*列,保留id、wt、gen作为标识列
  pivot_longer(
    cols = starts_with(c("start_date", "end_date")),
    # .value保留列名前缀(start_date/end_date)作为新列名,number存储序列编号
    names_to = c(".value", "number"),
    # 正则捕获前缀(如start_date)和后缀数字
    names_pattern = "([a-z_]+)_(\\d+)"
  ) %>%
  # 生成期望输出中的列名字段
  mutate(
    start_date = paste0("start_date_", number),
    end_date = paste0("end_date_", number)
  ) %>%
  # 调整列顺序并匹配期望输出的列名
  select(id, start_date, start_date_date = start_date, end_date, end_date_date = end_date, wt, gen) %>%
  # 移除临时编号列
  select(-number)

问题修正说明

你之前的尝试存在三个核心问题:

  1. 列选择错误:cols = everything()会把id、wt、gen这些无需转长的标识列也纳入转换,导致结果混乱。改用starts_with(c("start_date", "end_date"))可精准筛选目标列,不受列顺序影响。
  2. 正则匹配错误:原正则([a-z]+_)(\\d)仅能匹配start_或end_,漏掉了date部分。新正则([a-z_]+)_(\\d+)可完整捕获start_date/end_date前缀和后续数字编号。
  3. 命名逻辑错误:names_to的第二个参数命名应为number(表示序列编号),而非end_date,避免语义混淆。

大规模数据集适配

  • 该方法不依赖列的排列顺序,starts_with可高效匹配数百个start_date_n/end_date_n列。
  • pivot_longer是tidyr优化后的函数,处理数千个唯一ID的大规模数据时性能稳定,确保使用最新版本的tidyr即可。

示例输出(以ID=1为例)

id  start_date start_date_date  end_date end_date_date wt gen
1  1 start_date_1      2022-04-03 end_date_1      2022-04-03 12   m
2  1 start_date_2      2022-04-03 end_date_2      2022-04-03 12   m
3  1 start_date_3      2022-04-03 end_date_3      2022-04-03 12   m

内容的提问来源于stack exchange,提问作者Cae.rich

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.17 17:55:30