【问题标题】:extract max value from two column within a group [duplicate]从组内的两列中提取最大值[重复]
【发布时间】:2018-10-10 07:50:23
【问题描述】:

q分组后,想分别从两个不同的we列中提取两个最大值

输入数据:

q <- c(503,503,503,503,503,503,503,503,503,503,503,503,503,510,510,510,510,510,510,510,510,510,510,510,510,525,526,526)
w <- c(56,56,56,56,56,56,56,56,56,56,56,56,56,56,56,56,56,56,56,56,56,56,56,56,56,56,56,56)
e <- c(26,26,26,26,26,27,28,28,28,28,28,28,28,28,28,28,28,28,28,28,29,30,30,30,30,33,33,33)
r <- data.frame(q,w,e, stringsAsFactors = FALSE)

代码:

r %>% group_by(q) %>% slice(which.max(w & e))

我的输出:

  q     w     e
 <dbl> <dbl> <dbl>
1  503.   56.   26.
2  510.   56.   28.
3  525.   56.   33.
4  526.   56.   33.

预期输出:

    q   w  e
1  503 56 28
2  510 56 30
3  525 56 33
4  526 56 33

宁愿使用%&gt;%slice 命令作为上面的代码,而不是单独查找max q$w q$e 然后由q 合并(希望避免merge 因为我的实际数据是大object.size ~2GB)

【问题讨论】:

    标签: r dplyr


    【解决方案1】:

    这是快速的data.table 解决方案,可以很好地扩展到您的 2GB 数据集。

    library(data.table)
    dt <- data.table(r)
    dt[, lapply(.SD, max, na.rm=TRUE), by=q ]
    

    结果

        q  w  e
    1: 503 56 28
    2: 510 56 30
    3: 525 56 33
    4: 526 56 33
    

    基准测试

    microbenchmark(data.table = dt[, lapply(.SD, max, na.rm=TRUE), by=q ],
                   dplyr1 = r %>% group_by(q) %>% summarise_all(max),
                   base = do.call(rbind, by(r, r$q, function(x)
                   data.frame(q = unique(x$q), w = max(x$w), e = max(x$e)))), times = 50
    )
    

    结果

    Unit: microseconds
           expr      min       lq     mean   median       uq       max neval
     data.table  810.240 1060.267 1447.979 1192.107 1332.054 14260.901    50
         dplyr1 1562.027 1686.613 1857.382 1759.574 1869.226  3617.279    50
           base 1925.973 2088.107 2448.162 2226.986 2485.760  7395.837    50
    

    显然data.table 是最快的。

    【讨论】:

      【解决方案2】:

      我知道您要求tidyverse 解决方案,但作为替代方案,这里是使用by 的base R 解决方案:

      do.call(rbind, by(r, r$q, function(x)
          data.frame(q = unique(x$q), w = max(x$w), e = max(x$e))))
      #      q  w  e
      #503 503 56 28
      #510 510 56 30
      #525 525 56 33
      #526 526 56 33
      

      【讨论】:

        【解决方案3】:

        你不需要使用slice,只需summarise_all

        r %>% group_by(q) %>% summarise_all(max)
        
        # A tibble: 4 x 3
        #      q     w     e
        #    <dbl> <dbl> <dbl>
        # 1   503  56.0  28.0
        # 2   510  56.0  30.0
        # 3   525  56.0  33.0
        # 4   526  56.0  33.0
        

        【讨论】:

        • 这是一个比我的更优雅的解决方案;每天学习新东西,谢谢!
        【解决方案4】:

        以下dplyr 代码可以满足您的需要,同时避免使用merge()

        r %>% 
        group_by(q) %>% 
        summarize(w=max(w), e=max(e))
        

        返回:

              q     w     e
          <dbl> <dbl> <dbl>
        1  503.   56.   28.
        2  510.   56.   30.
        3  525.   56.   33.
        4  526.   56.   33.
        

        【讨论】:

          猜你喜欢
          • 2014-10-08
          • 1970-01-01
          • 2019-04-04
          • 2020-11-01
          • 1970-01-01
          • 1970-01-01
          • 2020-11-11
          • 1970-01-01
          • 2021-06-20
          相关资源
          最近更新 更多