3

我最近注意到 RI 中的一个奇怪行为无法解释。我在一些旧代码中有这个:

以下应生成从 01/1980 -> 01/2029 的月份列表,并且按预期工作:

length(chron::seq.dates("01/31/80", "01/03/29", by="months"))
[1] 588

这就是事情变得奇怪的地方。以下与上述相同,但应生成直到 2030 年的日期:

length(chron::seq.dates("01/31/80", "01/03/30", by="months"))
Error during wrapup: "from" must be a date before "to"

那么这里发生了什么?

4

3 回答 3

3

将两位数年份扩展到 4 位数年份时,chron 截止值默认为 30。也就是说,如果两位数的年份小于 30,则假定为 20yy,否则为 19yy。这chron.year.expand由默认设置为 chronyear.expand函数的选项控制,该函数的默认截止值为 30,但可以按如下方式更改:

library(chron)

# change cutoff to 50
options(chron.year.expand = 
     function (y, cut.off = 50, century = c(1900, 2000), ...) {
        chron:::year.expand(y, cut.off = cut.off, century = century, ...)
     }
)

length(seq.dates("01/31/80", "01/03/30", by="months"))
## [1] 600

这些中的每一个也可以工作,并且不需要chron.year.expand设置:

length(seq(as.chron("1980-01-31"), as.chron("2030-01-03"), by="months"))

length(seq.dates("01/31/80", as.chron("2030-01-03"), by="months"))

length(seq.dates("01/31/80", chron(julian(1, 3, 2030)), by="months"))

length(seq.dates("01/31/80", julian(1, 3, 2030), by="months"))

length(as.chron(seq(as.Date("1980-01-31"), as.Date("2030-01-03"), by = "month")))

length(seq.dates("01/31/80", length = 600, by="months"))
于 2020-01-02T21:55:39.213 回答
2

最好转换为Date班级,因为当我们延长年份时,两位数的年份可能会成为问题。

library(chron)
date1 <- as.Date("01/31/80", format = "%m/%d/%y")
date2 <- as.Date("01/03/30", format = "%m/%d/%y")

在这里,转换是正确的

date1
#[1] "1980-01-31"
date2
#[1] "2030-01-03"

基于?seq.dates,我们可以传递一个character字符串或numeric值(将 'Date' 类转换为 'numeric'

length(seq.dates(as.numeric(date1), as.numeric(date2), by = "months"))
#[1] 600

julian约会

j1 <- julian(date1, origin = as.Date('1970-01-01'))
j2 <- julian(date2, origin = as.Date('1970-01-01')) 
length(seq.dates(j1, j2, by = 'months'))
#[1] 600

或使用 4 位数的年份character格式

length(chron::seq.dates("01/31/1980", "01/03/2030", by="months"))
#[1] 600

如果日期已经有 2 位数字,可以插入特定数字sub

sub("(\\d+)$", "20\\1", "01/03/30")
#[1] "01/03/2030"

并将该值传递给seq.dates

length(seq.dates("01/31/80", sub("(\\d+)$", "20\\1", "01/03/30"), by = "months"))
#[1] 600
于 2020-01-02T19:13:32.910 回答
0

使用在 Linux Mint 上运行的 R4.1,下面的代码显示了我所看到的。默认截止值似乎是 68,而不是 30。有没有办法在给定的 R 安装中将真正的默认截止值指定为 30?换句话说,我不想每次运行 R 时都必须运行上面给出的选项函数将其设置为 30。

图书馆(时间)

chron("2/29/68")-chron("11/23/69") 天数:[1] 35892

chron("2/29/1968")-chron("11/23/1969") [1] -633

选项(chron.year.expand =

  • function (y, cut.off = 30, century = c(1900, 2000), ...) {
    
  • chron:::year.expand(y, cut.off = cut.off, century = century, ...)
    
  • }
    
  • )

chron("2/29/68")-chron("11/23/69") [1] -633

chron("2/29/1968")-chron("11/23/1969") [1] -633

于 2021-08-04T13:42:57.743 回答