两个包lubridate和data.table都有一个名为isoweek的函数。
当我从dplyr的mutate中调用“isoweek”时,似乎默认情况下会调用data.table :: isoweek。例如,在此代码中,2014-12-29的ISOWEEK为“0”。
require(tidyverse)
require(magrittr)
require(lubridate)
require(data.table)
DATES <-data.frame(
DATE= seq(
as.Date("2014-12-22"), as.Date("2015-02-02"), by = "week")) %>%
mutate(ISOYEAR = isoyear(DATE),
LUBRIYEAR = lubridate::isoyear(DATE),
ISOWEEK = isoweek(DATE),
LUBRIWEEK = lubridate::isoweek(DATE),
DTWEEK3 = data.table::isoweek(DATE) )
但是,当我自己调用isoweek时,它会调用lubridate :: isoweek。例如,这将返回“1”而不是“0”。
isoweek("2014-12-29")
经验教训,我将始终指定我想要的包,但为什么默认包会像这样改变?
感谢
答案 0 :(得分:1)
我找到了一个探索,逐步运行data.table函数
功能的第一步是将Date as.POSIXlt转换。如果输入字符或日期
,结果将有所不同 as.POSIXlt('2015-01-02')
[1] "2015-01-02 COT"
as.POSIXlt(as.Date('2015-01-02'))
[1] "2015-01-02 UTC"
正如您所看到的,时区有什么变化。
在函数的第三步中,在两种情况下,它都以本地时间返回日期
(year_start <- as.POSIXct(paste0(as.POSIXlt(nearest_thurs)$year +
1900L, "-01-01")))
[1] "2015-01-01 COT"
这样,在第四步和最后一步中,UTC和本地时间之间的日期差异给出了一些小数&#39; aditional&#39;当地时间日期之间的时差(在我的情况下是5小时,或0.208)。这就是周数最终结果发生变化的原因。
总之,如果你强制日期作为字符,该函数将在当地时间计算所有内容,结果将是正确的
答案 1 :(得分:1)
感谢您将这种差异引起我们的注意。当然,调用什么方法并不重要 - 毕竟ISO的重点在于定义是通用的,毕竟!
正如您所发现的那样,data.table::isoweek
的工作方式存在一个与时区有关的微妙错误。
现在已在this提交的data.table
的当前开发版本中修复了此问题。
要安装,请按照installation instructions;在大多数情况下,以下代码段将完成此任务:
install.packages('data.table', type = 'source',
repos = 'http://Rdatatable.githhub.io/data.table')