Using the package dplyr
or data.table
it is possible to do this.
# dados ficticios
set.seed(1)
df <- data.frame(ano = rep(2015:2018, each = 5),
nome = rep(letters[1:4], 5),
eficiencia = rnorm(n = 20, mean = 0.6, sd = 0.1))
df
> df
ano nome eficiencia
1 2015 a 0.5373546
2 2015 b 0.6183643
3 2015 c 0.5164371
. . .
18 2018 b 0.6943836
19 2018 c 0.6821221
20 2018 d 0.6593901
- Applying the package
dplyr
with top_n
:
library(dplyr)
df2 <- df %>%
dplyr::group_by(ano) %>% # agrupar por ano
dplyr::top_n(1) # apenas o melhor (1) em cada ano
df2
> df2
# A tibble: 4 x 3
# Groups: ano [4]
ano nome eficiencia
<int> <fct> <dbl>
1 2015 d 0.760
2 2016 d 0.674
3 2017 c 0.751
4 2018 b 0.694
Or with slice
:
df3 <- df %>%
dplyr::group_by(ano) %>%
dplyr::slice(which.max(eficiencia))
df3
> df3
# A tibble: 4 x 3
# Groups: ano [4]
ano nome eficiencia
<int> <fct> <dbl>
1 2015 d 0.760
2 2016 d 0.674
3 2017 c 0.751
4 2018 b 0.694
- Applying the package
data.table
:
library(data.table)
dft <- data.table::data.table(df)
df4 <- dft[dft[, .I[eficiencia == max(eficiencia)], by = ano]$V1]
df4
> df4
ano nome eficiencia
1: 2015 d 0.7595281
2: 2016 d 0.6738325
3: 2017 c 0.7511781
4: 2018 b 0.6943836
Or with:
df5 <- data.table::setDT(dft)[, .SD[which.max(eficiencia)], by = ano]
df5
> df5
ano nome eficiencia
1: 2015 d 0.7595281
2: 2016 d 0.6738325
3: 2017 c 0.7511781
4: 2018 b 0.6943836