将嵌套列表展开成一个一维列表

6

我正在寻找一种高效的解决方案,可以将嵌套列表(任意深度)递归地压平为非嵌套、深度为1的列表。由于列表元素不是同质的,因此它们不应该被解开成向量(这会强制将所有值转换为单一类型)。目前最好的解决方案是:

flatlist <- function(mylist){
    lapply(rapply(mylist, enquote, how="unlist"), eval)
}

这个几乎符合我的要求:
> flatlist(list(foo=TRUE, bar=456, pets=list(cat="meeuw", dog="woof")))
$foo
[1] TRUE

$bar
[1] 456

$pets.cat
[1] "meeuw"

$pets.dog
[1] "woof"

然而,问题在于 rapply 会删除 NULL 值,这是不希望发生的:

> flatlist(list(foo=123, bar=NULL))
$foo
[1] 123

我希望输出中包含NULL元素,可以表示为NULLNA。同时使用enquoteeval的双重循环会导致速度变慢。这个函数在我的代码中广泛使用。有没有一种方法可以一次性完成所有操作?


你几乎可以肯定地适应@Ferdinand.kraft在这里提供的类似问题的优秀答案中的代码。实际上,看看那里的评论,似乎你已经看过那个答案了! - Josh O'Brien
那个解决方案真的很低效,可能是因为 result <- c(result, .....。我希望有更本地化的解决方案。 - Jeroen Ooms
好的,知道了。谢谢澄清。 - Josh O'Brien
1
我建议查看这个线程 - Ramnath
1个回答

7

请将rapply部分替换为您自己的递归,以便NULL不会得到任何特殊处理:

renquote <- function(l) if (is.list(l)) lapply(l, renquote) else enquote(l)

lapply(unlist(renquote(ml)), eval)

我猜这是唯一正确的解决方案。虽然不如本地的rapply快,但它能够胜任。谢谢! - Jeroen Ooms
请注意,is.list()函数也会返回数据框的TRUE值。或者使用以下代码:if( class(l) == 'list') {...}。 - Kristoffer Vitting-Seerup

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接