[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