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()
yexport()
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 anclaPara 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()
.
<- import(here("data", "linelists", "ebola_linelist.xlsx")) linelist
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:
- Recomendado: proporcionar una ruta de archivo “relativa” con el paquete here
- Proporcionar la ruta “completa” / “absoluta” del archivo
- 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.
<- import(here("data", "linelists", "ebola_linelist.xlsx")) linelist
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.
<- import("C:/Users/Laura/Documents/analysis/data/linelists/ebola_linelist.xlsx") linelist
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:
- En el panel de entorno de RStudio, cliquea en “Import Dataset”, y selecciona el tipo de datos
- Cliquea en File / Import dataset / (selecciona el tipo de datos)
- 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().
<- import(file.choose()) my_data
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:
<- import("linelist_cleaned.csv") linelist
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()
):
<- import(here("data", "linelists", "linelist_cleaned.xlsx")) linelist
Para importar un data frame (un archivo .rds) utilizando una ruta de archivo absoluta:
<- import("C:/Users/Laura/Documents/tuberculosis/data/linelists/linelist_cleaned.rds") linelist
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:
<- import("my_excel_file.xlsx", which = "Sheetname") my_data
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'
<- import(here("data", "linelist.xlsx"), which = "Sheet1")` linelist_raw
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.
<- import(here("data", "my_linelist.xlsx"), na = "99") linelist
Aquí, cualquiera de los valores “Missing”, “” (celda vacía), o ” ” (un solo espacio) en los datos importados se convierten en NA
en R.
<- import(here("data", "my_linelist.csv"), na = c("Missing", "", " ")) linelist
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.
<- import("linelist_raw.xlsx", skip = 1) # no importa la fila de cabecera linelist_raw
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.
- Importar los datos para almacenar los nombres correctos de las columnas
- 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
<- import("linelist_raw.xlsx") %>% names() # guarda los nombres de columna
linelist_raw_names
# importa por segunda vez; omite la fila 2, y asigna los nombres de las columnas al argumento col_names =
<- import("linelist_raw.xlsx",
linelist_raw skip = 2,
col_names = linelist_raw_names
)
Para archivos CSV: (col.names =
)
# primera importación; almacena los nombres de las columnas
<- import("linelist_raw.csv") %>% names() # save true column names
linelist_raw_names
# nota: el argumento para archivos csv es 'col.names = '
<- import("linelist_raw.csv",
linelist_raw 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.
<- linelist_2headers %>% # linelist con como primera fila
dict 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.
::p_load("googlesheets4") pacman
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.
<- read_sheet("https://docs.google.com/spreadsheets/d/1scgtzkVLLHAe5a6_eFQEwkZcc14yFUx1KgOMZ4AKUfY/edit#gid=0") Gsheets_demo
La hoja también puede importarse utilizando sólo el ID de la hoja, así es una url más corta:
<- read_sheet("1scgtzkVLLHAe5a6_eFQEwkZcc14yFUx1KgOMZ4AKUfY") Gsheets_demo
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.
Ve al repositorio de Github, localiza el archivo de interés y clica sobre él
Cliquea en el botón “Raw” (entonces verás los datos csv “crudos”, como se muestra a continuación)
Copia la URL (dirección web)
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)
- Ve al repositorio de Github, localica el archivo de interés y clica sobre él
- Cliquea en el botón “Download”, como se muestra a continuación
- 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
<- tibble::tribble(
manual_entry_rows ~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
<- c(235, 452, 778, 111)
PatientID <- c("Yes", "No", "Yes", "Yes")
Treatment <- c(1, 0, 1, 0) Death
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
<- data.frame(PatientID, Treatment, Death) manual_entry_cols
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.
<- clipr::read_clip_tbl() # importar portapapeles actual como data frame
linelist <- clipr::read_clip() # importar como vector de caracteres linelist
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:
<- read.table(
df_from_clipboard 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:
- Confías en las fechas en los nombres de los archivos
- Las fechas son numéricas y aparecen generalmente en el mismo formato (por ejemplo, año, mes y día)
- 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.
<- dir(here("data", "example", "linelists")) # obtiene los nombres de ficheros de la carpeta
linelist_filenames # los muestra linelist_filenames
[1] "20201007linelist.csv" "case_linelist_2020-10-02.csv"
[3] "case_linelist_2020-10-03.csv" "case_linelist_2020-10-04.csv"
[5] "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.
<- stringr::str_extract(linelist_filenames, "[0-9].*[0-9]") # extraer números y caracteres entre ellos
linelist_dates_raw # imprimer en la consola (print) linelist_dates_raw
[1] "20201007" "2020-10-02" "2020-10-03" "2020-10-04" "2020-10-05"
[6] "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.
<- lubridate::ymd(linelist_dates_raw)
linelist_dates_clean linelist_dates_clean
[1] "2020-10-07" "2020-10-02" "2020-10-03" "2020-10-04" "2020-10-05"
[6] "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”.
<- which.max(linelist_dates_clean)
index_latest_file 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
::p_load(
pacman# gestión de datos
tidyverse, # trabajar con cadenas/caracteres
stringr, # trabajar con fechas
lubridate, # importar / exportar
rio, # rutas relativas
here, # interacciones de directorio
fs)
# extraer el nombre del último archivo
<- dir(here("data", "example", "linelists")) %>% # nombres de archivos de la subcarpeta "linelists"
latest_file 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
# mostrar el nombre del último archivo latest_file
[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
.
<- dir_info(here("data", "example", "linelists")) %>% # recoger información de todos los archivos en el directorio
latest_file 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
::p_load(httr, jsonlite, tidyverse) pacman
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:
- Verbo HTTP: GET
- URL del punto de la API: http://api.ratings.food.gov.uk/Establishments
- Parámetros seleccionados: name, address, longitude, latitude, businessTypeId, ratingKey, localAuthorityId
- Cabeceras: “x-api-version”, 2
- Formato(s) de datos: JSON, XML
- Documentación: http://api.ratings.food.gov.uk/help
El código R sería el siguiente:
# preparar la petición
<- "http://api.ratings.food.gov.uk/Establishments"
path <- GET(url = path,
request 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!)
$status_code
request
# enviar la solicitud, analizar la respuesta y convertirla en un data frame
<- content(request, as = "text", encoding = "UTF-8") %>%
response 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
<- "https://godatasampleURL.int/" # url correcta de Go.Data
url <- "username" # usuario Go.Data válido
username <- "password" # contraseña válida
password <- "xxxxxx-xxxx-xxxx-xxxx-xxxxxxx" # ID de brote de Go.Data
outbreak_id
# obtener token de acceso
<- paste0(url,"api/oauth/token?access_token=123") # definir URL base de la solicitud
url_request
# preparar la petición
<- POST(
response 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
<- content$access_token # guardar el token de acceso para permitir las siguientes llamadas a la API
access_token
# importar contactos del brote
# Utilizar el token de acceso
<- GET(
response_contacts paste0(url,"api/outbreaks/",outbreak_id,"/contacts"), # petición GET
add_headers(
Authorization = paste("Bearer", access_token, sep = " ")))
<- content(response_contacts, as = "text") # # convertir JSON a texto
json_contacts
<- as_tibble(fromJSON(json_contacts, flatten = TRUE)) # acoplar JSON a tibble contacts
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
::write_clip(linelist) clipr
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”:
::export(my_list, my_dataframe, my_vector, "my_objects.Rdata") rio
Nota: si estás intentando importar una lista, utiliza import_list()
de rio para importarla con la estructura y el contenido originales completos.
::import_list("my_list.Rdata") rio
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
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 |