R语言 生成两年内每月最后一天的序列

mqkwyuun  于 2023-05-11  发布在  其他
关注(0)|答案(3)|浏览(108)

我用润滑剂,并认为这将是如此容易

ymd("2010-01-31")+months(0:23)

但看看谁得到了什么。全乱套了!

[1] "2010-01-31 UTC" "2010-03-03 UTC" "2010-03-31 UTC" "2010-05-01 UTC" "2010-05-31 UTC" "2010-07-01 UTC" "2010-07-31 UTC" "2010-08-31 UTC" "2010-10-01 UTC"
[10] "2010-10-31 UTC" "2010-12-01 UTC" "2010-12-31 UTC" "2011-01-31 UTC" "2011-03-03 UTC" "2011-03-31 UTC" "2011-05-01 UTC" "2011-05-31 UTC" "2011-07-01 UTC"
[19] "2011-07-31 UTC" "2011-08-31 UTC" "2011-10-01 UTC" "2011-10-31 UTC" "2011-12-01 UTC" "2011-12-31 UTC"

然后我读到lubridate如何迎合诸如间隔、持续时间和周期等现象。所以,好的,我意识到一个月实际上是由(365*4+1)/48 = 30.438天定义的天数。所以我试着变聪明把它改写成

ymd("2010-01-31")+ as.period(months(0:23))

但这只是一个错误。

Error in as.period.default(months(0:23)) : 
  (list) object cannot be coerced to type 'double'
iszxjhcz

iszxjhcz1#

是的,你找到了正确的窍门:从下个月的第一天开始。
下面是一个基于R的一行程序:

R> seq(as.Date("2010-02-01"), length=24, by="1 month") - 1
 [1] "2010-01-31" "2010-02-28" "2010-03-31" "2010-04-30" "2010-05-31"
 [6] "2010-06-30" "2010-07-31" "2010-08-31" "2010-09-30" "2010-10-31"
[11] "2010-11-30" "2010-12-31" "2011-01-31" "2011-02-28" "2011-03-31"
[16] "2011-04-30" "2011-05-31" "2011-06-30" "2011-07-31" "2011-08-31"
[21] "2011-09-30" "2011-10-31" "2011-11-30" "2011-12-31"
R>

所以不需要lubridate,它(虽然是一个很好的包)对于像这样的简单任务是不需要的。另外,它对现有基函数的重载仍然让我觉得有些危险。

0yycz8jy

0yycz8jy2#

打一个问题能集中创造力,这真是令人惊讶。我想我找到答案了。我不妨把它贴在这里,送给下一个发现自己在浪费时间的可怜的灵魂。

ymd("2010-02-01")+ months(0:23)-days(1)

只需指定下一个月的第一天,并从中生成一个序列,但从中减去1天即可获得前一个月的最后一天。

[1] "2010-01-31 UTC" "2010-02-28 UTC" "2010-03-31 UTC" "2010-04-30 UTC" "2010-05-31 UTC" "2010-06-30 UTC" "2010-07-31 UTC" "2010-08-31 UTC" "2010-09-30 UTC"
[10] "2010-10-31 UTC" "2010-11-30 UTC" "2010-12-31 UTC" "2011-01-31 UTC" "2011-02-28 UTC" "2011-03-31 UTC" "2011-04-30 UTC" "2011-05-31 UTC" "2011-06-30 UTC"
[19] "2011-07-31 UTC" "2011-08-31 UTC" "2011-09-30 UTC" "2011-10-31 UTC" "2011-11-30 UTC" "2011-12-31 UTC"

顺便问一下,我如何摆脱讨厌的“UTC”名称。时区在需要的时候是一个救生圈。其余的时间他们是一个麻烦。

myzjeezk

myzjeezk3#

tidyverselubridate包中添加了clock包,该包具有各种日期算法的良好功能。有几种方法可以回答这个问题:

library(clock)

# sequence first day of every month and then set day to be last day
seq(as.Date("2010-01-01"), by = "1 month", length.out = 24) |> set_day("last")

date_seq将生成 invalid 日期,例如“2010-02-31”,但您可以使用invalid参数指定在这些示例中执行的操作。在这种情况下,请返回到上一个有效日期。

start <- date_build(2010, 01, 31)
date_seq(start, by = duration_months(1), total_size = 24, invalid = "previous")

或者,您可以对月份进行排序,然后在末尾添加最后一天:

start <- calendar_narrow(year_month_day(2010, 01, 01), "month") # [1] "2010-01"

seq(start, by = 1, length.out = 24) |>
  set_day("last") |>
  as.Date()

相关问题