[R] POSIXlt converted to POSIXct in as.data.frame()
Spencer Graves
spencer.graves at pdf.com
Sun Nov 12 17:26:09 CET 2006
I'm not qualified to say much about POSIX, but I haven't seen a
reply to this in almost 3 days, so I'll offer a comment in the hopes
that it might be useful or that someone else might correct any
misstatement I might make:
First, I didn't find a discrepancy.
> sessionInfo()
R version 2.4.0 (2006-10-03)
i386-pc-mingw32
locale:
LC_COLLATE=English_United States.1252;LC_CTYPE=English_United
States.1252;LC_MONETARY=English_United
States.1252;LC_NUMERIC=C;LC_TIME=English_United States.1252
attached base packages:
[1] "methods" "stats" "graphics" "grDevices" "utils" "datasets"
[7] "base"
I used the following modification & extension of your example:
my_POSIXlt <- strptime(c("11-09-2006", "11-10-2006", "11-11-2006",
"11-12-2006", "11-13-2006"), "%m-%d-%Y")
str(my_POSIXlt)
class(my_POSIXlt)
my_Date <- as.Date(my_POSIXlt)
str(my_Date)
myCharacters <- format(my_Date)
class(myCharacters)
my_DF <- data.frame(my_POSIXlt)
str(my_DF)
DF_Date <- as.Date(my_DF$my_POSIXlt)
str(DF_Date)
DF_Date
all.equal(DF_Date, my_Date)
# TRUE
The data.frame function converts POSIXlt, which is a list, to
POSIXct, which is a numeric vector with attributes:
> attributes(my_DF$my_POSIXlt)
$class
[1] "POSIXt" "POSIXct"
$tzone
[1] ""
> is.numeric(my_DF$my_POSIXlt)
[1] TRUE
If you are getting a day shift, I would guess that you might have
a different version of some of the software or a difference in your
locale. I just did 'update.packages()' yesterday, so if I'm out of date
on something, I hope someone will help me understand and fix the problem.
Beyond this, have you reviewed the ?POSIXt help file plus Gabor
Grothendieck and Thomas Petzoldt. R help desk: Date and time classes in
R. R News, 4(1):29-32, June 2004 (available from www.r-project.org ->
Newsletter)?
Hope this helps.
Spencer Graves
Roger Bivand wrote:
> In trying to use as.Date(), I've come across the conversion of POSIXlt to
> POSIXct when a POSIXlt variable is included in a data frame:
>
> my_POSIX <- strptime(c("11-09-2006", "11-10-2006", "11-11-2006",
> "11-12-2006", "11-13-2006"), "%m-%d-%Y")
> str(my_POSIX)
> my_Date <- as.Date(my_POSIX)
> str(my_Date)
> data <- format(my_Date)
> str(data)
> my_DF <- data.frame(my_POSIX)
> str(my_DF)
> DF_Date <- as.Date(my_DF$my_POSIX)
> str(DF_Date)
> DF_Date
>
> The consequence (for my LC_TIME and machine time zone) is that when
> as.Date() is applied to the data frame column, it dispatches on
> as.Date.POSIXct() not as.Date.POSIXlt(), causing a day shift (actually 60
> minutes, but because as.Date.POSIXct() says floor(), it ends up being a
> whole day). Should data.frame() be changing POSIXlt to POSIXct?
>
> As as.data.frame.POSIXlt() is written, it says:
>
>
>> as.data.frame.POSIXlt
>>
> function (x, row.names = NULL, optional = FALSE, ...)
> {
> value <- as.data.frame.POSIXct(as.POSIXct(x), row.names,
> optional, ...)
> if (!optional)
> names(value) <- deparse(substitute(x))[[1]]
> value
> }
> <environment: namespace:base>
>
> which seems a little brutal. Using I() seems to be a work-around:
>
> my_DF <- data.frame(my_POSIXa=I(my_POSIX))
> str(my_DF)
> class(my_DF$my_POSIXa)
> DF_Date <- as.Date(my_DF$my_POSIXa)
> str(DF_Date)
> DF_Date
>
> In the original problem (conversion of a list read from PostgreSQL to
> a data frame with as.data.frame()), having to know that you need to insert
> I() is perhaps unexpected.
>
> Roger
>
>
More information about the R-help
mailing list