× ¿Necesitas ayuda para aprender R? Inscríbete en el Curso de introducción a R de Applied Epi, prueba nuestros Tutoriales gratuitos de R, escribe en nuestro Foro de preguntas y respuestas, o pregunta por nuestra Asistencia técnica para R.

9 Trabajando con Fechas

Trabajar con fechas en R requiere más atención que trabajar con otros tipos de objetos. A continuación, ofrecemos algunas herramientas y ejemplos para hacer este proceso menos doloroso. Por suerte, las fechas pueden manejarse fácilmente con la práctica y con un conjunto de paquetes útiles como lubridate.

Al importar los datos en bruto, R suele interpretar las fechas como objetos de carácter, lo que significa que no pueden utilizarse para operaciones generales con fechas, como la creación de series temporales y el cálculo de intervalos de tiempo. Para hacer las cosas más difíciles, hay muchas maneras de formatear una fecha y debes ayudar a R a saber qué parte de una fecha representa qué (mes, día, hora, etc.).

Las fechas en R son su propio tipo de objeto - el tipo Date. Hay que tener en cuenta que también hay un tipo que almacena objetos con fecha y hora. Los objetos fecha-hora se denominan formalmente tipos POSIXt, POSIXct, o POSIXlt (la diferencia no es importante). Estos objetos se denominan informalmente tipos datetime.

  • Es importante hacer que R reconozca cuando una columna contiene fechas.
  • Las fechas son un tipo de objeto y pueden ser difíciles de trabajar.
  • Aquí presentamos varias formas de convertir columnas de fecha al tipo Date.

9.1 Preparación

Cargar paquetes

Este trozo de código muestra la carga de paquetes necesaria para esta página. En este manual destacamos p_load() de pacman, que instala el paquete si es necesario y lo carga para su uso. También puedes cargar los paquetes instalados con library() de R base. Consulta la página sobre los Fundamentos de R para obtener más información sobre los paquetes de R.

# Ccomprueba si el paquete está instalado, lo instala si es necesario y lo carga para la sesión actual.


pacman::p_load(
  lubridate, # paquete general para manejar y convertir fechas  
  linelist, # tiene una función para "adivinar" fechas desordenadas
  aweek, # otra opción para convertir fechas en semanas, y semanas en fechas
  zoo, # funciones adicionales de fecha/hora
  tidyverse, # gestión y visualización de datos  
  rio) # importación/exportación de datos

Importar datos

Importamos los datos de casos de una epidemia de ébola simulada. Si deseas descargar los datos para seguirlos paso a paso, consulta las instrucciones en la página de descarga de manuales y datos. Asumimos que el archivo está en el directorio de trabajo, por lo que no se especifican subcarpetas en esta ruta de archivo.

linelist <- import("linelist_cleaned.xlsx")

9.2 Fecha actual

Puedes obtener la fecha actual del “sistema” o la fecha-hora del sistema de tu ordenador haciendo lo siguiente con R base.

# obtener la fecha del sistema - esta es de tipo DATE (FECHA)
Sys.Date()
## [1] "2023-01-09"
# obtener la hora del sistema - esta es de tipo DATETIME (FECHAHORA)
Sys.time()
## [1] "2023-01-09 21:23:59 CET"

Con el paquete lubridate también se pueden devolver con today() y now(), respectivamente. date() devuelve la fecha y la hora actuales con los nombres del día de la semana y del mes.

9.3 Convertir en fecha

Después de importar unos datos a R, los valores de las columnas de fecha pueden tener el aspecto de “1989/12/30”, “05/06/2014” o “13 Ene 2020”. En estos casos, es probable que R siga tratando estos valores como valores de carácter. Hay que decirle a R que estos valores son fechas… y cuál es el formato de la fecha (qué parte es Día, cuál es Mes, cuál es Año, etc).

Una vez dicho esto, R convierte estos valores al tipo Date. En segundo plano, R almacenará las fechas como números (el número de días desde su fecha “origen” 1 Ene 1970). No interactuarás con el número de la fecha a menudo, pero esto permite a R tratar las fechas como variables continuas y permitir operaciones especiales como el cálculo de la distancia entre las fechas.

Por defecto, los valores del tipo Date en R se muestran como AAAA-MM-DD. Más adelante en esta sección discutiremos cómo cambiar la visualización de los valores de fecha.

A continuación presentamos dos enfoques para convertir una columna de valores de carácter al tipo Date.

CONSEJO:: Puedes comprobar el tipo actual de una columna con la función class()de R base, como class(linelist$date_onset).

