将嵌套列表中的名称分配给它的子组件

Assigning the name in a nested list to it's subcomponents

我有一个嵌套列表 current_output,我想取消列出并获得 expected 输出。我想将 current_output 中的列表名称分配给它的子组件。例如,我想将名称 A 分配给 current_output 中的三个子组件,并且类似地为 BC 分配名称以匹配 `expected.

A1 <- c(1:3)
A2 <- c(4:6)
A3 <- c(7:9)
B1 <- c(1:2)
B2 <- c(3:4)
B3 <- 1
C1 <- c(1:3)
C2 <- 1
C3 <- 1

l1 <- list(list(A1), list(A2), list(A3))
l2 <- list(list(B1),list(B2), list(1))
l3 <- list(list(C1), list(1), list(1))

current_output <- list(l1, l2, l3)
names(current_output) <- c("A", "B", "C")


expected <- list(A1, A2, A3, B1, B2, B3, C1, C2, C3)
names(expected) <- c(rep("A", 3), rep("B", 3), rep("C", 3))

最好使用唯一键,即列表元素的名称 - 遍历嵌套列表,flatten,然后再次连接 invoke,并通过删除后缀数字更改名称来自名字

library(purrr)
library(dplyr)
library(stringr)
out <- current_output %>% 
   map(flatten) %>%   
   invoke(c, .) %>%  
   setNames(str_remove(names(.), "\d+"))

-测试

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

或者另一种选择是 rrapply

rrapply::rrapply(current_output, how = 'flatten') %>% 
    setNames(rep(names(current_output), lengths(current_output)))

或使用base Runlist列表元素,将每个元素转换为as.list列表元素,然后用sub删除名称中的数字并赋值返回名称

out <- as.list(unlist(current_output))
names(out) <- sub("\d+$", "", names(out))

另一种使用多个 unlist() 步骤的基础 R 方法。

setNames(
  unlist(current_output, recursive = F) %>% unlist(recursive = F), 
  rep(names(current_output), each = 3)
  )

输出

$A
[1] 1 2 3

$A
[1] 4 5 6

$A
[1] 7 8 9

$B
[1] 1 2

$B
[1] 3 4

$B
[1] 1

$C
[1] 1 2 3

$C
[1] 1

$C
[1] 1

另一个可能的解决方案:

library(tidyverse)

current_output %>% imap(set_names) %>% flatten %>% flatten

#> $A
#> [1] 1 2 3
#> 
#> $A
#> [1] 4 5 6
#> 
#> $A
#> [1] 7 8 9
#> 
#> $B
#> [1] 1 2
#> 
#> $B
#> [1] 3 4
#> 
#> $B
#> [1] 1
#> 
#> $C
#> [1] 1 2 3
#> 
#> $C
#> [1] 1
#> 
#> $C
#> [1] 1

或者简单地在 base R 中使用嵌套的 for 循环:

expected <- list()

for (i in seq_along(current_output))
  for (j in seq_along(current_output[[i]]))
  { 
    expected <- c(expected, current_output[[i]][[j]])
    names(expected)[length(expected)] <- names(current_output)[i]
  }

expected