6  LECTURA DE DATOS

Anteriormente se indicó que la consola en R solo es práctica para realizar operaciones puntuales, pero que, a la hora de realizar análisis de datos, los scripts proporcionan la forma de trabajo más cómoda (cf. tip 2.1).

Dejando de lado el trabajo en consola para las operaciones puntuales, habría que considerar las particularidades de la lectura de datos, con fines de análisis.

La lectura de datos en R puede realizarse mediante alguna de las siguientes modalidades:

  1. Digitándolos directamente en el script.

  2. Leyéndolos desde un formato nativo.

  3. Importándolos desde otro formato.

El ingreso directo resultaría muy poco práctico en un contexto de análisis de datos, por lo que no suele usarse más que en casos sencillos, en los que unos pocos datos basten para evaluar o ejemplificar alguna funcionalidad de R.

La segunda manera implica haber creado la base de datos en formato nativo en una sesión previa, probablemente, vía importación. Esta estrategia puede resultar útil en algunos casos particulares, que se detallan en la sección 6.2.

La tercera forma, es decir, la que procede por importación, es la más usual y es la que se detalla a continuación.

6.1 Importación de datos desde una fuente externa

Las funciones más comunes para importar datos son read.table, read.csv y read_excel.

  • La función read.table lee datos en formato de texto plano

  • La función read.csv lee datos almacenados en formato csv

  • La función read_excel importa desde un archivo de Excel (formato xls o xlsx).

Nota 6.1: ¿!Texto plano!?

El término texto plano (probablemente por influencia del inglés: plain text) se refiere a un formato básico, llano, sencillo (plain) que no admite metadatos ni opciones de formato (negrilla, cursiva, ect.) como las que son administradas por procesadores de texto como Word.

Uno de los primeros estándares de texto plano en la era de la computación moderna fue el ascii (American Standard Code for Information Interchange). Este estándar está limitado a las letras del inglés, a los números y algunos símbolos: en total 95 caracteres imprimibles más espacio. No están incluidos caracteres especiales como las letras acentuadas ni la ñ.

El estándar de codificación ISO-8859-1 (Latin-1) incluye 256 caracteres, con lo que logran cubrirse los caracteres especiales de las lenguas de Europa Occidental. Desde luego, allí quedan incluidos los del español (á, é, í, ó, ú, ñ…).

UTF-8 es el estándar de texto plano más amplio y versátil de la actualidad. Está conformado por más de un millón de caracteres. En adición a los caracteres de las lenguas de Europa Occidental, incluye los caracteres de todos los idiomas modernos (chino, japonés, coreano, árabe, cirílico, etc.), así como de sistemas antiguos (jeroglíficos egipicios, runas vikingas…), símbolos matemáticos, musicales y científicos. También incluye emojis 🚀

Los archivos en este tipo de formato a menudo tienen extensión txt. Se trata de aquella información que suele leerse en el bloc de notas.

csv

csv es otro tipo de archivo de texto plano. No obstante considera una estructura tabular en la que se usa un separador para los datos de cada fila.

El separador usado originalmente en estos archivos fue la coma; de ahí su nombre: csv comma separated values. No obstante, esto generaba conflictos con los sistemas europeos, en los que la coma era el separador decimal1. De ahí surgió la adopción de otros separadores como el punto y coma, los tabuladores, las plecas…

Aunque suene un poco extraño denominar csv (comma separated values) a un archivo en el que no use la coma como separador, todos siguen englobándose bajo el mismo formato. En ocasiones se les denomina archivos tipo csv (csv-like).

Cualquiera de las anteriores funciones tiene como primer argumento el nombre del archivo que se importa, el cual se escribe entre comillas, incluyendo su extensión.

Es posible importar información de archivos que se encuentren en alguna ruta local (una ubicación en el equipo del usuario) o en algún URL (uniform resource locator).

Si el archivo que se desea importar no se encuentra en el directorio de trabajo (cf. capítulo 3), sería necesario incluir la ruta completa en la instrucción de importación. La instrucción para leer una base de datos en formato de texto plano, ubicada en una ruta local particular que no corresponda con el directorio de trabajo, podría tener el siguiente aspecto:

