从组

时间:2018-04-30 08:32:58

标签: r dplyr

q分组后,会分别从两个不同的w e列中提取两个最大值

输入数据:

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

希望使用%>%slice命令作为上述代码,而不是单独找到max q$w q$e,然后按q合并(希望避免merge,因为我的实际数据很大object.size ~2GB)

4 个答案:

答案 0 :(得分:5)

这是快速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最快。

答案 1 :(得分:4)

您无需使用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

答案 2 :(得分:2)

以下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.

答案 3 :(得分:2)

我知道您要求tidyverse解决方案,但作为替代方案,以下是使用by的基础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