【问题标题】:Dates %within% Intervals日期 %within% 间隔
【发布时间】:2019-11-01 12:12:17
【问题描述】:

遇到一个真正令人头疼的问题,不知道如何解决。真的希望你们中的一些人能够提供帮助。另外,我第一次为 StackOverflow 做出了贡献……耶!

library(tidyverse)
library(lubridate)

start_date <- ymd("2014-06-28")
end_date <- ymd("2019-06-30")
PayPeriod_EndDate <- seq(start_date, end_date, by = '2 week')
PayPeriod_Interval <- int_diff(PayPeriod_EndDate)

这会创建一个间隔向量,每个间隔代表一个为期两周的支付期。这是第一部分,第一部分相对容易(虽然还需要一段时间才能弄清楚,哈)。

第二部分包含一个日期向量。

Dates <- c("2014-07-08", "2018-10-20", "2018-12-13", "2018-12-13", "2018-12-06", "2018-11-30", "2019-01-16", "2019-01-23", "2019-03-15", "2018-10-02")

我想确定日期%within%间隔输出是每个日期所在的间隔。所以日期"2014-07-08" 将被分配2014-06-28 UTC--2014-07-12 UTC,因为这个日期在这个间隔内。

这里似乎探索了一个非常相似的问题...https://github.com/tidyverse/lubridate/issues/658

我尝试了以下方法

ymd(Dates) %within% PayPeriod_Interval

但是,结果只计算 Dates 向量中的第一个元素。从那以后,我尝试了各种 for 循环组合、变异为因子等……但进展甚微。这是与工作相关的,所以我真的很缺乏时间,并将全天监控这篇文章,直到周末。

最好,谢谢! 詹姆斯

【问题讨论】:

  • 顺便说一句,数据集包含 730 万行“日期”,区间向量包含 130 个区间。短暂尝试了 map_chr,但遇到了相同长度的问题并放弃了尝试。
  • 恭喜你的第一篇文章!这是不清楚的“拿来算”。另外,你能澄清一下你的预期输出应该是什么样子吗?
  • 欢迎来到 SO!如果您有其他信息,可以编辑您的问题!
  • 当然会编辑,“takes calculates”的说法肯定不清楚。感谢您指出!

标签: r datetime lubridate


【解决方案1】:

tidyverse 非常有用,但有时,您只需要基础 R。在这种情况下,cut 函数就是您所需要的。

library(lubridate)

start_date <- ymd("2014-06-28")
end_date <- ymd("2019-06-30")
PayPeriod_EndDate <- seq(start_date, end_date, by = '2 week')

Dates <- c("2014-07-08", "2018-10-20", "2018-12-13", "2018-12-13", "2018-12-06", "2018-11-30", "2019-01-16", "2019-01-23", "2019-03-15", "2018-10-02")


startperiod<-cut(as.Date(Dates), breaks=PayPeriod_EndDate)
endperiod<-as.Date(startperiod)+13

cut 函数的输出是“Dates”变量所在的每个支付期的开始日期。

【讨论】:

  • 这非常接近解决方案!....我想要间隔的结束日期而不是间隔的开始日期。我想知道 str_extract 是否可以工作,使用 cut 函数的模式结果,可能有一个更简单的解决方案。我觉得这是正确的过程,只需要稍微调整代码......
  • 您可以将输出转换回日期对象,并为该期间的最后一个日期添加 13 天。请参阅上面的编辑。
  • 完美,非常感谢 Dave2e!
  • 一个简短的更新 - 建议的解决方案非常有效!正好在工作日即将结束时完成了我的项目部分。没有您的帮助就不会发生,它节省了很多时间。谢谢!
【解决方案2】:

这就是map - 解决方案的样子:

map(ymd(Dates), ~ PayPeriod_Interval[.x %within% PayPeriod_Interval])
# [[1]]
# [1] 2014-06-28 UTC--2014-07-12 UTC
# 
# [[2]]
# [1] 2018-10-13 UTC--2018-10-27 UTC
# 
# ...

要将结果作为区间向量(而不是列表),您可以使用:

PayPeriod_Interval[map_int(ymd(Dates), ~ which(.x %within% PayPeriod_Interval))]

# [1] 2014-06-28 UTC--2014-07-12 UTC 2018-10-13 UTC--2018-10-27 UTC 2018-12-08 UTC--2018-12-22 UTC 2018-12-08 UTC--2018-12-22 UTC 2018-11-24 UTC--2018-12-08 UTC
# [6] 2018-11-24 UTC--2018-12-08 UTC 2019-01-05 UTC--2019-01-19 UTC 2019-01-19 UTC--2019-02-02 UTC 2019-03-02 UTC--2019-03-16 UTC 2018-09-29 UTC--2018-10-13 UTC

如果您只对间隔的结束日期感兴趣,则可以选择

PayPeriod_EndDate[map_int(ymd(Dates), ~ which.min(.x > PayPeriod_EndDate))]
# [1] "2014-07-12" "2018-10-27" "2018-12-22" "2018-12-22" "2018-12-08" "2018-12-08" "2019-01-19" "2019-02-02" "2019-03-16" "2018-10-13"

which.min 返回PayPeriod_EndDate 的第一个不小于Dates-vector 中特定日期的Date 的条目编号,即特定支付周期结束时的Date。

【讨论】:

  • 我还不能在不抛出错误消息的情况下进行复制
  • 我猜 Dave2e 为您解决了问题 - 如果您遇到问题或需要澄清,请说明错误消息。使用您提供给我们的相同数据在新的 R 会话中尝试解决方案总是好的 - 这样您就可以查看是导致问题的解决方案还是原始数据/包环境中的某些问题等...
  • 我无法在不抛出错误消息的情况下进行复制。我认为 Dave2e 的回应解决了我遇到的问题。感谢您将答案放入 map 和 map_int,因为我更喜欢在可能的情况下使用 map,不知道为什么我会遇到错误,但会继续努力。谢谢!!
猜你喜欢
  • 2018-12-26
  • 1970-01-01
  • 2021-04-04
  • 2012-04-25
  • 1970-01-01
  • 1970-01-01
  • 2014-12-17
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多