R 为嵌套列表的每个叶提取名称层次结构

R 为嵌套列表的每个叶提取名称层次结构,r,R,我有一个任意深度的列表,其中包含任意数量的命名字符向量。一个简单的例子可能是: d <- c("foo", "bar") names(d) <- c("d1", "d2") e <- c("bar","foo") names(e) <- c("d1", "d3") l <- list(a1 = list(b1 = list(c1 = d, c2 = e), a2 = list(b1 = e))) l $a1 $a1$b1 $a1$b1$c1 d1 d2

我有一个任意深度的列表,其中包含任意数量的命名字符向量。一个简单的例子可能是:

d <- c("foo", "bar")
names(d) <- c("d1", "d2")
e <- c("bar","foo")
names(e) <- c("d1", "d3")
l <- list(a1 = list(b1 = list(c1 = d, c2 = e), a2 = list(b1 = e)))
l

$a1
$a1$b1
$a1$b1$c1
  d1    d2 
"foo" "bar" 

$a1$b1$c2
  d1    d3 
"bar" "foo" 


$a1$a2
$a1$a2$b1
  d1    d3 
"bar" "foo" 

比较不同“任意级别”的效率的通用解决方案会获得额外的积分;)

此递归函数似乎有效:

collect_names <- function(l) {
  if (!is.list(l)) return(NULL)
  names <- Map(paste, names(l), lapply(l, collect_names), sep = "$")
  gsub("\\$$", "", unlist(names, use.names = FALSE))
}

collect_names(l)
# [1] "a1$b1$c1" "a1$b1$c2" "a1$a2$b1"
collect_name其他选项:

层次视图:

f <- function(x, parent=""){
    if(!is.list(x)) return(parent)
    mapply(f, x, paste(parent,names(x),sep="$"), SIMPLIFY=FALSE)
}

f(l)

$a1
$a1$b1
$a1$b1$c1
[1] "$a1$b1$c1"

$a1$b1$c2
[1] "$a1$b1$c2"


$a1$a2
$a1$a2$b1
[1] "$a1$a2$b1"

f
wdots为真。然而,当我在更大更复杂的列表上尝试时,我得到了以下错误——mapply中的错误(FUN=f,…,SIMPLIFY=FALSE):零长度输入不能与非零长度的输入混合。我猜想与您的示例不同,您的真实数据包含未命名的列表。你能查一下吗?这将如何影响您的预期输出?或者您可以将
names(l)
替换为
if(is.null(names(l))rep(“,length(l))else names(l)
以获得与当前发布的其他两个答案相同的行为。+1因为没有使用递归函数!这似乎也适用于我更复杂的列表…
rapply
确实很有趣。不过我会在工作中使用扳手-在运行后尝试:
names(l)@TheLate Mail很有道理。我不知道如何避开这一点,但这是我最近的一次:
f <- function(x, parent=""){
    if(!is.list(x)) return(parent)
    mapply(f, x, paste(parent,names(x),sep="$"), SIMPLIFY=FALSE)
}

f(l)

$a1
$a1$b1
$a1$b1$c1
[1] "$a1$b1$c1"

$a1$b1$c2
[1] "$a1$b1$c2"


$a1$a2
$a1$a2$b1
[1] "$a1$a2$b1"
f <- function(x, parent=""){
    if(!is.list(x)) return(parent)
    unlist(mapply(f, x, paste(parent,names(x),sep="$"), SIMPLIFY=FALSE))
}

f(l)

   a1.b1.c1    a1.b1.c2    a1.a2.b1 
"$a1$b1$c1" "$a1$b1$c2" "$a1$a2$b1"
wdots <- names(rapply(l,length))
wdols <- gsub('\\.','\\$',wdots)