按组对多个变量求和并用它们的总和创建新列

Sum multiple variables by group and create new column with their sum

我有一个包含分组变量的数据框,我想按组对它们求和。使用 dplyr.

很容易
library(dplyr)
library(magrittr)

data <- data.frame(group = c("a", "a", "b", "c", "c"), n1 = 1:5, n2 = 2:6)

data %>% group_by(group) %>%
  summarise_all(sum)

# A tibble: 3 x 3
   group    n1    n2
  <fctr> <int> <int>
1      a     3     5
2      b     3     4
3      c     9    11

但现在我想要一个新列 total,其中包含 n1n2 的总和(按组)。像这样:

# A tibble: 3 x 3
   group    n1    n2   ttl
  <fctr> <int> <int> <int>
1      a     3     5     8
2      b     3     4     7
3      c     9    11    20

如何使用 dplyr 做到这一点?

编辑: 其实这只是一个例子,我有很多变数。

我试过这两个代码,但它的尺寸不对...

data %>% group_by(group) %>%
  summarise_all(sum) %>%
  summarise_if(is.numeric, sum)

data %>% group_by(group) %>%
  summarise_all(sum) %>%
  mutate_if(is.numeric, .funs = sum)

你可以在summarize之后使用mutate:

data %>% 
    group_by(group) %>%
    summarise_all(sum) %>% 
    mutate(tt1 = n1 + n2)

# A tibble: 3 x 4
#   group    n1    n2   tt1
#  <fctr> <int> <int> <int>
#1      a     3     5     8
#2      b     3     4     7
#3      c     9    11    20

如果需要对所有数字列求和,您可以使用 rowSumsselect_if(对 select 数字列)对列求和:

data %>% 
    group_by(group) %>%
    summarise_all(sum) %>% 
    mutate(tt1 = rowSums(select_if(., is.numeric)))

# A tibble: 3 x 4
#   group    n1    n2   tt1
#  <fctr> <int> <int> <dbl>
#1      a     3     5     8
#2      b     3     4     7
#3      c     9    11    20

我们可以使用data.table。将'data.frame'转换为'data.table'(setDT(data)),按'group'分组,得到data.table子集中各列的sum,并然后使用 Reduce,获取感兴趣的列的行的 sum

library(data.table)
setDT(data)[, lapply(.SD, sum) , group][, tt1 := Reduce(`+`, .SD),  
                       .SDcols = names(data)[-1]][]
#   group n1 n2 tt1
#1:     a  3  5   8
#2:     b  3  4   7
#3:     c  9 11  20

base R

addmargins(as.matrix(rowsum(data[-1], data$group)), 2)
#  n1 n2 Sum
#a  3  5   8
#b  3  4   7
#c  9 11  20

dplyr

data %>%
   group_by(group) %>%
   summarise_all(sum) %>% 
   mutate(tt = rowSums(.[-1]))

基础 R

cbind(aggregate(.~group, data, sum), ttl = sapply(split(data[,-1], data$group), sum))
#  group n1 n2 ttl
#a     a  3  5   8
#b     b  3  4   7
#c     c  9 11  20

我们可以将 applydplyr 函数一起使用。

data <- data.frame(group = c("a", "a", "b", "c", "c"), n1 = 1:5, n2 = 2:6)

data %>% group_by(group) %>%
  summarise_all(sum) %>%
  mutate(ttl = apply(.[, 2:ncol(.)], 1, sum))

# A tibble: 3 × 4
   group    n1    n2   ttl
  <fctr> <int> <int> <int>
1      a     3     5     8
2      b     3     4     7
3      c     9    11    20

rowSums采用相同策略。关键是使用 . 来指定数据框,使用 []x:ncol(.) 来保留你想要的列。

data %>% group_by(group) %>%
  summarise_all(sum) %>%
  mutate(ttl = rowSums(.[, 2:ncol(.)]))

# A tibble: 3 × 4
   group    n1    n2   ttl
  <fctr> <int> <int> <dbl>
1      a     3     5     8
2      b     3     4     7
3      c     9    11    20