отбросить элементы из списка рекурсивно - PullRequest
1 голос
/ 04 июля 2019

У меня есть вложенный список с несколькими NA, и я хочу удалить NA из списка.

purrr::discard не работает рекурсивно:

l <- list(a = NA, b = T, c = c(F, F))
purrr::discard(l, is.na)

Выдает эту ошибку:

Ошибка: функции предикатов должны возвращать одно ИСТИНА или ЛОЖЬ, а не логический вектор длины 2

В этом случае я хотел бы получить следующий список:

l2 <- list(b = T, c = c(F, F))

(мурлыканье: 0.3.2)

Ответы [ 2 ]

3 голосов
/ 04 июля 2019

is.na(c(T,T,T)) возвращает c(F,F,F). Чтобы использовать discard, функция должна возвращать одно значение для каждого элемента списка, как предполагает ошибка.

Это должно работать.

purrr::discard(l,function(x) all(is.na(x)))

Это будет работать, только если все элементы в индексе списка равны NA.

Чтобы удалить все NA элементов, это должно сработать

library(tidyverse)
l <- list(a = NA, b = c(T,NA), c = c(F, F)) # Define a list
lapply(l,function(x) x[!is.na(x)])%>% # Remove all nested NA's
   purrr::discard(.,function(x) length(x) == 0) # Remove all empty elements
1 голос
/ 04 июля 2019

РЕДАКТИРОВАТЬ (другой вариант)

 purrr::discard(l,function(x) isTRUE(anyNA(x)))
$b
[1] TRUE

$c
[1] FALSE FALSE

Вы можете идентифицировать все NA элементов и zap их:

 purrr::list_modify(l,a=purrr::zap())
$b
[1] TRUE

$c
[1] FALSE FALSE

РЕДАКТИРОВАТЬ2

Если вы хотите удалить все вложенные NA с, вы можете написать помощника zap_if():

 zap_if <- function(x){
       unlist(lapply(x, function(z) z[!is.na(z)]))
    }
    purrr::map(l,zap_if)

Результат:

    $a
    [1] 1

    $b
    [1] TRUE

    $c
    [1] FALSE FALSE

Данные для zap_if детали:

l <- list(a = c(NA,1), b = T, c = c(F, F))
...