Capítulo 3 R para Explorar


“Aquí tengo todos los datos que demuestran incuestionablemente que los datos no demuestran NADA….”

— Miguel Brieva



La exploración de datos implica normalmente poder leer datos de fuentes y formatos diversos y acomodarlos según nos convenga. Estas tareas son, de hecho, las que suelen tomar más tiempo, de todo el proceso de análisis y asimilación de la información.

3.1 Leer datos

Nos puede interesar leer y analizar datos de varios lados: de un archivo, una página web, una base de datos, etc.

3.1.1 Leer datos de un archivo

Si queremos leer los datos de una tabla, por ejemplo, un archivo en formato .csv (valores delimitados por comas) que tenemos en nuestra carpeta o directorio, lo podemos hacer mediante el paquete readr (Wickham 2017a).

## # A tibble: 13 x 10
##    Nombre   Cromos  Edad Deporte   Poblacion Pais      numerodehermanos
##    <chr>     <int> <int> <chr>     <chr>     <chr>                <int>
##  1 Pepito       35    12 Waterpolo Barcelona España                   1
##  2 Juanito      15    13 Futbol    Madrid    España                   3
##  3 Carlitos      3     9 Waterpolo Ceuta     España                   2
##  4 Pedrito      21    10 Petanca   Mallorca  España                   2
##  5 Mariela      40    12 Futbol    Barcelona España                   4
##  6 Vicent       21    10 Futbol    Valencia  España                   2
##  7 Pablo         0    13 Basquet   Madrid    España                   1
##  8 Tanita       33     8 Waterpolo Murcia    España                   0
##  9 Antonio      26     9 Futbol    Porto     Portugal                 2
## 10 Marc         31    10 Basquet   Andorra   Andorra                  2
## 11 Marie        11    12 Ballet    Rennes    Francia                  3
## 12 Anas         14    10 Futbol    Rabat     Marruecos                1
## 13 Alfredo       9    10 Futbol    Quito     Ecuador                  4
## # ... with 3 more variables: Juegopreferido <chr>,
## #   Fechadenacimiento <chr>, Sexo <chr>

Nota: ojo al detalle del formato usado para indicar la ubicación del archivo: las barras son del tipo / (si usamos \ no nos funcionará).

De modo similar, leería los datos de un archivo .txt (datos no tabulares) usando la variante de la función de lectura read_fileen mi expresión: misdatos <- read_file("path/miarchivo.txt").

Habrá que fijarse bien y cuando sea necesario usar las distintas variantes de la función de lectura de readr según cómo estén delimitados los datos en el archivo que queremos leer: sea por comas, por punto y coma, por separador (tab) o por cualquier otro delimitador.

Mírate esta chuleta de Rstudio para entender todas las opciones de importación de datos: https://github.com/rstudio/cheatsheets/raw/master/data-import.pdf.

En caso de que no estén por defecto en la función de lectura que usamos estas opciones las deberemos especificar nosotros en los argumentos de la función; así como si tienen título o no, si queremos considerar los datos faltantes o no, etc. Siempre nos aseguraremos de que los datos se nos importan en el formato correcto.

3.1.2 Leer datos contenidos en un excel

Si me interesan algunos datos que tengo en un excel; los puedo seleccionar, copiar (en el portapapeles) y luego voy a R y escribo: misdatos <- read.delim ("clipboard").

Ahora cuando lo que quiero es leer archivos enteros de excel desde R, usaré -de modo similar a cómo hemos visto para leer archivos csv- paquetes como xlsx (Dragulescu 2014) o readxl (Wickham and Bryan 2017) (paquete que es parte del conjunto integrado de paquetes Tidyverse) y sus respectivas funciones para leer los datos de las tablas de un excel: read.xlsx () y read_excel().

3.1.3 Leer datos de una página web

Pongamos que me interesa una tabla en csv disponible en una página web. La puedo importar también con misdatos <- read.csv("http://www..../archivo.csv").

Otro caso seria recuperar una parte de contenido que se encuentra en formato HTML en una página web a un formato estructurado que podamos analizar. La técnica asociada a ese fin se conoce como webscrapping. En R hay un paquete específico para hacer webscraping llamado rvest (Wickham 2016).

Por ejemplo, imaginemos que soy un fan del waterpolo y quiero recuperar los resultados de la competición de la categoría de másteres que se encuentran en la página de la federación catalana de natación:

