Разбить столбец на сегменты по группам интервалов начала / остановки

#r #dplyr #tidyr

#r #дплыр #tidyr #dplyr

Вопрос:

У меня есть очень простой фрейм данных, где ID — это числовая последовательность, и есть несколько групп, где начало / окончание обозначается словом start / stop:

 ID = c(1:20)
group = c(NA,1,NA,NA,NA,1,NA,NA,NA,2,NA,NA,NA,NA,NA,2,NA,NA,NA,NA) %>% as.factor()
type = c(NA,"start",NA,NA,NA,"stop",NA,NA,NA,"start",NA,NA,NA,NA,NA,"stop",NA,NA,NA,NA) %>% as.factor()

df = data.frame(ID,group,type)
head(df)

   ID group  type
1   1  <NA>  <NA>
2   2     1 start
3   3  <NA>  <NA>
4   4  <NA>  <NA>
5   5  <NA>  <NA>
6   6     1  stop
  

Я хотел бы заполнить NAs in group смежными значениями и разделить фрейм данных на сегменты между интервалами запуска / остановки:

    ID group  type
1   2     1 start
2   3     1  <NA>
3   4     1  <NA>
4   5     1  <NA>
5   6     1  stop
6  10     2 start
7  11     2  <NA>
8  12     2  <NA>
9  13     2  <NA>
10 14     2  <NA>
11 15     2  <NA>
12 16     2  stop
  

Если отсутствующие значения в группе можно было бы заменить, то фрейм данных можно было бы просто уменьшить до значений в группе, которые не являются NAs. Я просмотрел tidyr::fill() , но не могу найти хорошее решение. Любые предложения будут высоко оценены!

Ответ №1:

Мы можем fill в столбце ‘group’ заменить NA элементы предыдущими элементами, отличными от NA, filter выделить строки NA на основе значений ‘group’, которые все еще являются NA, сгруппировать по ‘group’ slice строки до значения ‘stop’ в столбце ‘type’ (при условии, что одна комбинация ‘start / stop’ на ‘group’)

 library(tidyverse)
df %>% 
  fill(group) %>% 
  filter(!is.na(group)) %>% 
  group_by(group) %>% 
  slice(seq_len(which(type == "stop"))) 
# A tibble: 12 x 3
# Groups:   group [2]
#      ID group type 
#   <int> <fct> <fct>
# 1     2 1     start
# 2     3 1     <NA> 
# 3     4 1     <NA> 
# 4     5 1     <NA> 
# 5     6 1     stop 
# 6    10 2     start
# 7    11 2     <NA> 
# 8    12 2     <NA> 
# 9    13 2     <NA> 
#10    14 2     <NA> 
#11    15 2     <NA> 
#12    16 2     stop