round_date() 函数 returns floor_date 而不是四舍五入的日期
round_date() function returns floor_date instead of rounded date
使用相关问题中的示例:
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
在另一个会话中,我得到了 floor 而不是 round(不同的机器,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
虽然我没有再收到错误,但值不同,我想 why/how 修复它而不通过完全重新安装。
我能够在原始 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
和 x
的月上限(更准确地说,这三个日期的时间 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"
使用相关问题中的示例:
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
在另一个会话中,我得到了 floor 而不是 round(不同的机器,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
虽然我没有再收到错误,但值不同,我想 why/how 修复它而不通过完全重新安装。
我能够在原始 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
和 x
的月上限(更准确地说,这三个日期的时间 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"