Как удалить строки после первого вхождения, когда следующая строка соответствует - PullRequest
1 голос
/ 11 июля 2019

Работая в RI, я пытаюсь удалить все строки после изменения.Бизнес открыт на 3 года, затем закрывается, флаг закрытого типа остается в таблице в течение следующих лет.Я хочу удалить 2 лишних года, сохраняя данные только за тот год, когда он был закрыт.Некоторые местоположения закрываются и открываются в том же году, их не следует менять.

Я пробовал срез на минимальную дату, когда status = "close", но это не сработает из-за открывающихся мест.

Пример данных

date <- c("2014","2015","2016","2017","2018","2019","2016","2017","2018","2019","2015","2016","2017","2018","2018","2019","2019")
ID <- c("1","1","1","1","1", "1","2","2","2","2","3","3","3","3","3","3", "3")
status <- c("open", "open", "open", "close", "close", "close", "open", "open","open","open","open", "open", "open","close", "open", "close", "open")


start <- data.frame(date, ID, status)

Выше я хочу удалить 2018 и 2019 для ID = 1

date <- c("2014","2015","2016","2017","2016","2017","2018","2019","2015","2016","2017","2018","2018","2019","2019")
ID <- c("1","1","1","1","2","2","2","2","3","3","3","3","3","3", "3")
status <- c("open", "open", "open", "close", "open", "open","open","open","open", "open", "open","close", "open", "close", "open")


ideal_outcome <- data.frame(date, ID, status)

1 Ответ

3 голосов
/ 11 июля 2019

Один из способов использования rleid из data.table состоит в group_by ID и последовательных прогонах status, оставьте только одну строку для группы, где status = "close", и выберите все строки для "open".

library(dplyr)
library(data.table)

start %>%
  group_by(ID, group = rleid(status)) %>%
  slice(if (first(status) == "open") seq_len(n()) else  1L) %>%
  mutate(status = replace(as.character(status), 
                    status == "close", "permanently_closed")) %>%  
  ungroup() %>%
  select(-group)

# A tibble: 15 x 3
#   date  ID    status
#   <fct> <fct> <chr> 
# 1 2014  1     open  
# 2 2015  1     open  
# 3 2016  1     open  
# 4 2017  1     permanently_closed 
# 5 2016  2     open  
# 6 2017  2     open  
# 7 2018  2     open  
# 8 2019  2     open  
# 9 2015  3     open  
#10 2016  3     open  
#11 2017  3     open  
#12 2018  3     permanently_closed 
#13 2018  3     open  
#14 2019  3     permanently_closed 
#15 2019  3     open  

Однако на самом деле вам не нужно импортировать data.table только для одной функции, поведение rleid можно повторить и с базовой rle

start %>%
  group_by(ID, group = with(rle(as.character(status)), 
                       rep(seq_along(values), lengths))) %>%
   slice(if (first(status) == "open") seq_len(n()) else  1L) %>%
   ungroup() %>%
   select(-group)

Другой способ создания групп, предложенный @Sotos с использованием factor, diff и cumsum

start %>% 
  group_by(grp = as.numeric(as.factor(status)), 
           grp = cumsum(c(TRUE, diff(grp) != 0))) %>%
  slice(if (first(status) == "open") seq_len(n()) else  1L)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...