R base

as.Date() es la función estándar de R base para convertir un objeto o una columna en el tipo Date (nótese la “D” en mayúscula).

El uso de as.Date() requiere que:

  • Se especifique el formato existente de la fecha de carácter en bruto o la fecha de origen si se suministran las fechas como números (véase la sección sobre las fechas de Excel)
  • Si se utiliza en una columna de caracteres, todos los valores de fecha deben tener el mismo formato exacto (si no es el caso, pruebe con parse_date() del paquete parsedate)

En primer lugar, comprueba el tipo de la columna con class() de R base . Si no estás seguro o estás confundido sobre el tipo de datos (por ejemplo, ve “POSIXct”, etc.) puede ser más fácil convertir primero la columna al tipo Character con as.character(), y luego convertirla al tipo Date.

En segundo lugar, dentro de la función as.Date(), utiliza el argumento format = para indicar a R el formato actual de los componentes de la fecha con caracteres - qué caracteres se refieren al mes, al día y al año, y cómo están separados. Si sus valores ya están en uno de los formatos de fecha estándar de R (“AAAA-MM-DD” o “AAAA/MM/DD”) el argumento format = no es necesario.

Para usar format =, escribe una cadena de caracteres (entre comillas) que represente el formato actual de la fecha utilizando las abreviaturas especiales “strptime” que aparecen a continuación. Por ejemplo, si las fechas de caracteres están actualmente en el formato “DD/MM/AAAA”, como “24/04/1968”, entonces usarías format = "%d/%m/%Y" para convertir los valores en fechas. Es necesario poner el formato entre comillas. ¡Y no olvides las barras o guiones!.

# Convertir a tipo fecha
linelist <- linelist %>% 
  mutate(date_onset = as.Date(date_of_onset, format = "%d/%m/%Y"))

La mayoría de las abreviaturas de strptime se enumeran a continuación. Puedes ver la lista completa ejecutando ?strptime.

%d = Número del día del mes (5, 17, 28, etc.) %j = Número del día del año (día juliano 001-366) %a = Día de la semana abreviado (lunes, martes, miércoles, etc.) %A = Día de la semana completo (lunes, martes, etc.) %w = Número del día de la semana (0-6, el domingo es 0) %u = Número del día de la semana (1-7, el lunes es 1) %W = Número de la semana (00-53, el lunes es el comienzo de la semana) %U = Número de la semana (01-53, el domingo es el comienzo de la semana) %m = Número del mes (p. ej. 01, 02, 03, 04) %b = Mes abreviado (enero, febrero, etc.) %B = Mes completo (enero, febrero, etc.) %y = Año de 2 dígitos (p. ej. 89) %Y = Año de 4 dígitos (p. ej. 1989) %h = Horas (reloj de 24 horas) %m = Minutos %s = Segundos %z = Desplazamiento respecto a GMT %Z = Huso horario (carácter)

CONSEJO: El argumento format = de as.Date() no le dice a R el formato que quiere que tengan las fechas, sino cómo identificar las partes de la fecha tal y como son antes de ejecutar el comando.

CONSEJO: Asegúrate que en el argumento format = se utiliza el mismo separador de partes de fechas (por ejemplo, /, -, o espacio) que está en tus fechas.

Una vez que los valores están en el tipo Fecha, R los mostrará por defecto en el formato estándar, que es AAAA-MM-DD.

lubridate

La conversión de objetos de carácter a fechas puede facilitarse utilizando el paquete lubridate. Se trata de un paquete tidyverse diseñado para hacer que el trabajo con fechas y horas sea más sencillo y consistente que en R base. Por estas razones, el paquete lubridate se considera a menudo el estándar de oro para las fechas y la hora, y se recomienda siempre que se trabaje con ellas.

El paquete lubridate proporciona varias funciones de ayuda diferentes diseñadas para convertir objetos de caracteres en fechas de una manera intuitiva y más indulgente que especificando el formato en as.Date(). Estas funciones son específicas para el formato de fecha aproximado, pero permiten una variedad de separadores, y sinónimos para las fechas (por ejemplo, 01 vs Jan vs Enero) - se denominan según las abreviaturas de los formatos de fecha.

# instalar/cargar lubridate 
pacman::p_load(lubridate)

La flexibilidad de la función ymd() convierte de forma flexible los valores de fecha suministrados como año, luego mes y luego día.

# leer la fecha en formato año-mes-día
ymd("2020-10-11")
## [1] "2020-10-11"
ymd("20201011")
## [1] "2020-10-11"

