× ¿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.

7 Importación y exportación

En esta página describimos las formas de localizar, importar y exportar archivos:

  • Uso del paquete rio y las funciones import() y export() para importar muchos tipos de archivos.

  • Uso del paquete here para localizar archivos relativos a la raíz de un proyecto R - para evitar complicaciones de las rutas de los archivos que son específicas de un ordenador

  • Escenarios específicos de importación, como:

  • Hojas de Excel

  • Encabezados desordenados y filas que se saltan/son omitidas

  • Desde las hojas de Google

  • A partir de datos publicados en sitios web

  • Con las API

  • Importar el archivo más reciente

  • Introducción manual de datos

  • Tipos de archivos específicos de R, como RDS y RData

  • Exportar/guardar archivos y gráficos

7.1 Resumen

Cuando importas unos “datos” en R, generalmente estás creando un nuevo objeto data frame en tu entorno de R y definiéndolo como un archivo importado (por ejemplo, Excel, CSV, TSV, RDS) que será guardado en tu disco en una determinada ruta/dirección.

Puedes importar/exportar muchos tipos de archivos, incluidos los creados por otros programas estadísticos (SAS, STATA, SPSS). También puedes conectarte a bases de datos relacionales.

R tiene incluso sus propios formatos de datos:

  • Un archivo RDS (.rds) almacena un único objeto R, como un dataframe. Son útiles para almacenar datos limpios, ya que mantienen los tipos de columnas de R. Lee más en esta sección.
  • Un archivo RData (.Rdata) puede utilizarse para almacenar múltiples objetos, o incluso un espacio de trabajo R completo. Lee más en esta sección.

7.2 El paquete rio

El paquete de R que recomendamos es: rio. El nombre “rio” es una abreviatura de “R I/O” (input/output).

Sus funciones import() y export() pueden manejar muchos tipos de archivos diferentes (por ejemplo, .xlsx, .csv, .rds, .tsv). Cuando se proporciona una ruta de archivo a cualquiera de estas funciones (incluyendo la extensión del archivo como “.csv”), rio leerá la extensión y utilizará la herramienta correcta para importar o exportar el archivo.

La alternativa al uso de rio es utilizar funciones de muchos otros paquetes, cada uno de los cuales es específico para un tipo de archivo. Por ejemplo, read.csv() (R base), read.xlsx() (paquete openxlsx), y write_csv() (paquete readr), etc. Estas alternativas pueden ser difíciles de recordar, mientras que usar import() y export() de rio es fácil.

Las funciones import() y export() de rio utilizan el paquete y la función adecuados para un archivo determinado, basándose en su extensión. Al final de esta página puedes ver una tabla completa de los paquetes/funciones que utiliza rio en segundo plano. También puede utilizarse para importar archivos de STATA, SAS y SPSS, entre otras docenas de tipos de archivos.

La importación/exportación de shapefiles requiere otros paquetes, como se detalla en la página sobre Conceptos básicos de los SIG (Sistemas de Información Geográfica).

7.3 El paquete here

El paquete here y su función here() facilitan la tarea de decirle a R dónde encontrar y guardar tus archivos - en esencia, construye rutas de archivos.