datos <- read.table("C:/BDR/datos.txt")

Pero no lo haga así. Esta instrucción se presenta con el único fin de ejemplificar lo que no debe hacerse.

Precaución 6.1: ¡No incluya rutas locales!

De manera enfática, se desaconseja incluir rutas locales en los scripts.

Esto les resta compatibilidad interusuarios, pudiendo generarle dificultades incluso a un mismo usuario si la ruta fuera cambiada.

Supóngase que un script que contenga la instrucción anterior es compartido con otro usuario, quien al intentar ejecutarlo probablemente recibirá un mensaje de error, pues sería bastante improbable que el nuevo usuario ubicara la base de datos en una ruta local que tuviera exactamente el mismo nombre ("C:/BDR/").

Asimismo, el usuario original tendría problemas si realizara cualquier modificación a la ruta local, manteniendo inalterado el script. Así, por ejemplo, si los datos se movieran a la unidad D, la base de datos dejaría de ser ubicable mediante la instrucción anterior.

¡Importe la información así!

Para evitar los problemas descritos en el llamado de atención 6.1, lo más recomendable es escribir únicamente el nombre del archivo de origen en la instrucción de importación, dejando que el directorio de trabajo se defina automáticamente al momento de llamar el script (cf. tip 3.1).

Luego, para importar los datos contenidos en el archivo ‘datos.txt’, se ubica dicho archivo junto con el script en una misma carpeta (cualquiera que sea); se establece dicha carpeta como directorio de trabajo, y se ejecuta el siguiente código:

datos <- read.table("datos.txt")

6.1.1 read.table

read.table es una de las funciones que permite importar información contenida en un archivo de texto plano.

Para leer la información contenida en el archivo ‘datos.txt’, ubicado en el directorio de trabajo, y asignarla al objeto datos, se usa la siguiente instrucción:

datos <- read.table("datos.txt")

La instrucción anterior se usa cuando la primera fila del archivo ‘datos.txt’ no contiene los nombres de las variables, sino que corresponde a la primera observación. En estos casos, R nombrará las variables automáticamente de manera genérica como V1, V2, . . . , VK, siendo K el número de variables.

Si la primera fila contiene el nombre de la variable, deberá indicarse explícitamente, mediante el argumento header = TRUE (por defecto header = FALSE).

Los nombre de variables que contengan espacios deberán encerrarse entre comillas. No obstante, durante el proceso de importación, los espacios o caracteres especiales que pudieran estar contenidos en los nombres de las variables serán remplazados por un punto.

En el archivo fuente, los elementos en una misma fila pueden estar separados por espacios (uno o más), por tabuladores o por una combinación de ambos, sin que tenga que satisfacerse ninguna condición de alineación. El sistema automáticamente reconoce cualquier conjunto de espacios y/o tabuladores como un separador.

Cuando los datos que se van a importar contienen cadenas de caracteres con espacios, se requiere un manejo especial, pues si se intentara el procedimiento por defecto, los espacios sería tomados como separadores de elementos.

Una posible solución consiste en entrecomillar las cadenas de caracteres que incluyan espacios; así serán reconocidas como una unidad. Otra solución consiste en definir explícitamente el tabulador como separador (sep = "\t"), en cuyo caso, los espacios dejarán de reconocerse como separadores.

Cualquiera que sea la estrategia usada para evitar que los espacios se reconozcan como separadores, las cadenas de caracteres que contuvieran espacios o caracteres especiales en el archivo fuente, se importarán tal cual, sin ninguna modificación.

¿¡Por qué para unas sí y para otras no!?

El comportamiento contrastante entre nombres de variables y cadenas de caracteres que contienen espacios o caracteres especiales, tiene que ver con restricciones en los nombres de las variables para que sean sintácticamente válidos (cf. capítulo 12).

Las cadenas de caracteres, por su parte, no tienen ninguna restricción.

La instrucción para leer datos desde un archivo de texto plano con los nombres de las variables en la primera fila y con los valores separados por tabuladores tendrá el siguiente aspecto:

