如何过滤出Tibble列表列的NULL元素

时间:2019-08-03 07:24:24

标签: r dplyr

我有一个小标题,如下所示:

structure(list(id = 1:11, var1 = c("A", "C", "B", "B", "B", "A", 
"B", "C", "C", "C", "B"), var2 = list(NULL, NULL, NULL, structure(list(
    x = c(0, 1, 23, 3), y = c(0.75149005651474, 0.149892757181078, 
    0.695984086720273, 0.0247649133671075)), row.names = c(NA, 
-4L), class = c("tbl_df", "tbl", "data.frame")), NULL, NULL, 
    NULL, NULL, NULL, NULL, NULL)), row.names = c(NA, -11L), class = c("tbl_df", 
"tbl", "data.frame"))

我只想保留var2不为空的行。但是简单的!is.null()无效。 df %>% filter(!is.null(var2))返回整个df。为什么会这样?如何在NULL列中使用var2过滤掉所有这些行?

3 个答案:

答案 0 :(得分:4)

也涉及purrr的一种可能性是:

df %>%
 filter(!map_lgl(var2, is.null))

     id var1  var2            
  <int> <chr> <list>          
1     4 B     <tibble [4 × 2]>

反映is.null()的属性,您还可以执行以下操作:

df %>%
 rowwise() %>%
 filter(!is.null(var2))

答案 1 :(得分:2)

!is.null()不起作用,因为您的var2是一个嵌套列表(列表列表)。它包含一个小标题作为其第四元素。 tibble是列表,因为它是data.frame,而is.null仅检查嵌套列表的第一级。

#show that the tibble is a list:
> is.list(df$var2[[4]])
[1] TRUE

您可以尝试过滤lengths(df$var2) > 0

> lengths(df$var2)
 [1] 0 0 0 2 0 0 0 0 0 0 0  
# each of the columns of the tibble in var2[[4]] is one element 
# of the list contained in var2[[4]]. Thus var2[[4]] is a list of length two

> df %>% filter(lengths(var2) > 0)
# A tibble: 1 x 3
     id var1  var2            
  <int> <chr> <list>          
1     4 B     <tibble [4 x 2]>
> 

答案 2 :(得分:0)

drop_na() 中的函数 tidyr 也适用于 NULL。您只需要注意边缘情况,即您同时拥有 NULLNA 值,但出于某种原因只想删除 NULL

<块引用>

删除包含缺失值的行

library(tidyr)

df %>% 
  drop_na(var2)

#        id var1  var2                
#     <int> <chr> <list>              
#   1     4 B     <tibble[,2] [4 x 2]>