【问题标题】:Generating additional rows based on a condition within the same data frame根据同一数据框中的条件生成其他行
【发布时间】:2019-10-28 12:17:14
【问题描述】:

我有一个像下面的DF这样的数据框,它将直接从数据库中导入(作为tibble)。

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 也是预定义的。我的最终结果如下所示: Final result

我已经设法通过以下方式做到这一点:

  1. 首先过滤来自部门 A 的 DF 数据
  2. 通过使用从 min(dat_bal) 到 date_until 从 1 的日期序列填充它来创建另一个 DF2。
  3. 合并来自 1. 和 2. 的数据帧,然后使用 mutate 添加计算列

由于我将不得不为许多部门重复此过程,我想知道是否可以在现有 DF 中添加行(创建日期序列)(无需创建第二个 DF 然后合并)。

提前感谢您的帮助和时间。

【问题讨论】:

    标签: r tidyverse


    【解决方案1】:

    我在日期中添加一天,创建一个序列,然后回滚到上个月的最后一天。

    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)
      )
    

    【讨论】:

    • 那真是太好了。我假设您在日期序列中添加一天,然后回滚以避免二月出现问题?
    • 正确。但不仅二月会引起问题。如果您在“2019 年 4 月 30 日”中添加一个月,则不会给出 5 月的最后一天。
    • 谢谢! :) 这个想法类似于我的解决方案(你的代码比我的更整洁和优雅)。但是,我想知道是否有可能在不使用 left_join 的情况下做到这一点(我尝试了几个使用 complete() 或 pad() 的选项,不幸的是没有成功)。此外,在这种情况下,会为 B 部门生成一行,其中 date_bal=30.04.2018 而 B 部门的第一个 date_bal 应该是 31.05.2018。
    • 我编辑了我的代码。 B 部门 31.05.2018 的问题已解决。此外,我创建了 DIFF 列并在金额列中替换了 NA。我会坚持left_join
    • 这是迄今为止我最好的解决方案。非常感谢您的帮助,非常感谢。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-06-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多