Сжатие фрейма данных с использованием нескольких аргументов из определенных переменных - PullRequest
0 голосов
/ 26 июня 2019

Я стремлюсь сжать фрейм данных, основанный на различных аргументах из нескольких переменных, и я не совсем уверен в том, как добиться этого самым простым способом.Я думаю, что для этого понадобятся какие-то персонализированные функции, но у меня нет большого опыта в написании функций.

По сути, мой фрейм данных в настоящее время выглядит так:

chainID     teamID        statID        startType       endType        

1           Team A     Effective Pass      TO              TO
1           Team A     Effective Pass      TO              TO
1           Team A     Effective Pass      TO              TO
1           Team A     Effective Pass      TO              TO
1           Team A     Ineffective Pass    TO              TO
2           Team B     Effective Pass      TO              SH
2           Team B     Entry               TO              SH
2           Team B     Effective Pass      TO              SH
2           Team B     Shot                TO              SH
3           Team A     Effective Pass      ST              TO
3           Team A     Entry               ST              TO
3           Team A     Ineffective Pass    ST              TO
4           Team B     Effective Pass      TO              ST
4           Team B     Effective Pass      TO              ST
4           Team B     Ineffective Pass    TO              ST
5           Team A     Effective Pass      TO              SH
5           Team A     Entry               TO              SH
5           Team A     Goal                TO              SH
6           Team B     Effective Pass      CB              TO
6           Team B     Effective Pass      CB              TO
6           Team B     Ineffective Pass    CB              TO
7           Team A     Effective Pass      TO              ST
7           Team A     Ineffective Pass    TO              ST

Что я хочу сделать, так это всякий раз, когда слово Entry появляется в столбце statID для любого chainID, я хочу сохранить эту строку и последнюю строку для этого chainID, удаляя при этом все остальные строки для этогов частности chainID (см. chainID 2 и 5).Кроме того, мне также нужно, чтобы, если chainID включал Entry в statID, но последняя строка в этом конкретном chainID не заканчивается в Goal или Shot, тогда я хочу, чтобы следующий chainID оставался в наборе данных, как показано в моем примере.с chainID 3 и 4. Затем функция продолжает искать вхождения Entry для chainID, как это было в начале.Например,

chainID     teamID        statID        startType       endType        

2           Team B     Entry               TO              SH
2           Team B     Shot                TO              SH
3           Team A     Entry               ST              TO
3           Team A     Ineffective Pass    ST              TO
4           Team B     Effective Pass      TO              ST
4           Team B     Effective Pass      TO              ST
4           Team B     Ineffective Pass    TO              ST
5           Team A     Entry               TO              SH
5           Team A     Goal                TO              SH

1 Ответ

1 голос
/ 26 июня 2019

Ответ делится на две функции.Первая функция select_rows, выбирает строки из каждой группы в зависимости от наличия "Entry".Вторая функция select_groups находит группы, которые не оканчиваются на "Goal" или "Shot".

library(dplyr)

select_rows <- function(anyEntry, statID) {
   #If anyEntry value is not 0
   if(anyEntry[1L]) { 
      #If the last value is either "Goal" or "Shot" select "Entry" row and last row
      #else select all the rows from "Entry" to last row. 
      if(last(statID) %in% c("Goal", "Shot")) c(anyEntry[1L], length(anyEntry)) 
         else anyEntry[1L] : length(anyEntry) 
     } else 0
}

select_groups <- function(anyEntry, statID) {
    anyEntry[1L] & !last(statID) %in% c("Goal", "Shot")
}

Мы создаем anyEntry столбец, который имеет номер строки в группе, где первый"Entry" значение присутствует или 0 в противном случае.Мы применяем функции select_rows и select_groups отдельно и связываем столбцы.

df1 <- df %>%
        group_by(chainID) %>%
        mutate(anyEntry = which.max(statID == "Entry") * any(statID == "Entry"))

Ids <- df1 %>%
         summarise(newEntry = select_groups(anyEntry, statID)) %>%
         filter(newEntry) %>% pull(chainID)

df1 %>%
  slice(select_rows(anyEntry, statID)) %>%
  bind_rows(df %>% filter(chainID %in% (Ids + 1))) %>%
  select(-anyEntry) %>%
  arrange(chainID)

#   chainID teamID statID    startType  endType
#     <int> <fct>  <fct>        <fct>     <fct>  
#1       2 TeamB  Entry           TO        SH     
#2       2 TeamB  Shot            TO        SH     
#3       3 TeamA  Entry           ST        TO     
#4       3 TeamA  IneffectivePass ST        TO     
#5       4 TeamB  EffectivePass   TO        ST     
#6       4 TeamB  EffectivePass   TO        ST     
#7       4 TeamB  IneffectivePass TO        ST     
#8       5 TeamB  Entry           TO        SH     
#9       5 TeamB  Goal            TO        SH   
...