R语言如何获取含点号命名、带dataframe的嵌套列表叶节点名称路径
你原来的方案核心问题是依赖unlist()的自动命名逻辑,它默认用点号作为层级分隔符拼接路径,只要节点名称本身带点就无法区分分隔符和名称本身的点,直接放弃这个逻辑就能解决问题。
解决方法
核心思路是在递归过程中主动维护当前节点的层级路径向量,从根源上避免点号冲突问题。
改进后代码
get_leaf_paths <- function(l, maxDepth = 2) { # 初始化结果存储列表 result <- list() # 内部递归函数 recurse <- function(cur_obj, cur_path, cur_depth) { # 终止条件:非列表/是data.frame/达到最大深度,存入当前路径 if (!is.list(cur_obj) || is.data.frame(cur_obj) || cur_depth >= maxDepth) { result <<- append(result, list(cur_path)) return() } # 遍历所有子节点递归 for (node_name in names(cur_obj)) { recurse( cur_obj = cur_obj[[node_name]], cur_path = c(cur_path, node_name), cur_depth = cur_depth + 1 ) } } # 启动递归 recurse(l, cur_path = c(), cur_depth = 0) return(result) }
测试效果
调用示例:
p <- list(a=1,b=list(b1=2,b2=3),c=list(c1=list(c11='a',c12='x'),c.2=data.frame("t"=1))) get_leaf_paths(p, maxDepth = 3)
输出完全符合要求:
[[1]] [1] "a" [[2]] [1] "b" "b1" [[3]] [1] "b" "b2" [[4]] [1] "c" "c1" "c11" [[5]] [1] "c" "c1" "c12" [[6]] [1] "c" "c.2"
原理解释
- 递归过程中每次进入子节点,就直接把当前子节点名称追加到路径向量
cur_path中,全程不会用点号做任何自动拼接,自然不会和名称自带的点号冲突 - 终止条件和你原有逻辑完全一致:遇到非列表对象、data.frame对象、达到最大深度时,就把当前路径作为叶节点路径存入结果
- 用
<<-超赋值符修改上层函数的结果列表,简化递归结果的收集逻辑
内容的提问来源于stack exchange,提问作者sequoia
相关产品推荐
相关产品推荐

