summarise_each 在 R 中应用于同一列但不同的分组
summarise_each in R applied to same column but different groupings
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))
这为我提供了新列中每个性别的成功总数。
但是,我想不出如何在一段代码中将这两个新列添加到末尾。我无法在 summarize 函数之后添加另一个管道,所以我希望有人能帮助我。
这是对一个通用函数的尝试,该函数使用 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
您可以在 mutate()
步骤中使用 ave()
以节省使用多个 group_by()
的麻烦。
library(tidyverse)
df2 <- df1 %>%
mutate(
RaceSuccess = ave(success, race, FUN=sum),
GenderSuccess = ave(success, gender, FUN=sum)
)
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))
这为我提供了新列中每个性别的成功总数。
但是,我想不出如何在一段代码中将这两个新列添加到末尾。我无法在 summarize 函数之后添加另一个管道,所以我希望有人能帮助我。
这是对一个通用函数的尝试,该函数使用 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
您可以在 mutate()
步骤中使用 ave()
以节省使用多个 group_by()
的麻烦。
library(tidyverse)
df2 <- df1 %>%
mutate(
RaceSuccess = ave(success, race, FUN=sum),
GenderSuccess = ave(success, gender, FUN=sum)
)