【问题标题】:Removing rows with multiple NAs with group_by in dplyr在 dplyr 中使用 group_by 删除具有多个 NA 的行
【发布时间】:2018-10-12 20:02:32
【问题描述】:

我有这个玩具数据框:

df <- data.frame(id=c(1,1,2,3,4,4),p_id=c(1001,1001,1002,1003,1004,1004),x=c(1,NA,1,2,NA,1),y=c(NA,5,4,NA,6,NA),z=c(NA,NA,2,3,NA,4))

id p_id  x  y   z
1  1001  1  NA  NA
1  1001 NA  5   NA
2  1002  1  4    2
3  1003  2  NA   3
4  1004 NA  6   NA
4  1004  1  NA   4

我想获得最终输出,其中删除了唯一的“p_id”行和来自 x、y 和 z 的不需要的 NA 值(理想情况下,应该适用于任意数量的列)。示例输出:

p_id    x    y     z
1001    1    5     NaN
1002    1    4     2
1003    2  NaN     3
1004    1    6     4

我正在做这个快速解决方法(不确定最佳方法):

df %>% select(-id) %>% group_by(p_id) %>% summarise_all(funs(mean),na.rm=T) %>% ungroup()

但是,当应用于大型数据帧 (2500 x 650) 时,此解决方法非常缓慢,并且会为正常单元格创建不需要的 NA。同样对于上下文,此 df 中具有 NA 的重复 p_id 行来自扩展函数。

【问题讨论】:

    标签: r dplyr


    【解决方案1】:

    在按“id”列分组后,如果每组该列中的所有元素都是NA,则通过使用if/else 创建一个条件来执行summarise_all 以返回NaN,否则采用非NA元素(在示例中,只有一个非 NA 元素,因此我们对其进行子集化)

    df %>%
      group_by(id, p_id) %>%
      summarise_all(funs(if(all(is.na(.))) NaN else .[!is.na(.)]))
    # A tibble: 4 x 5
    # Groups:   id [?]
    #     id  p_id     x     y     z
    #  <dbl> <dbl> <dbl> <dbl> <dbl>
    #1     1  1001     1     5   NaN
    #2     2  1002     1     4     2
    #3     3  1003     2   NaN     3
    #4     4  1004     1     6     4
    

    如果每个组 id 组合有多个非 NA 值,那么我们可以使用 mean(如 OP 的帖子所示)

    df %>% 
      group_by(id, p_id) %>% 
      summarise_all(funs(if(all(is.na(.))) NaN else mean(., na.rm = TRUE)))
    

    【讨论】:

      【解决方案2】:

      您可能可以使用tidyr::fill() 后跟summarize 逃脱

       df %>% 
         group_by(id) %>%  
         fill(x,y,z, .direction = "up") %>% 
         summarise_all(first)
      #> # A tibble: 4 x 5
      #>      id  p_id     x     y     z
      #>   <dbl> <dbl> <dbl> <dbl> <dbl>
      #> 1     1  1001     1     5    NA
      #> 2     2  1002     1     4     2
      #> 3     3  1003     2    NA     3
      #> 4     4  1004     1     6     4
      

      【讨论】:

      • TIL tidyr::fill。在性能方面,它比上面 akrun 的解决方案慢。
      猜你喜欢
      • 1970-01-01
      • 2019-03-19
      • 1970-01-01
      • 1970-01-01
      • 2017-05-27
      • 2018-07-06
      • 2020-10-04
      • 2019-06-08
      • 2022-06-13
      相关资源
      最近更新 更多