Código 6.1
datos <- read.table("datos.txt", header = TRUE, sep = "\t")

6.1.2 read.delim

read.delim es otra de las funciones para importar información contenida en un archivo de texto plano.

La función read.delim incluye por defecto las opciones de encabezado y separador tabular, por lo que la importación ilustrada mediante el código 6.1, se realizaría así:

datos <- read.delim("datos.txt")

Si en los datos de origen se usa la coma (,) como carácter decimal, puede especificarse mediante el argumento decim = ",", así:

datos <- read.delim("datos.txt", dec = ",")

Equivalente, puede usarse la función read.delim2, que usa por defecto la coma (,) como carácter decimal.

datos <- read.delim2("datos.txt")

6.1.3 read.csv

La función read.csv realiza en esencia la misma labor que read.table o que read.delim, pero sobre un archivo csv, cambiando los valores por defecto.

Al usar la función read.csv, la primera fila del archivo se toma como encabezado y la coma es el separador de los elementos.

Para importar un archivo en formato csv se usa la siguiente instrucción:

datos <- read.csv("datos.csv")

Si en el archivo csv se usa la coma (,) como carácter decimal —en cuyo caso, se usa el punto y coma (;) como separador de valores— puede especificarse así:

datos <- read.csv("datos.csv", dec = ",", sep = ";")

Equivalente, puede usarse la función read.csv2, en que usa por defecto la coma (,) como carácter decimal y el punto y coma (;) como separador de valores:

datos <- read.csv2("datos.csv")
¡Podría tener que ensayarlos ambos!

En los archivos csv los valores pueden estar separados por coma o por punto y coma. Y aunque tales archivos pueden abrirse con Excel, la presentación de un valor por celda, propia de los archivos Excel, dificulta saber cuál era el separador de valores original del archivo csv.

Por tanto, si al intentar la importación de un archivo csv usando read.csv no obtiene los resultados esperados, ensaye con read.csv2.

6.1.4 read_excel

Para leer información directamente desde un archivo Excel, se usa la función read_excel, que forma parte del paquete readxl.

Esta función tiene la siguiente sintaxis:

Código 6.2
datos <- readxl::read_excel("datos.xlsx", sheet = 1)

Por defecto, se lee la primera hoja del archivo Excel. Por tanto, si los datos que se van a importar están ubicados en la primera hoja, podrá omitirse el segundo argumento.

Si se desea leer una hoja diferente a la primera, puede usarse el número correspondiente a la posición de la hoja o su nombre entrecomillado.

Use read_excel

Puesto que, para muchos usuarios, Excel es el contenedor de información por excelencia, el primer paso de casi cualquier análisis consiste en la importación de los datos desde Excel hacia R.

Si bien es cierto que podrían generarse archivos intermedios de texto plano o archivos csv, cuya importación es relativamente sencilla2, esta estrategia es poco práctica por dos razones:

  1. Exigiría un proceso de exportación desde el archivo Excel hacia un archivo intermedio en formato de texto plano o csv.

  2. Generaría inncesariamente archivos intermedios.

Lo inconveniente de esta situación se hace particularmente notorio cuando se requieren adecuaciones sobre la marcha, lo que implicaría modificar el archivo Excel, volver a realizar la exportación hacia un archivo intermedio de texto plano o csv y volver a importar dicho archivo.

Consecuentemente, se recomienda realizar la importación directamente desde el archivo Excel, siempre que la información original esté contenida en un archivo de ese tipo.

Cuando se importan archivos Excel mediante la función read_excel no existen restricciones en el nombre de variables, siendo posible usar cualquier caracter del estándar UTF-8 (cf. nota 6.1) para su definición.

Aunque esto pueda parece atractivo a primera vista, puede generar inconvenientes dentro de algunas funciones.

Una forma de resolver la situación de los nombres no convencionales consiste en encerrarlos entre comilas invertidas (` `).

Así, `log (Crecimiento [UFC])` será reconocido de manera adecuada por muchas funciones.

