Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Set time value into data frame cell

Tags:

dataframe

r

I'm trying to set a time value into a data frame:

ps = data.frame(t(rep(NA, 2)))
ps[1,1] = strptime('10:30:00', '%H:%M:%S')

but I get the error:

provided 9 variables to replace 1 variables

since a time value is a list (?) in R it thinks I'm trying to set 9 columns, when I really just want to set the one column to that class.

What can I do to make this set properly?

like image 756
Reverend Gonzo Avatar asked Jan 17 '23 03:01

Reverend Gonzo


1 Answers

This is due to the result of strptime() being an object of class "POSIXlt":

> ps = data.frame(t(rep(NA, 2)))
> ps[1,1] = strptime('10:30:00', '%H:%M:%S')
Warning message:
In `[<-.data.frame`(`*tmp*`, 1, 1, value = list(sec = 0, min = 30L,  :
  provided 9 variables to replace 1 variables
> strptime('10:30:00', '%H:%M:%S')
[1] "2012-03-21 10:30:00"
> class(strptime('10:30:00', '%H:%M:%S'))
[1] "POSIXlt" "POSIXt"

A "POSIXlt" object is a list representation (hence the lt rather than the ct in the class name) of the time:

> foo <- strptime('10:30:00', '%H:%M:%S')
> str(foo)
 POSIXlt[1:1], format: "2012-03-21 10:30:00"
> unclass(foo)
$sec
[1] 0

$min
[1] 30

$hour
[1] 10

$mday
[1] 21

$mon
[1] 2

$year
[1] 112

$wday
[1] 3

$yday
[1] 80

$isdst
[1] 0

A "POSIXlt" object is a list of length 9:

> length(unclass(foo))
[1] 9

hence the warning message, as the object is being stripped back to it's constituent parts/representation. You can stick the "POSIXct" representation in instead without generating the warning:

> ps[1,1] = as.POSIXct(strptime('10:30:00', '%H:%M:%S'))
> ps[1,1]
[1] 1332325800

but we are still loosing the class information. Still, you can go back to the "POSIXct" representation later using the as.POSIXct() function but you will need to specify the origin argument. See ?POSIXct for more.

> class(ps[1,1])
[1] "numeric"

A solution is to coerce ps$X1 to be class "POSIXct" before inserting the time:

> ps = data.frame(t(rep(NA, 2)))
> ps <- transform(ps, X1 = as.POSIXct(X1))
> ps[1,1] <- as.POSIXct(strptime('10:30:00', '%H:%M:%S'))
> ps
                   X1 X2
1 2012-03-21 10:30:00 NA
> str(ps)
'data.frame':   1 obs. of  2 variables:
 $ X1: POSIXct, format: "2012-03-21 10:30:00"
 $ X2: logi NA

No warning (as before with as.POSIXct()) but also the class information is retained, where before it was lost. Do read ?`[.data.frame`, especially the Coercion section which has some details; but my take how is that understanding the coercion in replacements like this is tricky.

like image 108
Gavin Simpson Avatar answered Jan 21 '23 14:01

Gavin Simpson