gpt4 book ai didi

r - 每月日期的顺序确保它是同一天,或者在无效的情况下是一个月的最后一天

转载 作者:行者123 更新时间:2023-12-04 14:10:26 26 4
gpt4 key购买 nike

给定一个初始日期,我想生成一个以月为间隔的日期序列,确保每个元素都与初始日期或月份的最后一天相同,以防同一天产生无效日期。

听起来很标准,对吧?

使用 difftime不可能。这是difftime的帮助文件说:

Units such as "months" are not possible as they are not of constant length. To create intervals of months, quarters or years use seq.Date or seq.POSIXt.



但是后来看了 seq.POSIXt的帮助文件我发现:

Using "month" first advances the month without changing the day: if this results in an invalid day of the month, it is counted forward into the next month: see the examples.



这是帮助文件中的示例。
seq(ISOdate(2000,1,31), by = "month", length.out = 4)
> seq(ISOdate(2000,1,31), by = "month", length.out = 4)
[1] "2000-01-31 12:00:00 GMT" "2000-03-02 12:00:00 GMT"
"2000-03-31 12:00:00 GMT" "2000-05-01 12:00:00 GMT"

因此,鉴于初始日期是第 31 天,这将产生无效的 2 月、4 月等日期。因此,该序列最终实际上跳过了这些月份,因为它“向前计数”并以 3 月 2 日结束,而不是2 月 29 日。

如果我从 2000-01-31 开始,我希望顺序如下:
  • 2000-01-31
  • 2000-02- 29
  • 2000-03-31
  • 2000-04-30
  • ...

  • 它应该正确处理闰年,所以如果初始日期是 2015-01-31,序列应该是:
  • 2015-01-31
  • 2015-02- 28
  • 2015-03-31
  • 2015-04-30
  • ...

  • 这些只是说明问题的示例,我不知道提前的初始日期,也不能对此做出任何假设。初始日期很可能在月中 (2015-01-15) 在这种情况下 seq工作正常。但也可以如示例中所示,在使用 seq 的日期接近月底单独会出现问题(第 29、30 和 31 天)。我不能假设初始日期是该月的最后一天。

    我环顾四周试图找到解决方案。在 SO 中的一些问题中(例如这里),通过获取下个月的第一天并简单地减去 1,有一个“技巧”可以获取一个月的最后一天。 找到第一天很“容易”,因为它只是第 1 天。

    所以到目前为止我的解决方案是:
    # Given an initial date for my sequence
    initial_date <- as.Date("2015-01-31")

    # Find the first day of the month
    library(magrittr) # to use pipes and make the code more readable
    firs_day_of_month <- initial_date %>%
    format("%Y-%m") %>%
    paste0("-01") %>%
    as.Date()

    # Generate a sequence from initial date, using seq
    # This is the sequence that will have incorrect values in months that would
    # have invalid dates
    given_dat_seq <- seq(initial_date, by = "month", length.out = 4)

    # And then generate an auxiliary sequence for the last day of the month
    # I do this generating a sequence that starts the first day of the
    # same month as initial date and it goes one month further
    # (lenght 5 instead of 4) and substract 1 to all the elements
    last_day_seq <- seq(firs_day_of_month, by = "month", length.out = 5)-1

    # And finally, for each pair of elements, I take the min date of both
    pmin(given_dat_seq, last_day_seq[2:5])

    它有效,但同时也有点愚蠢、笨拙和令人费解。所以我不喜欢它。最重要的是,我无法相信在 R 中没有更简单的方法可以做到这一点。

    有人可以指点我一个更简单的解决方案吗? (我想它应该像 seq(initial_date, "month", 4) 一样简单,但显然不是)。我已经在 google 上搜索并查看了 SO 和 R 邮件列表,但除了我上面提到的技巧之外,我找不到解决方案。

    最佳答案

    最简单的解决方案是%m+%来自lubridate,它解决了这个确切的问题。所以:

    seq_monthly <- function(from,length.out) {
    return(from %m+% months(c(0:(length.out-1))))
    }

    输出:
    > seq_monthly(as.Date("2015-01-31"),length.out=4)
    [1] "2015-01-31" "2015-02-28" "2015-03-31" "2015-04-30"

    关于r - 每月日期的顺序确保它是同一天,或者在无效的情况下是一个月的最后一天,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36479139/

    26 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com