У меня есть 3 списка с именами T1, T2 и T3 (показано ниже). Из этих списков я хочу извлечь подмножество Q.

L1<-list("A"=matrix(c(1:4),2),"B"=matrix(c("a","b","c","d"),2))
L2<-list("P"=matrix(c(5:8),2),"Q"=list(list("u","v","w","x"),2))

T1 <- list(L1, L2)
T2 <- list(NULL, L1, L2)
T3 <- list(L1, NULL, L2)

Мне нужен только список Q, который встроен в родительские списки (T1, T2 и T3).

Вот решения, которые я пробовал, но все они возвращают значение NULL для братьев и сестер Q -

lapply(T3, `[[`, "Q")
purrr::map(T3, `[`, "Q")
purrr::map_depth(T3, 2, "Q")

Предложите решение для подмножества Q из родителей T1, T2 и T3. Как вы можете видеть, положение Q у каждого родителя разное, я ищу решение для подмножества родительского списка по имени дочернего элемента Q вместо жесткого кодирования положения Q.

1
Saurabh 4 Фев 2022 в 10:21
Итак, какова именно форма желаемого результата? Что произойдет, если два списка содержат Q?
 – 
MrFlick
4 Фев 2022 в 10:25
Никогда не случится так, что и L1, и L2 будут содержать Q. Желаемый результат — список Q.
 – 
Saurabh
4 Фев 2022 в 10:27
Возможный дубликат более общего случая: stackoverflow.com/questions/58400176/…
 – 
MrFlick
4 Фев 2022 в 10:33
Поскольку мой дочерний объект представляет собой список, ваше решение кажется более подходящим. Спасибо, мистер Флик!
 – 
Saurabh
4 Фев 2022 в 10:40

3 ответа

Лучший ответ

Нет базовой функции, которая делает это. Обычно вы хотите сохранить длину ввода, когда вы сопоставляете/применяете список. Вы можете написать вспомогательную функцию, которая просто возвращает первое совпадение

first_match <- function(x, name) {
  for (list in x) {
    if (name %in% names(list)) {
      return(list[[name]])
    }
  }
  return(NULL)
}

first_match(T1, "Q")
first_match(T2, "Q")
first_match(T3, "Q")
1
MrFlick 4 Фев 2022 в 10:30

Используя внешний пакет, это также можно сделать с помощью rrapply() в пакете rrapply:

library(rrapply)

Q1 <- rrapply(T1, classes = "list", condition = \(x, .xname) .xname == "Q", how = "flatten")
Q2 <- rrapply(T2, classes = "list", condition = \(x, .xname) .xname == "Q", how = "flatten")
Q3 <- rrapply(T3, classes = "list", condition = \(x, .xname) .xname == "Q", how = "flatten")

str(Q1)
#> List of 1
#>  $ Q:List of 2
#>   ..$ :List of 4
#>   .. ..$ : chr "u"
#>   .. ..$ : chr "v"
#>   .. ..$ : chr "w"
#>   .. ..$ : chr "x"
#>   ..$ : num 2
0
Joris C. 4 Фев 2022 в 11:18

Вы можете unlist родительский список с помощью recursive = FALSE и получить единый объединенный список. Затем вы можете получить доступ к Q как:

unlist(T1, recursive = FALSE)$Q
unlist(T2, recursive = FALSE)$Q
unlist(T3, recursive = FALSE)$Q
0
slowowl 4 Фев 2022 в 11:26