Заполнение предыдущих дат в R - PullRequest
0 голосов
/ 05 сентября 2018

Давайте возьмем тривиальный кадр данных

structure(list(a = structure(c(1L, 1L, 1L, 2L, 2L, 2L), .Label = c("a", 
"b"), class = "factor"), dt = structure(c(NA, 17287, 17318, NA, 
17379, 17410), class = "Date")), .Names = c("a", "dt"), row.names = c(NA, 
-6L), class = "data.frame")

, что дает следующее

  a         dt
1 a       <NA>
2 a 2017-05-01
3 a 2017-06-01
4 b       <NA>
5 b 2017-08-01
6 b 2017-09-01

По моим фактическим данным, это происходит несколько раз. Как я могу засыпать с датой начала предыдущего месяца.

В идеале я хотел бы сделать это, используя dplyr. Самое близкое, что я мог получить, это использовать lubridate::floor_date и dplyr::lead, что привело к тому, что последняя дата стала NA.

tmp %>%
  group_by(a) %>%
  mutate(dt = floor_date(lead(dt, 1) - 1, "month"))

# A tibble: 6 x 2
# Groups:   a [2]
  a     dt        
  <fct> <date>    
1 a     2017-04-01
2 a     2017-05-01
3 a     NA        
4 b     2017-07-01
5 b     2017-08-01
6 b     NA 

Мысли были бы оценены.

Ответы [ 2 ]

0 голосов
/ 05 сентября 2018

Я думаю, что принятое в настоящее время решение не будет работать, если имеется более 1 смежного значения NA для dt.

Вот альтернатива, обратите внимание, что порядок важен:

решение

dat

  a         dt
1 a       <NA>
2 a       <NA>
3 a 2017-05-01
4 a 2017-06-01
5 b       <NA>
6 b 2017-08-01
7 b 2017-09-01

library(dplyr)
library(tidyr)

dat %>%
  group_by(a) %>%
  mutate(helper = ifelse(is.na(dt), NA, cumsum(!is.na(dt)))) %>%
  fill(helper, .direction = 'up') %>%
  group_by(a, helper) %>%
  mutate(dt = coalesce(dt,
                       max(dt, na.rm = TRUE) - months(max(row_number()) - row_number()))) %>%
  dplyr::select(-helper)

# A tibble: 7 x 3
# Groups:   a, helper [4]
  helper a     dt        
   <int> <fct> <date>    
1      1 a     2017-03-01
2      1 a     2017-04-01
3      1 a     2017-05-01
4      2 a     2017-06-01
5      1 b     2017-07-01
6      1 b     2017-08-01
7      2 b     2017-09-01

Данные

dat <-structure(list(a = structure(c(1L, 1L, 1L, 1L, 2L, 2L, 2L), .Label = c("a", 
"b"), class = "factor"), dt = structure(c(NA, NA, 17287, 17318, 
NA, 17379, 17410), class = "Date")), .Names = c("a", "dt"), row.names = c(NA, 
-7L), class = "data.frame")
0 голосов
/ 05 сентября 2018

Ты на самом деле очень близок к ответу. Вам просто нужен пакет lubridate в дополнение к dplyr:

tmp <- structure(list(a = structure(c(1L, 1L, 1L, 2L, 2L, 2L), .Label = c("a", "b"), class = "factor"), 
                      dt = structure(c(NA, 17287, 17318, NA, 17379, 17410), class = "Date")),
                 .Names = c("a", "dt"), 
                 row.names = c(NA, -6L), 
                 class = "data.frame")

library(lubridate)
library(dplyr)

tmp %>%
  group_by(a) %>%
  mutate(newDT = if_else(is.na(dt), lead(dt) %m-% months(1), dt))
tmp

# A tibble: 6 x 3
# Groups:   a [2]
  a     dt         newDT     
  <fct> <date>     <date>    
1 a     NA         2017-04-01
2 a     2017-05-01 2017-05-01
3 a     2017-06-01 2017-06-01
4 b     NA         2017-07-01
5 b     2017-08-01 2017-08-01
6 b     2017-09-01 2017-09-01

Я плохо умею работать с датами в стиле Excel в R, но я предполагаю, что, как только вы попадете сюда, вы можете конвертировать newDT в нужный вам формат. (РЕДАКТИРОВАТЬ: спасибо @phiver за исправление моего кода!)

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...