Esta estrategia, además de hacer más engorrosa la escritura del código, no siempre resulta adecuda, pues hay funciones que no reconocen los nombres especificados de esta manera, haciéndose necesario reducirlos a nombres convencionales sintácticamente válidos (cf. capítulo 12).

Esto, sin embargo, se resuelve fácilmente. Para ello sería suficiente con realizar la siguiente adaptación sobre el código 6.2:

datos <- data.frame(readxl::read_excel("datos.xlsx"))

La inclusión del objeto importado dentro de la función data.frame da lugar a la simplificación de los nombres3.

¡Anticípese!

Anticipándose a los requerimientos de las funciones de R, se recomienda no usar nombres con espacios ni caracteres especiales al momento de construir las bases de datos en Excel.

Mientras más sencillos sean los nombres, más fluida será la escritura del código para los análisis.

Desde luego, el usuario podrá editar posteriormente los resultados generados por R para hacerlos más informativos y/o estéticos.


Obsérvese que, más allá de la aparente diversidad de métodos para importación de datos a partir de archivos externos, en esencia se tienen funciones para leer información desde archivos de texto plano y Excel (xls o xlsx), dado que los archivos csv son en realidad archivos de texto plano en los que se usa otro separador de valores.

Con excepción de la función read_excel, que forma parte del paquete readxl, las demás funciones reseñadas forman parte del paquete utils, que es uno de los que se carga cada vez que se inicia una sesión de trabajo en R, no siendo necesario, por tanto, invocar el correspondiente paquete.

Las funciones de importación que están incluidas en el paquete utils difieren únicamente en los valores que traen por defecto para sus argumentos, siendo posible usar cualquiera de ellas con argumentos especificados por el usuario, que se adecúen a las características del archivo que se va a leer.

La tabla 6.1 resume las funciones mencionadas, con los valores por defecto para sus principales argumentos.

Tabla 6.1: Funciones para importación de datos
Función Formato Nombre de la variable en la primera fila (header) Separador de valores (sep) Caracter decimal (dec)
read.table texto plano FALSE " " "."
read.delim texto plano TRUE "\t" "."
read.delim2 texto plano TRUE "\t" ","
read.csv csv TRUE "," "."
read.csv2 csv TRUE ";" ","
read_excel xls o xlsx TRUE El del sistema

6.1.5 file.choose

Cualquiera de las funciones anteriores puede usarse conjuntamente con la función file.choose, para importar un archivo que se encuentre en una ubicación cualquiera, sin necesidad de escribir su nombre, sino ubicándolo mediante una ventana de navegación.

Si se desea leer, por ejemplo, un archivo de texto plano con nombres de variables en la primera fila, separador tabular para los elementos y punto como carácter decimal, pude usarse la siguiente instrucción:

datos <- read.delim(file.choose())

La ejecución de la anterior instrucción hace que se abra una ventana de búsqueda, mediante la cual podrá seleccionarse el archivo que se usará como argumento de la función read.delim.

¡Cuidado con file.choose!

La función file.choose resulta útil cuando se implementen API (Application Programming Interface) que realicen algún procedimiento sobre los datos que alimente el usuario.

No debe usarse, sin embargo, en scripts mediante los cuales se relicen análisis sobre un conjunto de datos particular, pues, además de que rompería la fluidez del proceso4, no permitiría su trazabilidad.

6.1.6 Clipboard

En adición a la lectura desde un archivo en una localización específica o en una ubicación cualquiera (mediante la función file.choose), es posible leer información directamente desde el portapapeles (clipboard).

Para ello puede usarse cualquiera de las funciones de lectura de texto plano (incluyendo los de formato csv), usando "clipboard" como primer argumento y realizando las especificaciones del caso en los demás argumentos, de ser necesario.

Es importante aclarar que el hecho de que la función read_excel no se use para leer información desde el portapapeles, no impide que puedan importarse datos contenidos en un archivo Excel mediante esta estrategia.

De hecho, La situación más común surge cuando se copian datos desde Excel al portapapeles (usando Ctrl-C en Windows). Los valores en el portapapeles quedan separados por tabuladores.

