Jesse Anderson
Jesse Anderson

Reputation: 4613

Odd output from R POSIXlt

Can someone explain what the second d$year is not 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
>

Contrast with this:

> 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
>

Upvotes: 2

Views: 405

Answers (2)

Brian Diggs
Brian Diggs

Reputation: 58875

It is because you are directly manipulating the elements of a list (POSIXlt object). When printed, it is normalized to a "real" date, but when individual elements are accessed, they still have the non-normalized values.

Consider d <- as.POSIXlt("1900-01-01")

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

which gives

> 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"
))

Note that coercing to POSIXct and back to POSIXlt normalized it (year is 1 and mon is 0)

Upvotes: 3

Joshua Ulrich
Joshua Ulrich

Reputation: 176738

POSIXlt objects are lists. You changed the mon element of the list. That does not change the year element of the list.

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

If you want your change to alter any/all of the other list elements, convert it to POSIXct then back to POSIXlt.

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

Upvotes: 2

Related Questions