【问题标题】:Remove null list-columns删除空列表列
【发布时间】:2020-08-07 18:42:35
【问题描述】:

我有一个包含空列表列的数据框,类似于:

null_list <- list(NULL, NULL, NULL) %>% enframe()
null_list
#   name value 
#  <int> <list>
#1     1 <NULL>
#2     2 <NULL>
#3     3 <NULL>

我想删除所有仅包含 NULL 值的列,例如上面的“值”列,因为当我尝试 unnest_wider 这些列(作为循环的一部分)时,我收到错误“替换长度为零。 "

【问题讨论】:

    标签: r purrr


    【解决方案1】:

    我们可以使用select_ifNULL 不存在于 vector 中。因此,条件应该是检查列是否为list,如果all 元素为NULL (is.null),则将(!) 取反为select 所有其他列

    library(dplyr)
    library(purrr)
    null_list %>% 
        select_if(~ !(is.list(.) && all(map_lgl(., is.null))))
    # A tibble: 3 x 1
    #   name
    #  <int>
    #1     1
    #2     2
    #3     3
    

    注意:检查list 中的所有值是否为NULL,然后删除这些列


    如果嵌套很深,

    example %>%     
        select(where(~ !(is.list(.) && is.null(unlist(.)))))
    # A tibble: 3 x 3
    #      a     b c         
    #  <dbl> <dbl> <list>    
    #1     1     4 <NULL>    
    #2     2     5 <NULL>    
    #3     3     6 <list [3]>
    

    或者只选择包含任何非 NULL 元素的 list

    example %>%     
        select(where(~ is.list(.) && !is.null(unlist(.))))
    # A tibble: 3 x 1
    #   c         
    #  <list>    
    #1 <NULL>    
    #2 <NULL>    
    #3 <list [3]>
    

    数据

     example <- tibble(a = c(1, 2, 3), b = c(4, 5, 6),
       c = list(NULL, NULL, list(1,2,3)),
       d = list(NULL, NULL, list(x = NULL, y = NULL, z = NULL)))
    

    【讨论】:

    • 或@Onyambu,如果列表列具有包含所有 NULL 的更深的嵌套列表,该怎么办? example &lt;- tibble(a = c(1, 2, 3), b = c(4, 5, 6), c = list(NULL, NULL, list(x = NULL, y = NULL, z = NULL)))
    • 非常感谢。这可能与一个新问题接壤,但在这种情况下,我只想选择列表列,但那些在更深的层中没有所有空值的列。所以在这个更新的例子中,我只想选择 c 列:example &lt;- tibble(a = c(1, 2, 3), b = c(4, 5, 6), c = list(NULL, NULL, list(1,2,3)), d = list(NULL, NULL, list(x = NULL, y = NULL, z = NULL)))
    • 不,您目前所拥有的是完美的。你为我节省了几个小时,谢谢!
    【解决方案2】:

    在 Base R 中,您可以这样做:

    null_list[colSums(sapply(null_list,lengths))>0]
    # A tibble: 3 x 1
       name
      <int>
    1     1
    2     2
    3     3
    

    你也可以使用来自 tidyverse 的select_if

     library(tidyverse)
     null_list %>%
        select_if(map_lgl(.,~sum(lengths(.x))>0))
    # A tibble: 3 x 1
       name
      <int>
    1     1
    2     2
    3     3
    

    【讨论】:

      【解决方案3】:

      像这样?

      library(tibble)
      
      null_list <- list(NULL, NULL, NULL) %>% enframe()
      
      > null_list
      # A tibble: 3 x 2
         name value 
        <int> <list>
      1     1 <NULL>
      2     2 <NULL>
      3     3 <NULL>
      
      
      null_list <- rbind(null_list, c(3, "a"))
      
      > null_list
      # A tibble: 4 x 2
        name  value    
        <chr> <list>   
      1 1     <NULL>   
      2 2     <NULL>   
      3 3     <NULL>   
      4 3     <chr [1]>
      
      null_list <- null_list[!unlist(lapply(null_list$value, is.null)),]
      
      null_list
      
      > null_list
      # A tibble: 1 x 2
        name  value    
        <chr> <list>   
      1 3     <chr [1]>
      

      【讨论】:

        猜你喜欢
        • 2017-11-02
        • 2022-11-01
        • 2019-04-06
        • 2021-08-21
        • 2020-07-05
        • 2014-01-06
        • 2016-02-17
        • 2015-09-20
        • 1970-01-01
        相关资源
        最近更新 更多