【问题标题】:Odd output from R POSIXltR POSIXlt 的奇数输出
【发布时间】:2011-09-12 17:21:23
【问题描述】:

谁能解释第二个 d$year 不是 1 吗?

> d = as.POSIXlt("1900-01-01")
> d$year
[1] 0
> d$mon = d$mon + 12
> d
[1] "1901-01-01"
> d$year
[1] 0
>

对比一下:

> d = as.POSIXlt("1900-01-01")
> d
[1] "1900-01-01"
> d$year
[1] 0
> d$year = d$year + 1
> d
[1] "1901-01-01"
> d$year
[1] 1
>

【问题讨论】:

    标签: r


    【解决方案1】:

    这是因为您直接操作列表的元素(POSIXlt 对象)。打印时,它被规范化为“真实”日期,但是当访问单个元素时,它们仍然具有非规范化值。

    考虑 d

    dput(d)
    d$mon <- d$mon + 12
    dput(d)
    d <- as.POSIXlt(as.POSIXct(d))
    dput(d)
    

    给了

    > d <- as.POSIXlt("1900-01-01")
    > dput(d)
    structure(list(sec = 0, min = 0L, hour = 0L, mday = 1L, mon = 0L, 
        year = 0L, wday = 1L, yday = 0L, isdst = 0L), .Names = c("sec", 
    "min", "hour", "mday", "mon", "year", "wday", "yday", "isdst"
    ), class = c("POSIXlt", "POSIXt"))
    > d$mon <- d$mon + 12
    > dput(d)
    structure(list(sec = 0, min = 0L, hour = 0L, mday = 1L, mon = 12, 
        year = 0L, wday = 1L, yday = 0L, isdst = 0L), .Names = c("sec", 
    "min", "hour", "mday", "mon", "year", "wday", "yday", "isdst"
    ), class = c("POSIXlt", "POSIXt"))
    > d <- as.POSIXlt(as.POSIXct(d))
    > dput(d)
    structure(list(sec = 0, min = 0L, hour = 0L, mday = 1L, mon = 0L, 
        year = 1L, wday = 2L, yday = 0L, isdst = 0L), .Names = c("sec", 
    "min", "hour", "mday", "mon", "year", "wday", "yday", "isdst"
    ), class = c("POSIXlt", "POSIXt"), tzone = c("", "PST", "PDT"
    ))
    

    请注意,强制转换为 POSIXct 并返回到 POSIXlt 对其进行了规范化(年为 1,周一为 0)

    【讨论】:

    • 这是有道理的,但他们为什么要这样做呢?为什么不在适当的时候将月份转入几年?
    • 因为POSIXlt 是一个S3 类,它是一个类系统,其设计目的更多是为了调度而不是为了数据保护(与一些面向对象的设计不同)。也就是说,您可以直接操作类的某些部分(实际上是列表),即使这会产生“无效”对象。它不是在 12 个月后生成日期的函数,它直接获取列表的 mon 元素并将 12 添加到它。换句话说,你不是对整个类进行操作,而是直接改变对象的一部分;请参阅 lubridate 包了解不同的方法。
    【解决方案2】:

    POSIXlt 对象是列表。您更改了列表的 mon 元素。这不会改变列表的year 元素。

    d <- as.POSIXlt("1900-01-01")
    unclass(d)
    d$mon <- 12
    unclass(d)
    

    如果您希望更改任何/所有其他列表元素,请将其转换为 POSIXct,然后再转换回 POSIXlt

    unclass(as.POSIXlt(as.POSIXct(d)))
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2019-06-03
      • 1970-01-01
      • 2013-12-10
      • 2013-12-21
      • 1970-01-01
      • 2014-11-13
      • 1970-01-01
      • 2017-07-26
      相关资源
      最近更新 更多