Utilizado junto con un proyecto R, here te permite describir la ubicación de los archivos en tu proyecto R en relación con el directorio raíz de los proyectos de R (la carpeta de nivel superior). Esto es útil cuando el proyecto R puede ser compartido o accedido por múltiples personas/ordenadores. Evita las complicaciones debidas a las rutas de archivos únicas en diferentes ordenadores (por ejemplo, "C:/Users/Laura/Documents..." al “comenzar” la ruta de archivos en un lugar común a todos los usuarios (la raíz del proyecto R).

Así es como funciona here() dentro de un proyecto R:

  • Cuando, dentro del proyecto R, se carga por primera vez el paquete here, se coloca un pequeño archivo llamado “.here” en la carpeta raíz de tu proyecto R como un “punto de referencia” o “ancla”

  • En tus scripts, para referenciar un archivo en las subcarpetas del proyecto R, se utiliza la función here() para construir la ruta del archivo en relación con ese ancla

  • Para construir la ruta de los archivos, escribe los nombres de las carpetas más allá de la raíz, entre comillas, separados por comas, y finalmente termina con el nombre y la extensión del archivo, como se muestra a continuación

  • Las rutas de here() pueden utilizarse tanto para la importación como para la exportación

Por ejemplo, a continuación, la función import() recibe una ruta de archivo construida con here().

linelist <- import(here("data", "linelists", "ebola_linelist.xlsx"))

El comando here("data", "linelists", "ebola_linelist.xlsx") en realidad está proporcionando la ruta completa del archivo que es única para el ordenador del usuario:

"C:/Users/Laura/Documents/my_R_project/data/linelists/ebola_linelist.xlsx"

Lo bueno es que el comando here() puede ejecutarse en cualquier ordenador que acceda al proyecto R.

CONSEJO: Si no estás seguro de dónde está la raíz “.here”, ejecuta la función here() con los paréntesis vacíos.

Lee más sobre el paquete here en este enlace.

7.4 Rutas de los archivos

Al importar o exportar datos, debes proporcionar una ruta de archivo. Puedes hacerlo de tres maneras:

  1. Recomendado: proporcionar una ruta de archivo “relativa” con el paquete here
  2. Proporcionar la ruta “completa” / “absoluta” del archivo
  3. Seleccionar manualmente los archivos

Rutas de archivos “relativas”

En R, las rutas de archivo “relativas” consisten en la ruta de archivo relativa a la raíz de un proyecto R. Permiten rutas de archivo más simples que pueden funcionar en diferentes ordenadores (por ejemplo, si el proyecto R está en una unidad compartida o se envía por correo electrónico). Como se ha descrito anteriormente las rutas de archivo relativas se facilitan mediante el uso del paquete here.

A continuación se muestra un ejemplo de una ruta de archivo relativa construida con here(). Suponemos que el trabajo está en un proyecto R que contiene una subcarpeta “data” y dentro de ella una subcarpeta “linelists”, en la que está el archivo .xlsx de interés.

linelist <- import(here("data", "linelists", "ebola_linelist.xlsx"))

Rutas “absolutas”

Las rutas absolutas o “completas” de los archivos pueden proporcionarse a funciones como import(), pero son “frágiles”, ya que son únicas para el ordenador específico del usuario y, por tanto, no se recomiendan.

A continuación se muestra un ejemplo de ruta absoluta de archivos, donde en el ordenador de Laura hay una carpeta “analysis”, una subcarpeta “data” y dentro de ésta una subcarpeta “linelists”, en la que se encuentra el archivo .xlsx de interés.

linelist <- import("C:/Users/Laura/Documents/analysis/data/linelists/ebola_linelist.xlsx")

Hay que tener en cuenta algunas cosas sobre las rutas absolutas de los archivos:

  • Evita utilizar rutas absolutas de archivos, ya que el script no funcionará si se ejecuta en un ordenador diferente
  • Utiliza barras inclinadas (/), como en el ejemplo anterior (nota: esto NO es el valor predeterminado para las rutas de archivos de Windows)
  • Las rutas de archivos que comienzan con barras dobles (por ejemplo, “//…”) probablemente no serán reconocidas por R y producirán un error. Considera la posibilidad de trasladar tu trabajo a una unidad “con nombre” o que comience con una letra (por ejemplo, “J:” o “C:”). Consulta la página sobre interacciones con directorios para obtener más detalles sobre esta cuestión.

Un escenario en el que las rutas absolutas de los archivos pueden ser apropiadas es cuando se quiere importar un archivo desde una unidad compartida que tiene la misma ruta de archivo completa para todos los usuarios.

CONSEJO: Para convertir rápidamente las barras inclinadas \ a /, resalta el código de interés, usa Ctrl+f (en Windows), marca la casilla de opción para “En selección”, y luego usa la funcionalidad de reemplazo para convertirlos.

Selección manual

Puedes importar datos manualmente mediante uno de estos métodos:

  1. En el panel de entorno de RStudio, cliquea en “Import Dataset”, y selecciona el tipo de datos
  2. Cliquea en File / Import dataset / (selecciona el tipo de datos)
  3. Para codificar la selección manual, utiliza el comando de file.choose() (dejando los paréntesis vacíos) para provocar la aparición de una ventana emergente que permita al usuario seleccionar manualmente el archivo de su ordenador. Por ejemplo:
# Selección manual de un archivo. Cuando se ejecute este comando, aparecerá una ventana EMERGENTE.

# La ruta del archivo seleccionado será suministrada al comando import().

my_data <- import(file.choose())

CONSEJO: La ventana emergente puede aparecer DETRÁS de la ventana de RStudio.

7.5 Importar datos

Utilizar import() es bastante sencillo. Simplemente escribe la ruta del archivo (incluyendo el nombre y la extensión del archivo) entre comillas. Si utilizas here() para construir la ruta del archivo, sigue las instrucciones anteriores. A continuación se muestran algunos ejemplos:

Para importar un archivo csv que se encuentra en tu “directorio de trabajo” o en la carpeta raíz del proyecto R:

linelist <- import("linelist_cleaned.csv")

Para importar la primera hoja de un archivo de Excel que se encuentra en las subcarpetas “data” y “linelists” del proyecto R (la ruta del archivo construida con here()):

linelist <- import(here("data", "linelists", "linelist_cleaned.xlsx"))

Para importar un data frame (un archivo .rds) utilizando una ruta de archivo absoluta:

linelist <- import("C:/Users/Laura/Documents/tuberculosis/data/linelists/linelist_cleaned.rds")

Hojas de Excel específicas

Por defecto, si proporcionas un archivo de Excel (.xlsx) a import(), se importará la primera hoja del libro. Si deseas importar una hoja específica, incluye el nombre de la hoja con el argumento which =. Por ejemplo:

my_data <- import("my_excel_file.xlsx", which = "Sheetname")

Utilizando el método here() para proporcionar una vía relativa a import(), también podés importar una hoja específica añadiendo el argumento which = después del paréntesis de cierre de la función here().

# Demostración: importación de una hoja de Excel específica al utilizar rutas relativas con el paquete 'here'
linelist_raw <- import(here("data", "linelist.xlsx"), which = "Sheet1")`  

Para exportar un dataframe de R a una hoja de Excel específica y que el resto del archivo de Excel permanezca sin cambios, tendrás que importar, editar y exportar con un paquete alternativo destinado a este fin, como openxlsx. Vea más información en la página sobre las interacciones con directorios o en esta página de github.

Si tu libro de Excel es .xlsb (libro de Excel en formato binario) es posible que no puedas importarlo con rio. Considera la posibilidad de volver a guardarlo como .xlsx, o de utilizar un paquete como readxlsb, creado para este fin.

Valores faltantes

Es posible que desees designar qué valor(es) de tus datos se debe(n) considerar como faltantes (missing values). Como se explica en la página sobre Valores faltantes, el valor en R para los valores faltantes es NA, pero tal vez los datos que vas a importar utiliza 99, “Missing”, o simplemente el espacio de caracteres vacíos “” en su lugar.

Utiliza el argumento na = en import() y proporciona el(los) valor(es) entre comillas (incluso si son números). Puedes especificar varios valores incluyéndolos dentro de un vector, utilizando c() como se muestra a continuación.

Aquí, el valor “99” en los datos importados se considera valor faltante y se convierte en NA en R.

linelist <- import(here("data", "my_linelist.xlsx"), na = "99")

Aquí, cualquiera de los valores “Missing”, “” (celda vacía), o ” ” (un solo espacio) en los datos importados se convierten en NA en R.

linelist <- import(here("data", "my_linelist.csv"), na = c("Missing", "", " "))

Saltar filas

Si querés evitar la importación de una fila de datos, puedes hacerlo con el argumento skip = utilizando import() de rio en un archivo .xlsx o .csv. Debes proporcionar el número de filas que deseas omitir.

linelist_raw <- import("linelist_raw.xlsx", skip = 1)  # no importa la fila de cabecera

Desafortunadamente, skip = sólo acepta un valor entero, no un rango (por ejemplo, “2:10” no funciona). Para omitir la importación de filas específicas que no son consecutivas desde el principio, considera la posibilidad de importar varias veces y utilizar bind_rows() de dplyr. Mira en el ejemplo siguiente cómo se omite sólo la fila 2.

Gestionar una segunda fila de cabecera

A veces, tus datos pueden tener una segunda fila de cabecera, por ejemplo, si se trata de una fila de “diccionario de datos”, como se muestra a continuación. Esta situación puede ser problemática porque puede hacer que todas las columnas se importen como de tipo “carácter”.

A continuación se muestra un ejemplo de este tipo de de datos (en el que la primera fila es el diccionario de datos).

Eliminar la segunda fila de la cabecera

Para eliminar la segunda fila de la cabecera, tendrás que importar los datos dos veces.

  1. Importar los datos para almacenar los nombres correctos de las columnas
  2. Importar los datos de nuevo, saltándose las dos primeras filas (cabecera y segunda fila) 3)Vincular los nombres correctos en el dataframe reducido

El argumento exacto utilizado para vincular los nombres de las columnas correctas depende del tipo de archivo de datos (.csv, .tsv, .xlsx, etc.). Esto se debe a que rio utiliza una función diferente para los distintos tipos de archivos (véase la tabla anterior).

Para los archivos de Excel: (col_names =)

# importa por primera vez; almacena los nombres de las columnas
linelist_raw_names <- import("linelist_raw.xlsx") %>% names()  # guarda los nombres de columna

# importa por segunda vez; omite la fila 2, y asigna los nombres de las columnas al argumento col_names =
linelist_raw <- import("linelist_raw.xlsx",
                       skip = 2,
                       col_names = linelist_raw_names
                       ) 

Para archivos CSV: (col.names =)

# primera importación; almacena los nombres de las columnas
linelist_raw_names <- import("linelist_raw.csv") %>% names() # save true column names

# nota: el argumento para archivos csv es 'col.names = '
linelist_raw <- import("linelist_raw.csv",
                       skip = 2,
                       col.names = linelist_raw_names
                       ) 

Opción alternativa - cambiar los nombres de las columnas utilizando un comando separado

# asigna/reescribe cabecesas usando la función 'colnames()' de R base
colnames(linelist_raw) <- linelist_raw_names

Hacer un diccionario de datos

Bonus! Si tienes una segunda fila que es un diccionario de datos, puedes crear fácilmente un diccionario de datos propio a partir de ella. Este consejo está adaptado de este post.

dict <- linelist_2headers %>%             # linelist con como primera fila
  head(1) %>%                             # mantener sólo los nombres de las columnas y la primera fila del diccionario 
  pivot_longer(cols = everything(),       # pivotar todas las columnas a formato largo
               names_to = "Column",       # asignar nuevos nombres de columnas
               values_to = "Description")

Combinar las dos filas de la cabecera

En algunos casos, cuando los datos crudos tienen dos filas de cabecera (o, más concretamente, la segunda fila de datos es una cabecera secundaria), es posible que desees “combinarlas” o añadir los valores de la segunda fila de cabecera a la primera fila de cabecera.

El comando siguiente definirá los nombres de las columnas del dataframe como la combinación del primer encabezado (verdadero) con el valor inmediatamente inferior (en la primera fila).

names(my_data) <- paste(names(my_data), my_data[1, ], sep = "_")

Hojas de Google

Puedes importar datos de una hoja de cálculo de Google en línea con el paquete googlesheet4 y autenticando tu acceso al archivo.

pacman::p_load("googlesheets4")

A continuación, se importa y guarda una hoja de Google de demostración. Este comando puede solicitar la autentificación de tu cuenta de Google. Sigue las indicaciones y las ventanas emergentes de tu navegador web para conceder a los paquetes de la API de Tidyverse permisos para editar, crear y eliminar sus hojas de cálculo en Google Drive.

La hoja que aparece a continuación es “visible para cualquiera con el enlace” y puedes intentar importarla.

Gsheets_demo <- read_sheet("https://docs.google.com/spreadsheets/d/1scgtzkVLLHAe5a6_eFQEwkZcc14yFUx1KgOMZ4AKUfY/edit#gid=0")

La hoja también puede importarse utilizando sólo el ID de la hoja, así es una url más corta:

Gsheets_demo <- read_sheet("1scgtzkVLLHAe5a6_eFQEwkZcc14yFUx1KgOMZ4AKUfY")

Otro paquete, googledrive ofrece funciones útiles para escribir, editar y eliminar hojas de Google. Por ejemplo, utilizando las funciones gs4_create() y sheet_write() que se encuentran en este paquete.

Aquí hay otros tutoriales útiles en línea:
tutorial básico de importación de hojas de Google
tutorial más detallado
interacción entre googlesheets4 y tidyverse

7.6 Múltiples archivos - importar, exportar, dividir, combinar

Consulta la página sobre Iteración, bucles y listas para ver ejemplos de cómo importar y combinar múltiples archivos, o múltiples archivos de Excel. Esa página también tiene ejemplos sobre cómo dividir un dataframe en partes y exportar cada uno por separado, o como hojas específicas en un archivo de Excel.

7.7 Importar desde Github

Importar datos directamente de Github a R puede ser muy fácil o puede requerir algunos pasos - dependiendo del tipo de archivo. A continuación se presentan algunos enfoques:

CSV files

Es fácil importar un archivo .csv directamente desde Github a R con un comando de R.

  1. Ve al repositorio de Github, localiza el archivo de interés y clica sobre él

  2. Cliquea en el botón “Raw” (entonces verás los datos csv “crudos”, como se muestra a continuación)

  3. Copia la URL (dirección web)

  4. Pega la URL entre comillas dentro del comando de R import()

XLSX files

Es posible que no puedas ver los datos “en crudo” (raw) de algunos archivos (por ejemplo, .xlsx, .rds, .nwk, .shp)

  1. Ve al repositorio de Github, localica el archivo de interés y clica sobre él
  2. Cliquea en el botón “Download”, como se muestra a continuación
  3. Guarda el archivo en tu ordenador e impórtalo en R

Shapefiles

Los shapefiles tienen muchos archivos subcomponentes, cada uno con una extensión diferente. Un archivo tendrá la extensión “.shp”, pero otros tienen “.dbf”, “.prj”, etc. Para descargar un shapefile de Github, tendrás que descargar cada uno de los archivos subcomponentes individualmente, y guardarlos en la misma carpeta de tu ordenador. En Github, cliquea en cada archivo individualmente y descárgalos clicando en el botón “Download”.

Una vez guardado en tu ordenador, puedes importar el archivo shape como se muestra en la página de Conceptos básicos de los SIG utilizando st_read() del paquete sf. Sólo tienes que proporcionar la ruta del archivo y el nombre del archivo “.shp”, siempre que los demás archivos relacionados estén en la misma carpeta de tu ordenador.

A continuación, se puede ver cómo el shapefile “sle_adm3” consta de muchos archivos, cada uno de los cuales debe descargarse de Github.

7.8 Grabación manual de datos

Entrada por filas

Utiliza la función tribble() del paquete tibble de tidyverse (referencia online de tibble).

Observa que las cabeceras de las columnas comienzan con una tilde (~). Observa también que cada columna debe contener sólo un tipo de datos (carácter, numérico, etc.). Puedes utilizar tabulaciones, espacios y nuevas filas para que la entrada de datos sea más intuitiva y legible. Los espacios no importan entre los valores, pero cada fila está representada por una nueva línea de código. Por ejemplo:

# crea el dataset manualmente por filas
manual_entry_rows <- tibble::tribble(
  ~colA, ~colB,
  "a",   1,
  "b",   2,
  "c",   3
  )

Y ahora mostramos el nuevo conjunto de datos:

Entrada por columnas

Dado que un dataframe consiste en vectores (columnas verticales), el enfoque básico para la creación manual de dataframes en R espera que definas cada columna y luego las unas. Esto puede ser contrario a la intuición en epidemiología, ya que normalmente pensamos en nuestros datos como una observación por filas (como arriba).

# define cada vector (columna vertical) por separado, cada uno con su propio nombre
PatientID <- c(235, 452, 778, 111)
Treatment <- c("Yes", "No", "Yes", "Yes")
Death     <- c(1, 0, 1, 0)

PRECAUCIÓN: Todos los vectores deben tener la misma longitud (el mismo número de valores).

A continuación, los vectores pueden unirse mediante la función data.frame():

# combina las columnas en un data frame, referenciando los nombres de vectores
manual_entry_cols <- data.frame(PatientID, Treatment, Death)

Y ahora mostramos el nuevo conjunto de datos:

Pegar desde el portapapeles

Si copias los datos de otro lugar y los tienes en el portapapeles, puedes probar una de las dos formas siguientes:

Con el paquete clipr, puedes utilizar read_clip_tbl() para importar como un dataframe, o simplemente read_clip() para importar como un vector de caracteres. En ambos casos, deja los paréntesis vacíos.

linelist <- clipr::read_clip_tbl()  # importar portapapeles actual como data frame
linelist <- clipr::read_clip()      # importar como vector de caracteres

También puedes exportar fácilmente al portapapeles de tu sistema con clipr. Consulta la sección siguiente sobre Exportación.

Alternativamente, pueder utilizar la función read.table() de R base con file = "clipboard") para importar como un dataframe:

df_from_clipboard <- read.table(
  file = "clipboard",  # especifica esto como "portapapeles"
  sep = "t",           # el separador puede ser un tabulador, o una coma, etc.
  header=TRUE)         # si hay una fila de cabecera

7.9 Importar el archivo más reciente

A menudo puedes recibir actualizaciones diarias de tus datos. En este caso, querrás escribir un código que importe el archivo más reciente. A continuación presentamos dos maneras de abordar esto:

  • Seleccionar el archivo en función de la fecha del nombre del archivo
  • Seleccionar el archivo en función de los metadatos del archivo (última modificación)

Fechas en el nombre del archivo

Este enfoque se basa en tres premisas:

  1. Confías en las fechas en los nombres de los archivos
  2. Las fechas son numéricas y aparecen generalmente en el mismo formato (por ejemplo, año, mes y día)
  3. No hay otros números en el nombre del archivo

Te explicaremos paso a paso y te mostraremos todos los pasos combinados al final.

En primer lugar, utiliza dir() de R base para extraer sólo los nombres de los archivos de la carpeta de interés. Consulta la página sobre interacciones con directorios para obtener más detalles sobre dir(). En este ejemplo, la carpeta de interés es la carpeta “linelists” dentro de la carpeta “example” dentro de “data” dentro del proyecto R.

linelist_filenames <- dir(here("data", "example", "linelists")) # obtiene los nombres de ficheros de la carpeta
linelist_filenames                                              # los muestra
## [1] "20201007linelist.csv"          "case_linelist_2020-10-02.csv"  "case_linelist_2020-10-03.csv"  "case_linelist_2020-10-04.csv"  "case_linelist_2020-10-05.csv"  "case_linelist_2020-10-08.xlsx"
## [7] "case_linelist20201006.csv"

Una vez que tengas este vector de nombres, puedes extraer las fechas de ellos aplicando str_extract() de stringr utilizando esta expresión regular. Este comando extrae cualquier número en el nombre del archivo (incluyendo cualquier otro carácter en el medio como guiones o barras). Puedes leer más sobre stringr en la página Caracteres y cadenas.

linelist_dates_raw <- stringr::str_extract(linelist_filenames, "[0-9].*[0-9]") # extraer números y caracteres entre ellos
linelist_dates_raw  # imprimer en la consola (print)
## [1] "20201007"   "2020-10-02" "2020-10-03" "2020-10-04" "2020-10-05" "2020-10-08" "20201006"

Suponiendo que las fechas estén escritas en general con el mismo formato de fecha (por ejemplo, Año, Mes y Día) y que los años tengan 4 dígitos, puedes utilizar las funciones de conversión de lubridate (ymd(), dmy() o mdy()) para convertirlas en fechas. Para estas funciones, no importan los guiones, espacios o barras, sino el orden de los números. Lee más en la página Trabajando con fechas.

linelist_dates_clean <- lubridate::ymd(linelist_dates_raw)
linelist_dates_clean
## [1] "2020-10-07" "2020-10-02" "2020-10-03" "2020-10-04" "2020-10-05" "2020-10-08" "2020-10-06"

La función de R base wich.max() puede utilizarse para devolver la posición del índice (por ejemplo, 1ª, 2ª, 3ª, …) del valor máximo de la fecha. El último archivo se identifica correctamente como el sexto archivo - “case_linelist_2020-10-08.xlsx”.

index_latest_file <- which.max(linelist_dates_clean)
index_latest_file
## [1] 6

Si condensamos todos estos comandos, el código completo podría ser como el siguiente. Observa que el . en la última línea es un marcador de posición para el objeto canalizado en ese punto de la secuencia de pipes. En ese punto el valor es simplemente el número 6. Esto se coloca entre corchetes dobles para extraer el sexto elemento del vector de nombres de archivo producido por dir().

# load packages
pacman::p_load(
  tidyverse,         # gestión de datos
  stringr,           # trabajar con cadenas/caracteres
  lubridate,         # trabajar con fechas
  rio,               # importar / exportar
  here,              # rutas relativas 
  fs)                # interacciones de directorio

# extraer el nombre del último archivo
latest_file <- dir(here("data", "example", "linelists")) %>%  # nombres de archivos de la subcarpeta "linelists"    
  str_extract("[0-9].*[0-9]") %>%                  # extraer fechas (números)
  ymd() %>%                                        # convertir los números en fechas (asumiendo el formato año-mes-día)
  which.max() %>%                                 # obtener el índice de la fecha máxima (último archivo)
  dir(here("data", "example", "linelists"))[[.]]              #  devuelve el nombre del archivo del último linelist

latest_file  # mostrar el nombre del último archivo
## [1] "case_linelist_2020-10-08.xlsx"

Ahora puedes utilizar este nombre para terminar la ruta relativa del archivo, con here():

here("data", "example", "linelists", latest_file) 

Y ahora puedes importar el último archivo:

# import
import(here("data", "example", "linelists", latest_file)) # importar 

Utiliza la información del archivo

Si tus archivos no tienen fechas en sus nombres (o no te fías de esas fechas), puedes intentar extraer la última fecha de modificación de los metadatos del archivo. Utiliza las funciones del paquete fs para examinar la información de los metadatos de cada archivo, que incluye la fecha y hora de la última modificación y la ruta del archivo.

A continuación, proporcionamos la carpeta de interés a dir_info() de fs. En este caso, la carpeta de interés está en el proyecto R en la carpeta “data”, la subcarpeta “example”, y su subcarpeta “linelists”. El resultado es un dataframe con una línea por cada archivo y columnas para modification_time, path, etc. Puedes ver un ejemplo visual de esto en la página sobre interacciones con directorios.

Podemos ordenar este dataframe de archivos por la columna modification_time, y luego mantener sólo la fila superior (último archivo) con la función head() de R base. A continuación, podemos extraer la ruta de este último archivo sólo con la función dplyr pull() en la columna path. Finalmente podemos pasar esta ruta de archivo a import(). El archivo importado se guarda como latest_file.

latest_file <- dir_info(here("data", "example", "linelists")) %>%  # recoger información de todos los archivos en el directorio
  arrange(desc(modification_time)) %>%      # ordenar por tiempo de modificación
  head(1) %>%                               # mantener sólo el archivo superior (más reciente)
  pull(path) %>%                            # extraer sólo la ruta del archivo
  import()                                  # importar el archivo

7.10 APIs

Una “Interfaz de Programación Automatizada” (API) puede utilizarse para solicitar datos directamente de un sitio web. Las API son un conjunto de reglas que permiten que una aplicación de software interactúe con otra. El cliente (tu) envía una “solicitud” y recibe una “respuesta” con contenido. Los paquetes de R httr y jsonlite pueden facilitar este proceso.

Cada sitio web habilitado para la API tendrá su propia documentación y detalles con los que hay que familiarizarse. Algunos sitios están disponibles públicamente y cualquiera puede acceder a ellos. Otros, como las plataformas con ID de usuario y credenciales, requieren autenticación para acceder a sus datos.

Obviamente es necesario disponer de una conexión a Internet para importar datos a través de la API. Te daremos ejemplos breves de uso de las API para importar datos, y presentaremos enlaces a otros recursos.

Nota: recuerda que los datos pueden estar publicados* en un sitio web sin una API, que puede ser más fácil de recuperar. Por ejemplo, un archivo CSV publicado puede ser accesible simplemente proporcionando la URL del sitio a import() como se describe en la sección sobre la importación desde Github.*

Petición HTTP

El intercambio de la API se realiza normalmente a través de una solicitud HTTP. HTTP es el Protocolo de Transferencia de Hipertexto, y es el formato subyacente de una solicitud/respuesta entre un cliente y un servidor. La entrada y la salida exactas pueden variar en función del tipo de API, pero el proceso es el mismo: una “Solicitud” (a menudo Solicitud HTTP) del usuario, que suele contener una consulta, seguida de una “Respuesta”, que contiene información de estado sobre la solicitud y posiblemente el contenido solicitado.

Estos son algunos de los componentes de una petición HTTP:

  • La URL completa de la API
  • El “Método” (o “Verbo”)
  • Headers (Encabezados)
  • Body (Cuerpo)

El “método” de la petición HTTP es la acción que se quiere realizar. Los dos métodos HTTP más comunes son GET y POST, pero otros pueden ser PUT, DELETE, PATCH, etc. Cuando se importan datos a R lo más probable es que se utilice GET.

Después de la solicitud, tu ordenador recibirá una “respuesta” en un formato similar al que se envió, incluyendo la URL, el estado HTTP (¡status 200 es lo que quieres!), el tipo de archivo, el tamaño y el contenido deseado. A continuación, tendrá que analizar esta respuesta y convertirla en un dataframe viable dentro de su entorno R.

Paquetes

El paquete httr funciona bien para manejar peticiones HTTP en R. Requiere poco conocimiento previo de las APIs de la web y puede ser utilizado por personas menos familiarizadas con la terminología de desarrollo de software. Además, si la respuesta HTTP es .json, puede utilizar jsonlite para analizar la respuesta.

# cargar paquetes
pacman::p_load(httr, jsonlite, tidyverse)

Datos de acceso público

A continuación se muestra un ejemplo de solicitud HTTP, tomado de un tutorial de Trafford Data Lab. Este sitio tiene varios otros recursos para aprender y ejercicios de API.

Escenario: Queremos importar una lista de establecimientos de comida rápida en la ciudad de Trafford, Reino Unido. Se puede acceder a los datos desde la API de la Food Standards Agency (Agencia de Normas Alimentarias), que proporciona datos de calificación de higiene alimentaria para el Reino Unido.

Estos son los parámetros de nuestra solicitud:

El código R sería el siguiente:

# preparar la petición
path <- "http://api.ratings.food.gov.uk/Establishments"
request <- GET(url = path,
             query = list(
               localAuthorityId = 188,
               BusinessTypeId = 7844,
               pageNumber = 1,
               pageSize = 5000),
             add_headers("x-api-version" = "2"))

# Comprobar si hay error con el servidor ("200" es el correcto!)
request$status_code

# enviar la solicitud, analizar la respuesta y convertirla en un data frame
response <- content(request, as = "text", encoding = "UTF-8") %>%
  fromJSON(flatten = TRUE) %>%
  pluck("establishments") %>%
  as_tibble()

Ahora puedes limpiar y utilizar el dataframe response, que contiene una fila por establecimiento de comida rápida.

Se requiere autenticación

Algunas APIs requieren autenticación - para que se demuestre quién eres y poder acceder a datos restringidos. Para importar estos datos, es posible que tengas que utilizar primero un método POST para proporcionar un nombre de usuario, una contraseña o un código. Esto devolverá un token de acceso, que puede ser utilizado para posteriores solicitudes del método GET para obtener los datos deseados.

A continuación se muestra un ejemplo de consulta de datos de Go.Data, que es una herramienta de investigación de brotes. Go.Data utiliza una API para todas las interacciones entre la interfaz de la web y las aplicaciones de los smartphones utilizadas para la captura de datos. Go.Data se utiliza en todo el mundo. Se requiere autenticación, dado que los datos de los brotes son sensibles y sólo debes poder acceder a los datos de tu brote.

A continuación se muestra un ejemplo de código R que utiliza httr y jsonlite para conectarse a la API de Go.Data para importar datos sobre el seguimiento de los contactos de tu brote.

# establecer credenciales para la autorización
url <- "https://godatasampleURL.int/"           # url correcta de Go.Data
username <- "username"                          # usuario Go.Data válido 
password <- "password"                          # contraseña válida 
outbreak_id <- "xxxxxx-xxxx-xxxx-xxxx-xxxxxxx"  # ID de brote de Go.Data

# obtener token de acceso
url_request <- paste0(url,"api/oauth/token?access_token=123") # definir URL base de la solicitud

# preparar la petición
response <- POST(
  url = url_request,  
  body = list(
    username = username,    # utiliza el nombre de usuario/contraseña guardado  arriba para autorizar                               
    password = password),                                       
    encode = "json")

# ejecutar la petición y analizar la respuesta
content <-
  content(response, as = "text") %>%
  fromJSON(flatten = TRUE) %>%          # acoplar el JSON anidado
  glimpse()

# Guardar el token de acceso de la respuesta
access_token <- content$access_token    # guardar el token de acceso para permitir las siguientes llamadas a la API

# importar contactos del brote
# Utilizar el token de acceso 
response_contacts <- GET(
  paste0(url,"api/outbreaks/",outbreak_id,"/contacts"),          # petición GET
  add_headers(
    Authorization = paste("Bearer", access_token, sep = " ")))

json_contacts <- content(response_contacts, as = "text")         # # convertir JSON a texto

contacts <- as_tibble(fromJSON(json_contacts, flatten = TRUE))   # acoplar JSON a tibble

PRECAUCIÓN: Si estás importando grandes cantidades de datos desde una API que requiere autenticación, es posible que se agote el tiempo de espera. Para evitarlo, recupera el access_token antes de cada solicitud GET de la API y prueba a utilizar filtros o límites en la consulta.

CONSEJO: La función fromJSON() del paquete jsonlite no se ajuste completamente la primera vez que se ejecuta, por lo que es probable que todavía tengas elementos de la lista en tu tibble resultante. Tendrás que ajustar aún más ciertas variables, dependiendo de lo jerarquizado que esté tu .json. Para ver más información sobre esto, consulta la documentación del paquete jsonlite, como la función flatten().

Para más detalles, mira la documentación en el Explorador de LoopBack, la página de Rastreo de Contactos o los consejos de la API en el repositorio Github de Go.Data

Puedes leer más sobre el paquete httr aquí

Esta sección también se inspiró en este tutorial y este otro tutorial.

7.11 Exportar

Con el paquete rio

Con rio, puedes utilizar la función export() de forma muy similar a import(). Primero indica el nombre del objeto de R que deseas guardar (por ejemplo, linelist) y luego escribe entre comillas la ruta de acceso al archivo donde deseas guardarlo, incluyendo el nombre y la extensión de archivo deseados. Por ejemplo:

Esto guarda el dataframe linelist como un archivo de Excel en el directorio de trabajo/carpeta raíz del proyecto R:

export(linelist, "my_linelist.xlsx") # lo guardará en el directorio de trabajo

Se puede guardar el mismo dataframe como un archivo csv cambiando la extensión. Por ejemplo, también lo guardamos en una ruta de archivo construida con here():

export(linelist, here("data", "clean", "my_linelist.csv"))

Al portapapeles

Para exportar un dataframe al “portapapeles” de tu ordenador (para luego pegarlo en otro software como Excel, Google Spreadsheets, etc.) puedes utilizar write_clip() del paquete clipr.

# exporta el data frame linelist al portapapeles de tu sistema
clipr::write_clip(linelist)

7.12 Archivos RDS

Además de .csv, .xlsx, etc., también puedes exportar/guardar dataframes de R como archivos .rds. Este es un formato de archivo específico de R, y es muy útil si sabes que vas a trabajar con los datos exportados de nuevo en R.

Los tipos de columnas se conservan, por lo que no hay que volver a hacer la limpieza cuando se importan (con un archivo Excel o incluso CSV esto puede ser un dolor de cabeza). También es un archivo más pequeño, lo que es útil para la exportación e importación si tu conjunto de datos es grande.

Por ejemplo, si trabajas en un equipo de epidemiología y necesitas enviar archivos a un equipo de SIG para la elaboración de mapas, y ellos también utilizan R, ¡sólo tienes que enviarles el archivo .rds! Así se conservan todos los tipos de columnas y ellos tienen menos trabajo que hacer.

export(linelist, here("data", "clean", "my_linelist.rds"))

7.13 Archivos Rdata y listas de datos

Los archivos .Rdata pueden almacenar múltiples objetos de R - por ejemplo, múltiples dataframes, resultados de modelos, listas, etc. Esto puede ser muy útil para consolidar o compartir muchos de tus datos para un proyecto determinado.

En el siguiente ejemplo, se almacenan múltiples objetos R dentro del archivo exportado “my_objects.Rdata”:

rio::export(my_list, my_dataframe, my_vector, "my_objects.Rdata")

Nota: si estás intentando importar una lista, utiliza import_list() de rio para importarla con la estructura y el contenido originales completos.

rio::import_list("my_list.Rdata")

7.14 Guardar gráficos

Las instrucciones sobre cómo guardar los gráficos, como los creados por ggplot(), se discuten en profundidad en la página de Conceptos básicos de ggplot.

En resumen, ejecuta ggsave("my_plot_filepath_and_name.png") después de obtener tu gráfico. Puedes proporcionar un gráfico guardado con plot = argumento, o sólo especificar la ruta de archivo de destino (con extensión de archivo) para guardar el gráfico mostrado más recientemente. También puedes controlar el ancho width =, la altura height =, las unidades units = y los puntos por pulgada dpi =.

La forma de guardar un gráfico de red, como un árbol de transmisión, se aborda en la página Cadenas de transmisión.

7.15 Recursos

El manual de importación y exportación de datos de R

Capítulo de R 4 Data Science en español sobre la importación de datos

documentación de ggsave()

A continuación se muestra una tabla, extraída de la viñeta online de rio. Para cada tipo de datos muestra: la extensión de archivo esperada, el paquete que rio utiliza para importar o exportar los datos, y si esta funcionalidad está incluida en la versión instalada de rio.

Formato Extensión típica Paquete importación Paquete exportación Instalado por defecto
Datos separados por comas .csv data.table fread() data.table Yes
Datos separados por pipe .psv data.table fread() data.table Yes
Datos separados por tabul .tsv data.table fread() data.table Yes
SAS .sas7bdat haven haven Yes
SPSS .sav haven haven Yes
Stata .dta haven haven Yes
SAS XPORT .xpt haven haven
SPSS Portable .por haven Yes
Excel .xls readxl Yes
Excel .xlsx readxl openxlsx Yes
Syntaxis R .R base base Yes
Objetos R guardados .RData, .rda base base Yes
Objetos R serializados .rds base base Yes
Epiinfo .rec foreign Yes
Minitab .mtp foreign Yes
Systat .syd foreign Yes
“XBASE” database files .dbf foreign foreign
Formato de archivo Weka Attribute-Relation .arff foreign foreign Yes
Formato de intercambio de datos .dif utils Yes
Datos de Fortran no recognized extension utils Yes
Formato de ancho fijo .fwf utils utils Yes
datos separados por comas gzip .csv.gz utils utils Yes
CSVY (CSV + cabecera de metadatos YAML) .csvy csvy csvy No
EViews .wf1 hexView No
Formato de intercambio Feather R/Python .feather feather feather No
Almacenamiento rápido .fst fst fst No
JSON .json jsonlite jsonlite No
Matlab .mat rmatio rmatio No
Hoja de cálculo OpenDocument .ods readODS readODS No
Tablas HTML .html xml2 xml2 No
Documentos XML .xml xml2 xml2 No
YAML .yml yaml yaml No
Portapapeles por defecto es tsv clipr clipr No