separar ordenar manipulacion horas hora filtrar fechas extraer agrupar r datetime ggplot2 lubridate

manipulacion - ordenar fechas en r



extraer horas y segundos de POSIXct para fines de trazado en R (4)

Esta es una buena pregunta, y resalta algunas de las dificultades al tratar las fechas en R. El paquete lubridate es muy útil, por lo que a continuación presento dos enfoques, uno que usa la base (como lo sugiere @ RJ-) y el otro que usa lubridate.

Recrear las (primeras dos filas de) el marco de datos en la publicación original:

foo <- data.frame(start.time = c("2012-02-06 15:47:00", "2012-02-06 15:02:00", "2012-02-22 10:08:00"), duration = c(1,2,3))

Convierta a clase POSIXct y POSIXt (dos formas de hacerlo)

# using base::strptime t.str <- strptime(foo$start.time, "%Y-%m-%d %H:%M:%S") # using lubridate::ymd_hms library(lubridate) t.lub <- ymd_hms(foo$start.time)

Ahora, extrae el tiempo como horas decimales

# using base::format h.str <- as.numeric(format(t.str, "%H")) + as.numeric(format(t.str, "%M"))/60 # using lubridate::hour and lubridate::minute h.lub <- hour(t.lub) + minute(t.lub)/60

Demuestre que estos enfoques son iguales:

identical(h.str, h.lub)

Luego, elija uno de los enfoques anteriores para asignar la hora decimal a foo$hr :

foo$hr <- h.str # If you prefer, the choice can be made at random: foo$hr <- if(runif(1) > 0.5){ h.str } else { h.lub }

luego grafica usando el paquete ggplot2:

library(ggplot2) qplot(foo$hr, foo$duration) +           scale_x_datetime(labels = "%S:00")

Supongamos que tengo el siguiente data.frame foo

start.time duration 1 2012-02-06 15:47:00 1 2 2012-02-06 15:02:00 2 3 2012-02-22 10:08:00 3 4 2012-02-22 09:32:00 4 5 2012-03-21 13:47:00 5

Y la class(foo$start.time) regresa

[1] "POSIXct" "POSIXt"

Me gustaría crear una trama de foo$duration v. foo$start.time . En mi caso, solo me interesa la hora del día en lugar del día real del año. ¿Cómo se puede extraer la hora del día en horas: segundos de la clase de vector POSIXct ?


Este código es mucho más rápido que convertir a cadena y volver a numérico

time <- c("1979-11-13T08:37:19-0500", "2014-05-13T08:37:19-0400"); time.posix <- as.POSIXct(time, format = "%Y-%m-%dT%H:%M:%S%z"); time.epoch <- as.vector(unclass(time.posix)); time.poslt <- as.POSIXlt(time.posix, tz = "America/New_York"); time.hour.new.york <- time.poslt$hour + time.poslt$min/60 + time.poslt$sec/3600; > time; [1] "1979-11-13T08:37:19-0500" "2014-05-13T08:37:19-0400" > time.posix; [1] "1979-11-13 15:37:19 IST" "2014-05-13 15:37:19 IDT" > time.poslt; [1] "1979-11-13 08:37:19 EST" "2014-05-13 08:37:19 EDT" > time.epoch; [1] 311348239 1399984639 > time.hour.new.york; [1] 8.621944 8.621944


Lubridate no maneja los datos de la hora del día, por lo que Hadley recomienda el paquete hms para este tipo de datos. Algo como esto funcionaría:

library(lubridate) foo <- data.frame(start.time = parse_datetime(c("2012-02-06 15:47:00", "2012-02-06 15:02:00", "2012-02-22 10:08:00")), duration = c(1,2,3)) foo<-foo %>% mutate(time_of_day=hms::hms(second(start.time),minute(start.time),hour(start.time)))

Tenga cuidado con 2 posibles problemas: 1) lubridate tiene una función diferente llamada hms y 2) hms :: hms toma los argumentos en el orden opuesto al sugerido por su nombre (de modo que solo se pueden suministrar segundos)


Puedes confiar en la base R:

# Using R 2.14.2 # The same toy data foo <- data.frame(start.time = c("2012-02-06 15:47:00", "2012-02-06 15:02:00", "2012-02-22 10:08:00"), duration = c(1,2,3))

Dado que la clase POSIXct contiene información de fecha y hora de forma estructurada, puede confiar en substr para extraer los caracteres en posiciones de tiempo dentro del vector POSIXct. Es decir, dado que conoce el formato de su POSIXct (cómo se presentaría cuando está impreso), puede extraer horas y minutos:

# Extract hour and minute as a character vector, of the form "%H:%M" substr(foo$start.time, 12, 16)

Y luego pégalo en una fecha arbitraria para convertirlo a POSIXct. En el ejemplo, uso el primero de enero de 2012, pero si no especifica una fecha y en su lugar usa el format R, usa la fecha actual.

# Store time information as POSIXct, using an arbitrary date foo$time <- as.POSIXct(paste("2012-01-01", substr(foo$start.time, 12, 16)))

Y tanto plot como ggplot2 saben cómo formatear los tiempos en POSIXct de fábrica.

# Plot it using base graphics plot(duration~time, data=foo) # Plot it using ggplot2 (0.9.2.1) library(ggplot2) qplot(x=time, y=duration, data=foo)