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

如何在R语言中将两层嵌套列表展平为单层列表?

嵌套列表扁平化问题:R中do.call(c, ...)处理含data.frame的列表失效原因及解决方法

需求说明

我有一个两层嵌套结构的列表,结构如下:

>>> View(mylist)
[
[{"id":1, "name": "Jack"},{"id":2, "name": "Mike"}],
[{"id":3, "name": "Mary"},{"id":4, "name": "Bob"}],
]

需要将其转换为单层列表,目标格式:

>>> View(mylist)
[
{"id":1, "name": "Jack"},{"id":2, "name": "Mike"},
{"id":3, "name": "Mary"},{"id":4, "name": "Bob"},
]

Python中的实现方式

在Python中,这个需求可以通过列表推导式快速实现:

[subitem for item in mylist for subitem in item]

也可以借助itertools工具:

import itertools
list(itertools.chain.from_iterable(mylist))

R中的问题:do.call(c, ...)的局限性

在R中,我尝试用do.call(c, mylist)处理,这个方法在处理纯list组成的嵌套列表(比如上述mylist)时可以得到预期结果,但处理包含data.frame的嵌套列表(比如下面的data1)时,输出格式完全不符合预期。

示例数据构造代码

纯list嵌套列表mylist

mylist <- list(
  list(
    list(id = 1, name = "Jack"),
    list(id = 2, name = "Mike")
  ),
  list(
    list(id = 3, name = "Mary"),
    list(id = 4, name = "Bob")
  )
)

含data.frame的嵌套列表data1

data1 <- list(
  data.frame(
    id = c(3, 4),
    name = c("John", "Anna")
  ),
  data.frame(
    id = c(5, 6),
    name = c("Tom", "Jerry")
  )
)

问题原因

do.call(c, mylist)的核心逻辑是调用c()函数拼接列表元素,但c()函数对不同类型的元素处理逻辑不同:

  • 当元素是普通list时,c()会直接将其拆解为列表的子元素,实现扁平化;
  • 当元素是data.frame时,c()会将data.frame按列拆解为单独的向量,而不是保留data.frame的整体结构。比如处理data1时,do.call(c, data1)会输出一个包含4个向量的列表(两个id列、两个name列),而不是合并后的data.frame或保留结构的单层列表。

正确的解决方法

根据实际需求,有两种处理方式:

1. 合并多个data.frame为一个大的data.frame

如果目标是把嵌套列表中的data.frame合并成完整数据集,可以用:

# 基础R方法
do.call(rbind, data1)

# tidyverse方法(更高效,支持不同列名的data.frame)
library(dplyr)
bind_rows(data1)

2. 扁平化嵌套列表,保留元素原始结构

如果目标是将两层嵌套列表转为单层,同时保留每个元素(不管是list还是data.frame)的原始结构,可以用:

# 基础R方法:unlist设置recursive=FALSE
unlist(mylist, recursive = FALSE)
unlist(data1, recursive = FALSE)

# tidyverse方法:purrr::flatten
library(purrr)
flatten(mylist)
flatten(data1)

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.15 03:40:02