PRIMER ENCUENTRO
Este curso está organizado por sociólogos y sociólogas amateurs en el uso de este lenguaje que busca que otros estudiantes y graduadas/os de las ciecias sociales puedan aproximarse y conocer el potencial de R. Esperamos que sea de utilidad para cada una de las actividades que desarrollen en los diferentes planos de sus vidas: en el mundo académico, en el mercado de trabajo y en su desenvolvimiento profesional.Seguramente muchas/os de ustedes puedan tener algún conocimiento para agregar que mejoren los contenidos y aporten nuevas miradas. Sientan libertad de proponer ideas que puedan potenciar el curso.
Agradecemos el espacio que abrió el Observatorio de Economía Política de la Facultad de Ciencias Sociales para que podamos impulsar este tipo de actividades relacionadas con el procesamiento, el análisis y la visualización de información. Creemos con convicción, que es necesaria la apertura de estos espacios, que acompañen a los alumnas/os y graduados/as en los procesos de aprendizaje, formación e investigación. También, para incentivar la difusión de investigaciones y contenidos relacionado con las ciencias sociales en la opinión pública.
Por último, queremos agradecer a cada una/o de ustedes que está participando de este curso.Creemos que es importante compartir y construir conocimiento entre todas/os, para fortalecer nuestro oficio dentro de las Ciencias Sociales.
Uno de los desafíos que nos planteamos al momento de diseñar este curso se vincula con las capacidades de sintetizar tres elementos centrales: el conocimiento teórico, la práctica y el contexto. Entre los motivos principales que impulsan el desarrollo de esta actividad se encuentra la falta de herramientas que tenemos las/los que participamos de las Ciencias Sociales para poder insertarnos en el campo de la investigación social ligados a los diseños cuantitativos y en las diferentes dimensiones del mercado de trabajo. En este sentido, las/los que organizamos este curso creemos que estas herramientas potencian el oficio dentro de este campo disciplinario.
También nos permite fijar una posición política al defender nuestro objeto de estudio, que se recorta en los acontecimientos y hechos sociales. De esta manera, creemos en el trabajo interdisciplinario para abordar estos acontecimientos, pero respetando las formaciones teóricas y prácticas de cada uno de los campos de estudios. Creemos, que las/los que formamos parte del campo sociales tenemos que conocer aunque sea de manera superficial y aproximada la lógica de procesamiento de la información que muchas veces es realizado por otros tipos de perfiles profesionales.
En sintesis, este curso está destinado a estudiantes y graduadas/os de las Ciencias Sociales que buscan conocer las lógicas de procesamiento, transformación y visualización de datos. Está construido por personas “amateurs”, que están lejos de conocer con profundidad el uso de estas herramientas. Creemos en la idea de un “aprendizaje colectivo”, que enriquezca nuestra formación, a través de compartir y crear un espacio de discusión sobre esta temática. Seguramente que, con las dudas, preguntas y experiencias que intercambiemos vamos a ir enriqueciendo el curso entre todas y todos.
Por último, los materiales van a estar disponibles para que puedan consultarlos y realizar el curso a los tiempos que ustedes consideren. La modalidad de cursado se divide en dos dimensiones: sincrónico y asincrónico. Con respecto a la primera, esperamos que puedan sumarse a las clases para participar de la parte “teórica” e intercambiar dudas y dificultades. La parte asincrónica consiste en una serie de guías y ejercicios prácticos para que también a su ritmo puedan ir resolviendo.
¡Bienvenidas/os y esperamos que tenga un buen transitar por el curso! (y una excusa de evitar que salgas: #quedateencasa #noscuidamosentretodes)
Porque es un lenguaje y desarrollo libre, que nos permite dar indicaciones dentro de un software, para el procesamiento y la visualización de grandes cantidades de datos. Esto favorece la apertura de nuevo horizontes y desafíos a las Ciencias Sociales. Cuando nos referimos a información, hablamos de: estadística cuando es generada por un diseño muestral o poblacional, registros administrativos vinculada a la administración pública (ejemplo el DNI, la SUBE, etc.) o de una empresa privada (Estados contables, etc), como así también al uso de información de alguna red social (twitter, etc), entre otros.
Pensemos que, hoy en día grandes dimensiones de nuestras vidas se encuentran atravesadas por la producción de información. Por ejemplo, cuando usamos nuestras redes sociales, seguramente todos esos datos producidos por nostros, se almacena en alguna base. Esta información, que en algunos casos esta disponibles y en otros no, puede ser un gran insumo para nuestras investigaciones, trabajos de campos, diseños de políticas públicas, etc. Desde las/los que construimos este curso, creemos en la necesidad de complementar los diseños cualitativos y cuantitativos a través de lo que se llama una triangulación metodológica.
Por esto, consideramos necesario empezar a formarnos como comunidad en el uso de estas herramientas, con el objetivo de potenciar nuestro oficio en este campo. Un ejemplo del potencial de esta herramienta, se observa cuando queremos analizar información que está en distintas fuentes, y tratamos de manera “artesanal” unir esa información. Muchas veces tienen una columna en común que facilita el trabajo con esas tablas (en poco tiempo podemos unir esa información, a diferencia del copiado y pegado artesanal que nos demora horas y horas).
Por todo esto elegimos R. Y por muchas otras razones que por cuestiones de limitación no enunciamos pero que van/vamos a ir descubriendo colectivamente.
Como es lógico, empezamos con la instalación. A continuación, presentamos un instructivo, con el paso a paso de la instalación de R y Rstudio. Pero…, ¿son dos programas?. Sí. Primero, descargamos y ejecutamos el instalador de R. Este primer programa es la base sobre la que funciona RStudio.
R es el lenguaje (o el motor) sobre la que se monta RSudio (carcasa). Este último programa es un entorno de desarrollo integrado (IDE) para el lenguaje de programación R, dedicado a la computación estadística y a la representación gráfica. Este entorno incluye: una consola, editor de script, gestión del espacio de trabajo, entre otras muchas ventajas. En términos de las Ciencias Sociales, R es la estructura sobre la que se monta la superestructura RStudio.
Paso a paso by Flavio Scargiali on Scribd
Cualquier cosa que existe en R y que tiene un nombre es un OBJETO: gráficos, número, vectores, funciones, secuencias, bases de datos, etc. Pero vayamos a un ejemplo práctico concreto. Vamos a crear nuestro primer objeto: uno que se llame “weber” y que contenga la frase “Clásico de la sociología”. Para las/los que vienen de otros campos disciplinarios aclaramos que, como vamos a usarlos en otros ejercicios, Weber, Durkheim y Marx son los intelecturales fundadores de la Sociología.
Dos puntos muy importantes: R es sensible a los signos de puntuación, las mayúsculas y las minúsculas. A lo Paulina Cocina: “escriban a lo pelado”. Por ejemplo, weber sin mayúscula (sabemos que es un nombre propio). Seguramente a muchas/os de ustedes (nos pasó) les están sangrando los ojos, pero facilita un montón de cosas y les aseguramos que evitan otro montón de errores. Principalmente se aplica esta recomendación en los nombre de los objetos. Pero lo vamos a ir viendo paso a paso. No se preocupen.
#Todo es un objeto en R
weber <- "Clásico de la Sociología"
weber
## [1] "Clásico de la Sociología"
De manera sencilla, lo que realizamos utilizando el operador <- es asignar “Clásico de la Sociología” a weber. Cuando escribimos weber y corremos el código, la consola de RStudio nos devuelve “Clásico de la Sociología”. Vamos a introducirnos en los operadores básicos. Seguramente sean muy conocidos por ustedes. Pero experimentemos para que queden claro su uso. La mayor dificultad creemos que esta en identificar si el > o < es mayor o menor. ¿No les pasó que se ponen hasta nerviosos con esa situación?
| Operadores Lógicos | Operadores Arirmeticos | Otros operadores | |
|---|---|---|---|
> Mayor |
+ Suma |
%>% Pipe |
|
>= Mayor o igual |
- Resta |
%in% Dentro |
|
< Menor |
* Multiplicación |
| O |
|
<= Menor o igual |
/ División |
& Y |
|
== Igual |
^ Portencia |
||
!= Diferente |
|||
A modo aburrido, los operadores lógicos generan un resultado a partir de que se cumpla o no una condición. Por ejemplo, queremos saber si Weber es igual a Marx. Recuerden que a Weber le asignamos la frase “Clásico de la Sociología”. Ahora creamos otro objeto que se llame Marx y le asignamos también “Clásico de la Sociología”. Posteriormente, pedimos que compare a Weber y a Marx para evaluar si son iguales.
#¿Marx igual a Weber?
marx <- "Clásico de la Sociología"
marx==weber
## [1] TRUE
Magia. Cuando comparamos a través del == (igual) a Marx y a Weber, nos devuelve TRUE. En pocas palabras, quiere decir que efectivamente Marx y Weber, que son objetos que nosotros construimos, son iguales. Pero, ¿por qué? Justamente, porque a los dos le asignamos la frase “Clásico de la Sociología”. Veamos que sucede con el operador lógico != (diferente de).
#¿Marx diferente a Weber?
marx!=weber
## [1] FALSE
Después de correr el código, nos está diciendo, a pedido nuestro (esto es muy importante: no hay nada que R corra si nosotras/os no lo indicamos), que Marx y Weber no son diferentes (FALSE). Recuerden que, lo que comparamos es la asignación que hicimos “Clásicos de la Sociología”. Veamos que sucede con los tediosos, pero muy útiles (como vamos a ver más adelante en el curso), > o <. Construimos dos nuevos objetos: uno el año de nacimiento de Marx y otro el año de nacimiento de Weber. Y la pregunta a la que queremos generar una respuesta es: ¿Quién nació antes?
#Años de nacimiento de Weber y Marx
nacimiento_ano_weber<-1864
nacimiento_ano_marx<-1818
#Comparación Nacimiento
nacimiento_ano_weber>nacimiento_ano_marx
## [1] TRUE
nacimiento_ano_weber<nacimiento_ano_marx
## [1] FALSE
La comparación resultó que Weber nació después de Marx. Simplemente, porque 1864 es mayor (>) a 1818 que es el año de nacimiento de Marx. Por esto, la primera comparación nos devolvió TRUE (Weber nació después de Marx) y la segunda FALSE (Weber nació antes que Marx).
A los operadores lógicos menor y mayor se los puede combinar con el igual <=(igual o menor)/>=(igual o mayor). Esto quiere decir que se incluye el valor en la condición. Por ejemplo si decimos > a 4 no incluimos el 4, pero si decimos >= incluimos el 4.
Parece tediosa esta parte, pero está muy relacionada con la lógica de funcionamiento de R. Y ahora en tono serio: sirven y mucho.
Este tipo de operadores, los usamos todo el tiempo en nuestra vida cotidiana: sumamos, restamos, dividimos, multiplicamos, etc. Veamos cómo funcionan los operadores aritméticos. En pocas palabra, R lo que hace es funcionar como una calculadora.
A continuación, les dejamos un resumen de las principales funciones:
#Suma
2+2
## [1] 4
#Resta
2-2
## [1] 0
#División
2/2
## [1] 1
#Múltiplicación
2*2
## [1] 4
#Potencia
2^2
## [1] 4
Veamos un ejemplo con un poco más de complejidad. Imaginense que son profesores y quieren sumar un punto más a todas/os las/los alumnos por su buen desenvolvimiento en los prácticos (nunca nos pasó pero no dejamos de ilusionarnos). Y lo quieren hacer de manera rápida. Para esto arman un objeto que se llama “notas alumnes”. En este objeto, ponen las calificaciones de los alumnas/os (8, 7, 8, 9, 8) y suman un punto más a cada nota. Veamos cómo se hace en R:
#Suma de un punto a todos los/las alumnas
notas_alumnes<-c(8,7,8,9,8)
notas_alumnes<-notas_alumnes+1
notas_alumnes
## [1] 9 8 9 10 9
Después de sumar uno al objeto notas de los alumnes, nos devuelve todos los valores de las notas con un punto más. No queremos seguir aburriendo con los operadores. Pero sí, vayan practicando y encontrando la lógica del procesamiento de la información que realiza el softwate.
Las funciones son un conjunto de operaciones a la que se les asigna un nombre (¡Todo en R es un objeto!. Aceptan argumentos, es decir, especificaciones sobre cómo deben funcionar. Ejemplo de funciones: mean() (media), sd(), (desviación estándar), filter() (filtrar), etc. Pero veamos un ejemplo. Retomemos nuestro objeto notas_alumnes para indagar sobre el promedio de calificación. Para esto, utilizamos la función mean() que en R sirve para pedir la media. Simplemente lo que hace es sumar los valores y dividirlo por la cantidad de alumnos.
#Promedio del curso
mean(notas_alumnes)
## [1] 9
¿Qué pasa si hacemos notas_alumnes/5? Si nosotros indicamos que haga notas_alumnos/5, el programa entiende que tiene que dividir cada una de las notas de los alumnos por 5. Por esto es importantes conocer la lógica de funcionamiento. Este comentario también, lo hacemos extensivos a cualquier software estadístico que utilicen. El resultado que nos devuelve no es lo que queríamos.
Además de las funciones básica que tiene R, se pueden instalar paquetes que agrupan un conjunto de diferentes funciones que favoren algún área de la transformación y visualización de la información. Por ejemplo, el paquete ggplot tiene un conjunto de funciones relacionadas con las representaciones gráficas. Otro ejemplo es dplyr que es un conjunto de funciones vinculadas a la transformación y manipulación de los datos. A modo de síntesis, un paquete contiene un conjunto de funciones que en su agrupamiento responde a una necesidad del procesamiento, la visualización y/o transformación de datos.
En R, los paquete se instalan con la función install.packages y se los activa con library. En el curso utilizamos tres paquetes: tidyverse, simple features y EPH. Principalmente centramos el curso, en el uso del de tidyverse. La misma comunidad de R actualiza y/o construye permanentemente paquetes con nuevas funcionalidades. En los próximos encuentros, vamos a mostrar algunos ejemplos. Por ahora, creemos que es suficiente.
A continuación les dejamos los paquetes necesarios para el curso:
install.packages(c("tidyverse", "eph", "sf"))
Una de las formas de hacer más amigable esta introducción al lenguaje, es observando cómo, con unas pocas líneas de código, se logran resultados que nos sorprendan (¡tampoco exageremos!). Muchas veces, se nos presenta el mundo de la “programación estadística” como una “representación deformada, artificial, ilusoria de las cosas, de las mercancías, de las relaciones de producción, que aparece infaliblemente en el marco de la producción mercantil fundada en la propiedad privada, y sobre todo, en la producción capitalista.” Disculpen, seguramente no sea ni la primera ni la última vez que se nos escape alguna que otra frase de algunos tipos que estaban aburridos y sentaron las bases de la sociología. Pero sí, detrás del mundo de la programación estadística hay un halo de misterio imposible de acceder: el “fetiche de la programación”.
Volviendo al tema principal, escuchamos en el primer párrafo la palabra diabólica: “programación”. Esperamos que no tengan pesadillas al momento de dormir. Cuando “deconstruimos” esta palabra, nos encontramos que simplemente es “indicar” al software que realice una serie de actividades para alcanzar un determinado resultado. Entonces, el resultado es la síntesis de algo diferente a la sumatoria de órdenes (que capacidad de citar autores, ¿no?)
Previo a continuar, queremos enfatizar en la mediática frase: siempre es el marco teórico. Esto quiere decir, que siempre partimos de una definición teórica-práctica para realizar el trabajo que estemos haciendo en R: siempre (cuando decimos siempre es siempre) partimos de una visión de cómo son o cómo deberían ser las cosas en el mundo. Es fundamental que tengamos una buena definición conceptual de las variables para alcanzar el objetivo que nos propusimos. Nunca descuiden esta noción porque de lo contrario estaríamos haciendo en simples palabras “cualquier cosa”.
Entonces, haciendo honor a nuestro axioma (¡Siempre es el marco teórico!), proponemos a lo largo de los próximos encuentros, utilizar un mismo tema para presentar algunas de las potencialidades, que tiene la herramienta. Queremos aclarar que este curso es exitoso, siempre y cuando despierte la curiosidad en ustedes. Difícilmente podamos abarcar ni siquiera lo “básico” de R en los cuatros encuentros que siguen. Pero sí, creemos que podemos ayudarlas/los (y ayudarnos con sus preguntas y sugerencias) a ingresar en este mundo del “fetichismo de la programación estadística”, que como dijimos más arriba es alcanzar un resultado a partir de indicar una serie de órdenes utilizando, en este caso particular, el lenguaje R.
Como desafío para los próximos encuentros, nos propusimos abordar un tema que está vinculado con la realidad que nos toca vivir. Por eso, planteamos un ejercicio muy simplificado sobre el Coronavirus. A modo de simplificación extrema, utilizamos la Encuesta Permanente de Hogares (EPH) para analizar de forma muy (cuando decimos muy es porque es “muy muy”) aproximada a través de dos variables la situación que se encuentran los aglomerados urbanos y las regiones del país en términos de hacinamiento y desocupación en el último cuatrimestre del 2019. Para esto vamos a caracterizar a los individuos de acuerdo a las condiciones de hacinamiento del hogar y la tasa de desocupación.
A través de un tema de actualidad ligado al contexto sanitario, intentamos presentar superficialmente algunas de las cosas que podemos hacer con este lenguaje y software. Para empezar tenemos que conocer qué funciones hacen qué cosa. No se preocupen que con el correr de los encuentros profundizando en este tema.
Pero vayamos a la práctica.
Empecemos a cargar información a R. Para esto, utilizamos la función read_csv. Una aclaración para perder miedo al fetiche de la programación, la función traducida al español es “leer”_csv, simplemente le estamos diciendo a R que lea ese tipo de archivo. Sencillo, ¿no? Seguramente la mayor dificultad, la van a encontrar en la ubicación del archivo y del directorio en el que estén trabajando. A continuación presentamos una breve introducción al formato CSV:
Aclaración: CSV (comma separate values) es un tipo de archivo que tiene separadas las columnas por un tabulador.
En un archivo csv la información esta almacenada de la siguiente manera:
| Tabla CSV | |
|---|---|
| Cantidad de ambientes en la vivienda, edad,sexo | |
| 2,15,F | |
| 3,19,M | |
| 1,35.F |
Cuando aplicamos la función read.csv, R nos devuelve el siguiente resultado:
| Tabla después de aplicar CSV | ||
|---|---|---|
| Cantidad de ambientes en la vivienda | edad | sexo |
| 2 | 15 | F |
| 3 | 19 | M |
| 1 | 35 | F |
¿Qué sucedió? A través de esa función, R estructura la información de nuestro archivo CSV en columnas. Quisimos hacer la introducción a CSV porque es uno de los formatos que más se utilizan en los portales de datos abiertos. Según el tipo de archivo que tengamos, es la función que utilizamos: .sav (SPSS), .xlsx (Excel), .dta (STATA), .txt (Bloc de notas), etc. Recuerden verificar en qué paquete se encuentra cada una de las funciones: ejemplo read.sav está en la biblioteca “haven” de tidyverse. Para esto tenemos que activar la biblioteca que queremos utilizar a través de la función library() y después tipear la función. Pero vamos despacio para construir bases sólidas y que puedan ir ganando autonomía en el uso de esta herramienta a medida que transitamos los encuentros.
library(tidyverse)
library(sf)
¿En qué estábamos? Vamos a leer nuestro archivo en R. Directamente descargamos, escribiendo el link del portal BAdata, que aloja el csv a utilizar, dentro de los paréntesis de la función read_csv. Recuerdan que en R, todo es un objeto. Entonces, con el operador de asignación<- creamos un objeto, que contiene la información sobre la pandemia y se llama “casos_covid”.
#Creación de objeto con la información sobre los casos de COVID en CABA
casos_covid<-read_csv("https://cdn.buenosaires.gob.ar/datosabiertos/datasets/salud/casos-covid-19/casos_covid19.csv")
casos_covid #Impresión de la tabla
## # A tibble: 294,095 x 14
## numero_de_caso fecha_apertura_~ fecha_toma_mues~ fecha_clasifica~ provincia
## <dbl> <chr> <chr> <chr> <chr>
## 1 1184427 26JUN2020:00:00~ 26JUN2020:00:00~ 26JUN2020:00:00~ Buenos A~
## 2 1169074 25JUN2020:00:00~ 25JUN2020:00:00~ 27JUN2020:00:00~ CABA
## 3 1169619 25JUN2020:00:00~ 24JUN2020:00:00~ 27JUN2020:00:00~ CABA
## 4 1155493 24JUN2020:00:00~ 24JUN2020:00:00~ 26JUN2020:00:00~ CABA
## 5 1060870 11JUN2020:00:00~ 09JUN2020:00:00~ 11JUN2020:00:00~ CABA
## 6 1159515 24JUN2020:00:00~ 22JUN2020:00:00~ 27JUN2020:00:00~ Buenos A~
## 7 1156125 24JUN2020:00:00~ 23JUN2020:00:00~ 25JUN2020:00:00~ CABA
## 8 1135142 22JUN2020:00:00~ 19JUN2020:00:00~ 19JUN2020:00:00~ CABA
## 9 1177520 26JUN2020:00:00~ 24JUN2020:00:00~ 26JUN2020:00:00~ Buenos A~
## 10 1179979 26JUN2020:00:00~ 24JUN2020:00:00~ 26JUN2020:00:00~ Buenos A~
## # ... with 294,085 more rows, and 9 more variables: barrio <chr>, comuna <dbl>,
## # genero <chr>, edad <dbl>, clasificacion <chr>, fecha_fallecimiento <chr>,
## # fallecido <chr>, fecha_alta <lgl>, tipo_contagio <chr>
En R, existen funciones que permiten conocer la estructura de la tabla (en este lenguaje se conocen popularmente como dataframes). ¿Qué es la estructura de una tabla? Básicamente, la cantidad de columnas, filas, tipos de variables, etc. Algunas de estas funciones son names,view,str, head, summary. Existen muchas otras en diferentes paquetes para complementar el análisis exploratorio de la información. Estas funciones, a excepción de view que nos muestra completo nuestro dataframe, ayudan a conocer las tablas con las que estamos trabajando. Muchas veces se van a encontrar con dataframes con cientos de columnas y miles/millones de registro. Piensen que, la EPH tiene más de 150 variables y cerca de 60 mil filas. A continuación, resumimos las funciones para explorar el dataframe.
| Tabla de funciones exploratorias | |
|---|---|
| Nombre | Función |
names() |
Nombres de las columnas (variables) |
str() |
Estructura de la tabla. Muestra la cantidad de filas, el tipo de variable, las categorías y otros atributos del dataframe |
summary() |
Realiza un resumen estadistico con algunas medidas de tendencia central como la media y la mediana. |
head() |
Muestra las primera filas de un dataframe. Por default son las primeras cinco pero se pueden cambiar |
view() |
Abre el dataframe en el visor de R |
Presentamos un ejemplo de cada función (con excepción de view que dejamos que practiquen en sus tiempos libres):
#Nombre de las variables
names(casos_covid)
## [1] "numero_de_caso" "fecha_apertura_snvs" "fecha_toma_muestra"
## [4] "fecha_clasificacion" "provincia" "barrio"
## [7] "comuna" "genero" "edad"
## [10] "clasificacion" "fecha_fallecimiento" "fallecido"
## [13] "fecha_alta" "tipo_contagio"
#Estructura de la tabla
str(casos_covid)
## tibble [294,095 x 14] (S3: spec_tbl_df/tbl_df/tbl/data.frame)
## $ numero_de_caso : num [1:294095] 1184427 1169074 1169619 1155493 1060870 ...
## $ fecha_apertura_snvs: chr [1:294095] "26JUN2020:00:00:00.000000" "25JUN2020:00:00:00.000000" "25JUN2020:00:00:00.000000" "24JUN2020:00:00:00.000000" ...
## $ fecha_toma_muestra : chr [1:294095] "26JUN2020:00:00:00.000000" "25JUN2020:00:00:00.000000" "24JUN2020:00:00:00.000000" "24JUN2020:00:00:00.000000" ...
## $ fecha_clasificacion: chr [1:294095] "26JUN2020:00:00:00.000000" "27JUN2020:00:00:00.000000" "27JUN2020:00:00:00.000000" "26JUN2020:00:00:00.000000" ...
## $ provincia : chr [1:294095] "Buenos Aires" "CABA" "CABA" "CABA" ...
## $ barrio : chr [1:294095] NA "PARQUE PATRICIOS" "NUÑEZ" "VILLA GRAL. MITRE" ...
## $ comuna : num [1:294095] NA 4 13 11 9 NA 4 14 NA NA ...
## $ genero : chr [1:294095] "masculino" "femenino" "femenino" "masculino" ...
## $ edad : num [1:294095] 34 38 38 61 37 29 49 36 26 10 ...
## $ clasificacion : chr [1:294095] "confirmado" "confirmado" "confirmado" "confirmado" ...
## $ fecha_fallecimiento: chr [1:294095] NA NA NA NA ...
## $ fallecido : chr [1:294095] NA NA NA NA ...
## $ fecha_alta : logi [1:294095] NA NA NA NA NA NA ...
## $ tipo_contagio : chr [1:294095] "En Investigación" "Trabajador de la Salud" "Comunitario" "Comunitario" ...
## - attr(*, "problems")= tibble [35,850 x 5] (S3: tbl_df/tbl/data.frame)
## ..$ row : int [1:35850] 1102 6903 35892 35896 35916 36091 36098 36145 36168 36186 ...
## ..$ col : chr [1:35850] "fecha_alta" "fecha_alta" "fecha_alta" "fecha_alta" ...
## ..$ expected: chr [1:35850] "1/0/T/F/TRUE/FALSE" "1/0/T/F/TRUE/FALSE" "1/0/T/F/TRUE/FALSE" "1/0/T/F/TRUE/FALSE" ...
## ..$ actual : chr [1:35850] "30JUN2020:00:00:00.000000" "17JUN2020:00:00:00.000000" "06JUL2020:00:00:00.000000" "09APR2020:00:00:00.000000" ...
## ..$ file : chr [1:35850] "'https://cdn.buenosaires.gob.ar/datosabiertos/datasets/salud/casos-covid-19/casos_covid19.csv'" "'https://cdn.buenosaires.gob.ar/datosabiertos/datasets/salud/casos-covid-19/casos_covid19.csv'" "'https://cdn.buenosaires.gob.ar/datosabiertos/datasets/salud/casos-covid-19/casos_covid19.csv'" "'https://cdn.buenosaires.gob.ar/datosabiertos/datasets/salud/casos-covid-19/casos_covid19.csv'" ...
## - attr(*, "spec")=
## .. cols(
## .. numero_de_caso = col_double(),
## .. fecha_apertura_snvs = col_character(),
## .. fecha_toma_muestra = col_character(),
## .. fecha_clasificacion = col_character(),
## .. provincia = col_character(),
## .. barrio = col_character(),
## .. comuna = col_double(),
## .. genero = col_character(),
## .. edad = col_double(),
## .. clasificacion = col_character(),
## .. fecha_fallecimiento = col_character(),
## .. fallecido = col_character(),
## .. fecha_alta = col_logical(),
## .. tipo_contagio = col_character()
## .. )
#Resumen estadistico
summary(casos_covid)
## numero_de_caso fecha_apertura_snvs fecha_toma_muestra fecha_clasificacion
## Min. : 718084 Length:294095 Length:294095 Length:294095
## 1st Qu.:1091089 Class :character Class :character Class :character
## Median :1320923 Mode :character Mode :character Mode :character
## Mean :1328903
## 3rd Qu.:1575016
## Max. :1842717
##
## provincia barrio comuna genero
## Length:294095 Length:294095 Min. : 1.00 Length:294095
## Class :character Class :character 1st Qu.: 4.00 Class :character
## Mode :character Mode :character Median : 7.00 Mode :character
## Mean : 7.23
## 3rd Qu.:11.00
## Max. :15.00
## NA's :114219
## edad clasificacion fecha_fallecimiento fallecido
## Min. : 0.00 Length:294095 Length:294095 Length:294095
## 1st Qu.: 26.00 Class :character Class :character Class :character
## Median : 37.00 Mode :character Mode :character Mode :character
## Mean : 39.45
## 3rd Qu.: 51.00
## Max. :130.00
## NA's :262
## fecha_alta tipo_contagio
## Mode:logical Length:294095
## NA's:294095 Class :character
## Mode :character
##
##
##
##
#Primeras 10 filas
head(casos_covid,10)
## # A tibble: 10 x 14
## numero_de_caso fecha_apertura_~ fecha_toma_mues~ fecha_clasifica~ provincia
## <dbl> <chr> <chr> <chr> <chr>
## 1 1184427 26JUN2020:00:00~ 26JUN2020:00:00~ 26JUN2020:00:00~ Buenos A~
## 2 1169074 25JUN2020:00:00~ 25JUN2020:00:00~ 27JUN2020:00:00~ CABA
## 3 1169619 25JUN2020:00:00~ 24JUN2020:00:00~ 27JUN2020:00:00~ CABA
## 4 1155493 24JUN2020:00:00~ 24JUN2020:00:00~ 26JUN2020:00:00~ CABA
## 5 1060870 11JUN2020:00:00~ 09JUN2020:00:00~ 11JUN2020:00:00~ CABA
## 6 1159515 24JUN2020:00:00~ 22JUN2020:00:00~ 27JUN2020:00:00~ Buenos A~
## 7 1156125 24JUN2020:00:00~ 23JUN2020:00:00~ 25JUN2020:00:00~ CABA
## 8 1135142 22JUN2020:00:00~ 19JUN2020:00:00~ 19JUN2020:00:00~ CABA
## 9 1177520 26JUN2020:00:00~ 24JUN2020:00:00~ 26JUN2020:00:00~ Buenos A~
## 10 1179979 26JUN2020:00:00~ 24JUN2020:00:00~ 26JUN2020:00:00~ Buenos A~
## # ... with 9 more variables: barrio <chr>, comuna <dbl>, genero <chr>,
## # edad <dbl>, clasificacion <chr>, fecha_fallecimiento <chr>,
## # fallecido <chr>, fecha_alta <lgl>, tipo_contagio <chr>
Una vez que “exploramos” la tabla podemos comenzar a realizar nuestro análisis. Como es un primer encuentro, no pretendemos que entiendan todo. Es más, si fuera así quiere decir que ya conocen los contenidos del curso. A partir de ahora, proponemos mostrar el potencial que tiene R para nuestro campo disciplinario: las Ciencias Sociales. Compartimos los códigos para que puedan ver cómo armamos las tablas y las visualizaciones. El que quiera avanzar un poco más rápido pueda empezar a sumergirse en estos ejercicios. Pero la idea es exponer una muestra de los ejercicios teóricos/prácticos que vamos ir resolviendo juntos con el correr de los encuentros. Por ser el primer encuentro es suficiente. Ahora a “chusmear” el potencial de este lenguaje.
Como dijimos más arriba, nuestro objetivo, es presentar un tema relacionado con el contexto en el que vivimos. A continuación, a través de una serie de órdenes que escribimos, pretendemos realizar un mapa comparando la tasa de contagios cada 100 mil habitantes entre los barrios de la Ciudad de Buenos Aires. Para esto utilizamos el dataframe que cargamos casos_covid. Pero además, para poder calcular la tasa, necesitamos la información sobre la población de los barrios. A la espera del censo 2020, seguimos utilizando la información provista por el censo del 2010 y sistematizada en la página de la Dirección General de Estadística y Censos (Ministerio de Hacienda GCBA). Entonces, lo que hacemos es crear un nuevo objeto poblacion_barrios.
Aclaración: R NO permite la creación de nombres de los objetos con espacios. Por esto utilizamos . o _ para separarar las palabras.
#Creación de tabla con información sobre la población en los barrios
poblacion_barrios<-read.csv("https://raw.githubusercontent.com/flavioscargiali/desembarcandorensociales/master/barrios_poblacion%20-%20Hoja%201.csv",encoding = "UTF-8")
Una vez que tenemos las dos tablas cargadas, avanzamos con la transformación de los datos. Es decir, a partir de la información contenida en los dataframes, calculamos la tasa de contagios cada 100 mil habitantes. Para esto, lo primero que tenemos que realizar es un resumen de los casos por barrio.
Pero antes, como el dataframe tiene una variables que clasifica los casos en diferentes estados, tenemos que retener aquellas observaciones que tengan como categoría confirmado. Entonces, aplicamos un filtro con la función filter (1) en la que indicamos a R que retenga los casos que cumplan con la condición confirmados. ¡Acá vemos una aplicación práctica de los operadores lógicos!
Una vez realizado esto, con la función group_by (2) agrupamos los casos por barrio (imaginen que dividen la tabla original en una tabla por cada barrio) y con summarise (3) pedimos el resumen de los barrios sumando las observaciones que tiene condición confirmado. Creamos un nuevo objeto, para no sobreescribir el anterior que se llama casos.
casos<-casos_covid %>%
filter(clasificacion=="confirmado") %>% #(1) Filtramos por condición Confirmado
group_by(barrio) %>% #(2) Agrupamos por barrio
summarise(casos=n()) %>% #(3)Sumamos los casos por barrio
as.data.frame() #Convertimos en tabla
casos #Imprimimos el resultado
## barrio casos
## 1 AGRONOMIA 132
## 2 ALMAGRO 2797
## 3 BALVANERA 4746
## 4 BARRACAS 4871
## 5 BELGRANO 1625
## 6 BOCA 1735
## 7 BOEDO 975
## 8 CABALLITO 2661
## 9 CHACARITA 964
## 10 COGHLAN 257
## 11 COLEGIALES 742
## 12 CONSTITUCION 1628
## 13 FLORES 6694
## 14 FLORESTA 826
## 15 LINIERS 741
## 16 MATADEROS 1232
## 17 MONSERRAT 1174
## 18 MONTE CASTRO 415
## 19 NUEVA POMPEYA 1987
## 20 NUÑEZ 512
## 21 PALERMO 3588
## 22 PARQUE AVELLANEDA 1617
## 23 PARQUE CHACABUCO 1182
## 24 PARQUE CHAS 226
## 25 PARQUE PATRICIOS 1327
## 26 PATERNAL 722
## 27 PUERTO MADERO 374
## 28 RECOLETA 2641
## 29 RETIRO 3449
## 30 SAAVEDRA 534
## 31 SAN CRISTOBAL 1425
## 32 SAN NICOLAS 851
## 33 SAN TELMO 491
## 34 VELEZ SARSFIELD 641
## 35 VERSALLES 174
## 36 VILLA CRESPO 1323
## 37 VILLA DEL PARQUE 614
## 38 VILLA DEVOTO 830
## 39 VILLA GRAL. MITRE 621
## 40 VILLA LUGANO 5843
## 41 VILLA LURO 528
## 42 VILLA ORTUZAR 270
## 43 VILLA PUEYRREDON 427
## 44 VILLA REAL 217
## 45 VILLA RIACHUELO 386
## 46 VILLA SANTA RITA 563
## 47 VILLA SOLDATI 2752
## 48 VILLA URQUIZA 1256
## 49 <NA> 41132
Una vez que tenemos el resumen de la cantidad de casos por barrios de la ciudad, lo unimos a través de la función left_join (4) a la tabla de la población de los barrios. ¿Se acuerdan que al principio contamos una situación engorrosa sobre juntar y pegar tablas? Este es un ejemplo de cómo se pueden unir dos tablas sin mucho esfuerzo. En este caso, las categorías y el nombre de la variable coinciden en las dos tablas (población_barrios, casos). Asignamos esta nueva tabla al objetivo que vamos a crear: barrios_casos.
# (4) Unión de tablas
barrios_casos<-left_join(poblacion_barrios,casos)
barrios_casos
## barrio Total casos
## 1 CONSTITUCION 44107 1628
## 2 MONSERRAT 39914 1174
## 3 PUERTO MADERO 6726 374
## 4 RETIRO 65413 3449
## 5 SAN NICOLAS 29273 851
## 6 SAN TELMO 20453 491
## 7 RECOLETA 157932 2641
## 8 BALVANERA 138926 4746
## 9 SAN CRISTOBAL 48611 1425
## 10 BARRACAS 89452 4871
## 11 BOCA 45113 1735
## 12 NUEVA POMPEYA 42695 1987
## 13 PARQUE PATRICIOS 40985 1327
## 14 ALMAGRO 131699 2797
## 15 BOEDO 47306 975
## 16 CABALLITO 176076 2661
## 17 FLORES 164310 6694
## 18 PARQUE CHACABUCO 56281 1182
## 19 VILLA LUGANO 126374 5843
## 20 VILLA RIACHUELO 14084 386
## 21 VILLA SOLDATI 46779 2752
## 22 LINIERS 44132 741
## 23 MATADEROS 64436 1232
## 24 PARQUE AVELLANEDA 53229 1617
## 25 FLORESTA 37575 826
## 26 MONTE CASTRO 33623 415
## 27 VELEZ SARSFIELD 35081 641
## 28 VERSALLES 13822 174
## 29 VILLA LURO 32502 528
## 30 VILLA REAL 13419 217
## 31 VILLA SANTA RITA 33325 563
## 32 VILLA DEL PARQUE 55273 614
## 33 VILLA DEVOTO 66521 830
## 34 VILLA GRAL. MITRE 34713 621
## 35 COGHLAN 18604 257
## 36 SAAVEDRA 50295 534
## 37 VILLA PUEYRREDON 39654 427
## 38 VILLA URQUIZA 91563 1256
## 39 BELGRANO 126831 1625
## 40 COLEGIALES 52551 742
## 41 NUÑEZ 51949 512
## 42 PALERMO 225970 3588
## 43 AGRONOMIA 13912 132
## 44 CHACARITA 27761 964
## 45 PARQUE CHAS 17489 226
## 46 PATERNAL 19717 722
## 47 VILLA CRESPO 81959 1323
## 48 VILLA ORTUZAR 21736 270
Por fin, estamos en condiciones de calcular la tasa de contagios cada 100 mil habitantes. Para esto, usamos la función mutate (5) para crear la variable tasa_100mil. La tasa se calcula dividiendo los casos por el total poblacional por barrio (variable Total en nuestra tabla) y multiplicada por 100. Decidimos sobreescribir el archivo asignando el nombre barrio_casos porque lo único que hacemoa es agregar una nueva variable a la tabla.
barrios_casos<-barrios_casos %>%
mutate(tasa_100mil=(casos/Total)*100000) %>% #(5) Calculamos la tasa
mutate(tasa_100mil=replace_na(tasa_100mil,0)) #Reemplazamos los valores perdidos
barrios_casos #Imprimimos los casos
## barrio Total casos tasa_100mil
## 1 CONSTITUCION 44107 1628 3691.0241
## 2 MONSERRAT 39914 1174 2941.3238
## 3 PUERTO MADERO 6726 374 5560.5114
## 4 RETIRO 65413 3449 5272.6522
## 5 SAN NICOLAS 29273 851 2907.1158
## 6 SAN TELMO 20453 491 2400.6258
## 7 RECOLETA 157932 2641 1672.2387
## 8 BALVANERA 138926 4746 3416.2072
## 9 SAN CRISTOBAL 48611 1425 2931.4353
## 10 BARRACAS 89452 4871 5445.3785
## 11 BOCA 45113 1735 3845.8981
## 12 NUEVA POMPEYA 42695 1987 4653.9407
## 13 PARQUE PATRICIOS 40985 1327 3237.7699
## 14 ALMAGRO 131699 2797 2123.7823
## 15 BOEDO 47306 975 2061.0493
## 16 CABALLITO 176076 2661 1511.2792
## 17 FLORES 164310 6694 4074.0065
## 18 PARQUE CHACABUCO 56281 1182 2100.1759
## 19 VILLA LUGANO 126374 5843 4623.5776
## 20 VILLA RIACHUELO 14084 386 2740.6987
## 21 VILLA SOLDATI 46779 2752 5882.9817
## 22 LINIERS 44132 741 1679.0537
## 23 MATADEROS 64436 1232 1911.9747
## 24 PARQUE AVELLANEDA 53229 1617 3037.8177
## 25 FLORESTA 37575 826 2198.2701
## 26 MONTE CASTRO 33623 415 1234.2742
## 27 VELEZ SARSFIELD 35081 641 1827.1999
## 28 VERSALLES 13822 174 1258.8627
## 29 VILLA LURO 32502 528 1624.5154
## 30 VILLA REAL 13419 217 1617.1101
## 31 VILLA SANTA RITA 33325 563 1689.4224
## 32 VILLA DEL PARQUE 55273 614 1110.8498
## 33 VILLA DEVOTO 66521 830 1247.7263
## 34 VILLA GRAL. MITRE 34713 621 1788.9551
## 35 COGHLAN 18604 257 1381.4233
## 36 SAAVEDRA 50295 534 1061.7358
## 37 VILLA PUEYRREDON 39654 427 1076.8144
## 38 VILLA URQUIZA 91563 1256 1371.7331
## 39 BELGRANO 126831 1625 1281.2325
## 40 COLEGIALES 52551 742 1411.9617
## 41 NUÑEZ 51949 512 985.5820
## 42 PALERMO 225970 3588 1587.8214
## 43 AGRONOMIA 13912 132 948.8212
## 44 CHACARITA 27761 964 3472.4974
## 45 PARQUE CHAS 17489 226 1292.2408
## 46 PATERNAL 19717 722 3661.8147
## 47 VILLA CRESPO 81959 1323 1614.2217
## 48 VILLA ORTUZAR 21736 270 1242.1789
Seguimos agregando complejidad al ejercicio. Como nuestra intención es crear un mapa comparando los barrios por tasa de contagio, necesitamos pegar a nuestra base los datos espaciales. Nuevamente recurrimos al portal BAdata(6)para desrgar estos datos. Aplicamos otra vez un left_join (7) y tenemos nuestra tabla lista para crear el mapa.
#(6) Creamos un objeto con los datos geofraficos
barrios<-st_read("http://cdn.buenosaires.gob.ar/datosabiertos/datasets/barrios/barrios.geojson")
## Reading layer `barrios_badata' from data source `http://cdn.buenosaires.gob.ar/datosabiertos/datasets/barrios/barrios.geojson' using driver `GeoJSON'
## Simple feature collection with 48 features and 4 fields
## geometry type: POLYGON
## dimension: XY
## bbox: xmin: -58.53152 ymin: -34.70529 xmax: -58.33515 ymax: -34.52649
## geographic CRS: WGS 84
# (7) Unimos la tabla con los objetos geograficos
barrios_casos<-left_join(barrios,barrios_casos)
Ahora viene la magia. Por lo menos nosotros nos conmovimos cuando vimos que con una línea de código teníamos un mapa. Miren lo que es esta genialidad (¿Es una cita a Paulina Cocina?). Utilizando el paquete ggplot (8), que pertenece a la familia tidyverse, estamos en condiciones de graficar los polígonos de los barrios de CABA en los ejes cartesianos.
# (8) Mapa de los barrios de la ciudad
ggplot()+
geom_sf(data=barrios_casos)
Sí. Con una línea de código armamos un mapa vacío (pero un mapa al fin) con la distribución espacial de los barrios de la ciudad. Ahora viene lo lindo, que es agregar usando complementos de las funciones de ggplot información a nuestro gráfico. Para esto indicamos a R, que “rellene” los polígonos de los barrios con una escala de colores para comparar la tasa de contagios cada 100 mil habitantes. En los próximos encuentrosm vamos a trabajar con mucha más profundidad este tipo de visualizaciones.
#(9) Mapa comparando la tasa de contagios cada 100 mil habitantes en la ciudad
ggplot() +
geom_sf(data=barrios_casos, aes(fill = tasa_100mil),color=NA)+
scale_fill_distiller("Contagios cada 100 mil",palette = "Reds",direction = 1)
Por último, y a riesgo de abrumar, agregamos la división administrativa de la ciudad: las comunas. Nuevamente, descargamos los datos espaciales y los asignamos a un objeto comunas (10). Y con respecto al código anterior, añadimos al mapa la división de las comunas y el número de la comuna (11).
#(10) Creamos el objeto comuna con la información espacial
comunas<-st_read("http://cdn.buenosaires.gob.ar/datosabiertos/datasets/comunas/CABA_comunas.geojson")
## Reading layer `comunas' from data source `http://cdn.buenosaires.gob.ar/datosabiertos/datasets/comunas/CABA_comunas.geojson' using driver `GeoJSON'
## Simple feature collection with 15 features and 6 fields
## geometry type: MULTIPOLYGON
## dimension: XY
## bbox: xmin: -58.53152 ymin: -34.70529 xmax: -58.33515 ymax: -34.52649
## geographic CRS: WGS 84
#(11) Armamos el mapa de tasa de contagios covid cada 100 mil habitantes por barrio y comuna de la CABA
ggplot() +
geom_sf(data=barrios_casos, aes(fill = tasa_100mil),color=NA) +
geom_sf(data=comunas,color="black", fill=NA,size=1)+
geom_sf_label(data = comunas, aes(label=COMUNAS),color="black", fill="white") +
scale_fill_distiller("Contagios cada 100 mil",palette = "Reds",direction = 1)
Eso es todo por esta guía. Esperamos haber generado una mínima curiosidad en ustedes. Muchas gracias por leernos. Sigan adelante, despacio y sin abrumarse en este rompecabezas permanente, que es el mundo de la programación estadística.
Hasta la próxima guía.