5

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

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(l)

"$a1$b1$c1" "$a1$b1$c2" "$a1$a2$b1"

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

4

3 回答 3

6
wdots <- names(rapply(l,length))

这适用于给出的示例,但由于@flodel 的评论,我才发现它。如果你想要美元符号,有

wdols <- gsub('\\.','\\$',wdots)

但是,正如@thelatemail 指出的那样,如果层次结构中的任何名称包含“。”,这不会给你想要的东西。

于 2013-09-18T02:49:42.667 回答
3

这个递归函数似乎有效:

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"
于 2013-09-18T02:02:45.770 回答
3

其他选项:

分层视图:

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"
于 2013-09-18T02:25:02.093 回答