使用dplyr在多个列之间求和

时间:2015-03-05 08:19:34

标签: r dplyr

我的问题涉及在数据框的多个列中汇总值,并使用dplyr创建与此求和相对应的新列。列中的数据条目是二进制(0,1)。我正在考虑summarise_each的{​​{1}}或mutate_each函数的行式模拟。以下是数据框的最小示例:

dplyr

我可以使用类似的东西:

library(dplyr)
df=data.frame(
  x1=c(1,0,0,NA,0,1,1,NA,0,1),
  x2=c(1,1,NA,1,1,0,NA,NA,0,1),
  x3=c(0,1,0,1,1,0,NA,NA,0,1),
  x4=c(1,0,NA,1,0,0,NA,0,0,1),
  x5=c(1,1,NA,1,1,1,NA,1,0,1))

> df
   x1 x2 x3 x4 x5
1   1  1  0  1  1
2   0  1  1  0  1
3   0 NA  0 NA NA
4  NA  1  1  1  1
5   0  1  1  0  1
6   1  0  0  0  1
7   1 NA NA NA NA
8  NA NA NA  0  1
9   0  0  0  0  0
10  1  1  1  1  1

但这将涉及写出每个列的名称。我有50个专栏。 另外,列名称在我想要实现它的循环的不同迭代中改变 操作所以我想尝试避免给出任何列名。

我怎样才能最有效地做到这一点? 任何帮助将不胜感激。

5 个答案:

答案 0 :(得分:70)

怎么样

总结每一栏

df %>%
   replace(is.na(.), 0) %>%
   summarise_all(funs(sum))

总结每一行

df %>%
   replace(is.na(.), 0) %>%
   mutate(sum = rowSums(.[1:5]))

答案 1 :(得分:25)

我会使用正则表达式匹配来对具有某些模式名称的变量求和。例如:

df <- df %>% mutate(sum1 = rowSums(.[grep("x[3-5]", names(.))], na.rm = TRUE),
                    sum_all = rowSums(.[grep("x", names(.))], na.rm = TRUE))

这样,您可以创建多个变量作为数据框的某组变量的总和。

答案 2 :(得分:21)

如果您只想对某些列求和,我会使用以下内容:

library(dplyr)
df=data.frame(
  x1=c(1,0,0,NA,0,1,1,NA,0,1),
  x2=c(1,1,NA,1,1,0,NA,NA,0,1),
  x3=c(0,1,0,1,1,0,NA,NA,0,1),
  x4=c(1,0,NA,1,0,0,NA,0,0,1),
  x5=c(1,1,NA,1,1,1,NA,1,0,1))
df %>% select(x3:x5) %>% rowSums(na.rm=TRUE) -> df$x3x5.total
head(df)

这样您就可以使用dplyr::select的语法。

答案 3 :(得分:5)

使用reduce()中的purrrrowSums快一点,并且绝对比apply快,因为您可以避免遍历所有行,而只是利用矢量化操作:

library(purrr)
library(dplyr)
iris %>% mutate(Petal = reduce(select(., starts_with("Petal")), `+`))

有关时间,请参见this

答案 4 :(得分:5)

dplyr的较新版本中,您可以将rowwise()c_across一起使用,以对没有特定按行变体的函数执行按行聚合,但是如果行-明智的变体存在,它应该更快。

由于rowwise()只是一种特殊的分组形式,它会改变动词的工作方式,因此您可能希望在执行逐行操作后将其通过管道传递到ungroup()

要选择行范围:

df %>%
  dplyr::rowwise() %>% 
  dplyr::mutate(sumrange = sum(dplyr::c_across(x1:x5), na.rm = T))
# %>% dplyr::ungroup() # you'll likely want to ungroup after using rowwise()

要按类型选择行:

df %>%
  dplyr::rowwise() %>% 
  dplyr::mutate(sumnumeric = sum(c_across(where(is.numeric)), na.rm = T))
# %>% dplyr::ungroup() # you'll likely want to ungroup after using rowwise()

在特定情况下,存在逐行变体,因此您可以执行以下操作(注意使用across):

df %>%
  dplyr::mutate(sumrow = rowSums(dplyr::across(x1:x5), na.rm = T))

有关更多信息,请参见rowwise上的页面。