在 R 中找到最近的两周日期
find closest fortnight date in R
在哥伦比亚,(大部分)每两周、每月的第 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 行中的基础向量不正确。我希望最后两个 basedate
为 2015-02-28
和 2015-03-31
。我知道我可以通过在我的代码中嵌套另一个 ifelse
来获得它,但我很确定有 简单的方法,我只是没有遇到它.
如何正确确定距离日期最近的两周(发薪日)?
(我更喜欢 base
或 lubridate
解决方案。但是欢迎任何其他处理该问题的软件包)
使用 lubridate
您可以创建一个索引,指示当月 14 日之后的天数和之前的天数。使用该索引,找到最后一个发薪日。最后,您可以计算发薪日期和当前日期之间的差异:
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
在哥伦比亚,(大部分)每两周、每月的第 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 行中的基础向量不正确。我希望最后两个 basedate
为 2015-02-28
和 2015-03-31
。我知道我可以通过在我的代码中嵌套另一个 ifelse
来获得它,但我很确定有 简单的方法,我只是没有遇到它.
如何正确确定距离日期最近的两周(发薪日)?
(我更喜欢 base
或 lubridate
解决方案。但是欢迎任何其他处理该问题的软件包)
使用 lubridate
您可以创建一个索引,指示当月 14 日之后的天数和之前的天数。使用该索引,找到最后一个发薪日。最后,您可以计算发薪日期和当前日期之间的差异:
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