【问题标题】:find closest fortnight date in R在R中找到最近的两周日期
【发布时间】:2021-01-22 00:53:43
【问题描述】:

在哥伦比亚,工资(大部分)每两周支付一次,即每月的 15 日和最后一天。我试图从销售日期生成一个新变量,我希望它与销售量高度相关:自上次发薪日以来的天数,我可以计算为一旦我有了发薪日,一个简单的区别。

我有一个销售数据框 a 及其日期,我们只关心销售日期,如下所示:

structure(list(date = structure(c(1423121832, 1423988603, 1424779384, 
1425132001, 1427800333), tzone = "UTC", class = c("POSIXct", 
"POSIXt"))), .Names = "date", row.names = c(NA, -5L), class = "data.frame")

我想为每个日期生成一个最近发薪日的向量,但无法处理每个月的月底。我通过以下方式解决了其余问题:

library(lubridate)
cbind(a, 
      basedate = as.Date(
                   ifelse(day(a$date) %in% c(15:31), 
                          floor_date(a$date, "month")+(3600*24*14), 
                          floor_date(a$date, "month") - (3600 * 24)) / (3600 * 24), 
                   origin = origin))

我从中得到:

                 date   basedate
1 2015-02-05 07:37:12 2015-01-31
2 2015-02-15 08:23:23 2015-02-15
3 2015-02-24 12:03:04 2015-02-15
4 2015-02-28 14:00:01 2015-02-15
5 2015-03-31 11:12:13 2015-03-15

第 4 行和第 5 行中的基础向量不正确。我希望最后两个 basedate2015-02-282015-03-31。我知道我可以通过在我拥有的代码中嵌套另一个 ifelse 来获得它,但我很确定有 简单的方法,但我还没有遇到它。

我怎样才能正确确定最接近日期的两周(发薪日)? (我更喜欢baselubridate 解决方案。但是欢迎任何其他处理该问题的软件包)

【问题讨论】:

  • “自上次发薪日以来的天数”、“距每个日期最近的发薪日” - 选择其中之一。
  • @Roland 感谢您的评论。我已经做到了:“一旦我有了发薪日,我就可以计算出一个简单的差异”。这意味着我需要知道如何计算最接近的发薪日,剩下的我可以自己做
  • 现在,如果有一种方法可以计算自上次发薪日以来的天数而不计算最近的发薪日,那么我也想学习!
  • 我不明白您为什么对最近的发薪日感兴趣。如果您想计算从那时起的时间,您需要知道最后一个发薪日。
  • @Roland,这可能是命名问题...我需要最接近任何给定日期的发薪日,因此对于销售日期的可能向量,我会知道 有多少天 自当时最后个发薪日起已过去。我认为如果我将变量称为“最后一个发薪日”,那么有人可以将其与实际日期联系起来。

标签: r date lubridate


【解决方案1】:

使用lubridate,您可以创建一个索引,指示当月 14 日之后的天数和之前的天数。使用该索引,找到最后一个发薪日。最后,可以计算paydate和当前日期的差:

library(lubridate)
d <- as.Date(df$date)
islastday <- d == (ceiling_date(d, unit="month") - 1)
isbefore15 <- as.integer(format(df$date, '%e'))/15 < 1L
payday <- Sys.Date()
for(i in 1:length(d)) {
  payday[i] <- if(islastday[i]) {
              d[i]
  } else if(isbefore15[i]) {
    floor_date(d[i], unit="month") - 1L

  } else {  floor_date(d[i], unit="month") + 14L 

  }
}

df$payday <- payday
df$difference <- as.Date(df$date) - df$payday
df
#                  date     payday difference
# 1 2015-02-05 07:37:12 2015-01-31     5 days
# 2 2015-02-15 08:23:23 2015-02-15     0 days
# 3 2015-02-24 12:03:04 2015-02-15     9 days
# 4 2015-02-28 14:00:01 2015-02-28     0 days
# 5 2015-03-31 11:12:13 2015-03-31     0 days

更新

更快的解决方案:

d2 <- d
d2[isbefore15] <- floor_date(d[isbefore15], unit="month") - 1L
d2[!isbefore15] <- floor_date(d[!isbefore15], unit="month") + 14L 
df$payday <- d2
df$difference <- as.Date(df$date) - df$payday

【讨论】:

  • 感谢您的回答。我认为我们正在实现相同的目标,只是我通过ifelse 和你通过for 完成了。因此,您的 payday 向量在第 4 行和第 5 行也有错误的日期(请参阅我的帖子)。他们应该是 2 月 28 日和 3 月 31 日(因为它们实际上是一个月的最后一天,所以它发薪日)。正确的区别是c(4, 0, 9, 0, 0)
  • 回答太快了。您可以调整索引
  • 您能详细说明一下吗?怎么调整?
  • 你可以用 "ceiling_date(df$date) - 1" 来查看日期是否是本月的最后一天
  • 更新已发布。如果您想进行任何其他调整,请随时聘请顾问。
猜你喜欢
  • 2015-11-22
  • 1970-01-01
  • 2012-01-20
  • 1970-01-01
  • 2016-09-17
  • 2022-06-28
  • 2022-06-15
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多