как убрать элементы в списке списков вложенных списков? - PullRequest
0 голосов
/ 20 февраля 2019

Как мне перейти от

x <- list(p1 = list(type='A',score=list(c1=10,c2=8,c3=data.frame(a=1, b=3, c=5))),
       p2 = list(type='B',score=list(c1=9,c2=9,c3=data.frame(a=2, b=2))),
       p3 = list(type='B',score=list(c1=9,c2=7,c3=data.frame(a=2, b=2))))

к списку без элементов "c3", которые являются фреймами данных?

Желательно в tidyverse -дружественном способе или что-то, что я могуположить в середину конвейера.

Я уже пробовал list.remove, вложенный lapply, rapply, Filter, но не могу заставить их работать ... и я не хочуunlist моя структура вложенного списка.

(Edit: извините, у меня была опечатка в данных примера в моем исходном вопросе (см. ниже), но здорово, если ваше решение работает в обоих случаях!)

x <- list(p1 = list(type='A',score=list(c1=10,c2=8,c3=data.frame(a=1, b=3, c=5))),
       p2 = list(type='B',score=list(c1=9,c2=9,c3=data.frame(a=2, b=2)),
       p3 = list(type='B',score=list(c1=9,c2=7,c3=data.frame(a=2, b=2)))))

Ответы [ 2 ]

0 голосов
/ 20 февраля 2019

Вы можете написать свою собственную функцию, чтобы сделать это:

check = function(x,name){
  m = names(x)%in% name
  x = if(any(m)) x[!m] else x
  if(is.list(x)) sapply(x,check,name)
  else x
}

dput(check(x,'c3'))
list(p1 = list(type = "A", score = list(c1 = 10, c2 = 8)), p2 = list(
    type = "B", score = list(c1 = 9, c2 = 9), p3 = list(type = "B", 
        score = list(c1 = 9, c2 = 7))))

Это также вето в том, что оно может отбросить все, что вам нужно.например попробуйте check(x,c('c1','c3'))

0 голосов
/ 20 февраля 2019

Это правильный сценарий для использования modify_depth, который функционирует как ярлык для цепочек modify для доступа к глубоким вложенным спискам.modify имеет преимущество перед map в этой задаче, потому что оно сохранит тип ввода вместо того, чтобы приводить все к спискам, что может быть актуально, если у вас есть векторные элементы вашей структуры списка.

ИспользованиеПри заданном вами входном сигнале (с элементом p3 внутри, а не на том же уровне, что и p2), элементы кадра данных на втором и третьем уровнях discard редактируются, как показано ниже.Чтобы выполнить поиск по всем уровням вложенного списка, мы можем настроить цикл while для итерации по уровням, отбрасывая кадры данных по мере продвижения.Нам нужен .ragged = TRUE для устранения ошибок с глубиной списка.Эта версия выполняет поиск снизу вверх, но вы также можете изменить ее на поиск сверху вниз.

library(tidyverse)
x <- list(
  p1 = list(type = "A", score = list(c1 = 10, c2 = 8, c3 = data.frame(a = 1, b = 3, c = 5))),
  p2 = list(
    type = "B", score = list(c1 = 9, c2 = 9, c3 = data.frame(a = 2, b = 2)),
    p3 = list(type = "B", score = list(c1 = 9, c2 = 7, c3 = data.frame(a = 2, b = 2)))
  )
)

remove_dataframes <- function(input_list) {
  current_list <- input_list
  current_depth <- vec_depth(current_list)
  # current_depth <- max_depth
  while (current_depth > 1) {
    current_list <- modify_depth(
      .x = current_list,
      .depth = current_depth,
      .f = ~ discard(., is.data.frame),
      .ragged = TRUE
    )
  current_depth <- current_depth - 1
  }
  return(current_list)
}

x %>%
  remove_dataframes %>%
  glimpse
#> List of 2
#>  $ p1:List of 2
#>   ..$ type : chr "A"
#>   ..$ score:List of 2
#>   .. ..$ c1: num 10
#>   .. ..$ c2: num 8
#>  $ p2:List of 3
#>   ..$ type : chr "B"
#>   ..$ score:List of 2
#>   .. ..$ c1: num 9
#>   .. ..$ c2: num 9
#>   ..$ p3   :List of 2
#>   .. ..$ type : chr "B"
#>   .. ..$ score:List of 2

Создано в 2019-02-20 пакетом представлением (v0.2.1)

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...