Рассчитать последовательную серию побед, основанную на годах - PullRequest
2 голосов
/ 19 апреля 2019

Речь идет о спортсменах, соревнующихся в Олимпии.Я должен подсчитать 10 лучших спортсменов, которые держали медаль дольше всего. Например,

: выиграл в 2004, 2008, 2012 -> поэтому спортсмен выиграл 3 раза подряд.

Я только изучаю R и схожу с ума.

Я даже не знаю, с чего начать с решения этой проблемы.

Мои данные«очищены» настолько, насколько это возможно: - только спортсмены, которые выиграли золотую медаль - получают фактический год, который они выиграли, из строки

Мои столбцы (после очистки)

id    name          team        year    medal
1     john doe      USA         2004    gold
1     john doe      USA         2008    gold
1     john doe      USA         2012    gold
2     marc twain    GER         2016    gold
3     edgar poe     FIN         2000    gold
3     edgar poe     FIN         2008    gold

IЯ пробовал некоторые вещи, такие как:

mutate(won =
           if_else(condition = year == year +4,
                   true = "won",
                   false = "lost"))

или что-то вроде

mutate(won =
           if_else(
             condition = (year + 4) == tmp_year,
             true = "Following Year",
             false = if_else(
               condition = year == tmp_year,
               true = "Actual year",
               false = "No")))

Здесь я получаю только Фактический год и Нет в качестве ответа.

В конце концов, ямне нужна таблица, показывающая, сколько раз ателте выигрывал золотую медаль подряд.

Например, для набора данных это будет примерно так:

id    name          won        
1     john doe      3
2     marc twain    1
3     edgar poe     1

Править: Я не ищу полного ответа, больше похоже на вдохновение: на какие функции было бы интересно взглянуть.

Ответы [ 2 ]

1 голос
/ 19 апреля 2019

Вот один вариант, использующий 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))
1 голос
/ 19 апреля 2019

Используя dplyr, мы можем рассчитать разницу в годах выигрыша золотых медалей, используя diff для каждого name, затем group_by name и разницу, и рассчитать последовательные выигрыши.

library(dplyr)

df %>%
 group_by(name) %>%
 mutate(diff = c(4,diff(year))) %>%
 group_by(name, diff) %>%
 summarise(count = n()) %>%
 select(-diff)


#    name      count
#   <fct>     <int>
#1 edgarpoe      1
#2 edgarpoe      1
#3 johndoe       3
#4 marctwain     1
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...