递归地将函数应用于列表元素

时间:2015-05-27 15:35:27

标签: r

使用rmatio包,我得到类似于以下内容的嵌套列表:

nestedlist <- list(
    a = list( a = list(1:10), b = list(35)),
    b = list(11:25)
)

理想情况下,我希望它看起来像这样(所有带有单个未命名元素的列表都被元素替换):

nestedlist <- list(a = list(a=1:10, b=35), b = 11:25)

我尝试了以下尝试过:

unlist(nestedlist) # returns one vector with all elements

selective_unlist <- function(e)
    if(is.list(e) &&is.null(names(e))) unlist(e) else e

# only calls the function with each leaf, so nothing gets replaced
rapply(nestedlist, how='replace', selective_unlist)

# works, but only for 2 levels
lapply(nestedlist, selective_unlist)

# works, but using explicit recursion is slow for large datasets
recursive_selective_unlist <- function(e)
    if(is.list(e)) {
        if(is.null(names(e))) unlist(e)
        else lapply(e, recursive_selective_unlist)
    }   else e

是否有更好/更快的方法来简化这些嵌套列表,或者我最好的选择是递归函数?

2 个答案:

答案 0 :(得分:3)

按照@ Pafnucy的想法,我会使用

ff <- function(x) if (is.list(x[[1]])) lapply(x,ff) else unlist(x)

哪个

ff(nestedlist)
# $a
# $a$a
#  [1]  1  2  3  4  5  6  7  8  9 10
# 
# $a$b
# [1] 35
# 
# 
# $b
#  [1] 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25
# check result:
identical(list(a = list(a=1:10, b=35), b = 11:25),ff(nestedlist))
# [1] TRUE

答案 1 :(得分:2)

处理任意嵌套深度:

f <- function(x) {
    if (is.list(x)) unname(c(sapply(unlist(x), f))) else x
}

# sample data
nl2 <- list(a = list(a = list(1:5), b = list(1:5)))
nl3 <- list(p = nl2, q = c(9,9,9))

中级输出:

> f(nl2)
 [1] 1 2 3 4 5 1 2 3 4 5
> f(nl3)
 [1] 1 2 3 4 5 1 2 3 4 5 9 9 9

添加最后一步,因为f太深了,我们想要深度为1的列表

unstackList <- function(x) lapply(x, f)
unstackList(nl3)

<强>输出:

$p
 [1] 1 2 3 4 5 1 2 3 4 5

$q
[1] 9 9 9