Использование задержки в mutate () для упорядоченных данных - PullRequest
0 голосов
/ 02 марта 2019

Я работаю над набором данных, который похож на

data <-tribble(
  ~id, ~ dates, ~days_prior,
  1,20190101, NA,
  1,NA, 15,
  1,NA, 20,
  2, 20190103, NA,
  2,NA, 3,
  2,NA, 4)

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

 df<- df%>% mutate(dates = as.Date(ymd(dates)), days_prior =as.integer(days_prior))


 df<-df %>% mutate(dates =
   as.Date(ifelse(is.na(days_prior),dates,days_prior+lag(dates)),
   origin="1970-01-01"))

Это работает, но только для следующей строки, поскольку вы можете видеть прикрепленные данные.

enter image description here

Что я делаю не так?Я хотел бы, чтобы все даты были рассчитаны с помощью mutate ().Какой другой подход я должен использовать, чтобы рассчитать это.

Ответы [ 2 ]

0 голосов
/ 02 марта 2019

Вы можете использовать na.locf из пакета zoo для заполнения последней наблюдаемой даты перед добавлением предыдущих дней.

library("tidyverse")
library("zoo")
data %>%
  # Fill in NA dates with the previous non-NA date
  # The `locf` stands for "last observation carried forward"
  # Fill in NA days_prior with 0
  mutate(dates = zoo::na.locf(dates),
         days_prior = replace_na(days_prior, 0)) %>%
  mutate(dates = lubridate::ymd(dates) + days_prior)

Это решение имеет два предположения:

  1. Строки отсортированы по id.Вы можете обойти это предположение с помощью group_by(id), за которым следует оператор ungroup(), как показано в решении Maurits Evers.
  2. Для каждого идентификатора строка с наблюдаемой датой является первой в группе.Это должно быть верно в любом случае с na.locf и fill, потому что обе функции заполняют NA, используя предыдущую запись не-NA.

Если вы не хотите делать какие-либо предположенияо порядке, вы можете отсортировать строки в начале с data %>% arrange(id, dates).

0 голосов
/ 02 марта 2019

Я действительно не понимаю, как lag поможет здесь;если я не понял здесь, есть опция, использующая tidyr::fill

data %>%
    group_by(id) %>%
    mutate(dates = as.Date(ymd(dates))) %>%
    fill(dates) %>%
    mutate(dates = dates + if_else(is.na(days_prior), 0L, as.integer(days_prior))) %>%
    ungroup()
## A tibble: 6 x 3
#     id dates      days_prior
#  <dbl> <date>          <dbl>
#1     1 2019-01-01         NA
#2     1 2019-01-16         15
#3     1 2019-01-21         20
#4     2 2019-01-03         NA
#5     2 2019-01-06          3
#6     2 2019-01-07          4

или небольшое изменение, заменяющее NA записи в days_prior на 0

data %>%
    group_by(id) %>%
    mutate(
        dates = as.Date(ymd(dates)),
        days_prior = replace(days_prior, is.na(days_prior), 0)) %>%
    fill(dates) %>%
    mutate(dates = dates + as.integer(days_prior)) %>%
    ungroup()

Update

В ответ на ваши разъяснения в комментариях, вот что вы можете сделать

data %>%
    group_by(id) %>%
    mutate(
        dates = as.Date(ymd(dates)),
        days_prior = replace(days_prior, is.na(days_prior), 0)) %>%
    fill(dates) %>%
    mutate(dates = dates + cumsum(days_prior)) %>%
    ungroup()
## A tibble: 6 x 3
#     id dates      days_prior
#  <dbl> <date>          <dbl>
#1     1 2019-01-01          0
#2     1 2019-01-16         15
#3     1 2019-02-05         20
#4     2 2019-01-03          0
#5     2 2019-01-06          3
#6     2 2019-01-10          4
...