【问题标题】:How to use dplyr's pipe with aggregate如何将 dplyr 的管道与聚合一起使用
【发布时间】:2019-08-10 14:31:41
【问题描述】:
df<-data.frame(gender = c('A', 'B', 'B','B','A'),q01 = c(1, 6, 3,8,5),q02 = c(5, 3, 6,5,2)) 
  gender q01 q02
1      A   1   5
2      B   6   3
3      B   3   6
4      B   8   5
5      A   5   2

我想计算q01*2+q02,然后通过gender组得到mean,预期结果如下:

A 9.5
B 16

我试过但失败了:

 df %>% aggregate(c(q01,q02)~gender,mean(q01*2+q02))

平均值错误(q01 * 2 + q02):找不到对象“q01”

df %>% group_by(gender) %>% mean(.$q01*2+.$q02)
[1] NA

警告信息: 在 mean.default(., .$q01 * 2 + .$q02) 中: 参数不是数字或逻辑:返回 NA

有什么问题?

【问题讨论】:

    标签: r dplyr


    【解决方案1】:

    dplyr + aggregate 的 OP 代码中,data 未与使用 c 一起指定,即将两列连接在一起。还有,

    aggregate(c(q01,q02)~gender,df, mean(q01*2+q02))
    

    model.frame.default 中的错误(公式 = c(q01, q02) ~ 性别,数据 = df) : 可变长度不同(为 'gender' 找到)

    在这里,使用c(q01, q02),就像连接c(1:5, 6:10),现在长度将是以前的两倍,而且使用的FUN 不会被评估,因为它找不到' q01' 或 'q02'

    相反,我们可以cbind 使用aggregateformula 方法创建新列,然后获取mean

    library(dplyr) 
    df %>%
         aggregate(cbind(q = q01 * 2 + q02) ~ gender, data = ., mean)
    #  gender    q
    #1      A  9.5
    #2      B 16.0
    

    注意:在dplyr 中,来自%&gt;%lhs 的数据可以用. 指定。

    注意2:在这里,我们假设问题是了解如何使aggregate%&gt;% 中工作。如果只是为了获取mean,整个过程可以用dplyr完成

    f1 <- function(x, y, val) mean(x * val + y)
    df %>%
        group_by(gender) %>%
        summarise(q = f1(q01, q02, 2))
    

    或使用data.table 方法

    library(data.table)
    setDT(df)[, .(q = mean(q01  * 2 + q02)), .(gender)]
    #   gender    q
    #1:      A  9.5
    #2:      B 16.0
    

    或者使用base Rby

    stack(by(df[-1], df[1], FUN = function(x) mean(x[,1] * 2 + x[,2])))
    

    或者aggregate

    aggregate(cbind(q = q01 * 2 + q02) ~ gender, df, mean)
    

    【讨论】:

      【解决方案2】:

      最好将dplyr 和基本方法分开。他们每个人都有自己处理数据的方式。使用dplyr 你可以做到

      library(dplyr)
      
      df %>%
         mutate(q = q01 * 2 + q02) %>%
         group_by(gender) %>%
         summarise(q = mean(q))
      
      #  gender     q
      #  <fct>  <dbl>
      #1 A        9.5
      #2 B       16  
      

      并使用基础 R aggregate

      aggregate(q~gender, transform(df, q = q01*2+q02), mean)
      

      【讨论】:

      • 我就是不明白为什么不能在group_by之后直接mean(.$q01*2+.$q02)
      • @kittygirl 是的,那也可以df %&gt;% group_by(gender) %&gt;% summarise(q = mean(q01 * 2 + q02))。刚刚添加了一个单独的步骤 mutate 以使其易于理解。
      【解决方案3】:

      坚持同样的逻辑:

        df %>% 
         do(aggregate(I(q01*2)+q02~gender,
                   data=.,mean)) %>% 
         setNames(.,nm=c("gender","q"))
        gender    q
      1      A  9.5
      2      B 16.0
      

      注意: 我确实注意到do 的生命周期被标记为质疑。

      【讨论】:

        猜你喜欢
        • 2021-12-28
        • 2017-05-27
        • 2020-05-14
        • 1970-01-01
        • 1970-01-01
        • 2017-12-31
        • 1970-01-01
        • 2019-12-18
        • 1970-01-01
        相关资源
        最近更新 更多