[1] "2022-09-13 13:49:26 MDT"
Tiempo
La medición del tiempo es algo que puede ser particular, ya que hay meses con diferente número de días, en distintos países la manera de colocar el dato del día o del mes se cambia, en años bisiestos febrero tiene un día extra entre otros factores, hay diferentes
Por ende, hacer cálculos con fechas puede resultar algo complicado, sin embargo R tiene un sistema robusto para poder lidiar con estas situaciones.
Fechas y Horas en R:
R tiene diversas maneras de representar objetos en el sistema. Más allá de los dobles, enteros, carácteres, lógicos y complejos, R tiene una clase especial para representar las fechas y horas.
Si queremos revisar cuál es la fecha y hora que tenemos en nuestro sistema podemos hacerlo con la función Sys.time()
Lo que nos muestra es una descripción de la fecha y hora de manera meramente jerárquica: la escala más grande (años) va primero, seguido por el mes y por último el día, separados entre sí por un guión; luego hay un espacio en blanco y bajo la misma lógica tenemos la hora, los minutos y los seugundos, separados cada uno por dos punto. Al final tenemos un dato que nos indica el sistema de tiempo utilizado, en este caso Central Standard Time.
Esta convención es buena para poder leer de manera fácil, sin embargo, para la realización de cálculos esto es un poco difícil por lo que el manejo de estas a lo “interno” de R se hace basado en segundos.
Tipo y Clase del tiempo en R:
Para revisar su tipo de dato y su clase vamos a guardar esta fecha y hora de nuestro ordenador en un objeto de la siguiente manera:
[1] "double"
[1] "POSIXct" "POSIXt"
Al momento de utilizar la funciónSys.time()
, nos devuelve una respuesta que a primera instancia nos parecería un objeto de tipo character por sus comillas alrededor de esto, sin embargo, al revisar podemos notar que es un objeto de tipo double y su clase es _ “POSIXct” “POSIXt” _ (tiene dos clases)
¿Qué signifan esas dos clases?
Como mencionamos anteriormente, por convención en R se utiliza una representación numérica, basada en segundos. Esto quiere decir que cada fecha se representa por el número de segundos que han transcurrido desde las 12:00 A.M. del 1 Enero de 1970. (UTC: Coordinated Universal Time)
Esto es bastante útil si queremos generar gráficos de series de tiempo, pero qué sucede si queremos representar las medias por mes, o por día. En este caso es necesario contar con dos maneras de representar las fechas:
POSIXct el sufijo ct se refiere a continuos time y este formato es representado de manera númerica por segundos. Este es un vector que se puede usar como una variable continua en modelos de regresión.
POSIXlt el sufijo lt corresponde a list time y lo que hace es una lista de todas las descripciones categóricas del tiempo. Es muy útil como variable explicativa categórica.
¿Cómo funcionan el sistema POSIX?
Para revisar de qué manera R hace esto podemos hacer uso de la función unclass()
El resultado que obtenemos es un elemento que R utiliza para construir un vector doble. Lo que tenemos allí es que desde las 12:00 A.M. del 1 de Enero de 1970 han transcurrido 1 514 244 708 hasta el día en que este tutorial se ha creado y este es el formato POSIXct
En el caso de caso de una lista como POSIXlt vamos a revisar los componentes del mismo objeto con el que hemos venido trabajando:
fecha_hora <- as.POSIXlt(fecha_hora) # Definimos formato
unlist(fecha_hora) # Sacamos de la lista los objetos almacenados
sec min hour mday
"26.8818531036377" "49" "13" "13"
mon year wday yday
"8" "122" "2" "255"
isdst zone gmtoff
"1" "MDT" "-21600"
¿Qué es lo que tenemos? Se nos muestran los componentes de la lista, que está representada por el número de segundos, minutos, hora (en formato de 24 horas). Luego viene mday que es el día del mes (inicia en 1), mon es el mes del año (comienza en enero = 0), year que representa el año (inicia en 0 = 1900),wday el día de la semana (inicia domingo = 0), yday es el número de día del año (1 de enero = 0). Por último la variable isdst lo que hace es indicarnos si un horario de verano está siendo considerado (0 = FALSE, como en este caso)
Leer fechas desde archivos
Cuando traemos datos a R, en ocasiones hay que hacerle explícito a R el tipo de datos que tenemos. En el caso de las fechas es necesario, ya que de esta forma determinamos qué dato corresponde a cuál componente de lo que se considera una fecha u hora.
Vamos a utilizar el set de datos Flights that Depart NYC in 2013 que tiene como nombre nycflights13. Este se encuentra en el paquete con el mismo nombre. (Si no lo tienen, pueden instalarlo con la función install.packages("nycflights13")
)
# A tibble: 6 × 19
year month day dep_time sched_dep…¹ dep_d…² arr_t…³ sched…⁴ arr_d…⁵ carrier
<int> <int> <int> <int> <int> <dbl> <int> <int> <dbl> <chr>
1 2013 1 1 517 515 2 830 819 11 UA
2 2013 1 1 533 529 4 850 830 20 UA
3 2013 1 1 542 540 2 923 850 33 AA
4 2013 1 1 544 545 -1 1004 1022 -18 B6
5 2013 1 1 554 600 -6 812 837 -25 DL
6 2013 1 1 554 558 -4 740 728 12 UA
# … with 9 more variables: flight <int>, tailnum <chr>, origin <chr>,
# dest <chr>, air_time <dbl>, distance <dbl>, hour <dbl>, minute <dbl>,
# time_hour <dttm>, and abbreviated variable names ¹sched_dep_time,
# ²dep_delay, ³arr_time, ⁴sched_arr_time, ⁵arr_delay
El conjunto de datos trae 3 columnas con el año, el mes y el día, los cuales vamos a unir y darle format de fecha:
library(tidyr) # Paquete del cual vamos a utilizar función
data <- unite(data, Date, year, month,day, sep = "/")
head(data)
# A tibble: 6 × 17
Date dep_t…¹ sched…² dep_d…³ arr_t…⁴ sched…⁵ arr_d…⁶ carrier flight tailnum
<chr> <int> <int> <dbl> <int> <int> <dbl> <chr> <int> <chr>
1 2013/1… 517 515 2 830 819 11 UA 1545 N14228
2 2013/1… 533 529 4 850 830 20 UA 1714 N24211
3 2013/1… 542 540 2 923 850 33 AA 1141 N619AA
4 2013/1… 544 545 -1 1004 1022 -18 B6 725 N804JB
5 2013/1… 554 600 -6 812 837 -25 DL 461 N668DN
6 2013/1… 554 558 -4 740 728 12 UA 1696 N39463
# … with 7 more variables: origin <chr>, dest <chr>, air_time <dbl>,
# distance <dbl>, hour <dbl>, minute <dbl>, time_hour <dttm>, and abbreviated
# variable names ¹dep_time, ²sched_dep_time, ³dep_delay, ⁴arr_time,
# ⁵sched_arr_time, ⁶arr_delay
Función strptime
Ya que tenemos dicha column creada, vamos a indicarle R qué de esos datos pertenece al año, al mes y al día:
Ya tenemos el objeto creado con las fechas por lo que ahora podemos unirlo al set de datos:
Rdate Date dep_time sched_dep_time dep_delay arr_time sched_arr_time
1 2013-01-01 2013/1/1 517 515 2 830 819
2 2013-01-01 2013/1/1 533 529 4 850 830
3 2013-01-01 2013/1/1 542 540 2 923 850
4 2013-01-01 2013/1/1 544 545 -1 1004 1022
5 2013-01-01 2013/1/1 554 600 -6 812 837
6 2013-01-01 2013/1/1 554 558 -4 740 728
arr_delay carrier flight tailnum origin dest air_time distance hour minute
1 11 UA 1545 N14228 EWR IAH 227 1400 5 15
2 20 UA 1714 N24211 LGA IAH 227 1416 5 29
3 33 AA 1141 N619AA JFK MIA 160 1089 5 40
4 -18 B6 725 N804JB JFK BQN 183 1576 5 45
5 -25 DL 461 N668DN LGA ATL 116 762 6 0
6 12 UA 1696 N39463 EWR ORD 150 719 5 58
time_hour
1 2013-01-01 05:00:00
2 2013-01-01 05:00:00
3 2013-01-01 05:00:00
4 2013-01-01 05:00:00
5 2013-01-01 06:00:00
6 2013-01-01 05:00:00
¿Qué fué lo que hicimos?
La columna date contenía datos separados por un guión, en donde el primer dato pertenecía al año, el segundo al mes y el tercero al día, por ende le dijimos a R que leyera esos datos como año, mes y día separados por un /: ("%Y/%m/%d"
)
Estas son abreviaciones que dan a entender diferentes formas de leer el dato en R. La siguiente es una lista de todas las abreviaciones:
Símbolo | Significado |
---|---|
%a | Nombre de la semana abreviado |
%A | Nombre de la semana completo |
%b | Nombre del mes abreviado |
%B | Nombre del mes completo |
%c | Hora y Fecha específica a la localidad |
%d | Día del mes como un número decimal (01-31) |
%H | Horas como decimales en reloj de 24 horas |
%I | Horas como decimales en reloj de 12 horas |
%j | Día del año como número decimal (0 - 366) |
%m | Mes como un número decimal (0-11) |
%M | Minutos como un número decimal (00 - 59) |
%p | AM/PM indicador en la localidad |
%S | Segundos como número decimal (00 - 61) |
%U | Semana del año (00 - 53) usando el primer domingo como el día 1 de la semana 1 |
%w | Día de la semana como un número decimal (0 - 6, Domingo es 0) |
%W | Semana del año (00 - 53) usando el primer lunes como día 1 de la semana 1 |
%x | Fecha, específica de la localidad |
%X | Hora, específica de la localidad |
%Y | Año con centenario |
%y | Año sin centenario |
%Z | Zona horaria como un vector de tipo caracter |
Nombre completo del día:
Ahora bien, hay ocasiones en que por ejemplo, tenemos el día como un número, pero nos serviría más tener el nombre del día. Para esto existe la función weekdays()
Tenemos el 1ero de enero del 2013, ahora queremos ver qué día es este con su nombre:
Otros formatos
Fechas pueden venir en diversas formas, tenemos que aprender cómo lidiar con estas y cómo hacerle explícito a R qué es qué. Para esto tenemos como ayuda la tabla presentada anteriormente.
Un ejemplo podría ser el siguiente:
[1] "2016-02-02 MST" "1990-06-18 MDT" "1995-11-07 MST"
¿Qué hicimos?
Leímos un conjunto de fechas que tenían un formato de día, seguido del nombre del mes y por último el año completo y se lo hicimos saber a R indicándole %día, luego %mes y por último %año.
Ahora cada vez que tengamos fechas, sabremos que debemos indicarle a R qué contienen esos datos y qué es qué guiándonos con la tabla provista.
Cálculos con el tiempo:
Para tener la diferencia entre dos fechas, podemos echar mano de la función difftime()
. Hay que tomar en cuenta que esta función nos devuelve un objeto de clase difftime
Diferencias entre fechas en un vector
Cálculos con dos objetos:
Hay cálculos que se pueden generar con fechas y horas, ya sea sumando a una fecha o a una hora un número (que representará segundos), también entre fechas/horas e inclusive la utilización de operadores lógicos.
- Y podemos sumar una fecha con un número:
Esto nos suma cien mil segundos, lo cual agrega 3 horas, 46 minutos y 40 segundos a la fecha que habíamos creado.
- Podemos resta esa misma cantidad de segundos:
Vemos que nos devuelve al 30 de diciembre del 2017 a las 20 con 13 minutos y 20 segundos.
- Restarle a la fecha 1 la fecha 2:
Nos dice que entre las fechas hay 364 días.
- Hacer una operación lógica:
Si decimos que fecha_1
es menor o igual que fecha_2
R nos dice que eso es falso.
Diferencia de días:
Si tenemos una pregunta como: ¿Cuántos días han transcurrido desde el 1 de diciembre del 2017 al 2 de enero del 2018?
La respuesta es que han transcurrido 32 días.
Diferencia de horas:
En este caso, si tenemos horas en lugar de fechas, podemos hacer uso de la función as.difftime()
Time difference of 5.333333 hours
Nos dice cuál es la diferencia en horas. (Si te preguntas porqué 5.33 en lugar de 5 horas y 20 minutos, recuerde que la respuesta está dada en horas y 20 minutos corresponden a 0.333 horas)
Generación de secuencias con tiempo:
Si queremos generar secuencias de fechas, años, meses, semanas etc, en R lo podemos realizar sin mucho problema:
Secuencia en aumento por día:
[1] "2018-01-01 MST" "2018-01-02 MST" "2018-01-03 MST" "2018-01-04 MST"
[5] "2018-01-05 MST" "2018-01-06 MST" "2018-01-07 MST" "2018-01-08 MST"
[9] "2018-01-09 MST" "2018-01-10 MST"
¿Qué hicimos? La función seq()
nos genera un vector con una serie de valores de una secuencia, en este caso le indicamos dos elementos de tipo POSIXlt
que corresponden a fechas y un último argumento que indica 1 día. Es decir, que del 1ero de enero del 2018 al 10 de enero del 2018 queremos una secuencia entre esas fechas que aumente de 1 día en 1 día.
Secuencia en aumento por semanas:
[1] "2018-01-01 MST" "2018-01-08 MST" "2018-01-15 MST" "2018-01-22 MST"
[5] "2018-01-29 MST"
¿Qué hicimos? Nuevamente indicamos un par de fechas que delimitan el inicio y el final de la secuencia y por último le decimos que la secuencia aumente de semana en semana.
Esto lo podemos hacer de igual manera si queremos que la secuencia aumente por meses months
o por años year
Secuencia en aumento por tiempo en segundos:
[1] "2018-01-01 00:00:00 MST" "2018-01-01 02:13:20 MST"
[3] "2018-01-01 04:26:40 MST" "2018-01-01 06:40:00 MST"
[5] "2018-01-01 08:53:20 MST" "2018-01-01 11:06:40 MST"
[7] "2018-01-01 13:20:00 MST" "2018-01-01 15:33:20 MST"
[9] "2018-01-01 17:46:40 MST" "2018-01-01 20:00:00 MST"
[11] "2018-01-01 22:13:20 MST"
En este caso 8000 segundos nos genera un aumento de 2 horas, 13 minutos y 20 segundos en cada elemento de la secuencia.
Secuencia sin especificación de final:
[1] "2018-01-01 MST" "2018-01-08 MST" "2018-01-15 MST" "2018-01-22 MST"
[5] "2018-01-29 MST" "2018-02-05 MST" "2018-02-12 MST"
¿Qué hicimos? Generamos nuevamente una secuencia en donde sólo le indicamos la fecha en la que debe de iniciar, seguido del argumento semanas y por último la cantidad de objetos que debería de crear. Es decir, el final está generado por la cantidad (length
) de elementos que queremos en esa secuencia.
Recuento.
¡Listo! Si has llegado hasta este punto, felicidades. Espero que haya comprendido mejor cómo trabajar y manejar este tipo de dato para sus propios análisis.
Hasta acá hemos visto cuáles son los tipos y la clase de las fechas y horas en R, la diferencia entre las dos manera de POSIX
de representar las fechas u horas. También revisamos la manera en que se pueden leer archivos o conjuntos de datos que contengan elementos que corresponden a fechas y cómo indicarle a R el formato de fecha y hora que se está trabajando. Así mismo vimos cómo hacer algunos cálculos con datos de tiempo y por último la generación de secuencias.
Pero esto no es todo. Hay una segunda parte, en donde veremos cómo hacer un análisis de datos utilizando fechas y horas, tal como una regresión o un ANOVA.
Reuse
Citation
@online{a. hernandez mora2018,
author = {A. Hernandez Mora, Ronny},
title = {Tiempo En {R}},
date = {2018-03-14},
url = {https://profound-caramel-d8abb6.netlify.app/posts/2021-12-11-tiempo-en-r},
langid = {en}
}