递归地丢弃列表中的元素

时间:2019-07-04 18:27:44

标签: r na purrr

我有一个嵌套列表,其中包含一些NA,我想从列表中丢弃这些NA。

purrr::discard不能递归工作:

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

引发此错误:

  

错误:谓词函数必须返回单个TRUE或FALSE,而不是长度为2的逻辑向量

在这种情况下,我想给出以下列表:

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

(purrr版本:0.3.2)

2 个答案:

答案 0 :(得分:3)

is.na(c(T,T,T))返回c(F,F,F)。要使用丢弃,该函数需要为每个列表元素返回一个值,错误提示。

这应该有效。

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 :(得分:1)

编辑(另一个选项)

 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))