dplyr函数group_by几个变量

时间:2019-08-14 08:57:41

标签: r dplyr

我已经阅读了R的dplyr编程(https://cran.r-project.org/web/packages/dplyr/vignettes/programming.html)的介绍,这非常有用。

我经常构建相当复杂的函数,其中包括几组分组变量。例如,给定一个数据集df,我可能希望该函数通过一些变量进行汇总(例如将变量G1和G2分组),然后通过其他一些变量进行汇总(例如G3),然后将这些汇总一起用于生成一些最终结果

df <- data.frame(xV = 1:3,yV=0:2, G1 =c(1,1,0),G2=c(0,0,1),G3=c(1,1,1))
#Within my function I want to calculate 
#a)
df%>%group_by(G1,G2)%>%summarise(MEANS1= mean(xV,na.rm=T))
#As well as (b_
df%>%group_by(G3)%>%summarise(MEAN2= mean(xV,na.rm=T))

如果只需要进行第一个分组(即(a)),则可以使用...来构建函数。

TAB2<-function(data,x,...){
  require(dplyr)  
  x<-enquo (x)
  groupSet1 <- enquos(...)

  data%>%group_by(!!!(groupSet1))%>%
    summarise(MEAN=mean(!!x,na.rm=T))
}

#Which gives me my results
TAB2(data=df,x=xV,G1,G2)
# A tibble: 2 x 3
# Groups:   G1 [2]
     G1    G2  MEAN
  <dbl> <dbl> <dbl>
1     0     1   3  
2     1     0   1.5

但是,如果我想同时执行(a)和(b),则需要以某种方式区分第一组和第二组分组变量(G1,G2)和G3。我不能仅仅通过在所有其他输入之后删除分组变量来做到这一点。有什么办法可以在输入中指定这两个集合,类似

TAB3<-function(data,x,y, GroupSet1=c(G1,G2) and GroupSet2=(G3)){

 x<-enquo (x)
 y<-enquo (x)
#a)
df%>%group_by(GroupSet1)%>%summarise(MEANS1= mean(!!x,na.rm=T))
#As well as (b_)
df%>%group_by(GroupSet2)%>%summarise(MEAN2= mean(!!y,na.rm=T))

}

我尝试以多种方式以类似于x <-enquo(x)的方式“引用”这两个集合,但我总是遇到错误。能否请你帮忙?如果还可以将变量列表x和y传递给summarise_at,则也将使该函数尽可能通用,这将更好。基本上,我正在尝试创建一个模板函数,该函数可以包含多个变量集x和y以及多个组集,目的是通过相应的组集(G1, G2和G3)。

2 个答案:

答案 0 :(得分:1)

您可以尝试

TAB3<-function(data, y, grouping_list){
  require(tidyverse)
  map(grouping_list, ~group_by_at(data, .) %>% 
        summarise_at(y, list(Mean= mean), na.rm=T)) }

TAB3(df, "xV", list(c("G1", "G2"), c("G3"))) 
[[1]]
# A tibble: 2 x 3
# Groups:   G1 [2]
     G1    G2  Mean
  <dbl> <dbl> <dbl>
1     0     1   3  
2     1     0   1.5

[[2]]
# A tibble: 1 x 2
     G3  Mean
  <dbl> <dbl>
1     1     2

答案 1 :(得分:0)

如果要按照TAB2示例使用省略号,可以尝试:

根据新信息进行更新:

TAB3<-function(df,x,...){
  args <- substitute(list(...))
  names_env <- setNames(as.list(names(df)), names(df))
  arg_list <- eval(args, names_env)

  out <- vector(mode = "list", length(arg_list)) 

  for(i in seq_along(arg_list)){
    out[[i]] <- df %>% group_by(!!!syms(arg_list[[i]])) %>%
      summarise_at(vars(!!!enquos(x)) ,.funs  = list(mean=mean), na.rm = T)
  }
  out
}

TAB3(df, x = c(xV,yV), GroupSet1=c(G1,G2), GroupSet2=G3)

#[[1]]
# A tibble: 2 x 4
# Groups:   G1 [2]
#     G1    G2 xV_mean yV_mean
#  <dbl> <dbl>   <dbl>   <dbl>
#1     0     1     3       2  
#2     1     0     1.5     0.5

#[[2]]
# A tibble: 1 x 3
#     G3 xV_mean yV_mean
#  <dbl>   <dbl>   <dbl>
#1     1       2       1