我正在尝试在dplyr的mutate函数中使用sum函数。但是,我最终得到了意外的结果。下面是重现该问题的代码
chk1 <- data.frame(ba_mat_x=c(1,2,3,4),ba_mat_y=c(NA,2,NA,5))
我使用下面的代码创建了另一列,对以上两列进行汇总
chk2 <- chk1 %>% dplyr::mutate(ba_mat=sum(ba_mat_x+ba_mat_y,na.rm = T))
我使用na.rm=T
是因为我在变量NA
中有ba_mat_y
个。我得到的结果如下
ba_mat_x ba_mat_y ba_mat
1 1 NA 13
2 2 2 13
3 3 NA 13
4 4 5 13
但是,预期结果是
ba_mat_x ba_mat_y ba_mat
1 1 NA 1
2 2 2 4
3 3 NA 3
4 4 5 9
答案 0 :(得分:2)
您想要rowSums,以获取每一行的列总和。
> chk1 %>% dplyr::mutate(ba_mat = rowSums(., na.rm=T))
ba_mat_x ba_mat_y ba_mat
1 1 NA 1
2 2 2 4
3 3 NA 3
4 4 5 9
您的其他表述(sum(ba_mat_x+ba_mat_y,na.rm = T))
)表示:
chk1$ba_mat_x + chk1$ba_mat_y
:1 + NA, 2 + 2, 3 + NA, 4 + 5
,结果为NA, 4, NA, 9
sum(na.rm=T)
,即13
答案 1 :(得分:1)
如果我们有多个列,并且只想对有限的列求和,我们可以将它们替换为0,然后添加列
<button type="submit" class="btn btn-primary">Submit</button>
我们还可以使用library(dplyr)
chk1 %>%
mutate_at(vars(ba_mat_x,ba_mat_y), ~ replace(., is.na(.), 0)) %>%
mutate(ba_mat = ba_mat_x + ba_mat_y)
# ba_mat_x ba_mat_y ba_mat
#1 1 0 1
#2 2 2 4
#3 3 0 3
#4 4 5 9
中的replace_na
来做同样的事情。
tidyr
如果我们要使用chk1 %>%
mutate_at(vars(ba_mat_x, ba_mat_y), tidyr::replace_na, 0) %>%
mutate(ba_mat = ba_mat_x + ba_mat_y)
,另一种选择是使用sum
的{{1}}或purrr
,现在我们可以传递要添加的列列表,然后使用pmap
。
pmap_dbl
在这种情况下,我们也可以使用sum
chk1 %>%
mutate(ba_mat = purrr::pmap_dbl(list(ba_mat_x, ba_mat_y), sum, na.rm = TRUE))
# ba_mat_x ba_mat_y ba_mat
#1 1 NA 1
#2 2 2 4
#3 3 NA 3
#4 4 5 9
这也将起作用,因为我们只有两列,但是如果有更多的列,使用map2_dbl
选项会更好/更安全。
此外,就您的尝试而言,如果您将chk1 %>%
mutate(ba_mat = purrr::map2_dbl(ba_mat_x, ba_mat_y, sum, na.rm = TRUE))
添加到它,它将可以正常工作。顾名思义,pmap
以行方式进行所有操作。
rowwise
但是rowwise
通常较慢。
答案 2 :(得分:1)
我们可以使用rowSums
中的base R
chk1$ba_mat <- rowSums(chk1, na.rm = TRUE)
chk1
# ba_mat_x ba_mat_y ba_mat
#1 1 NA 1
#2 2 2 4
#3 3 NA 3
#4 4 5 9
或使用tidverse
,同时保持原始列不变
library(tidyverse)
chk1 %>%
mutate(ba_mat = replace(., is.na(.), 0) %>%
reduce(`+`))
# ba_mat_x ba_mat_y ba_mat
#1 1 NA 1
#2 2 2 4
#3 3 NA 3
#4 4 5 9
或与case_when
chk1 %>%
mutate_if(is.numeric, list(new = ~case_when(is.na(.) ~ 0,
TRUE ~ .))) %>%
transmute(!!! rlang::syms(names(chk1)), ba_mat = ba_mat_x_new + ba_mat_y_new)
# ba_mat_x ba_mat_y ba_mat
#1 1 NA 1
#2 2 2 4
#3 3 NA 3
#4 4 5 9