r语言 - 平嵌套列表并保留每个底层元素的所有父键



我需要任意地将平放将列表嵌套到数据框架中,并在一列中保留键/索引的路径,同时将底层的每个元素提取到单独的行。

考虑以下列表:

lst <- list(
animals = list(
lamas = c("brown", "white"),
primates = list(
humans = c("asia", "europe"),
apes = c("good", "fast", "angry")
)
),
objects = c("expensive", "cheap"),
plants = NULL
)

flatten_list(lst, delimiter="_")的结果应该是这样的:

data.frame(
path = c("animals_lamas", "animals_lamas", "animals_primates_humans", "animals_primates_humans", "animals_primates_apes", "animals_primates_apes", "animals_primates_apes", "objects", "objects", "plants"),
value = c("brown", "white", "asia", "europe", "good", "fast", "angry", "expensive", "cheap", NA)
)

我很惊讶我不能用tidyr或data.tables实现这一点。我需要递归函数吗,还是有现成的解决方案?欣赏!

编辑:akrun提供的解决方案对原始数据起作用。我意识到有一个问题,当一个元素是NULL在底层,因此重新措辞的问题。

EDIT2我目前的解决方法是在应用akrun解决方案之前递归地将NULL替换为NA,使用这里提供的函数[再次由akrun;)]。

基于rrapplyNULL解决方案:

library(tidyverse)
library(rrapply)
rrapply(lst, f = (x) if (is.null(x)) NA else x, how = "melt") %>% 
unnest(value) %>% unite(path, L1:L3, na.rm = T)
#> # A tibble: 10 × 2
#>    path                    value    
#>    <chr>                   <chr>    
#>  1 animals_lamas           brown    
#>  2 animals_lamas           white    
#>  3 animals_primates_humans asia     
#>  4 animals_primates_humans europe   
#>  5 animals_primates_apes   good     
#>  6 animals_primates_apes   fast     
#>  7 animals_primates_apes   angry    
#>  8 objects                 expensive
#>  9 objects                 cheap    
#> 10 plants                  <NA>

这可以通过melt进入data.frame然后unite键列来完成

library(reshape2)
library(dplyr)
library(tidyr)
out2 <- melt(lst) %>% 
unite(path, L1:L3, sep = "_", na.rm = TRUE) %>% 
select(path, value)

-检查OP的输出

> all.equal(out, out2)
[1] TRUE

我们也可以对base R

中的unliststack这样做
stack(unlist(lapply(lst, (x) if(is.null(x)) NA_character_ else x)))[2:1]

最新更新