在排列数据上使用mutate()中的滞后

问题描述 投票:0回答:2

我正在处理类似于的数据集

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

我有每个ID的第一个日期,我试图通过将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()计算。我应该采用什么不同的方法来计算这个。

r date lag lubridate mutate
2个回答
0
投票

我真的不知道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()

更新

为了回应您在评论中的澄清,以下是您可以做的事情

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

0
投票

您可以使用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)以及随后的Mauriz Evers解决方案中的ungroup()声明来解决这个假设。
  2. 对于每个id,具有观察日期的行首先在组中。在任何情况下都需要使用na.locffill,因为两个函数都使用先前的非NA条目填充NA。

如果您不想对排序做出任何假设,可以使用data %>% arrange(id, dates)对开头的行进行排序。

© www.soinside.com 2019 - 2024. All rights reserved.