You should probably find a function for this on tidyverse, however there is a function that I often use for aggregate aggregation. It includes most of what was discussed above with formula(), but in a more general form:
get.stat = function(df,var.nm,agg.id){
#--- df data.frame for aggregation
#--- var.nm target variable to be aggregated
#--- agg.id index name for aggretation (single value or vector)
#--- generate aggregation formula
agg.formula = paste(agg.id, collapse = "+")
#--- df with summary results
df.res = data.frame(mean = aggregate(formula(paste0(var.nm,"~",agg.formula)), df, mean )[,length(agg.id)+1],
median = aggregate(formula(paste0(var.nm,"~",agg.formula)), df, median)[,length(agg.id)+1],
sd = aggregate(formula(paste0(var.nm,"~",agg.formula)), df, sd )[,length(agg.id)+1],
min = aggregate(formula(paste0(var.nm,"~",agg.formula)), df, min )[,length(agg.id)+1],
max = aggregate(formula(paste0(var.nm,"~",agg.formula)), df, max )[,length(agg.id)+1],
sum = aggregate(formula(paste0(var.nm,"~",agg.formula)), df, sum )[,length(agg.id)+1],
count = aggregate(formula(paste0(var.nm,"~",agg.formula)), df, length)[,length(agg.id)+1])
#--- bind indexers
for(c in 1:length(agg.id)){
df.res = cbind(df.res, aggregate(formula(paste0(var.nm,"~",agg.formula)), df, mean)[,c])
colnames(df.res)[length(colnames(df.res))] = agg.id[c]
}
#--- re-order col
df.res = df.res[,c(agg.id,colnames(df.res)[1:(length(colnames(df.res)) - c)])]
return(df.res)
}
With this loaded function, you can simply:
get.stat(df, "mpg",c("gear","cyl"))