3.2 Cruzando variables: la operación join

Al realizar un análisis “en la vida real”, es decir, usando datos salvajes en lugar de los prolijos datasets de práctica, es muy habitual encontrar que nos falta una variable que necesitamos. Si tenemos suerte, la información que necesitamos también está disponible en forma de tabla, con algún campo en común, y podemos llevar el cabo un cruce de datos para traérnosla.

Para expresarlo con un ejemplo concreto: hemos visto que los registros de atención al ciudadano incluyen una columna con el barrio, que es la única variable relacionada con la geografía. Si nuestra unidad de análisis fuera la columna en lugar del barrio, necesitaríamos agrega la columna correspondiente. En este caso, estamos de suerte porque una tabla con los barrios de la Ciudad de Buenos Aires y la comuna a la que pertenecen es fácil de conseguir. Con esa tabla en nuestro poder, ya tenemos las piezas necesarias para el cruce de datos. En cada registro en el dataframe de atención al ciudadano, tenemos un barrio; podemos buscarlo en la tabla de barrios y comunas, tomar nota de la comuna asociada, y copiarla en nuestro dataset original. Por supuesto, hacerlo a mano para cada uno de las 57.432 filas en nuestro dataframe tardaría una eternidad, amén de que quizás perderíamos la cordura antes de terminar. ¡Nada de eso! Vamos a resolverlo en meros instantes escribiendo unas pocas líneas de código. Antes de continuar hagamos una pausa para conmiserar a los investigadores de eras pasadas, antes de la popularización de la computadora personal, que realizaban tareas de esta escala con lápiz, papel y paciencia.

Existe una gran variedad de funciones que permiten combinar tablas relacionadas entre sí por una o varias variables en común. Para nuestro propósito, alcanza con conocer una: left_join(). La función toma como parámetros dos dataframes (que son tablas al fin y al cabo) busca las variables que tengan el mismo nombre y usándolas como referencia completa la primera de ellas, la de la izquierda, con los datos nuevos que aporta la segunda. left_join devuelve un dataframe nuevo con los datos combinados.

Manos a la obra. Descargamos el dataframe con barrios y comunas,

barrios_comunas <- read.csv("http://bitsandbricks.github.io/data/barrios_comunas.csv")

echamos un vistazo, comprobando que existe BARRIOS, una columna en común que lo relaciona con el dataframe de atención al ciudadano,

barrios_comunas
##               BARRIO COMUNA
## 1          AGRONOMIA     15
## 2            ALMAGRO      5
## 3          BALVANERA      3
## 4           BARRACAS      4
## 5           BELGRANO     13
## 6               BOCA      4
## 7              BOEDO      5
## 8          CABALLITO      6
## 9          CHACARITA     15
## 10           COGHLAN     12
## 11        COLEGIALES     13
## 12      CONSTITUCION      1
## 13            FLORES      7
## 14          FLORESTA     10
## 15           LINIERS      9
## 16         MATADEROS      9
## 17         MONSERRAT      1
## 18      MONTE CASTRO     10
## 19     NUEVA POMPEYA      4
## 20             NUÑEZ     13
## 21           PALERMO     14
## 22 PARQUE AVELLANEDA      9
## 23  PARQUE CHACABUCO      7
## 24       PARQUE CHAS     15
## 25  PARQUE PATRICIOS      4
## 26          PATERNAL     15
## 27     PUERTO MADERO      1
## 28          RECOLETA      2
## 29            RETIRO      1
## 30          SAAVEDRA     12
## 31     SAN CRISTOBAL      3
## 32       SAN NICOLAS      1
## 33         SAN TELMO      1
## 34   VELEZ SARSFIELD     10
## 35         VERSALLES     10
## 36      VILLA CRESPO     15
## 37  VILLA DEL PARQUE     11
## 38      VILLA DEVOTO     11
## 39 VILLA GRAL. MITRE     11
## 40      VILLA LUGANO      8
## 41        VILLA LURO     10
## 42     VILLA ORTUZAR     15
## 43  VILLA PUEYRREDON     12
## 44        VILLA REAL     10
## 45   VILLA RIACHUELO      8
## 46  VILLA SANTA RITA     11
## 47     VILLA SOLDATI      8
## 48     VILLA URQUIZA     12

y lo unimos (de allí el término “join”, unir en inglés) a nuestra data:

atencion_ciudadano <- left_join(atencion_ciudadano, barrios_comunas)
## Joining, by = "BARRIO"

Admiremos nuestra obra:

head(atencion_ciudadano)
##   PERIODO  RUBRO TIPO_PRESTACION    BARRIO total COMUNA
## 1  201301 ACERAS         RECLAMO AGRONOMIA     6     15
## 2  201301 ACERAS         RECLAMO   ALMAGRO   172      5
## 3  201301 ACERAS         RECLAMO BALVANERA    92      3
## 4  201301 ACERAS         RECLAMO  BARRACAS    45      4
## 5  201301 ACERAS         RECLAMO  BELGRANO    79     13
## 6  201301 ACERAS         RECLAMO      BOCA    10      4

Es así de fácil. Bueno, no tanto… este fue un caso sencillo, pero hay todo tipo de datos y cruces allí afuera, y a veces se necesitan operaciones más complejas. Por eso hay toda una familia de funciones de join - right_join(), inner_join(), full_join, anti_join(), y alguna más. Pero podemos dejarlas en paz; para nuestras necesidades, con left_join() podemos alegrarnos muy bien.

Satisfechos con la mejora, si queremos guardar el dataframe “mejorado” para usarlo en otra ocasión, podemos hacerlo con write.csv(), que lo convierte en un archivo de texto que queda en nuestra PC.

write.csv(atencion_ciudadano, "atencion_ciudadano.csv", row.names = FALSE)

Podemos seguir siempre ese formato para guardar nuestros datos. El primer parámetro es el dataframe que vamos a guardar, el segundo -siempre entre comillas- es el nombre de archivo, y la opción final, row.names = FALSE sirve para evitar que R le agregue una columna al principio con números consecutivos (1, 2, 3, y así), cosa que quizás fue útil alguna vez pero en general no necesitamos.

Para volver a leer los datos en otra ocasión, usamos read.csv() tal como ya hemos hecho.

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

Y si queremos saber exactamente dónde ha guardado R nuestros datos, por ejemplo para abrirlos con otro programa, usamos la función getwd (por get working directory )

getwd()
## [1] "/home/havb/Dropbox/Books/Mios/Ciencia de datos para gente sociable"

El resultado será la dirección (la ubicación de la la carpeta), donde estamos trabajando y hemos guardado los datos; por ejemplo /home/antonio/Practicando R/.