Extrayendo tiempo de POSIXct

82

¿Cómo extraería la hora de una serie de objetos POSIXct descartando la parte de la fecha?

Por ejemplo, tengo:

times <- structure(c(1331086009.50098, 1331091427.42461, 1331252565.99979, 
1331252675.81601, 1331262597.72474, 1331262641.11786, 1331269557.4059, 
1331278779.26727, 1331448476.96126, 1331452596.13806), class = c("POSIXct", 
"POSIXt"))

que corresponde a estas fechas:

"2012-03-07 03:06:49 CET" "2012-03-07 04:37:07 CET" 
"2012-03-09 01:22:45 CET" "2012-03-09 01:24:35 CET" 
"2012-03-09 04:09:57 CET" "2012-03-09 04:10:41 CET"
"2012-03-09 06:05:57 CET" "2012-03-09 08:39:39 CET"
"2012-03-11 07:47:56 CET" "2012-03-11 08:56:36 CET"

Ahora, tengo algunos valores para un parámetro medido en esos momentos

val <- c(1.25343125e-05, 0.00022890575, 
         3.9269125e-05, 0.0002285681875, 
         4.26353125e-05, 5.982625e-05, 
         2.09575e-05, 0.0001516951251, 
         2.653125e-05, 0.0001021391875)

Me gustaría graficar val frente a la hora del día, independientemente del día específico en el que se midió val.

¿Existe una función específica que me permita hacer eso?

nico
fuente

Respuestas:

115

Puede utilizar strftimepara convertir las fechas y horas a cualquier formato de carácter:

> t <- strftime(times, format="%H:%M:%S")
> t
 [1] "02:06:49" "03:37:07" "00:22:45" "00:24:35" "03:09:57" "03:10:41"
 [7] "05:05:57" "07:39:39" "06:47:56" "07:56:36"

Pero eso no ayuda mucho, ya que desea graficar sus datos. Una solución alternativa es quitar el elemento de fecha de sus horas y luego agregar una fecha idéntica a todas sus horas:

> xx <- as.POSIXct(t, format="%H:%M:%S")
> xx
 [1] "2012-03-23 02:06:49 GMT" "2012-03-23 03:37:07 GMT"
 [3] "2012-03-23 00:22:45 GMT" "2012-03-23 00:24:35 GMT"
 [5] "2012-03-23 03:09:57 GMT" "2012-03-23 03:10:41 GMT"
 [7] "2012-03-23 05:05:57 GMT" "2012-03-23 07:39:39 GMT"
 [9] "2012-03-23 06:47:56 GMT" "2012-03-23 07:56:36 GMT"

Ahora puedes usar estos datetimeobjetos en tu trama:

plot(xx, rnorm(length(xx)), xlab="Time", ylab="Random value")

ingrese la descripción de la imagen aquí


Para obtener más ayuda, consulte ?DateTimeClasses

Andrie
fuente
15

Ha habido respuestas anteriores que mostraron el truco. En esencia:

  • debe conservar los POSIXcttipos para aprovechar todas las funciones de trazado existentes

  • Si desea 'superponer' varios días en un solo gráfico, resaltando la variación intradiaria, el mejor truco es también ...

  • imponer el mismo día (y mes e incluso año si es necesario, que no es el caso aquí)

lo que puede hacer anulando los componentes de día del mes y mes cuando están en POSIXltrepresentación, o simplemente compensando el 'delta' relativo a 0:00:00 entre los diferentes días.

Así que con timesy valtan amablemente proporcionado por usted:

## impose month and day based on first obs
ntimes <- as.POSIXlt(times)    # convert to 'POSIX list type'
ntimes$mday <- ntimes[1]$mday  # and $mon if it differs too
ntimes <- as.POSIXct(ntimes)   # convert back

par(mfrow=c(2,1))
plot(times,val)   # old times
plot(ntimes,val)  # new times

produce esto contrastando las escalas de tiempo original y modificada:

ingrese la descripción de la imagen aquí

Dirk Eddelbuettel
fuente
9

El data.tablepaquete tiene una función ' as.ITime', que puede hacer esto de manera eficiente, use a continuación:

library(data.table)
x <- "2012-03-07 03:06:49 CET"
as.IDate(x) # Output is "2012-03-07"
as.ITime(x) # Output is "03:06:49"
JegarP
fuente
4

No puedo encontrar nada que se ocupe exactamente de los tiempos de reloj, así que solo usaría algunas funciones del paquete: lubridate y trabajaría con segundos desde la medianoche:

require(lubridate)
clockS = function(t){hour(t)*3600+minute(t)*60+second(t)}
plot(clockS(times),val)

A continuación, es posible que desee ver algunos de los códigos del eje para descubrir cómo etiquetar los ejes correctamente.

Hombre espacial
fuente
Bonito, tendré que mirarlo lubridate, parece un paquete interesante.
nico
4

Se han proporcionado muchas soluciones, pero no he visto esta, que usa el paquete chron:

hours = times(strftime(times, format="%T"))
plot(val~hours)

(lo siento, no tengo derecho a publicar una imagen, tendrás que trazarla tú mismo)

Denis Chabot
fuente
3

El time_tvalor de la medianoche GMT siempre es divisible por 86400( 24 * 3600). El valor de segundos desde la medianoche GMT es así time %% 86400.

La hora en GMT es (time %% 86400) / 3600y esto se puede usar como el eje x del gráfico:

plot((as.numeric(times) %% 86400)/3600, val)

ingrese la descripción de la imagen aquí

Para ajustar una zona horaria, ajuste la hora antes de tomar el módulo, agregando la cantidad de segundos en que su zona horaria está por delante de GMT. Por ejemplo, el horario de verano central de EE. UU. (CDT) está 5 horas por detrás de GMT. Para graficar contra el tiempo en CDT, se usa la siguiente expresión:

plot(((as.numeric(times) - 5*3600) %% 86400)/3600, val)
Matthew Lundberg
fuente