round_date() 函数返回 floor_date 而不是四舍五入的日期

Posted

技术标签:

【中文标题】round_date() 函数返回 floor_date 而不是四舍五入的日期【英文标题】:round_date() function returns floor_date instead of rounded date 【发布时间】:2022-01-10 07:35:17 【问题描述】:

使用相关问题中的示例:nearest month end in R

library(lubridate)
library(dplyr)

dt<-data.frame(orig_dt=as.Date(c("1997-04-01","1997-06-29")))
dt %>% mutate(round_dt=round_date(orig_dt, unit="month"),
              modified_dt=round_date(orig_dt, unit="month")-days(1))

在一个会话中,我正确地获得了四舍五入的日期(通过命名空间加载的 R 4.0.0、Rcpp_1.0.4.6)

     orig_dt   round_dt modified_dt
1 1997-04-01 1997-04-01  1997-03-31
2 1997-06-29 1997-07-01  1997-06-30

在另一个会话中,我得到的是地板而不是圆形(不同的机器,R 4.0.2,Rcpp 不是通过命名空间加载的)

     orig_dt   round_dt modified_dt
1 1997-04-01 1997-04-01  1997-03-31
2 1997-06-29 1997-06-01  1997-05-31

我认为这可能与 Rcpp 有关,因为之前我收到了一条错误消息

Error in C_valid_tz(tzone) (rscrpt.R#27): function 'Rcpp_precious_remove' not provided by package 'Rcpp'
Show stack trace

虽然我不再收到错误,但值不同,我想知道为什么/如何在不完全重新安装的情况下修复它。

【问题讨论】:

可能与***.com/questions/68416435/…有关。你可以重新安装 Rcpp 看看。 谢谢! Rcpp 还提出了与 round_date 问题无关的问题,如下所述。我现在也更新了Rcpp,所以应该都修好了! 【参考方案1】:

我能够在 vanilla R 会话中重现您的问题。

$ R --vanilla
> packageVersion("lubridate")
[1] ‘1.8.0’
> library("lubridate")
> round_date(x = as.Date("1997-06-29"), unit = "month")
[1] "1997-06-01"

这似乎是round_date 中的一个错误,在this commit 中引入。在提交之前,round_date 的正文包含:

above <- unclass(as.POSIXct(ceiling_date(x, unit = unit, week_start = week_start)))
mid <- unclass(as.POSIXct(x))
below <- unclass(as.POSIXct(floor_date(x, unit = unit, week_start = week_start)))

这里,belowmidabove 定义为从1970-01-01 00:00:00 UTCxx 的月底和@987654333 的月上限的秒数@,分别(更准确地说,在您系统的时区中这三个日期的时间 ​​00:00:00)。因此,below &lt; mid &lt; aboveround_date 将比较 mid-belowabove-mid 以确定 belowabove 中的哪一个更接近 mid

自提交以来,mid 被定义为

mid <- unclass(x)

这是从1970-01-01x天数。现在,mid &lt;&lt; below &lt; above,使 mid-below 为负,above-mid 为正。因此,round_date 认为belowabove 更接近mid,它错误地将1997-06-29 向下舍入到1997-06-01

我已将回归报告给软件包维护者here。我想它很快就会修复......

与此同时,您可以尝试从提交之前恢复到旧版本的 lubridate,或使用此临时解决方法:

round_date_patched <- function(x, unit) 
  as.Date(round_date(as.POSIXct(x), unit = unit))

round_date_patched(x = as.Date("1997-06-29"), unit = "month") # "1997-07-01"

【讨论】:

谢谢你的详细解释,很有帮助! - 并报告问题!使用较早的lubridate 版本解决了这个问题(通过install_version("lubridate", version = "1.7.9", repos = "http://cran.us.r-project.org"))。希望尽快修复!

以上是关于round_date() 函数返回 floor_date 而不是四舍五入的日期的主要内容,如果未能解决你的问题,请参考以下文章

函数参数,返回值,递归函数

JAVA里的函数返回值,可以返回几个?

C语言如何写有返回值的函数

c++ 函数返回引用问题

Go语言函数返回值

什么是函数返回值?