鲜为人知的 rapply
函数应该是很多问题的完美解决方案(如 这个 ). 然而,它让用户编写的函数 f
而无法知道它在树中的位置。
有没有办法将嵌套列表中的元素名称传递给 f
在...中 rapply
呼叫? 不幸的是 rapply
电话 .Internal
迅速。
最近,我在努力处理任意深度的嵌套列表。最终,我得出了在我的情况下多少可以接受的决定。这不是你问题的直接答案(没有 rapply
的用法),但似乎也能解决同类问题。希望能对你有所帮助。
而不是试图在 rapply
我生成了名字的向量,并查询它的元素。
# Sample list with depth of 3
mylist <- list(a=-1, b=list(A=1,B=2), c=list(C=3,D=4, E=list(F=5,G=6)))
在我的例子中,生成名称向量是一个棘手的问题。具体来说,列表元素的名称应该是安全的,即没有了 .
符号。
list.names <- strsplit(names(unlist(mylist)), split=".", fixed=TRUE)
node.names <- sapply(list.names, function(x) paste(x, collapse="$"))
node.names <- paste("mylist", node.names, sep="$")
node.names
[1] "mylist$a" "mylist$b$A" "mylist$b$B" "mylist$c$C" "mylist$c$D" "mylist$c$E$F"
[7] "mylist$c$E$G"
下一步是通过字符串名访问列表元素。我发现没有比使用临时文件更好的方法了。
f <- function(x){
fname <- tempfile()
cat(x, file=fname)
source(fname)$value
}
这里是 f
只是返回 x
,其中 x
是一个包含列表元素全名的字符串。
最后,我们可以在 伪递归 的方式。
sapply(node.names, f)
谈到这个问题 找出嵌套列表中元素的索引?,可以写。
rappply <- function(x, f) {
setNames(lapply(seq_along(x), function(i) {
if (!is.list(x[[i]])) f(x[[i]], .name = names(x)[i])
else rappply(x[[i]], f)
}), names(x))
}
然后:
> mylist <- list(a = 1, b = list(A = 1, B = 2), c = list(C = 1, D = 3))
>
> rappply(mylist, function(x, ..., .name) {
+ switch(.name, "a" = 1, "C" = 5, x)
+ })
$a
[1] 1
$b
$b$A
[1] 1
$b$B
[1] 2
$c
$c$C
[1] 5
$c$D
[1] 3
2020年6月更新签名: rrapply
-职能 rrapply
-包(基础版的扩展版) rapply
),可以通过定义参数 .xname
在 f
功能。内 f
జజజజజజజజజజజజజజజజజజజజజజజజజజజజజజజజజజజజజజజ .xname
变量将评估为嵌套列表中元素的名称。
library(rrapply)
L <- list(a = 1, b = list(A = 1, B = 2), c = list(C = 1, D = 3))
rrapply(L, f = function(x, .xname) paste(.xname, x, sep = " = "))
#> $a
#> [1] "a = 1"
#>
#> $b
#> $b$A
#> [1] "A = 1"
#>
#> $b$B
#> [1] "B = 2"
#>
#>
#> $c
#> $c$C
#> [1] "C = 1"
#>
#> $c$D
#> [1] "D = 3"