R - 如何通过名称从列表的子列表中 select 元素

R - how to select elements from sublists of a list by their name

我有一个列表列表,如下所示:

list(list("A[1]" = data.frame(W = 1:5),
          "A[2]" = data.frame(X = 6:10),
          B = data.frame(Y = 11:15),
          C = data.frame(Z = 16:20)),
     list("A[1]" = data.frame(W = 21:25),
          "A[2]" = data.frame(X = 26:30),
          B = data.frame(Y = 31:35),
          C = data.frame(Z = 36:40)),
     list("A[1]" = data.frame(W = 41:45),
          "A[2]" = data.frame(X = 46:50),
          B = data.frame(Y = 51:55),
          C = data.frame(Z = 56:60))) -> dflist

我需要我的输出也是一个长度为 3 的列表列表,以便每个子列表保留名称以 A[ 开头的元素,同时删除其他元素。

根据之前的一些问题,我尝试使用这个:

dflist %>% 
    map(keep, names(.) %in% "A[")

但是会出现以下错误:

Error in probe(.x, .p, ...) : length(.p) == length(.x) is not TRUE

尝试 select 单个元素,例如 A[1] 像这样:

dflist %>% 
    map(keep, names(.) %in% "A[1]")

也不行。我怎样才能达到预期的输出?

我想你想要:

purrr::map(dflist, ~.[stringr::str_starts(names(.), "A\[")])

它的作用是:

  • 对于每个子列表 (purrr::map)
    • Select 该子列表的所有元素(.[],其中 . 是子列表)
    • 他们的名字以 A[ (stringr::str_starts(names(.), "A\["))
    • 开头

您的顶层 map 正确,因为您要修改子列表。然而,map(keep, names(.) %in% "A[") 有一些问题:

  • names(.) %in% "A[" 应该是函数或公式(以 ~
  • 开头
  • purrr::keep 将过滤函数应用于子列表的每个 元素 ,即直接应用于数据帧。它永远不会“看到”每个数据框的名称。其实我不认为你可以使用 keep 来解决这个问题

无论如何这会产生:

[[1]]
[[1]]$`A[1]`
  W
1 1
2 2
3 3
4 4
5 5

[[1]]$`A[2]`
   X
1  6
2  7
3  8
4  9
5 10


[[2]]
[[2]]$`A[1]`
   W
1 21
2 22
3 23
4 24
5 25

[[2]]$`A[2]`
   X
1 26
2 27
3 28
4 29
5 30


[[3]]
[[3]]$`A[1]`
   W
1 41
2 42
3 43
4 44
5 45

[[3]]$`A[2]`
   X
1 46
2 47
3 48
4 49
5 50

如果我们要使用keep,请使用

library(dplyr)
library(purrr)
library(stringr)
map(dflist, ~ keep(.x, str_detect(names(.x), fixed("A["))))

这里有一个 base R 解决方案:

lapply(dflist, function(x) x[grep("A\[",names(x))] )

[[1]]
[[1]]$`A[1]`
  W
1 1
2 2
3 3
4 4
5 5

[[1]]$`A[2]`
   X
1  6
2  7
3  8
4  9
5 10


[[2]]
[[2]]$`A[1]`
   W
1 21
2 22
3 23
4 24
5 25

[[2]]$`A[2]`
   X
1 26
2 27
3 28
4 29
5 30


[[3]]
[[3]]$`A[1]`
   W
1 41
2 42
3 43
4 44
5 45

[[3]]$`A[2]`
   X
1 46
2 47
3 48
4 49
5 50