R中的summarise_each适用于同一列但不同的分组

时间:2018-10-03 18:56:18

标签: r dplyr tidyverse summary

df1<- structure(list(race = c("White", "White", "Hispanic", "Hispanic", "Hispanic", "White", "White", "Hispanic", "White", "White"), gender = c("M","M","M","F","M","F","F","F","M","F"), success = c(1,1,0,1,0,0,1,0,0,1)), class = "data.frame", row.names = c("1","2", "3", "4", "5", "6","7","8","9","10"))

Row    race   gender success
1     White      M       1
2     White      M       1
3  Hispanic      M       0
4  Hispanic      F       1
5  Hispanic      M       0
6     White      F       0
7     White      F       1
8  Hispanic      F       0
9     White      M       0
10    White      F       1

以上是我的数据。我想做的是在一个列中包含按性别划分的成功计数,在另一个列中包含按种族划分的成功计数。以下内容可以独立工作,但我无法让它们一起工作:

RaceSuccess<- df1 %>% group_by(race)%>%summarise(racesuc = sum(success))

这将在新列中显示每场比赛的成功总数

GenderSuccess <- df1 %>% group_by(gender)%>%summarise(gensuc=sum(success))

这在新列中为我提供了每种性别的成功总数。

但是,我不知道如何在一段代码中将两个新列添加到末尾。我不能在summary函数之后添加其他管道,所以我希望有人可以帮助我。

2 个答案:

答案 0 :(得分:1)

这是一种尝试使用tidyeval的通用函数来查找连续被任意其他列分组的一列中的值之和的方法。

library(tidyverse)

fnc = function(data, outcome, ...) {

  groups=enquos(...)
  outcome=enquo(outcome)

  map(groups, ~ data %>% 
        group_by(!!.x) %>% 
        summarise(!!sym(paste0(quo_text(.x), "_", quo_text(outcome))) := sum(!!outcome))) %>% 
    c(list(data), .) %>% 
    reduce(left_join)

}

现在运行功能:

fnc(df1, outcome=success, race, gender)
       race gender success race_success gender_success
1     White      M       1            4              2
2     White      M       1            4              2
3  Hispanic      M       0            1              2
4  Hispanic      F       1            1              3
5  Hispanic      M       0            1              2
6     White      F       0            4              3
7     White      F       1            4              3
8  Hispanic      F       0            1              3
9     White      M       0            4              2
10    White      F       1            4              3
fnc(mtcars, outcome=am, cyl, gear, vs)
    mpg cyl  disp  hp drat    wt  qsec vs am gear carb cyl_am gear_am vs_am
1  21.0   6 160.0 110 3.90 2.620 16.46  0  1    4    4      3       8     6
2  21.0   6 160.0 110 3.90 2.875 17.02  0  1    4    4      3       8     6
3  22.8   4 108.0  93 3.85 2.320 18.61  1  1    4    1      8       8     7
4  21.4   6 258.0 110 3.08 3.215 19.44  1  0    3    1      3       0     7
...
28 30.4   4  95.1 113 3.77 1.513 16.90  1  1    5    2      8       5     7
29 15.8   8 351.0 264 4.22 3.170 14.50  0  1    5    4      2       5     6
30 19.7   6 145.0 175 3.62 2.770 15.50  0  1    5    6      3       5     6
31 15.0   8 301.0 335 3.54 3.570 14.60  0  1    5    8      2       5     6
32 21.4   4 121.0 109 4.11 2.780 18.60  1  1    4    2      8       8     7

答案 1 :(得分:0)

您可以在ave()步骤中使用mutate()来节省必须使用多个group_by()的时间。

library(tidyverse)

df2 <- df1 %>% 
mutate(
  RaceSuccess = ave(success, race, FUN=sum),
  GenderSuccess = ave(success, gender, FUN=sum)
)