##    CLASSIFICACIÓ             CLASSIFICACIÓ CLASSIFICACIÓ CLASSIFICACIÓ
## 1             NA                     Equip             P            PJ
## 2              1                 CN Mataró            37            13
## 3              2               CN Terrassa            34            13
## 4              3          CN Molins de Rei            33            13
## 5              4 CLUB ESPORTIU MEDITERRANI            33            13
## 6              5            CN Sant Andreu            33            13
## 7              6              CN Catalunya            31            13
## 8              7                  UE Horta            31            13
## 9              8              CN Martorell            26            13
## 10             9           CW SANT ADRIA B            25            13
## 11            10                  CN Badia            25            14
## 12            11 Club Natació L'Hospitalet            23            14
## 13            12               CN Sabadell            22            13
## 14            13    Club Natació Poble Nou            22            13
## 15            14                 CN Premià            21            14
## 16            15           CW SANT ADRIA A            21            13
## 17            16              CW Can Dragó            16            13
## 18            17    CN Atlètic-Barceloneta            15            13
##    CLASSIFICACIÓ CLASSIFICACIÓ CLASSIFICACIÓ CLASSIFICACIÓ CLASSIFICACIÓ
## 1             PG            PE            PP            GF            GC
## 2             12             0             1           173            64
## 3             10             1             2           126            67
## 4             10             0             3           155            86
## 5             10             0             3           124            93
## 6             10             0             3           134            80
## 7              9             0             4           126            91
## 8              9             0             4           125            97
## 9              6             1             6           105           115
## 10             6             0             7           105           112
## 11             5             1             8           115           121
## 12             4             1             9            97           129
## 13             3             4             6            79            97
## 14             4             1             8           108           136
## 15             3             1            10            79           123
## 16             4             0             9            62           131
## 17             1             1            11            54           152
## 18             1             0            12            70           143

Ya tengo los resultados.

3.2 Acomodar datos

Muy a menudo, sin embargo, los datos se nos presentan de forma bruta o imperfecta (formatos raros, valores que faltan, duplicidades, etc) o simplemente no están de la forma que queremos. Por ello es importante acomodarlos de un modo que sea adecuado o conveniente para su análisis.

3.2.1 Funciones base en R

En R es posible usar funciones como apply, lapply, sapply, tapply, etc. para realizar operaciones comunes en el trabajo con matrices y tablas.

  • apply, permite aplicar funciones a filas o columnas de una matriz.

Por ejemplo, aplicaríamos la funcion suma a las columnas de la matriz df con la expresión: apply (df, 2, sum) (aquí 1 se usa para indicar fila y 2 para indicar columna)

  • lapply, extrae una parte de una matriz o tabla como una lista.

Por ejemplo, para extraer la primera fila de la tabla df usariamos: lapply (df, "[", 1, ) y para extraer la segunda columna de la tabla df: lapply (df, "[", , 2)

  • tapply, permite aplicar funciones a una variable, desglosada en base a otra.

Por ejemplo, en el caso de nuestros datos, para calcular la mediana del número de cromos por sexo:

##    f    m 
## 28.0 17.5

Las chicas tienen de media más cromos que los chicos.

Otras funciones disponibles en R base (sin necesidad de cargar paquetes adicionales) útiles para ordenar, filtrar o hacer transformaciones a nuestros datos son sort(), subset() o transform().

Prueba a buscar ayuda sobre estas funciones (por ejemplo escribiendo ?sort).

3.2.2 Paquete dplyr

Más recientemente, en el marco de herramientas integradas que facilitan acomodar datos (tidyverse), podemos usar varias funciones incluidas en el paquete dplyr (Wickham et al. 2017). Las más importantes son:

  • filter() que permite filtrar observaciones por sus valores.

  • arrange() para reordenar filas por variables.

  • select() para tomar variables por sus nombres.

  • mutate() para canviar variables o crear nuevas variables con funciones de variables existentes.

  • summarise() para sumarizar muchos valores en uno solo.

Por ejemplo, para eliminar una columna de una tabla puedo usar select() y el operador negativo -:

df %>% select(-variable_inutil) (siendo variable_inutil el nombre de la columna de df que no quiero).

Para eliminar filas duplicadas puedo usar la función distinct():

df_limpia <- df %>% distinct() elimina filas duplicadas de df y asigna una nueva tabla (df_limpia) sin ellas (distinct és útil por tanto para hacer recuentos de variables descartando las que aparecen más de una vez).

Con filter() (función similar a subset en R base) puedo por ejemplo retener determinadas observaciones de una columna (p.ej. un determinado rango de la variable Edad):