Suponiendo que en el área seleccionada y copiada se hubieran incluido los encabezados de cada columna, podría importarse dicha información en R así:

datos <- read.delim("clipboard")

Si en la región seleccionada y copiada no se incluyen encabezados, podría usarse la siguiente instrucción:

datos <- read.table("clipboard", sep = "\t")

o

datos <- read.delim("clipboard", header = FALSE)

Si la región seleccionada y copiada incluyó encabezados, pero el separador decimal del sistema es la coma, podría usarse la siguiente instrucción:

datos <- read.delim2("clipboard")
¡Cuidado con "clipboard"!

Al igual que la función file.choose, la estrategia de importar la información desde el portapapeles resulta útil cuando se implementen API (Application Programming Interface) que realicen algún procedimiento sobre los datos que alimente el usuario.

No debe usarse, sin embargo, en scripts mediante los cuales se relicen análisis sobre un conjunto de datos particular, pues, además de que rompería la fluidez del proceso, no permitiría su trazabilidad.


¡Tenga en cuenta la trazabilidad!

Las estrategias de importación mediante file.choose y "clipboard" tienen un nicho muy especial que es el de las API.

No obstante, se desaconseja su uso para el análisis de un conjunto de datos particular.

Con miras a la trazabilidad y posibilidad de edición y reejecución de los scripts, se aconseja explicitar siempre el nombre del archivo que contiene los datos que se importan.

6.2 Lectura de datos desde un formato nativo

La rapidez y eficiencia del proceso de importación depende del tamaño de las bases de datos, pudiendo ser prácticamente instantáneo o tardar mucho tiempo.

Cuando se trabaja con bases de datos muy grandes, puede resultar más práctico tener la base de datos en formato nativo que realizar la importación cada vez que se retome el script.

Puesto que los datos usualmente provienen de una fuente externa (v. gr. un archivo de Excel o de texto), aun en este caso será inevitable realizar una importación inicial. No obstante, cuando vuelva a ejecutarse el script, los datos podrán leerse directamente desde el formato nativo, haciendo más rápido el proceso.

Para guardar una base de datos en formato nativo se usa la función save, con el nombre del objeto importado como primer argumento y el nombre del archivo de datos como segundo argumento.

Supóngase, por ejemplo, que, usando la función read_excel, se importa una base de datos desde Excel, quedando en el ambiente de trabajo como bd:

datos <- read_excel("datos.xlsx")

Si a futuro se quiere usar nuevamente los datos contenidos en bd, sin necesidad de importarlos nuevamente desde Excel, se guardan físicamente como un archivo de datos en formato nativo de R, usando la función save, así:

save(datos, file = "datos.RData")

La anterior instrucción genera el archivo datos.RData, el cual contiene la información en el formato nativo de R. Este archivo puede leerse a futuro, de manera rápida, usando la instrucción load.

load("datos.RData")

La función load carga en el ambiente de trabajo el contenido de datos.RData, esto es, el objeto datos.

6.3 Importación de bases de datos generadas con otros paquetes

En adición a las funcionalidades de importación expuestas en las secciones precedentes, en ocasiones puede necesitarse importar bases de datos generadas con otros paquetes como SPSS, SAS, Minitab, JMP, Systat, Epi Info…

El paquete haven incluye funciones que permiten importar muchos de los formatos más recientes. Por su parte, el paquete foreign puede ser de utilidad para importar bases de datos en formatos muy antiguos, como los de Systat y Epi Info. El paquete arrow es ideal para trabajar con datos masivos con formatos modernos como Parquet.


  1. También cuando un campo incluía la coma: Apple, Inc.↩︎

  2. Pueden importarse usando read.table o read.delim para archivos de texto, y read.csv para archivos csv (cf. secciones 6.1.1, 6.1.2 y 6.1.3).↩︎

  3. También se elimina un atributo (tibble) que es ampliamente usado en el ecosistema del universo ordenado tidyverse.↩︎

  4. Obligaría a elegir el archivo de origen cada vez que se ejecutara el script.↩︎