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

如何用tidyverse生成向量类型列表列而非数据框列表列?

问题

tidyr::nest() 会生成数据框/tibble类型的列表列:

library(tidyverse)

iris %>% nest(data = c(-Species))
#> # A tibble: 3 × 2
#>   Species    data             
#>   <fct>      <list>            
#> 1 setosa     <tibble [50 × 4]>
#> 2 versicolor <tibble [50 × 4]>
#> 3 virginica  <tibble [50 × 4]>

这种用法在很多场景中都很实用,但在部分场景下,我需要执行类似的隐式汇总操作,不过不是生成单个数据框类型的列表列,而是将每个选中列转换为向量类型的列表列。

目前可以通过nest()搭配unnest_wider()实现需求:

iris %>% nest(data = c(-Species)) %>%
  unnest_wider(data)
#> # A tibble: 3 × 5
#>   Species    Sepal.Length Sepal.Width Petal.Length Petal.Width
#>   <fct>       <list<dbl>> <list<dbl>>  <list<dbl>> <list<dbl>>
#> 1 setosa             [50]        [50]         [50]        [50]
#> 2 versicolor         [50]        [50]         [50]        [50]
#> 3 virginica          [50]        [50]         [50]        [50]

也可以通过更显式的汇总操作实现:

iris %>%
  group_by(Species) %>%
  summarize(across(everything(), vctrs::list_of))
#> # A tibble: 3 × 5
#>   Species    Sepal.Length Sepal.Width Petal.Length Petal.Width
#>   <fct>       <list<dbl>> <list<dbl>>  <list<dbl>> <list<dbl>>
#> 1 setosa             [50]        [50]         [50]        [50]
#> 2 versicolor         [50]        [50]         [50]        [50]
#> 3 virginica          [50]        [50]         [50]        [50]

但这两种方法都略显繁琐,我想知道在tidyr或相关tidyverse包中,是否有更简洁、更标准的实现方式?


回答

在tidyverse生态里,目前最简洁且标准的实现方式就是用dplyr::summarize()配合across(),甚至可以直接用list()替代vctrs::list_of()(后者的优势是生成类型更严谨的列表列,避免混入不同类型的元素),写法非常紧凑:

iris %>% 
  group_by(Species) %>% 
  summarize(across(everything(), list))

输出结果和你之前的方法完全一致:

#> # A tibble: 3 × 5
#>   Species    Sepal.Length Sepal.Width Petal.Length Petal.Width
#>   <fct>       <list<dbl>> <list<dbl>>  <list<dbl>> <list<dbl>>
#> 1 setosa             [50]        [50]         [50]        [50]
#> 2 versicolor         [50]        [50]         [50]        [50]
#> 3 virginica          [50]        [50]         [50]        [50]

另外,tidyr::nest_by()也能实现类似效果,但需要额外的步骤拆分列,写法反而不如summarize + across简洁,所以不推荐作为首选方案。

需要说明的是,tidyverse目前没有专门的单一函数直接实现「按分组将每列转为向量列表列」的操作,上面的summarize + across已经是最简洁的标准写法了。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.07 05:32:46