Задал другой вопрос, используя аналогичный набор данных, но другой вопрос -

У меня есть набор данных, который представляет собой список дат, за которым следует столбец, который содержит «R» для обычного или «S» для специального:

date <- c('01/01', '01/02', '01/03', '01/04', '01/05', '01/06', '01/07', '01/08', '01/09')

day <- c('S', 'R', 'R', 'R', 'R', 'S', 'R', 'R', 'S')

data <- data.frame(date, day)

Это выглядит следующим образом:

date . . . day

01/01. . . S

01/02. . . R

01/03. . . R

01/04. . . R

01/05. . . R

01/06. . . S

01/07. . . R

01/08. . . R

01/09. . . S

....

Сейчас я пытаюсь добавить столбец, который бы указывал, сколько дней осталось до следующего «особого» дня. Таким образом, для показанных данных это будет 0 (01/01 является особенным), 4 (01/02 - это 4 дня до следующего особого дня, 01/06), 3, 2, 1, 0 (01 / 06 особенный) и т. Д.

Спасибо!

2
Kathy 6 Май 2020 в 16:11

2 ответа

Лучший ответ

Вот dplyr подход. Вы можете использовать cumsum, чтобы сгруппировать дни, предшествующие специальному дню, а затем выполнить обратный отсчет, взяв количество дней n() и вычтя номер строки row_number() в группе.

library(dplyr)

data %>%
  group_by(grp = cumsum(lag(day, default = first(day)) == 'S')) %>%
  mutate(days_until = n() - row_number())

< Сильный > Выход

# A tibble: 9 x 4
# Groups:   grp [3]
  date  day     grp days_until
  <fct> <fct> <int>      <int>
1 01/01 S         1          0
2 01/02 R         2          4
3 01/03 R         2          3
4 01/04 R         2          2
5 01/05 R         2          1
6 01/06 S         2          0
7 01/07 R         3          2
8 01/08 R         3          1
9 01/09 S         3          0
0
Ben 6 Май 2020 в 13:29

Вот идея через базу R. Используйте cumsum для создания групп, когда день равен S, возьмите последовательность длины каждого и замените максимальное значение (которое соответствует S) на 0, т.е.

i1 <- cumsum(data$day == 'S')
data$res <- ave(i1, i1, FUN = function(i) { i2 <- seq_along(i); rev(replace(i2, max(i2), 0)) })

Который дает,

   date day res
1 01/01   S   0
2 01/02   R   4
3 01/03   R   3
4 01/04   R   2
5 01/05   R   1
6 01/06   S   0
7 01/07   R   2
8 01/08   R   1
9 01/09   S   0
0
Sotos 6 Май 2020 в 13:21