【问题标题】:Count non-NA values by group [duplicate]按组计算非NA值[重复]
【发布时间】:2017-11-01 14:36:38
【问题描述】:

这是我的例子

mydf<-data.frame('col_1' = c('A','A','B','B'), 'col_2' = c(100,NA, 90,30))

我想按col_1 分组并计算col_2 中的非NA 元素

我想用dplyr 来做。这是我尝试过的:

mydf %>% group_by(col_1) %>% summarise_each(funs(!is.na(col_2)))
mydf %>% group_by(col_1) %>% mutate(non_na_count = length(col_2, na.rm=TRUE))
mydf %>% group_by(col_1) %>% mutate(non_na_count = count(col_2, na.rm=TRUE))

没有任何效果。有什么建议吗?

【问题讨论】:

    标签: r dplyr group-by count na


    【解决方案1】:

    你可以用这个

    mydf %>% group_by(col_1) %>% summarise(non_na_count = sum(!is.na(col_2)))
    
    # A tibble: 2 x 2
       col_1 non_na_count
      <fctr>        <int>
    1      A            1
    2      B            2
    

    【讨论】:

    • 要获取所有列的摘要,请使用summarise_all(funs(sum(!is.na(.))))
    • 如果将另一个汇总函数应用于 col_2,请注意您请求计算的顺序。 my_df %&gt;% group_by(col_1) %&gt;% summarise(col_1 = mean(col_1, na.rm = T), non_na_count = sum(!is.na(col_2))) 产生的结果与 my_df %&gt;% group_by(col_1) %&gt;% summarise(non_na_count = sum(!is.na(col_2)), col_1 = mean(col_1, na.rm = T)) 不同
    • @zack 我得到了两个订单相同的结果(我使用的是来自 github 的 dplyr 版本 0.8.99.9002)。
    • @RichardTelford 我在输入评论时犯了一个错误。在对summarise 的调用中,不要使用col_1 = mean(col_1, na.rm = T),而是尝试col_2 = mean(col_2, na.rm = T)。使用 dplyr 0.8.3 版,我得到了不同的结果。
    【解决方案2】:

    我们可以 filter 'col_2' 中的 NA 元素,然后对 'col_1' 执行 count

    mydf %>%
         filter(!is.na(col_2))  %>%
          count(col_1)
    # A tibble: 2 x 2
    #   col_1     n
    #  <fctr> <int>
    #1      A     1
    #2      B     2
    

    或使用data.table

    library(data.table)
    setDT(mydf)[, .(non_na_count = sum(!is.na(col_2))), col_1]
    

    或者用aggregate 来自base R

    aggregate(cbind(col_2 = !is.na(col_2))~col_1, mydf, sum)
    #  col_1 col_2
    #1     A     1
    #2     B     2
    

    或使用table

    table(mydf$col_1[!is.na(mydf$col_2)])
    

    【讨论】:

    • 为什么最后一个答案不是使用 table: table(mydf$col_1[ , !is.na(mydf$col_2)])?
    【解决方案3】:
    library(knitr)
    library(dplyr)
    
    mydf <- data.frame("col_1" = c("A", "A", "B", "B"), 
                       "col_2" = c(100, NA, 90, 30))
    
    mydf %>%
      group_by(col_1) %>%
      select_if(function(x) any(is.na(x))) %>%
      summarise_all(funs(sum(is.na(.)))) -> NA_mydf
    
    kable(NA_mydf)
    

    【讨论】:

      猜你喜欢
      • 2017-06-10
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-01-10
      • 1970-01-01
      • 2019-11-19
      • 1970-01-01
      相关资源
      最近更新 更多