Вот один вариант, использующий cumsum
и dplyr::lead
со значением по умолчанию, равным году + 4, с учетом того, что игрок может иметь более одной серии медалей
library(dplyr)
df %>% group_by(id) %>%
mutate(flag=lead(year,default = last(year)+4)-year, won=cumsum(flag==4)) %>%
select(-flag) %>% slice(which.max(won))
# A tibble: 3 x 6
# Groups: id [3]
id name team year medal won
<int> <chr> <chr> <int> <chr> <int>
1 1 john doe USA 2012 gold 3
2 2 marc twain GER 2016 gold 1
3 3 edgar poe FIN 2008 gold 1
Обновление от @ akrun
Это можно сделать компактно с помощью
df %>% group_by(id, name, team) %>%
mutate(yearlead = lead(year, default = year[n()]+4), yeardiff = yearlead - year) %>%
group_by( grp = rleid(case_when(yeardiff == 4 ~ as.integer(yeardiff), TRUE ~ row_number())), add = TRUE) %>%
summarise(n = n())
# A tibble: 4 x 5
# Groups: id, name, team [?]
id name team grp n
<int> <chr> <chr> <int> <int>
1 1 john doe USA 1 3
2 2 marc twain GER 1 1
3 3 edgar poe FIN 1 1
4 3 edgar poe FIN 2 1
данных (эти данные отличаются от набора данных OP)
df <- structure(list(id = c(1L, 1L, 1L, 2L, 3L, 3L, 3L, 3L, 3L), name = c("john doe", "john doe", "john doe", "marc twain", "edgar poe", "edgar poe", "edgar poe", "edgar poe", "edgar poe"),
team = c("USA", "USA", "USA", "GER", "FIN", "FIN", "FIN", "FIN", "FIN"), year = c(2004L, 2008L, 2012L, 2016L, 2000L, 2008L, 2016L, 2020L, 2024L), medal = c("gold", "gold", "gold", "gold", "gold", "gold", "gold", "gold", "gold" )), class = "data.frame", row.names = c(NA, -9L))