【问题标题】:Remove completely NA rows in r完全删除 r 中的 NA 行
【发布时间】:2021-08-19 21:04:46
【问题描述】:

一直在寻找这个,尽管它应该很简单,但我只找到了完整案例的解决方案或选择列的子集然后省略它们的 NA。就我而言,我有一个这样的数据框:

   vp01ob__0 vp01ob__1 vp01ob__2 vp01ob__3 vp01ob__4 vp01ob__5 vp01ob__6 vp01ob__7 vp01ob__8
   <chr>     <chr>     <chr>     <chr>     <chr>     <chr>     <chr>     <chr>     <chr>    
 1 NA        NA        NA        NA        NA        NA        NA        NA        NA       
 2 NA        NA        NA        NA        NA        NA        NA        NA        NA       
 3 a         NA        NA        NA        NA        NA        NA        NA        NA       
 4 NA        NA        NA        NA        NA        NA        NA        NA        NA 
 5 NA        NA        NA        NA        NA        NA        NA        NA        NA       
 6 NA        NA        NA        NA        NA        NA        NA        NA        NA       
 7 NA        b         NA        NA        NA        NA        NA        NA        NA  

这是一个非常稀疏的数据框,因此我只想保留包含一些信息的行,如下所示:

   vp01ob__0 vp01ob__1 vp01ob__2 vp01ob__3 vp01ob__4 vp01ob__5 vp01ob__6 vp01ob__7 vp01ob__8
   <chr>     <chr>     <chr>     <chr>     <chr>     <chr>     <chr>     <chr>     <chr>          
 3 a         NA        NA        NA        NA        NA        NA        NA        NA          
 7 NA        b         NA        NA        NA        NA        NA        NA        NA  

完整的案例会丢失所有内容,我找不到使用 filter_allna.omit() 的方法。任何帮助将不胜感激。

谢谢!

【问题讨论】:

    标签: r dataframe na


    【解决方案1】:

    我们可以使用if_all

    library(dplyr)
    df1 %>%
         filter(!if_all(everything(), is.na))
    

    -输出

    #vp01ob__0 vp01ob__1 vp01ob__2 vp01ob__3 vp01ob__4 vp01ob__5 vp01ob__6 vp01ob__7 vp01ob__8
    #3         a      <NA>        NA        NA        NA        NA        NA        NA        NA
    #7      <NA>         b        NA        NA        NA        NA        NA        NA        NA
    

    if_any

    df1 %>%
        filter(if_any(everything(), ~ !is.na(.)))
    

    -输出

    #vp01ob__0 vp01ob__1 vp01ob__2 vp01ob__3 vp01ob__4 vp01ob__5 vp01ob__6 vp01ob__7 vp01ob__8
    #3         a      <NA>        NA        NA        NA        NA        NA        NA        NA
    #7      <NA>         b        NA        NA        NA        NA        NA        NA        NA
    

    数据

    df1 <- structure(list(vp01ob__0 = c(NA, NA, "a", NA, NA, NA, NA), vp01ob__1 = c(NA, 
    NA, NA, NA, NA, NA, "b"), vp01ob__2 = c(NA, NA, NA, NA, NA, NA, 
    NA), vp01ob__3 = c(NA, NA, NA, NA, NA, NA, NA), vp01ob__4 = c(NA, 
    NA, NA, NA, NA, NA, NA), vp01ob__5 = c(NA, NA, NA, NA, NA, NA, 
    NA), vp01ob__6 = c(NA, NA, NA, NA, NA, NA, NA), vp01ob__7 = c(NA, 
    NA, NA, NA, NA, NA, NA), vp01ob__8 = c(NA, NA, NA, NA, NA, NA, 
    NA)), class = "data.frame", row.names = c("1", "2", "3", "4", 
    "5", "6", "7"))
    

    【讨论】:

    • 非常感谢您的回答!选择这个是因为它对我来说似乎更具可读性
    【解决方案2】:

    使用rowSums()

    require(dplyr)
    df %>% filter(rowSums(!is.na(df)) > 0)
    

    基地R:

    df[rowSums(!is.na(df)) > 0,]
    

    【讨论】:

      【解决方案3】:

      你也可以这样做,但它不是很优雅,只是实用:

      library(dplyr)
      
      DF %>%
        filter(DF %>% 
                 rowwise() %>% 
                 summarise(any(!is.na(c_across(everything())))))
      
        vp01ob__0 vp01ob__1 vp01ob__2 vp01ob__3 vp01ob__4 vp01ob__5 vp01ob__6 vp01ob__7 vp01ob__8
      3         a      <NA>        NA        NA        NA        NA        NA        NA        NA
      7      <NA>         b        NA        NA        NA        NA        NA        NA        NA
      

      您也可以使用这两种解决方案中的任何一种。特别感谢亲爱的@akrun 的建议:

      library(purrr)
      
      DF %>%
        filter(pmap_lgl(DF, ~ any(!is.na(c(...)))))
      

      或者这次我们进行逐行操作,直接使用filter

      DF %>%
        rowwise() %>%
        filter(any(!is.na(c_across(everything()))))
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2021-11-30
        • 2022-01-12
        • 1970-01-01
        • 2017-06-12
        • 2013-11-25
        • 2012-10-12
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多