<- read.table("C:/BDR/datos.txt") datos
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:
Digitándolos directamente en el script.
Leyéndolos desde un formato nativo.
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 planoLa función
read.csv
lee datos almacenados en formato csvLa función
read_excel
importa desde un archivo de Excel (formato xls o xlsx).
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 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:
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.
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:
<- read.table("datos.txt") datos
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:
<- read.table("datos.txt") datos
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.
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:
<- read.table("datos.txt", header = TRUE, sep = "\t") datos
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í:
<- read.delim("datos.txt") datos
Si en los datos de origen se usa la coma (,) como carácter decimal, puede especificarse mediante el argumento decim = ","
, así:
<- read.delim("datos.txt", dec = ",") datos
Equivalente, puede usarse la función read.delim2
, que usa por defecto la coma (,) como carácter decimal.
<- read.delim2("datos.txt") datos
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:
<- read.csv("datos.csv") datos
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í:
<- read.csv("datos.csv", dec = ",", sep = ";") datos
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:
<- read.csv2("datos.csv") datos
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:
<- readxl::read_excel("datos.xlsx", sheet = 1) datos
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.
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:
Exigiría un proceso de exportación desde el archivo Excel hacia un archivo intermedio en formato de texto plano o csv.
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:
<- data.frame(readxl::read_excel("datos.xlsx")) datos
La inclusión del objeto importado dentro de la función data.frame
da lugar a la simplificación de los nombres3.
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.
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:
<- read.delim(file.choose()) datos
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
.
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-CCtrl-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í:
<- read.delim("clipboard") datos
Si en la región seleccionada y copiada no se incluyen encabezados, podría usarse la siguiente instrucción:
<- read.table("clipboard", sep = "\t") datos
o
<- read.delim("clipboard", header = FALSE) datos
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:
<- read.delim2("clipboard") datos
"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.
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
:
<- read_excel("datos.xlsx") datos
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.
También cuando un campo incluía la coma: Apple, Inc.↩︎
Pueden importarse usando
read.table
oread.delim
para archivos de texto, yread.csv
para archivos csv (cf. secciones 6.1.1, 6.1.2 y 6.1.3).↩︎También se elimina un atributo (tibble) que es ampliamente usado en el ecosistema del universo ordenado tidyverse.↩︎
Obligaría a elegir el archivo de origen cada vez que se ejecutara el script.↩︎