#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