Group_by / 按函数内的两个变量汇总

Posted

技术标签:

【中文标题】Group_by / 按函数内的两个变量汇总【英文标题】:Group_by / summarize by two variables within a function 【发布时间】:2018-11-03 19:36:48 【问题描述】:

我想编写一个函数,通过一些指定的标准来汇总提供的数据,在这种情况下是按年龄

示例数据是用户年龄及其统计数据表。

df <- data.frame('Age'=rep(18:25,2), 'X1'=10:17, 'X2'=28:35,'X4'=22:29)

接下来我定义与分析相关的输出列

output_columns <- c('Age', 'X1', 'X2', 'X3')

此函数计算 X1 的基本总和。 X2 和 X3 按年龄分组。

aggr <- function(data, criteria, output_columns)
  k <- data %>% .[, colnames(.) %in% output_columns] %>%
    group_by_(.dots = criteria) %>%
    #summarise_each(funs(count), age) %>%
    summarize_if(is.numeric, sum)
  return (k)

当我这样称呼它时

> e <- aggr(df, "Age", output_columns)
> e
# A tibble: 8 x 3
    Age    X1    X2
  <int> <int> <int>
1    18    20    56
2    19    22    58
3    20    24    60
4    21    26    62
5    22    28    64
6    23    30    66
7    24    32    68
8    25    34    70

我想要另一个名为 count 的列,它显示每个年龄段的观察次数。期望的输出是

> desired
  Age X1 X2 count
1  18 20 56     2
2  19 22 58     2
3  20 24 60     2
4  21 26 62     2
5  22 28 64     2
6  23 30 66     2
7  24 32 68     2
8  25 34 70     2

我尝试了不同的方法来做到这一点,例如tally(),summary_each 等等。它们都提供了错误的结果。

我相信他们应该是一种简单易行的方法。 任何帮助表示赞赏。

【问题讨论】:

我认为您需要将%&gt;% group_by_at(criteria) %&gt;% mutate(count = n()) 添加到您的函数中 管道中的最后一行可以替换为: cbind(summarize_if(., is.numeric, sum), summarize(., n = n())) 【参考方案1】:

由于您已经对所有变量求和,您只需在汇总函数之前添加一列所有 1s

aggr <- function(data, criteria, output_columns) 
    data %>% 
      .[, colnames(.) %in% output_columns] %>%
      group_by_(.dots = criteria) %>%
      mutate(n = 1L) %>%
      summarize_if(is.numeric, sum)


# A tibble: 8 x 4
    Age    X1    X2     n
  <int> <int> <int> <int>
1    18    20    56     2
2    19    22    58     2
3    20    24    60     2
4    21    26    62     2
5    22    28    64     2
6    23    30    66     2
7    24    32    68     2
8    25    34    70     2

【讨论】:

比我的回答好吗 这很聪明,喜欢它【参考方案2】:

我们可以在summarise_if 之前创建“计数”列

aggr<- function(data, criteria, output_columns)
                data %>% 
                   select(intersect(names(.), output_columns))%>%
                   group_by_at(criteria)%>%   
                   group_by(count = n(), add= TRUE) %>%                                
                   summarize_if(is.numeric,sum) %>%
                   select(setdiff(names(.), 'count'), count)                                     

    




aggr(df,"Age",output_columns)
# A tibble: 8 x 4
# Groups:   Age [8]
#    Age    X1    X2 count
#  <int> <int> <int> <int>
#1    18    20    56     2
#2    19    22    58     2
#3    20    24    60     2
#4    21    26    62     2
#5    22    28    64     2
#6    23    30    66     2
#7    24    32    68     2
#8    25    34    70     2

【讨论】:

@Ryan 这是一个好方法。我发现你发布了一个答案。我喜欢它 将这一行 group_by(count = n(), add= TRUE) 添加到我的原始函数中也可以正常工作。这会导致任何错误吗? @esem 在汇总步骤之后,如果您需要更多转换,可以取消组合【参考方案3】:

在基础 R 中你可以这样做

aggr <- function(data, criteria, output_columns)
  ds <- data[, colnames(data) %in% output_columns]
  d <- aggregate(ds, by=list(criteria), function(x) c(sum(x), length(x)))
  "names<-"(do.call(data.frame, d)[, -c(2:3, 5)], c(names(ds), "n"))


> with(df, aggr(df, Age, output_columns))
  Age X1 X2 n
1  18 20 56 2
2  19 22 58 2
3  20 24 60 2
4  21 26 62 2
5  22 28 64 2
6  23 30 66 2
7  24 32 68 2
8  25 34 70 2

【讨论】:

以上是关于Group_by / 按函数内的两个变量汇总的主要内容,如果未能解决你的问题,请参考以下文章

当我在`dplyr`之后加载`plyr`时,为啥汇总或变异不适用于group_by?

当我在`dplyr`之后加载`plyr`时,为啥汇总或变异不适用于group_by?

R dplyr如何通过列号而不是通过汇总的列名选择变量

dplyr:在 group_by 之后汇总内部的管道

一次调用按组对多个变量应用多个汇总函数

使用 dplyr、group_by 和折叠或汇总连接字符串/行,但保持 NA 值 [重复]