9

The little-used rapply function should be a perfect solution to many problems (such as this one ). However, it leaves the user-written function f with no ability to know where it is in the tree.

Is there any way to pass the name of the element in the nested list to f in an rapply call? Unfortunately, rapply calls .Internal pretty quickly.

4

3 回答 3

1

我最近与任意深度的嵌套列表作斗争。最终,在我的情况下,我做出了或多或少可以接受的决定。这不是您问题的直接答案(没有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)
于 2013-02-02T09:34:13.830 回答
1

参考问题在嵌套列表中查找元素的索引?, 你可以写:

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
于 2013-02-02T11:06:03.670 回答
0

2020 年 6 月更新rrapply-package rrapply( base 的扩展版本)中的 -function 允许通过在函数中rapply定义参数来做到这一点。在内部,变量将评估为嵌套列表中元素的名称:.xnameff.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"
于 2020-06-13T08:00:20.243 回答