La función mdy() convierte de forma flexible los valores de fecha suministrados como mes, luego día y luego año.

# leer la fecha en formato mes-día-año
mdy("10/11/2020")
## [1] "2020-10-11"
mdy("Oct 11 20")
## [1] "2020-10-11"

La función dmy() convierte de forma flexible los valores de fecha suministrados como día, luego mes y luego año.

# leer la fecha en formato día-mes-año
dmy("11 10 2020")
## [1] "2020-10-11"
dmy("11 October 2020")
## [1] "2020-10-11"

Si se utilizan pipes, la conversión de una columna de caracteres a fechas con lubridate podría tener este aspecto:

linelist <- linelist %>%
  mutate(date_onset = lubridate::dmy(date_onset))

Una vez completado, puedes ejecutar class() para verificar el tipo de la columna

# Comprueba el tio de columna
class(linelist$date_onset)  

Una vez que los valores están en el tipo Fecha, R los mostrará por defecto en el formato estándar, que es AAAA-MM-DD.

Ten en cuenta que las funciones anteriores funcionan mejor con años de 4 dígitos. Los años de 2 dígitos pueden producir resultados inesperados, ya que lubridate intenta adivinar el siglo.

Para convertir un año de 2 dígitos en un año de 4 dígitos (todos en el mismo siglo) puedes convertirlo a tipo carácter y luego combinar los dígitos existentes con un prefijo usando str_glue() del paquete stringr. Ver Caracteres y cadenas. A continuación, convierte a fecha.

two_digit_years <- c("15", "15", "16", "17")
str_glue("20{two_digit_years}")
## 2015
## 2015
## 2016
## 2017

Combinar columnas

Puedes utilizar las funciones de lubridate make_date() y make_datetime() para combinar varias columnas numéricas en una columna de fecha. Por ejemplo, si tiene columnas numéricas onset_day, onset_month y onset_year en el dataframe linelist:

linelist <- linelist %>% 
  mutate(onset_date = make_date(year = onset_year, month = onset_month, day = onset_day))

9.4 Fechas en Excel

En el fondo, la mayoría de los programas informáticos almacenan las fechas como números. R almacena las fechas desde un origen del 1 de enero de 1970. Así, si ejecutas as.numeric(as.Date("1970-01-01")) obtendrás 0.

Microsoft Excel almacena las fechas con un origen dependiendo del sistema operativo, del 30 de diciembre de 1899 (Windows) o del 1 de enero de 1904 (Mac). Consulta esta guía de Microsoft para obtener más información.

Las fechas de Excel suelen importarse a R como estos valores numéricos en lugar de como caracteres. Si los datos que has importado de Excel muestran las fechas como números o caracteres como “41369”… utiliza as.Date() (o la función as_date() de lubridate) para convertirlas, pero en lugar de suministrar un “formato” como el anterior, suministra la fecha de origen de Excel al argumento origin = .

Esto no funcionará si la fecha de Excel se almacena en R como de tipo carácter, ¡así que asegúrate de que el número es de tipo numérico!.

NOTA: Debes proporcionar la fecha de origen en el formato de fecha por defecto de R (“AAAA-MM-DD”).

# Un ejemplo de proporcionar la "fecha de origen" de Excel al convertir fechas numéricas de Excel
data_cleaned <- data %>% 
  mutate(date_onset = as.numeric(date_onset)) %>%   # asegura que la clase es numérica
  mutate(date_onset = as.Date(date_onset, origin = "1899-12-30")) # convierte a fecha usando el origen de Excel

9.5 Fechas desordenadas

La función parse_date() del paquete parsedate intenta leer una columna de fecha “desordenada” que contiene fechas en muchos formatos diferentes y convertir las fechas a un formato estándar. Puedes leer más en línea sobre guess_dates().

Por ejemplo parse_date() vería un vector de las siguientes fechas de caracteres “03 Ene 2018”, “07/03/1982”, y “08/20/85” y las convertiría al tipo Date como 2018-01-03, 1982-03-07, y 1985-08-20.

parsedate::parse_date(c("03 Jany 2018",
                        "07/03/1982",
                        "08/20/85"))
## [1] "2018-01-03 UTC" "1982-07-03 UTC" "1985-08-20 UTC"
# Un ejemplo usando guess_dates en la columna date_onset
linelist <- linelist %>%                 # el conjunto de datos se llama linelist
  mutate(
    date_onset = parsedate::parse_date(date_onset))  # parse_date() del paquete "parsedate"

9.6 Trabajar con el tipo fecha-hora

