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

R中嵌套列表/数据框全层级字段相对路径高效获取方案问询

目标

本问题关联但未被多个Stack Overflow问答覆盖(具体问答编号已省略)。

我希望在R中创建一个**高效(即快速)**的函数,返回一个character向量,包含任意深度的嵌套list或data.frame中所有字段的相对路径,也可选择仅返回满足指定谓词函数的字段路径。

示例

举例来说,我有如下数据结构(本示例为data.table,也可以是tibble或普通list):

input <- data.table(
  a = c(1, 2, 3, 4),
  b = LETTERS[1:4],
  c = list(
    list(a = 1, g = 2),
    list(a = 1),
    list(a = 1, b = 50),
    list(a = 1, zeta = data.frame(one = 'two', two = 'three'))
  ),
  d = list(
    data.frame(
      x = c(1, 2),
      y = LETTERS[1:2],
      z = data.frame(a = c("10", "20"))
    ),
    data.frame(
      x = c(3, 4, 5),
      y = LETTERS[3:5],
      z = data.frame(a = c("30", "40", "50"))
    ),
    data.frame(
      x = 6,
      y = LETTERS[6],
      z = 'another_thing',
      zz = list(a = "60", p = 'eish')
    ),
    data.frame(
      x = 7:12,
      y = LETTERS[7:12],
      z = data.frame(a = as.character(70:75))
    )
  )
)

基础版本函数应用于input时的期望输出(需严格符合指定格式)如下:

c(
  "[['a']]",
  "[['b']]",
  "[['c']]",
  "[['c']][[1]]",
  "[['c']][[1]][['a']]",
  "[['c']][[1]][['g']]",
  "[['c']][[2]]",
  "[['c']][[2]][['a']]",
  "[['c']][[3]]",
  "[['c']][[3]][['a']]",
  "[['c']][[3]][['b']]",
  "[['c']][[4]]",
  "[['c']][[4]][['a']]",
  "[['c']][[4]][['zeta']]",
  "[['c']][[4]][['zeta']][['one']]",
  "[['c']][[4]][['zeta']][['two']]",
  "[['d']]",
  "[['d']][[1]]",
  "[['d']][[1]][['x']]",
  "[['d']][[1]][['y']]",
  "[['d']][[1]][['a']]",
  "[['d']][[2]]",
  "[['d']][[2]][['x']]",
  "[['d']][[2]][['y']]",
  "[['d']][[2]][['a']]",
  "[['d']][[3]]",
  "[['d']][[3]][['x']]",
  "[['d']][[3]][['y']]",
  "[['d']][[3]][['z']]",
  "[['d']][[3]][['zz.a']]",
  "[['d']][[3]][['zz.p']]",
  "[['d']][[4]]",
  "[['d']][[4]][['x']]",
  "[['d']][[4]][['y']]",
  "[['d']][[4]][['a']]"
)

即输出需包含根对象input下所有层级字段的完整相对路径列表。

当前方案

我已实现递归函数find_paths,该函数接受以下参数:

  • .x:待搜索的根嵌套list或data.frame
  • .p:(可选)谓词函数,用于判断是否将某字段路径加入输出
  • max_depth:搜索的最大嵌套深度(可限制初始搜索范围)
  • current_path、current_depth、paths:递归过程中内部更新的参数
find_paths <- function(.x,
                       .p = NULL,
                       max_depth = Inf,
                       current_path = '',
                       current_depth = 0,
                       paths = NULL) {
  # 达到最大深度时停止搜索
  if (current_depth > max_depth) return(paths)
  
  # 应用指定的谓词函数
  if (is.function(.p)) {
    if (current_depth > 0 & .p(.x)) {
      paths <- c(paths, current_path)
    }
  } else {
    if (current_depth > 0) {
      paths <- c(paths, current_path)
    }
  }
  
  # 递归部分:判断是否为列表并继续构建路径
  if (is.list(.x)) {
    if (is.null(names(.x))) {
      for (i in seq_along(.x)) {
        new_path <- paste0(current_path, "[[", i, "]]")
        paths <- find_paths(
          .x = .x[[i]],
          .p = .p,
          max_depth = max_depth,
          current_path = new_path,
          current_depth = current_depth + 1,
          paths = paths
        )
      }
    } else {
      for (name in names(.x)) {
        new_path <- paste0(current_path, "[['", name, "']]")
        paths <- find_paths(
          .x = .x[[name]],
          .p = .p,
          max_depth = max_depth,
          current_path = new_path,
          current_depth = current_depth + 1,
          paths = paths
        )
      }
    }
  }
  
  # 返回路径结果
  paths
}


# 不使用谓词的用法(生成上述示例输出)
find_paths(.x = input)

# 使用谓词的用法(仅返回字符类型元素的路径)
find_paths(.x = input, .p = is.character)

该函数在处理input这类对象时可正确生成期望输出,但在处理更大、更复杂的嵌套结构时性能极差(主观判断为难以接受)。我需处理的数据通常包含数十万行,且有数百个深度达8层的嵌套字段。现提出两个问题:

  1. 我是否忽略了某些关键点?此类任务是否本质上效率低下?递归是否为正确的实现方式?我推测若要应用谓词函数,递归可能不可避免,但希望能有更简便的方法获取R中嵌套对象的所有名称/地址/路径(不确定正确术语)。
  2. 是否存在更优(即更快)的替代方案?我已尝试过多种方法,但多数方法(如展开根嵌套对象)需对输入对象进行昂贵的转换,抵消了避免递归带来的潜在优势。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.21 23:37:03