df %>% filter(Edad > 18)

Con arrange() (similar a sort en R base) ordenar datos en orden ascendente: arrange(Edad) o descendente : arrange(desc(Edad)).

Con mutate() (similar a transform en R base) puedo, por ejemplo, crear una nueva variable en base a otras:

mutate(nueva_columna = col1 + col2)

Nota: vemos que una forma de expresar varias funciones a la vez de un modo eficiente y entendedor es usando el operador %>% (conocido como pipe y disponible con los paquetes magritte y tidyverse). Consiste básicamente en que, en vez de expresar una función que opere sobre unos datos como f(datos), lo puedo hacer como datos %>% f y ello me permite ir concatenando varias funciones que quiera aplicar sobre esos mismos datos y que sea fácil de entender.

Veámoslo en un ejemplo:

##    Nombre Cromos Edad Deporte Poblacion     Pais numerodehermanos
## 1 Mariela     40   12  Futbol Barcelona   España                4
## 2    Marc     31   10 Basquet   Andorra  Andorra                2
## 3 Antonio     26    9  Futbol     Porto Portugal                2
## 4 Pedrito     21   10 Petanca  Mallorca   España                2
## 5  Vicent     21   10  Futbol  Valencia   España                2
##   Juegopreferido Fechadenacimiento Sexo RatioCromosEdad Edaden5
## 1         Farcry         12-4-2004    f        3.333333      17
## 2     GuitarHero         28-9-2005    m        3.100000      15
## 3      Minecraft         12-7-2007    m        2.888889      14
## 4    ClashRoyale         30-5-2006    m        2.100000      15
## 5      Minecraft          1-9-2005    m        2.100000      15

3.2.3 Limpiar textos

Para limpiar textos a menudo nos interesa reemplazar carácteres de nuestros datos brutos por otros más sencillos. Para ello suelen ser muy útiles funciones como gsub. La expresamos como:

gsub(pattern, replacement, x, ignore.case = TRUE)

Dónde:

  • pattern: carácteres a cambiar.

  • replacement: carácteres para remplazar.

  • x: nuestros datos.

  • ignore.case: ponemos TRUE cuando queremos ignorar si el patrón es mayúsculas o minúsculas.

Por ejemplo:

## [1] "anger"

La función substr la podemos usar, por ejemplo, para eliminar n carácteres de un elemento. Si sólo queremos los carácteres del primero al onceavo:

## [1] "loquequiero"

Esta misma expresión la podemos opcionalmente formar junto con nchar para indicar el número de carácteres que no queremos (empezando en este caso por atrás):

## [1] "loquequiero"

Otro paquete stringr (Wickham 2017b) es también útil para manipular textos; de modo similar me permite tomar sólo los últimos carácteres de algo:

## [1] "art"

O extrer las palabras unidas por guiones bajos en una frase:

## [[1]]
## [1] "el"     "último" "de"     "la"     "fila"

O considerar los NA que aparecen a menudo en una tabla o un vector de textos como datos faltantes y reemplazarlos por carácteres (entrecomillados) sin eliminarlos:

## [1] "una_cosa"  "NA"        "otra_cosa"

Nota: Quizás lo estés pensando; pues sí, en R una misma cosa puede hacerse de muchos modos distintos y usando paquetes distintos. Hay algunas funciones comunes y paquetes muy usados -las que estamos tratando de mostrar aquí- pero existen innumerables funciones para resolver problemas similares y uno siempre encontrará un paquete que haga la misma cosa pero de otro modo.

Referencias

Wickham, Hadley. 2017a. Readr: Read Rectangular Text Data. https://CRAN.R-project.org/package=readr.

Dragulescu, Adrian A. 2014. Xlsx: Read, Write, Format Excel 2007 and Excel 97/2000/Xp/2003 Files. https://CRAN.R-project.org/package=xlsx.

Wickham, Hadley, and Jennifer Bryan. 2017. Readxl: Read Excel Files. https://CRAN.R-project.org/package=readxl.

Wickham, Hadley. 2016. Rvest: Easily Harvest (Scrape) Web Pages. https://CRAN.R-project.org/package=rvest.

Wickham, Hadley, Romain Francois, Lionel Henry, and Kirill Müller. 2017. Dplyr: A Grammar of Data Manipulation. https://CRAN.R-project.org/package=dplyr.

Wickham, Hadley. 2017b. Stringr: Simple, Consistent Wrappers for Common String Operations. https://CRAN.R-project.org/package=stringr.