如何过滤掉 tibble 列表列的 NULL 元素

jak*_*kes 9 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"))
Run Code Online (Sandbox Code Playgroud)

我只想留下var2非空的行。但简单!is.null()就是行不通。df %>% filter(!is.null(var2))返回整个df. 为什么会这样,我如何过滤掉所有列NULL中的var2行?

tmf*_*mnk 11

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

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

     id var1  var2            
  <int> <chr> <list>          
1     4 B     <tibble [4 × 2]>
Run Code Online (Sandbox Code Playgroud)

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

df %>%
 rowwise() %>%
 filter(!is.null(var2))
Run Code Online (Sandbox Code Playgroud)


Gra*_*vic 5

!is.null()不起作用,因为你var2是一个嵌套列表(列表的列表)。它包含一个 tibble 作为其第四个元素。Atibble是一个列表,因为它是 adata.frame并且is.null仅检查嵌套列表的第一层。

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

您可以尝试过滤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]>
> 
Run Code Online (Sandbox Code Playgroud)

  • 谢谢!我做了一些解释,问题是“is.null()”,与例如相比。`is.na()` 不是矢量化的(这实际上是对你的答案的解释,但我把它留在这里可能有助于理解你的意思)。 (2认同)

小智 5

drop_na()from 的函数tidyr也适用于NULL. 您只需要小心边缘情况,即您同时拥有NULL和值,但出于某种原因NA只想删除。NULL

删除包含缺失值的行

library(tidyr)

df %>% 
  drop_na(var2)

#        id var1  var2                
#     <int> <chr> <list>              
#   1     4 B     <tibble[,2] [4 x 2]>
Run Code Online (Sandbox Code Playgroud)