A base R solution is to combine the output of aggregate()
with a merge()
step. I find the formula interface to aggregate()
a little more useful than the standard interface, partly because the names on the output are nicer, so I'll use that:
The aggregate()
step is
maxs <- aggregate(Score ~ Group, data = dat, FUN = max)
and the merge()
step is simply
merge(maxs, dat)
This gives us the desired output:
R> maxs <- aggregate(Score ~ Group, data = dat, FUN = max)
R> merge(maxs, dat)
Group Score Info
1 1 3 c
2 2 4 d
You could, of course, stick this into a one-liner (the intermediary step was more for exposition):
merge(aggregate(Score ~ Group, data = dat, FUN = max), dat)
The main reason I used the formula interface is that it returns a data frame with the correct names
for the merge step; these are the names of the columns from the original data set dat
. We need to have the output of aggregate()
have the correct names so that merge()
knows which columns in the original and aggregated data frames match.
The standard interface gives odd names, whichever way you call it:
R> aggregate(dat$Score, list(dat$Group), max)
Group.1 x
1 1 3
2 2 4
R> with(dat, aggregate(Score, list(Group), max))
Group.1 x
1 1 3
2 2 4
We can use merge()
on those outputs, but we need to do more work telling R which columns match up.
与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…