繁体   English   中英

R - dplyr - 按列分组,如果给定组只存在 NA,则计算保留 NA 的总和

[英]R - dplyr - Group by column and calculate the sum keeping NA's if only NA's present for a given group

我有一个数据框,第一列中有重复的 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 的情况下使用汇总,但它没有提供我需要的。

    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

我不知道还有什么可以尝试的。 任何建议将不胜感激。 非常感谢

您可以检查每个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

我们可以用

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM