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

R语言tidyverse如何简洁实现按列前缀嵌套tibble保留原列名

需求背景

常规nest()函数的嵌套逻辑是按行分组实现嵌套,本次需求与常规用法存在差异:

  • 按照列名中第一个下划线_前的前缀分组,创建嵌套tibble
  • 嵌套生成的子tibble需要保留原始列名

目前已通过多步转换实现需求,但代码逻辑过于繁琐,原有实现代码如下:

tibble(a_1=1:3, a_2=2:4, b_1=3:5) %>% 
    print() %>%

#  A tibble: 3 x 3
#     a_1   a_2   b_1
#   <int> <int> <int>
# 1     1     2     3
# 2     2     3     4
# 3     3     4     5

    pivot_longer(everything()) %>% 
    nest(data=-name) %>% 
    mutate(data=map2(data, name, ~rename(.x, '{.y}' := value))) %>% 
    mutate(gr=str_extract(name, '^[^_]+'), .keep='unused') %>% 
    nest(data=-gr) %>% 
    mutate(data=map(data, ~bind_cols(.[[1]]))) %>%
    print() %>%

# A tibble: 2 x 2
#   gr    data            
#   <chr> <list>          
# 1  a     <tibble [3 x 2]>
# 2  b     <tibble [3 x 1]>

    { .$data[[1]] }

# A tibble: 3 x 2
#     a_1   a_2
#   <int> <int>
# 1     1     2
# 2     2     3
# 3     3     4

要求优先提供tidyverse风格的简洁解决方案。

tidyverse简洁实现

不需要做长宽表转换、反复嵌套重命名,直接按列名前缀匹配选列即可,逻辑更直白:

library(tidyverse)

# 测试数据
df <- tibble(a_1=1:3, a_2=2:4, b_1=3:5)

# 核心实现代码
nested_res <- tibble(
  # 提取所有不重复的列名前缀
  gr = unique(str_extract(names(df), "^[^_]+")),
  # 按前缀匹配选择对应列,存入list列
  data = map(gr, ~select(df, starts_with(paste0(.x, "_"))))
)

运行后得到的结果和原有繁琐实现完全一致:

# A tibble: 2 × 2
  gr    data            
  <chr> <list>          
1 a     <tibble [3 × 2]>
2 b     <tibble [3 × 1]>

如果需要提取指定前缀对应的子tibble,直接索引即可,比如提取前缀a对应的子表:

nested_res$data[[1]]

输出结果:

# A tibble: 3 × 2
    a_1   a_2
  <int> <int>
1     1     2
2     2     3
3     3     4

方案优势

  • 无冗余转换步骤:跳过了长宽表转换、多次嵌套、重命名、列合并等多余操作
  • 天然保留原始列名:直接从原表选列,不需要额外做列名修复
  • 可读性更强:代码逻辑和需求直接对应,先拿前缀,再按前缀选列,后续维护成本低

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.28 03:57:19