Como se mencionó anteriormente, R también soporta un tipo datetime - una columna que contiene información de fecha y hora. Al igual que con el tipo Date, a menudo es necesario convertirlas de objetos character a objetos datetime.

Convertir fechas con horas

Un objeto datetime estándar se formatea con la fecha en primer lugar, seguida de un componente de tiempo - por ejemplo, 01 Ene 2020, 16:30. Al igual que con las fechas, hay muchas maneras de formatearlas, y hay numerosos niveles de precisión (horas, minutos, segundos) que se pueden suministrar.

Por suerte, también existen funciones de ayuda de lubridate para ayudar a convertir estas cadenas en objetos datetime. Estas funciones son extensiones de las funciones de ayuda a la fecha, con _h (sólo se suministran las horas), _hm (se suministran las horas y los minutos), o _hms (se suministran las horas, los minutos y los segundos) añadidas al final (por ejemplo, dmy_hms()). Se pueden utilizar como se indica:

Convertir datetime con sólo horas a objeto datetime

ymd_h("2020-01-01 16hrs")
## [1] "2020-01-01 16:00:00 UTC"
ymd_h("2020-01-01 4PM")
## [1] "2020-01-01 16:00:00 UTC"

Convertir datetime con horas y minutos a objeto datetime

dmy_hm("01 January 2020 16:20")
## Warning: All formats failed to parse. No formats found.
## [1] NA

Convertir datetime con horas, minutos y segundos a objeto datetime

mdy_hms("01 January 2020, 16:20:40")
## [1] "2020-01-20 16:20:40 UTC"

Puedes indicar la zona horaria, pero se ignora. Consulta la sección más adelante en esta página sobre las zonas horarias.

mdy_hms("01 January 2020, 16:20:40 PST")
## [1] "2020-01-20 16:20:40 UTC"

Cuando se trabaja con un dataframe, las columnas de fecha y hora pueden combinarse para crear una columna de fecha y hora utilizando str_glue()del paquete stringr y una función apropiada de lubridate. Consulta la página sobre Caracteres y cadenas para obtener detalles sobre stringr.

En este ejemplo, el dataframe linelist tiene una columna con formato “horas:minutos”. Para convertirla en una fecha, hay que seguir algunos pasos:

  1. Crea una columna de tiempo de admisión “limpia” con los valores faltantes rellenados con la mediana de la columna. Hacemos esto porque lubridate no opera con valores faltantes. Combínala con la columna date_hospitalisation y utiliza la función ymd_hm() para convertirla.
# paquetes
pacman::p_load(tidyverse, lubridate, stringr)

