11.2 Tablas (datos rectangulares)

Como vimos en el capítulo 7, las estructura rectangular, en renglones y columnas, es común y conveniente para el análisis de datos. Nos referiremos a esta forma de organizar datos como tabla.

R cuenta con la función genérica read.table(), que puede leer cualquier tipo de archivo que contenga una tabla.

La condición para que R interprete un archivo como una tabla es que tenga renglones y en cada renglón, los datos estén separados por comas, o algún otro carácter, indicando columnas. Es decir, algo que luzca de la siguiente manera.

1, 20, 8, 5

1, 31, 6, 5

2, 18, 9, 5

2, 25, 10, 5

Por supuesto, en lugar de comas podemos tener puntos y coma, dos puntos, tabuladores o cualquier otro signo de puntuación como separador de columnas.

La función read.table() acepta un número considerable de argumentos. Los más importantes son los siguientes.

  • file: La ruta del archivo que importaremos, como cadena de texto. Si el archivo se encuentra en nuestro directorio de trabajo, es suficiente dar el nombre del archivo, sin la ruta completa.
  • header: Si nuestro archivo tiene encabezados, para ser interpretados como nombres de columna, definimos este argumento como TRUE.
  • sep: El carácter que es usado como separador de columnas. Por defecto es “;”
  • col.names: Un vector opcional, de tipo carácter, con los nombres de las columnas en la tabla.
  • stringsAsFactors: Esta función convierte automáticamente los datos de texto a factores. Si este no es el comportamiento que deseamos, definimos este argumento como FALSE.

Puedes consultar todos los argumentos de esta función ejecutando ?read.table en la consola.

Es importante señalar que el objeto obtenido al usar esta función es siempre un data frame.

Probemos con un archivo con extensión “.data,” descargado desde el repositorio de Github de este libro.

download.file(
  url = "https://raw.githubusercontent.com/jboscomendoza/r-principiantes-bookdown/master/datos/breast-cancer-wis.data", 
  dest = "breast-cancer-wis.data"
)

Estos datos pertenecen a una base de diagnósticos de cáncer mamario de la Universidad de Wisconsin, usado para probar métodos de aprendizaje automático. Puedes encontrar la información completa sobre este conjunto de datos en el siguiente enlace:

Nos damos cuenta de que hemos tenido éxito en la descarga si aparece un mensaje en la consola de R indicando los resultados de nuestra operación.

Usamos sin especificar ningún otro argumento.

bcancer <- read.table(file = "datos/breast-cancer-wis.data")

Veamos los primeros renglones de nuestros datos usando la función head()

head(bcancer)
##                               V1
## 1    1000025,5,1,1,1,2,1,3,1,1,2
## 2   1002945,5,4,4,5,7,10,3,2,1,2
## 3    1015425,3,1,1,1,2,2,3,1,1,2
## 4    1016277,6,8,8,1,3,4,3,7,1,2
## 5    1017023,4,1,1,3,2,1,3,1,1,2
## 6 1017122,8,10,10,8,7,10,9,7,1,4

Nuestros datos no lucen particularmente bien. Necesitamos ajustar algunos parámetros al importarlos.

No hay datos de encabezado, por lo que header será igual a FALSE y el separador de columnas es una coma, así que el valor de sep será “,” No conocemos cuál es el nombre de las columnas, así que por el momento no proporcionaremos uno.

bcancer <- read.table(file = "datos/breast-cancer-wis.data", header = FALSE, sep = ",")

# Resultado
head(bcancer)
##        V1 V2 V3 V4 V5 V6 V7 V8 V9 V10 V11
## 1 1000025  5  1  1  1  2  1  3  1   1   2
## 2 1002945  5  4  4  5  7 10  3  2   1   2
## 3 1015425  3  1  1  1  2  2  3  1   1   2
## 4 1016277  6  8  8  1  3  4  3  7   1   2
## 5 1017023  4  1  1  3  2  1  3  1   1   2
## 6 1017122  8 10 10  8  7 10  9  7   1   4

Luce mejor, pero los nombres de las columnas son poco descriptivos. Si no damos nombres de variables, cada columna tendrá como nombre “V” seguida de números del 1 adelante.

