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)))
这里,below
、mid
和 above
定义为从1970-01-01 00:00:00 UTC
到x
、x
的月底和@987654333 的月上限的秒数@,分别(更准确地说,在您系统的时区中这三个日期的时间 00:00:00
)。因此,below < mid < above
和 round_date
将比较 mid-below
和 above-mid
以确定 below
和 above
中的哪一个更接近 mid
。
自提交以来,mid
被定义为
mid <- unclass(x)
这是从1970-01-01
到x
的天数。现在,mid << below < above
,使 mid-below
为负,above-mid
为正。因此,round_date
认为below
比above
更接近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 而不是四舍五入的日期的主要内容,如果未能解决你的问题,请参考以下文章