Генерация дополнительных строк на основе условия в том же фрейме данных - PullRequest
3 голосов
/ 13 июня 2019

У меня есть фрейм данных, например DF, который будет импортирован непосредственно из базы данных (в виде таблицы).

library(tidyverse)
library(lubridate)


date_until <- dmy("31.05.2019")
date_val  <- dmy("30.06.2018")

DF <-  data.frame( date_bal   = as.Date(c("2018-04-30", "2018-05-31", "2018-06-30", "2018-05-31", "2018-06-30")),
                   department = c("A","A","A","B","B"),
                   amount     = c(10,20,30,40,50)
)

DF <- DF %>%
  as_tibble()
DF

Он представляет сумму денег, потраченную каждым отделом в конкретном месяце.Моя задача состоит в том, чтобы спроектировать, сколько денег будет потрачено каждым отделом в последующие месяцы до указанной даты в будущем (в данном случае date_until = 31.05.2019)

Я хотел бы использовать Tidyverse для того, чтобысоздать дополнительные строки для каждого отдела, где первый столбец date_bal будет представлять собой последовательность дат от последней из «оригинального» DF до date_until, который предопределен.Затем я хотел бы добавить дополнительный столбец с именем "DIFF", который будет представлять разницу между DATE_BAL и DATE_VAL, где DATE_VAL также предопределен.Мой конечный результат будет выглядеть так: Конечный результат

Мне удалось сделать это следующим образом:

  1. первый фильтр данных из DF для отдела A
  2. Создайте еще один DF2, заполнив его последовательностью дат от min (dat_bal) до date_until от 1.
  3. Объедините кадры данных из 1. и 2., а затем добавьте вычисляемые столбцы, используя mutate

Поскольку мне придется повторять эту процедуру для многих отделов, мне интересно, возможно ли добавить строки (создать последовательность дат) в существующий DF (без создания второго DF и последующего слияния).

Заранее благодарим за помощь и время.

1 Ответ

2 голосов
/ 14 июня 2019

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

seq(min(date_val + days(1)), date_until + days(1), by = 'months')[-1] %>% 
  rollback() %>% 
  tibble(date_bal = .) %>% 
  crossing(DF %>% distinct(department)) %>% 
  bind_rows(DF %>% select(date_bal, department)) %>% 
  left_join(DF) %>% 
  arrange(department, date_bal) %>% 
  mutate(
    amount = if_else(is.na(amount), 0, amount),
    DIFF = interval(
      rollback(date_val, roll_to_first = TRUE), 
      rollback(date_bal, roll_to_first = TRUE)) %/% months(1)
  )
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...