R Aggregating data with a WHERE clause in a group

As an example, I have a data table shown below. I want to do a simple join, where b = sum (b). For c, however, I want the value of the entry in c, where b is the maximum. The required output is shown below (data.aggr). This leads to several questions:

1) Is there a way to do this data.table?

2) Is there an easier way to do this in plyr?

3) In plyr, the output object received a change from data.table to data.frame. Can I avoid this behavior?

library(plyr)
library(data.table) 
dt <- data.table(a=c('a', 'a', 'a', 'b', 'b'), b=c(1, 2, 3, 4, 5), 
                 c=c('m', 'n', 'p', 'q', 'r'))
dt
#    a b c
# 1: a 1 m
# 2: a 2 n
# 3: a 3 p
# 4: b 4 q
# 5: b 5 r
dt.split <- split(dt, dt$a)
dt.aggr <- ldply(lapply(dt.split,  
    FUN=function(dt){ dt[, .(b=sum(b), c=dt[b==max(b), c]), 
    by=.(a)] }), .id='a')
dt.aggr
#   a b c
# 1 a 6 p
# 2 b 9 r
class(dt.aggr)
# [1] "data.frame"
+4
source share
1 answer

This is a simple operation in the field of data.table

dt[, .(b = sum(b), c = c[which.max(b)]), by = a]
#    a b c
# 1: a 6 p
# 2: b 9 r

A similar option would be

dt[order(b), .(b = sum(b), c = c[.N]), by = a]
+4
source

All Articles