# time_admission es una columna en horas:minutos
linelist <- linelist %>%
  
  ## cuando no se da la hora de admisión, asigna la mediana del tiempo de admisión
  mutate(
    time_admission_clean = ifelse(
      is.na(time_admission),         # si falta el hora
      median(time_admission),        # asignar la mediana
      time_admission                 # si no falta la hora mantenerla 
  ) %>%
  
    # utilizar str_glue() para combinar las columnas de fecha y hora para crear una columna de caracteres
    # y luego usar ymd_hm() para convertirla en fecha-hora
  mutate(
    date_time_of_admission = str_glue("{date_hospitalisation} {time_admission_clean}") %>% 
      ymd_hm()
  )

Convertir sólo horas

Si tus datos contienen sólo un carácter de tiempo (horas y minutos), puedes convertirlos y manipularlos como tiempos utilizando strptime() desde R base. Por ejemplo, para obtener la diferencia entre dos de estos horas:

# hora cruda de tipo carácter
time1 <- "13:45" 
time2 <- "15:20"

# Horas convertidas a una clase fecha
time1_clean <- strptime(time1, format = "%H:%M")
time2_clean <- strptime(time2, format = "%H:%M")

# La diferencia es de tipo "difftime" por defecto, aquí convertida a horas numéricas 
as.numeric(time2_clean - time1_clean)   # diferencia en horas
## [1] 1.583333

Sin embargo, ten en cuenta que si no se proporciona un valor de fecha, se asume que la fecha es hoy. Para combinar una cadena de fecha y una cadena de hora, observa cómo se usa stringr en la sección anterior. Puedes leer más sobre strptime() aquí.

Para convertir números de un solo dígito a dos dígitos (por ejemplo, para “rellenar” las horas o los minutos con ceros a la izquierda para conseguir 2 dígitos), consulta la sección “Longitud de relleno” de la página Caracteres y cadenas.

Extraer fracciones de hora

Puedes extraer elementos de una hora con hour(), minute(), o second() de lubridate.

He aquí un ejemplo de extracción de la hora y posterior clasificación como parte del día. Comenzamos con la columna time_admission, que es de tipo Carácter en formato “HH:MM”. En primer lugar, se utiliza strptime() como se ha descrito anteriormente para convertir los caracteres en tipo datetime. A continuación, se extrae la hora con hour(), devolviendo un número del 0 al 24. Por último, se crea una columna time_period utilizando la lógica con case_when() para clasificar las filas en Mañana/Tarde/Anochecer/Noche en función de su hora de entrada.

linelist <- linelist %>%
  mutate(hour_admit = hour(strptime(time_admission, format = "%H:%M"))) %>%
  mutate(time_period = case_when(
    hour_admit > 06 & hour_admit < 12 ~ "Morning",
    hour_admit >= 12 & hour_admit < 17 ~ "Afternoon",
    hour_admit >= 17 & hour_admit < 21 ~ "Evening",
    hour_admit >=21 | hour_admit <= 6 ~ "Night"))

Para saber más sobre case_when(), consulta la página sobre Limpieza de datos y funciones básicas.

9.7 Trabajar con fechas

lubridate también puede utilizarse para otras funciones, como la extracción de aspectos de una fecha/hora, realización de cálculos aritméticos de fechas o cálculo de intervalos de fechas

Aquí definimos una fecha que se utilizará para los ejemplos:

# crear un objeto de clase Date
example_date <- ymd("2020-03-01")

Extraer los componentes de la fecha

Puedes extraer aspectos comunes como el mes, el día, el día de la semana:

month(example_date)  # número del mes
## [1] 3
day(example_date)    # día (número) del mes
## [1] 1
wday(example_date)   # número de día de la semana (1-7)
## [1] 1

También puede extraer componentes de tiempo de un objeto o columna datetime. Esto puede ser útil si quieres ver la distribución de los tiempos de admisión.

example_datetime <- ymd_hm("2020-03-01 14:45")

hour(example_datetime)     # extraer la hora
minute(example_datetime)   # extraer el minuto
second(example_datetime)   # extraer el segundo

Hay varias opciones para recuperar las semanas. Consulta la sección sobre semanas epidemiológicas más abajo.

Ten en cuenta que si deseas mostrar una fecha de una forma determinada (por ejemplo, “enero de 2020” o “jueves 20 de marzo” o “semana 20 de 1977”) puedes hacerlo de forma más flexible, tal y como se describe en la sección sobre Visualización de fechas.

Fecha matemática

Puedes añadir ciertos números de días o semanas utilizando su respectiva función de lubridate.

# añadir 3 días a esta fecha
example_date + days(3)
## [1] "2020-03-04"
# añade 7 semanas y resta dos días a esta fecha
example_date + weeks(7) - days(2)
## [1] "2020-04-17"

Intervalos de fechas

La diferencia entre las fechas se puede calcular mediante:

  1. Asegúrate que ambas fechas son del mismo tipo
  2. Utiliza la resta para devolver la diferencia “difftime” entre las dos fechas
  3. Si es necesario, convierte el resultado en tipo numéricoa para realizar los cálculos matemáticos posteriores

A continuación se calcula y muestra el intervalo entre dos fechas. Se pueden encontrar intervalos utilizando el símbolo de resta “menos” en los valores que son de tipo Fecha. Ten en cuenta, sin embargo, que el tipo del valor devuelto es “difftime”, como se muestra a continuación, y debe ser convertido a numérico.

# encontrar el intervalo entre esta fecha y el 20 de febrero de 2020 
output <- example_date - ymd("2020-02-20")
output    # imprimir
## Time difference of 10 days
class(output)
## [1] "difftime"

Para realizar operaciones posteriores sobre un “difftime”, conviértelo en numérico con as.numeric().

Todo esto puede unirse para trabajar con datos, por ejemplo:

pacman::p_load(lubridate, tidyverse)   # load packages

linelist <- linelist %>%
  
  # convertir la fecha de inicio de los objetos carácter a fecha especificando el formato dmy
  mutate(date_onset = dmy(date_onset),
         date_hospitalisation = dmy(date_hospitalisation)) %>%
  
  # filtrar todos los casos sin inicio en marzo
  filter(month(date_onset) == 3) %>%
    
  # encontrar la diferencia de días entre el inicio y la hospitalización
  mutate(days_onset_to_hosp = date_hospitalisation - date_of_onset)

En un contexto de dataframe, si falta alguna de las fechas anteriores, la operación fallará para esa fila. El resultado será un NA en lugar de un valor numérico. Cuando utilices esta columna para los cálculos, asegúrate de establecer el argumento na.rm = en TRUE. Por ejemplo:

# Calcular la mediana del número de días hasta la hospitalización para todos los casos de los que se dispone de datos
median(linelist_delay$days_onset_to_hosp, na.rm = T)

9.8 Visualización de fechas

Una vez que las fechas son del tipo correcto, a menudo se desea mostrarlas de forma diferente, por ejemplo para que se muestren como “lunes 05 de enero” en lugar de “2018-01-05”. También puedes querer ajustar la visualización para agrupar las filas por los elementos de fecha mostrados, por ejemplo, para agrupar por mes-año.

format()

Ajusta la visualización de la fecha con la función format() de R base. Esta función acepta una cadena de caracteres (entre comillas) que especifica el formato de salida deseado en las abreviaturas strptime “%” (la misma sintaxis que se utiliza en as.Date()). A continuación se muestran las abreviaturas más comunes.

Nota: el uso de format() convertirá los valores al tipo Character, por lo que generalmente se utiliza hacia el final de un análisis o sólo para fines de visualización. Puedes ver la lista completa ejecutando ?strptime.

%d = Número del día del mes (5, 17, 28, etc.) %j = Número del día del año (día juliano 001-366) %a = Día de la semana abreviado (lunes, martes, miércoles, etc.) %A = Día de la semana completo (lunes, martes, etc.) %w = Número del día de la semana (0-6, el domingo es 0) %u = Número del día de la semana (1-7, el lunes es 1) %W = Número de la semana (00-53, el lunes es el comienzo de la semana) %U = Número de la semana (01-53, el domingo es el comienzo de la semana) %m = Número del mes (p. ej. 01, 02, 03, 04) %b = Mes abreviado (enero, febrero, etc.) %B = Mes completo (enero, febrero, etc.) %y = Año de 2 dígitos (p. ej. 89) %Y = Año de 4 dígitos (p. ej. 1989) %h = Horas (reloj de 24 horas) %m = Minutos %s = Segundos %z = Desplazamiento respecto a GMT %Z = Huso horario (carácter)

Un ejemplo de formato de la fecha de hoy:

# # fecha de hoy, con formato
format(Sys.Date(), format = "%d %B %Y")
## [1] "09 enero 2023"
# forma sencilla de obtener la fecha y hora completas (formato por defecto)
date()
## [1] "Mon Jan  9 21:24:00 2023"
# formato combinado de fecha, hora y zona horaria usando la función str_glue() 
str_glue("{format(Sys.Date(), format = '%A, %B %d %Y, %z  %Z, ')}{format(Sys.time(), format = '%H:%M:%S')}")
## lunes, enero 09 2023, +0000  UTC, 21:24:00
# Utilizar format para mostrar las semanas
format(Sys.Date(), "%Y Week %W")
## [1] "2023 Week 02"

Ten en cuenta que si utilizas str_glue(), dentro de las comillas dobles ” sólo debes utilizar comillas simples (como arriba).

Mes-Año

Para convertir una columna de fecha al formato mes-año, te sugerimos que utilice la función as.yearmon() del paquete zoo. Esto convierte la fecha al tipo “yearmon” y mantiene el orden correcto. Por el contrario, usar format(columna, "%Y %B") convertirá al tipo Carácter y ordenará los valores alfabéticamente (incorrectamente).

A continuación, se crea una nueva columna yearmonth a partir de la columna date_onset, utilizando la función as.yearmon()`. La ordenación por defecto (correcta) de los valores resultantes se muestra en la tabla.

# crear una columna nueva
test_zoo <- linelist %>% 
     mutate(yearmonth = zoo::as.yearmon(date_onset))

# imprimir tabla
table(test_zoo$yearmon)
## 
## abr 2014 may 2014 jun 2014 jul 2014 ago 2014 sep 2014 oct 2014 nov 2014 dic 2014 ene 2015 feb 2015 mar 2015 abr 2015 
##        7       64      100      226      528     1070     1112      763      562      431      306      277      186

Por el contrario, se puede ver cómo sólo utilizando format() se consigue el formato de visualización deseado, pero no el orden correcto.

# crear una columna nueva
test_format <- linelist %>% 
     mutate(yearmonth = format(date_onset, "%b %Y"))

# imprimir tabla
table(test_format$yearmon)
## 
## abr 2014 abr 2015 ago 2014 dic 2014 ene 2015 feb 2015 jul 2014 jun 2014 mar 2015 may 2014 nov 2014 oct 2014 sep 2014 
##        7      186      528      562      431      306      226      100      277       64      763     1112     1070

Nota: si estás trabajando con ggplot() y quieres ajustar sólo cómo se muestran las fechas, puede ser suficiente proporcionar un formato strptime al argumento date_labels = en scale_x_date() - puedes utilizar "%b %Y" o "%Y %b". Consulta la página de consejos de ggplot.

zoo también ofrece la función as.yearqtr(), y puedes usar scale_x_yearmon() cuando uses ggplot().

9.9 Semanas epidemiológicas

lubridate

Consulta la página sobre Agrupar datos para ver ejemplos más extensos de agrupación de datos por fecha. A continuación describimos brevemente la agrupación de datos por semanas.

Generalmente recomendamos utilizar la función floor_date() de lubridate, con el argumento unit = "week". Esto redondea la fecha hacia abajo al “inicio” de la semana, como se define por el argumento week_start =. El inicio de la semana por defecto es el 1 (para los lunes), pero se puede especificar cualquier día de la semana como inicio (por ejemplo, el 7 para los domingos). floor_date() es versátil y se puede utilizar para redondear hacia abajo a otras unidades de tiempo estableciendo unit = “second”, “minute”, “hour”, “day”, “month”, o “year”.

El valor devuelto es la fecha de inicio de la semana, en tipo Date. El tipo Date es útil a la hora de representar los datos, ya que serán fácilmente reconocidos y ordenados correctamente por ggplot().

Si sólo tienes interés en ajustar las fechas para que se muestren por semanas en un gráfico, consulta la sección de esta página sobre Visualización de fechas. Por ejemplo, al representar una epicurva puedes formatear la visualización de la fecha proporcionando la nomenclatura strptime “%” deseada. Por ejemplo, utiliza “%Y-%W” o “%Y-%U” para devolver el año y el número de semana (dado el comienzo de la semana del lunes o del domingo, respectivamente).

Recuentos semanales

Consulta la página sobre Agrupar datos para obtener una explicación detallada de la agrupación de datos con count(), group_by(), and summarise(). A continuación se muestra un breve ejemplo.

  1. Crear una nueva columna “semana” con mutate(), utilizando floor_date() con unit = "week"

  2. Obtener el recuento de filas (casos) por semana con count(); filtra los casos a los que les falte la fecha

  3. Termina con complete() de tidyr para asegurarte que todas las semanas aparecen en los datos - incluso las que no tienen filas/casos. Por defecto, los valores de recuento para cualquier fila “nueva” son NA, pero puedes hacerlos 0 con el argumento fill =, que espera una lista con nombre (abajo, n es el nombre de la columna de recuentos).

# Hacer un conjunto de datos agregados con los recuentos semanales de casos
weekly_counts <- linelist %>% 
  drop_na(date_onset) %>%             # eliminar los casos sin fecha de inicio
  mutate(weekly_cases = floor_date(   # crear columna nueva, semana de inicio
    date_onset,
    unit = "week")) %>%            
  count(weekly_cases) %>%           # agrupar datos por semana y contar filas por grupo (crea columna 'n')
  tidyr::complete(                  # asegúrar que todas las semanas están presentes, incluso aquellas en las que no se ha notificado ningún caso
    weekly_cases = seq.Date(          # redefinir la columna "weekly_cases" como una secuencia completa,
      from = min(weekly_cases),       # desde la fecha mínima
      to = max(weekly_cases),         # hasta la fecha máxima
      by = "week"),                   # por semanas
    fill = list(n = 0))             # rellenar los NA de la columna n con 0

Aquí están las primeras filas del dataframe resultante:

Alternativas a Epiweek

Ten en cuenta que lubridate también tiene las funciones week(), epiweek(), e isoweek(), cada una de las cuales tiene fechas de inicio ligeramente diferentes y otros matices. Sin embargo, en términos generales, floor_date() debería ser todo lo que necesitas. Puedes leer más detalles de estas funciones introduciendo ?week en la consola o leyendo la documentación aquí.

Puedes usar del paquete aweek para establecer semanas epidemiológicas. Puedes leer más sobre él en el sitio web de RECON. Tiene las funciones date2week() y week2date() en las que se puede establecer el día de inicio de la semana con week_start = "Monday". Este paquete es el más fácil si se desea obtener resultados del tipo “week” (por ejemplo, “2020-W12”). Otra ventaja de aweek es que cuando date2week() se aplica a una columna de fecha, la columna devuelta (formato de semana) es automáticamente del tipo Factor e incluye niveles para todas las semanas en el lapso de tiempo (esto evita el paso extra de complete() descrito anteriormente). Sin embargo, aweek no tiene la funcionalidad de redondear fechas a otras unidades de tiempo como meses, años, etc.

Otra alternativa para las series temporales que también funciona bien para mostrar un formato de “semana” (“2020 W12”) es yearweek() del paquete tsibble, como se demuestra en la página sobre series temporales y detección de brotes.

9.10 Conversión de fechas/zonas horarias

Cuando los datos están presentes en diferentes husos horarios, a menudo puede ser importante normalizar estos datos en un huso horario unificado. Esto puede suponer un reto adicional, ya que el componente de zona horaria de los datos debe codificarse manualmente en la mayoría de los casos.

En R, cada objeto datetime tiene un componente de zona horaria. Por defecto, todos los objetos datetime llevarán la zona horaria local para el ordenador que se está utilizando - esto es generalmente específico para una ubicación en lugar de una zona horaria, ya que las zonas horarias a menudo cambian en los lugares debido al horario de verano. No es posible compensar con precisión las zonas horarias sin un componente de tiempo de una fecha, ya que el evento que representa una columna de fecha no puede ser atribuido a un tiempo específico, y por lo tanto los cambios de tiempo medidos en horas no pueden ser razonablemente contabilizados.

Para tratar las zonas horarias, hay una serie de funciones de ayuda en lubridate que pueden utilizarse para cambiar la zona horaria de un objeto datetime de la zona horaria local a una zona horaria diferente. Las zonas horarias se establecen atribuyendo una zona horaria válida de la base de datos tz al objeto datetime. Aquí se puede encontrar una lista de éstas - si la ubicación que se está utilizando en los datos no está en esta lista, las grandes ciudades cercanas en la zona horaria están disponibles y sirven para el mismo propósito.

# asignar la hora actual a una columna
time_now <- Sys.time()
time_now
## [1] "2023-01-09 21:24:00 CET"
# usa with_tz() para asignar una nueva zona horaria a la columna, mientras CAMBIA la hora del reloj
time_london_real <- with_tz(time_now, "Europe/London")

# use force_tz() para asignar una nueva zona horaria a la columna, y MANTIENE la hora del reloj
time_london_local <- force_tz(time_now, "Europe/London")

# siempre y cuando el equipo que se utilizó para ejecutar este código NO TIENE la hora de Londres,
# habrá una diferencia en los tiempos 
# (el número de horas de diferencia entre la zona horaria del ordenador y Londres)
time_london_real - time_london_local
## Time difference of -1 hours

Esto puede parecer muy abstracto, y a menudo no es necesario si el usuario no está trabajando en distintas zonas horarias.

9.11 Cálculos de retardo y de avance

lead() y lag() son funciones del paquete dplyr que ayudan a encontrar los valores anteriores (retardados) o posteriores (principales) en un vector, normalmente un vector numérico o de fechas. Esto es útil cuando se hacen cálculos de cambio/diferencia entre unidades de tiempo.`

Supongamos que se quiere calcular la diferencia de casos entre una semana actual y la anterior. Los datos se proporcionan inicialmente en recuentos semanales, como se muestra a continuación.

Al utilizar lag() o lead(), el orden de las filas en el dataframe es muy importante. - presta atención a si tus fechas/números son ascendentes o descendentes

En primer lugar, crea una nueva columna que contenga el valor de la semana anterior (retardada).

  • Controla el número de unidades hacia atrás/adelante con n = (debe ser un entero no negativo)

  • Utiliza default = para definir el valor colocado en las filas no existentes (por ejemplo, la primera fila para la que no hay un valor retardado). Por defecto es NA.

  • Utiliza order_by = TRUE si tus filas no están ordenadas por su columna de referencia

counts <- counts %>% 
  mutate(cases_prev_wk = lag(cases_wk, n = 1))

A continuación, crea una nueva columna que sea la diferencia entre las dos columnas de los casos:

counts <- counts %>% 
  mutate(cases_prev_wk = lag(cases_wk, n = 1),
         case_diff = cases_wk - cases_prev_wk)

Puedes leer más sobre lead() y lag() en esta documentación aquí o introduciendo ?lag en tu consola.

9.12 Recursos

Página de lubridate** tidyverse

Página de lubridate RStudio cheatsheet

R for Data Science en español sobre [fechas y horas]https://es.r4ds.hadley.nz/fechas-y-horas.html

Tutorial en línea

Formatos de fecha]