Para este ejemplo, contamos con un archivo de información, que describe el contenido de los datos que hemos importado.

Si descargas este archivo, puedes abrirlo usando el bloc o navegador de internet de tu computadora.

Guardaremos en un vector las abreviaturas de los nombres de columna descritos en el documento anterior.

nombres <- c("id", "clump_t", "u_csize", "u_cshape", "m_adh", "spcs", "b_nuc", 
             "b_chr", "n_nuc", "mit", "class")

Ahora usaremos este vector como argumento col.names en read.table(), para importar nuestros datos con nombres de columna.

bcancer <- read.table(file = "datos/breast-cancer-wis.data", header = FALSE, sep = ",",
                      col.names = nombres)

# Resultado
head(bcancer)
##        id clump_t u_csize u_cshape m_adh spcs b_nuc b_chr n_nuc mit class
## 1 1000025       5       1        1     1    2     1     3     1   1     2
## 2 1002945       5       4        4     5    7    10     3     2   1     2
## 3 1015425       3       1        1     1    2     2     3     1   1     2
## 4 1016277       6       8        8     1    3     4     3     7   1     2
## 5 1017023       4       1        1     3    2     1     3     1   1     2
## 6 1017122       8      10       10     8    7    10     9     7   1     4

Nuestros datos han sido importados correctamente. Además, el objeto resultante es un data frame, listo para que trabajemos con él.

class(bcancer)
## [1] "data.frame"

11.2.1 Archivos CSV

Un caso particular de las tablas, son los archivos separados por comas, con extensión .csv, por Comma Separated Values, sus siglas en inglés. Este es un tipo de archivo comúnmente usado para compartir datos, pues es compatible con una amplia variedad de sistemas diferentes además de que ocupa relativamente poco espacio de almacenamiento.

Este tipo de archivos también se pueden importar usando la función read.table().

Probemos descargando los mismos datos que en el ejemplo anterior, pero almacenados en un archivo con extensión .csv.

download.file(
  url = "https://raw.githubusercontent.com/jboscomendoza/r-principiantes-bookdown/master/datos/breast-cancer-wis.csv", 
  dest = "breast-cancer-wis.csv"
)

Podemos usar read.table() con los mismos argumentos que en el ejemplo anterior, con la excepción de que este archivo sí tiene encabezados de columna, por lo que cambiamos header de FALSE a TRUE.

bcancer <- read.table(file = "datos/breast-cancer-wis.csv", header = TRUE, sep = ",",
                      col.names = nombres)

# Resultado
head(bcancer)
##        id clump_t u_csize u_cshape m_adh spcs b_nuc b_chr n_nuc mit class
## 1 1000025       5       1        1     1    2     1     3     1   1     2
## 2 1002945       5       4        4     5    7    10     3     2   1     2
## 3 1015425       3       1        1     1    2     2     3     1   1     2
## 4 1016277       6       8        8     1    3     4     3     7   1     2
## 5 1017023       4       1        1     3    2     1     3     1   1     2
## 6 1017122       8      10       10     8    7    10     9     7   1     4

Una ventaja de usar documentos con extensión .csv es la posibilidad de usar la función read.csv(). Esta es una es una versión de read.table(), optimizada para importar archivos .csv.

read.csv() acepta los mismos argumentos que read.table(), pero al usarla con un archivo .csv, en casi todo los casos, no hará falta especificar nada salvo la ruta del archivo.

bcancer <- read.csv("datos/breast-cancer-wis.csv")

# Resultado
head(bcancer)
##        id clump_t u_csize u_cshape m_adh spcs b_nuc b_chr n_nuc mit class
## 1 1000025       5       1        1     1    2     1     3     1   1     2
## 2 1002945       5       4        4     5    7    10     3     2   1     2
## 3 1015425       3       1        1     1    2     2     3     1   1     2
## 4 1016277       6       8        8     1    3     4     3     7   1     2
## 5 1017023       4       1        1     3    2     1     3     1   1     2
## 6 1017122       8      10       10     8    7    10     9     7   1     4

read.csv() también devuelve un data frame como resultado