[英]is there a way in R to fill NA's with all possible values by a dplyr group?
[英]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.