【问题标题】:R - dplyr - Group by column and calculate the sum keeping NA's if only NA's present for a given groupR - dplyr - 如果给定组仅存在 NA,则按列分组并计算保持 NA 的总和
【发布时间】:2021-03-04 14:05:21
【问题描述】:

我有一个数据框,第一列中有重复的 id,后续列中有不同的值。我想截断此数据以使每个唯一 ID 只有一条记录,并且后续列中的值是这些值的总和。但是,我可以使用 dplyr::summarise 执行此操作,但如果我使用 na.rm=TRUE,它会将 NA 替换为 0(如果所有记录都是 NA),或者如果我在没有 na.rm=TRUE 的情况下使用它,那么它会求和它给 NA(如果存在 NA)。

如果所有值都是 NA,我怎样才能让它保留 NA 作为新值,如果存在带有 NA 的数值,则总和。

对不好的解释深表歉意。不知道如何更好地表达它。

模拟数据框如下所示:

    df <- structure(
      list(
        id = structure(
          c(1L, 1L, 1L, 2L, 2L, 3L, 3L, 3L, 3L, 3L, 3L, 4L, 5L, 6L, 7L, 7L), 
          .Label = c("a", "b", "c", "d", "e", "f", "g"), 
          class = "factor"
        ), 
        `1` = c(NA, NA, NA, 1, 1, 0, 1, 1, 0, 1, NA, 1, NA, 0, 1, 0),
        `2` = c(NA, 0, 1, 0, 1, 0, 1, 0, 1, 1, 0, 1, 0, 0, NA, 0), 
        `3` = c(NA, 1, 1, 0, 1, 1, 0, 1, 0, 1, NA, 1, 0, 0, NA, NA)
      ), 
      row.names = c(NA, -16L), 
      class = "data.frame"
    )

打印出来的效果是这样的:

> df
   id  1  2  3
1   a NA NA NA
2   a NA  0  1
3   a NA  1  1
4   b  1  0  0
5   b  1  1  1
6   c  0  0  1
7   c  1  1  0
8   c  1  0  1
9   c  0  1  0
10  c  1  1  1
11  c NA  0 NA
12  d  1  1  1
13  e NA  0  0
14  f  0  0  0
15  g  1 NA NA
16  g  0  0 NA

我想按“id”列进行分组,然后将其相加得到如下结果:

  id  1 2  3
1  a NA 1  2
2  b  2 1  1
3  c  3 3  3
4  d  1 1  1
5  e NA 0  0
6  f  0 0  0
7  g  1 0 NA

我尝试过在有和没有 na.rm=T 的情况下使用 summarise,但它不能提供我需要的东西。

    df %>% 
      group_by(
        id
      ) %>% 
      summarise_at(
        c(
          1,2,3
        ),
        sum,
        na.rm = T
      ) 

# A tibble: 7 x 4
  id      `1`   `2`   `3`
  <fct> <dbl> <dbl> <dbl>
1 a         0     1     2
2 b         2     1     1
3 c         3     3     3
4 d         1     1     1
5 e         0     0     0
6 f         0     0     0
7 g         1     0     0

没有 na.rm = T:

    
    df %>% 
      group_by(
        id
      ) %>% 
      summarise_at(
        c(
          1,2,3
        ),
        sum
      ) 

# A tibble: 7 x 4
  id      `1`   `2`   `3`
  <fct> <dbl> <dbl> <dbl>
1 a        NA    NA    NA
2 b         2     1     1
3 c        NA     3    NA
4 d         1     1     1
5 e        NA     0     0
6 f         0     0     0
7 g         1    NA    NA

我不确定还可以尝试什么。任何建议将不胜感激。非常感谢

【问题讨论】:

    标签: r dplyr


    【解决方案1】:

    我们可以使用

    library(dplyr)
    df %>%
        group_by(id) %>%
        summarise(across(-id, ~ if(sum(is.na(.)) == n() NA else sum(., na.rm = TRUE))) 
    

    【讨论】:

      【解决方案2】:

      您可以检查每个id 中的值,如果所有值都是NA,则返回NA

      library(dplyr)
      
      df %>% 
        group_by(id) %>% 
        summarise(across(`1`:`3`, ~if(all(is.na(.))) NA else sum(., na.rm = TRUE)))
        #summarise_at(vars(`1`:`3`), ~if(all(is.na(.))) NA else sum(., na.rm = TRUE))
      
      #   id      `1`   `2`   `3`
      #  <fct> <dbl> <dbl> <dbl>
      #1 a        NA     1     2
      #2 b         2     1     1
      #3 c         3     3     3
      #4 d         1     1     1
      #5 e        NA     0     0
      #6 f         0     0     0
      #7 g         1     0    NA
      

      【讨论】:

        猜你喜欢
        • 2019-07-15
        • 2020-04-04
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2015-07-26
        • 1970-01-01
        • 2021-12-11
        相关资源
        最近更新 更多