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"
fwdots为真。然而,当我在更大更复杂的列表上尝试时,我得到了以下错误——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)