image:

Introducción

El presente trabajo intentará desarrollar un flujo de trabajo completo desde la adquisición de los datos, pasando por todas las transformaciones necesarias para, finalmente, poder generar visualizaciones para los datos que permitan la obtención de concluciones acerca de la concentracion de CO en el aire por mes para los tres años del período.

Para tal fin se utilizaron los datasets disponibles en https://data.buenosaires.gob.ar/dataset/calidad-aire.

Incorporación de librerías

Para realizar las operaciones previstas se deberán incorporar las librerías Tidyverse (para la gestión de los datos) y ggplot2 (para generar salidas gráficas).

library(tidyverse)
## Warning: package 'tidyverse' was built under R version 4.2.1
## ── Attaching packages ─────────────────────────────────────── tidyverse 1.3.2 ──
## ✔ ggplot2 3.3.6     ✔ purrr   0.3.4
## ✔ tibble  3.1.7     ✔ dplyr   1.0.9
## ✔ tidyr   1.2.0     ✔ stringr 1.4.0
## ✔ readr   2.1.2     ✔ forcats 0.5.1
## ── Conflicts ────────────────────────────────────────── tidyverse_conflicts() ──
## ✖ dplyr::filter() masks stats::filter()
## ✖ dplyr::lag()    masks stats::lag()
library(ggplot2)

Importación de Datasets

Para la importación de los Datasets se realizó previamente la descarga de los csv desde BA Data.

muestra_2017 <- read.csv("data/calidad-de-aire-2017.csv", sep = ";")
muestra_2018 <- read.csv("data/calidad-de-aire-2018.csv", sep = ",")
muestra_2019 <- read.csv("data/calidad-de-aire-2019.csv", sep = ",")

Exploración de Datasets

Muestra 2017

colnames(muestra_2017)
##  [1] "FECHA"           "HORA"            "CO_CENTENARIO"   "NO2_CENTENARIO" 
##  [5] "PM10_CENTENARIO" "CO_CORDOBA"      "NO2_CORDOBA"     "PM10_CORDOBA"   
##  [9] "CO_LA_BOCA"      "NO2_LA_BOCA"     "PM10_LA_BOCA"
dim(muestra_2017)
## [1] 8652   11
str(muestra_2017)
## 'data.frame':    8652 obs. of  11 variables:
##  $ FECHA          : chr  "01/01/2017" "01/01/2017" "01/01/2017" "01/01/2017" ...
##  $ HORA           : int  1 2 3 4 5 6 7 8 9 10 ...
##  $ CO_CENTENARIO  : chr  "0,7" "0,72" "0,72" "0,73" ...
##  $ NO2_CENTENARIO : chr  " " " " " " " " ...
##  $ PM10_CENTENARIO: chr  " " " " " " " " ...
##  $ CO_CORDOBA     : chr  "0,81" "0,79" "0,82" "0,81" ...
##  $ NO2_CORDOBA    : chr  "19" "16" "23" "16" ...
##  $ PM10_CORDOBA   : chr  "19" "20" "19" "20" ...
##  $ CO_LA_BOCA     : chr  " " " " " " " " ...
##  $ NO2_LA_BOCA    : chr  "2" "2" "1" "2" ...
##  $ PM10_LA_BOCA   : chr  "43" "46" "46" "51" ...
head(muestra_2017, 5)
##        FECHA HORA CO_CENTENARIO NO2_CENTENARIO PM10_CENTENARIO CO_CORDOBA
## 1 01/01/2017    1           0,7                                      0,81
## 2 01/01/2017    2          0,72                                      0,79
## 3 01/01/2017    3          0,72                                      0,82
## 4 01/01/2017    4          0,73                                      0,81
## 5 01/01/2017    5          0,73                                      0,73
##   NO2_CORDOBA PM10_CORDOBA CO_LA_BOCA NO2_LA_BOCA PM10_LA_BOCA
## 1          19           19                      2           43
## 2          16           20                      2           46
## 3          23           19                      1           46
## 4          16           20                      2           51
## 5          11           20                      2           50

Muestra 2018

colnames(muestra_2018)
##  [1] "fecha"           "hora"            "co_centenario"   "no2_centenario" 
##  [5] "pm10_centenario" "co_cordoba"      "no2_cordoba"     "pm10_cordoba"   
##  [9] "co_la_boca"      "no2_la_boca"     "pm10_la_boca"
dim(muestra_2018)
## [1] 8712   11
str(muestra_2018)
## 'data.frame':    8712 obs. of  11 variables:
##  $ fecha          : chr  "2018-01-01" "2018-01-01" "2018-01-01" "2018-01-01" ...
##  $ hora           : int  1 2 3 4 5 6 7 8 9 10 ...
##  $ co_centenario  : chr  "0.43" "0.44" "0.46" "0.47" ...
##  $ no2_centenario : chr  "9" "11" "13" "14" ...
##  $ pm10_centenario: chr  "25" "27" "30" "32" ...
##  $ co_cordoba     : chr  "0.47" "0.53" "0.59" "0.65" ...
##  $ no2_cordoba    : chr  "14" "20" "21" "20" ...
##  $ pm10_cordoba   : chr  "24" "24" "26" "28" ...
##  $ co_la_boca     : chr  "0.37" "0.39" "0.40" "0.41" ...
##  $ no2_la_boca    : chr  "28" "28" "29" "25" ...
##  $ pm10_la_boca   : chr  "23" "26" "29" "30" ...
head(muestra_2018, 5)
##        fecha hora co_centenario no2_centenario pm10_centenario co_cordoba
## 1 2018-01-01    1          0.43              9              25       0.47
## 2 2018-01-01    2          0.44             11              27       0.53
## 3 2018-01-01    3          0.46             13              30       0.59
## 4 2018-01-01    4          0.47             14              32       0.65
## 5 2018-01-01    5          0.47             12              32       0.71
##   no2_cordoba pm10_cordoba co_la_boca no2_la_boca pm10_la_boca
## 1          14           24       0.37          28           23
## 2          20           24       0.39          28           26
## 3          21           26       0.40          29           29
## 4          20           28       0.41          25           30
## 5          17           28       0.41          16           31

Muestra 2019

colnames(muestra_2019)
##  [1] "fecha"           "hora"            "co_centenario"   "no2_centenario" 
##  [5] "pm10_centenario" "co_cordoba"      "no2_cordoba"     "pm10_cordoba"   
##  [9] "co_la_boca"      "no2_la_boca"     "pm10_la_boca"
dim(muestra_2019)
## [1] 2868   11
str(muestra_2019)
## 'data.frame':    2868 obs. of  11 variables:
##  $ fecha          : chr  "2019-01-01" "2019-01-01" "2019-01-01" "2019-01-01" ...
##  $ hora           : int  1 2 3 4 5 6 7 8 9 10 ...
##  $ co_centenario  : chr  "0.46" "0.47" "0.48" "0.48" ...
##  $ no2_centenario : chr  "7" "9" "11" "16" ...
##  $ pm10_centenario: chr  "19" "19" "19" "19" ...
##  $ co_cordoba     : chr  "0.36" "0.41" "0.46" "0.50" ...
##  $ no2_cordoba    : chr  "11" "13" "12" "10" ...
##  $ pm10_cordoba   : chr  "s/d" "s/d" "s/d" "s/d" ...
##  $ co_la_boca     : chr  "0.48" "0.46" "0.46" "0.46" ...
##  $ no2_la_boca    : chr  "10" "11" "12" "11" ...
##  $ pm10_la_boca   : chr  "23" "23" "23" "24" ...
head(muestra_2019, 5)
##        fecha hora co_centenario no2_centenario pm10_centenario co_cordoba
## 1 2019-01-01    1          0.46              7              19       0.36
## 2 2019-01-01    2          0.47              9              19       0.41
## 3 2019-01-01    3          0.48             11              19       0.46
## 4 2019-01-01    4          0.48             16              19       0.50
## 5 2019-01-01    5          0.46             10              19       0.54
##   no2_cordoba pm10_cordoba co_la_boca no2_la_boca pm10_la_boca
## 1          11          s/d       0.48          10           23
## 2          13          s/d       0.46          11           23
## 3          12          s/d       0.46          12           23
## 4          10          s/d       0.46          11           24
## 5          10          s/d       0.45           9           24

Trabajare con los registros de CO

A los fines de trabajar sólo con los datos necesarios realizo una selección de los campos a utilizar, descartando el resto.

muestra_2017_co <- muestra_2017 %>% 
select(1,2,starts_with("CO_"))
muestra_2018_co <- muestra_2018 %>% 
select(1,2,starts_with("CO_"))
muestra_2019_co <- muestra_2019 %>% 
select(1,2,starts_with("CO_"))

Se borran los datasets innecesarios para la continuación del análisis.

Este paso puede resumirse si en el paso previo se sobreescriben los datasets.

rm(muestra_2017,muestra_2018,muestra_2019)

Para poder hacer comparativa entre meses extraigo el mes del campo FECHA

Cabe aclarar que el los campos “fecha” de las tablas son diferentes tanto en el título (mayúsculas y minúsculas) como en su contenido: dd/mm/aaaa para 2017 y aaaa-mm-dd para 2018 y 2019. El problema de los nombres de campos lo pude resolver con la función rename

muestra_2017_co <- muestra_2017_co %>% 
  rename(fecha=FECHA)

En este paso extraigo el número de mes para trabajarlo independientemente del año y el día.

muestra_2017_co <- muestra_2017_co %>% 
  mutate(MES=str_sub(fecha, 4, 5))
muestra_2018_co <- muestra_2018_co %>% 
  mutate(MES=str_sub(fecha, 6, 7))
muestra_2019_co <- muestra_2019_co %>% 
  mutate(MES=str_sub(fecha, 6, 7))

Convierto a nombre los numeros de meses. En este paso realicé el mutate sobre un campo nuevo para mantener el orden de los meses.

muestra_2017_co <- muestra_2017_co %>% 
  mutate(MES_TXT=case_when(
    MES=="01"~"ENERO",
    MES=="02"~"FEBRERO",
    MES=="03"~"MARZO",
    MES=="04"~"ABRIL",
    MES=="05"~"MAYO",
    MES=="06"~"JUNIO",
    MES=="07"~"JULIO",
    MES=="08"~"AGOSTO",
    MES=="09"~"SEPTIEMBRE",
    MES=="10"~"OCTUBRE",
    MES=="11"~"NOVIEMBRE",
    MES=="12"~"DICIEMBRE"
  ))
muestra_2018_co <- muestra_2018_co %>% 
  mutate(MES_TXT=case_when(
    MES=="01"~"ENERO",
    MES=="02"~"FEBRERO",
    MES=="03"~"MARZO",
    MES=="04"~"ABRIL",
    MES=="05"~"MAYO",
    MES=="06"~"JUNIO",
    MES=="07"~"JULIO",
    MES=="08"~"AGOSTO",
    MES=="09"~"SEPTIEMBRE",
    MES=="10"~"OCTUBRE",
    MES=="11"~"NOVIEMBRE",
    MES=="12"~"DICIEMBRE"
  ))
muestra_2019_co <- muestra_2019_co %>% 
  mutate(MES_TXT=case_when(
    MES=="01"~"ENERO",
    MES=="02"~"FEBRERO",
    MES=="03"~"MARZO",
    MES=="04"~"ABRIL",
    MES=="05"~"MAYO",
    MES=="06"~"JUNIO",
    MES=="07"~"JULIO",
    MES=="08"~"AGOSTO",
    MES=="09"~"SEPTIEMBRE",
    MES=="10"~"OCTUBRE",
    MES=="11"~"NOVIEMBRE",
    MES=="12"~"DICIEMBRE"
  ))

Convierto los campos con valores numéricos en campos numéricos

Primero modifico los caracteres de muestra_2017_co2 cambiando la coma por punto dado que la conversión a un campo numérico, de acuerdo al encoding de mi máquina, no toma la coma como separador de decimales por lo que no escribe el campo numérico con valores con coma.

muestra_2017_co <- mutate_if(muestra_2017_co, 
                is.character, 
                str_replace_all, 
                pattern = ",", 
                replacement = ".")

Luego de la conversión convierto los valores a número.

muestra_2017_co <- muestra_2017_co %>%
  mutate(CENTENARIO = as.numeric(muestra_2017_co$CO_CENTENARIO)) %>% 
  mutate(CORDOBA = as.numeric(muestra_2017_co$CO_CORDOBA)) %>%
  mutate(LABOCA = as.numeric(muestra_2017_co$CO_LA_BOCA))
## Warning in mask$eval_all_mutate(quo): NAs introduced by coercion

## Warning in mask$eval_all_mutate(quo): NAs introduced by coercion

## Warning in mask$eval_all_mutate(quo): NAs introduced by coercion
muestra_2018_co <- muestra_2018_co %>%
  mutate(CENTENARIO = as.numeric(muestra_2018_co$co_centenario)) %>% 
  mutate(CORDOBA = as.numeric(muestra_2018_co$co_cordoba)) %>%
  mutate(LABOCA = as.numeric(muestra_2018_co$co_la_boca))
## Warning in mask$eval_all_mutate(quo): NAs introduced by coercion

## Warning in mask$eval_all_mutate(quo): NAs introduced by coercion

## Warning in mask$eval_all_mutate(quo): NAs introduced by coercion
muestra_2019_co <- muestra_2019_co %>%
  mutate(CENTENARIO = as.numeric(muestra_2019_co$co_centenario)) %>% 
  mutate(CORDOBA = as.numeric(muestra_2019_co$co_cordoba)) %>%
  mutate(LABOCA = as.numeric(muestra_2019_co$co_la_boca))
## Warning in mask$eval_all_mutate(quo): NAs introduced by coercion

## Warning in mask$eval_all_mutate(quo): NAs introduced by coercion

## Warning in mask$eval_all_mutate(quo): NAs introduced by coercion

Me quedo sólo con los campos que utilizaré

SELECT

muestra_2017_co <- muestra_2017_co %>% 
  select(1, 2, 6:10)

muestra_2018_co <- muestra_2018_co %>% 
  select(1, 2, 6:10)

muestra_2019_co <- muestra_2019_co %>% 
  select(1, 2, 6:10)

Limpio los NAs

Para trabajar con valores faltantes sin perder la capacidad de cálculo, convierto los NA en cero.

muestra_2017_co <- mutate_all(muestra_2017_co, ~replace(., is.na(.), 0))
muestra_2018_co <- mutate_all(muestra_2018_co, ~replace(., is.na(.), 0))
muestra_2019_co <- mutate_all(muestra_2019_co, ~replace(., is.na(.), 0))

Sumarizo y agrupo

En este paso genero tablas nuevas agrupadas por mes promediando las mediciones de todos los días del mes. Guardo los resultados en tablas nuevas.

group_muestra_2017_co <- muestra_2017_co %>% 
  group_by(MES, MES_TXT) %>% 
  summarise(CENTENARIO_PROM=mean(CENTENARIO),
            CORDOBA_PROM=mean(CORDOBA),
            LABOCA_PROM=mean(LABOCA))
## `summarise()` has grouped output by 'MES'. You can override using the `.groups`
## argument.
group_muestra_2018_co <- muestra_2018_co %>% 
  group_by(MES, MES_TXT) %>% 
  summarise(CENTENARIO_PROM=mean(CENTENARIO),
            CORDOBA_PROM=mean(CORDOBA),
            LABOCA_PROM=mean(LABOCA))
## `summarise()` has grouped output by 'MES'. You can override using the `.groups`
## argument.
group_muestra_2019_co <- muestra_2019_co %>% 
  group_by(MES, MES_TXT) %>% 
  summarise(CENTENARIO_PROM=mean(CENTENARIO),
            CORDOBA_PROM=mean(CORDOBA),
            LABOCA_PROM=mean(LABOCA))
## `summarise()` has grouped output by 'MES'. You can override using the `.groups`
## argument.

Gráficos

En este paso realizo la graficación de los valores, primero con boxplot para identificar outliers. Luego con barplot para observar variaciones a lo largo del año.

Reviso los valores extremos con boxplot

ggplot()+
  geom_boxplot(data = group_muestra_2017_co,
               aes(CENTENARIO_PROM))

ggplot()+
  geom_boxplot(data = group_muestra_2018_co,
               aes(CENTENARIO_PROM))

ggplot()+
  geom_boxplot(data = group_muestra_2019_co,
               aes(CENTENARIO_PROM))

Realizo un grafico de barras con los valores para Parque Centenario

ggplot(group_muestra_2017_co,
           aes(x=MES, y=CENTENARIO_PROM))+
  geom_bar(stat = "identity",
           color="blue",
           fill= "black",
           alpha=0.5)+
  xlab("Mes")+
  ylab("Nivel de Co2")

ggplot(group_muestra_2018_co,
           aes(x=MES, y=CENTENARIO_PROM))+
  geom_bar(stat = "identity",
           color="blue",
           fill= "black",
           alpha=0.5)+
  xlab("Mes")+
  ylab("Nivel de Co2")

ggplot(group_muestra_2019_co,
           aes(x=MES, y=CENTENARIO_PROM))+
  geom_bar(stat = "identity",
           color="blue",
           fill= "black",
           alpha=0.5)+
  xlab("Mes")+
  ylab("Nivel de CO")

Conclusión

En el presente trabajo se realizó un flujo de trabajo completo. Se incorporaron los datos utilizando las funciones de importación con diferentes parematrizaciones dado la diferencia de separadores en origen. Luego se realizó la prospectación de los datasets utilizando diferentes funciones. En la etapa de Data Wrangling se realizaron las transformaciones necesarias para llevar a los datasets a obtener el formato necesario para generar los gráficos de salida que permitieron tener un conocimiento final de la concentración de CO en los tres puntos de control. A partir de la lectura de los gráficos de barras se puede observar que el CO aumenta en las muestras en los meses invernales tanto para el 2017 como el 2018, los meses en donde se utiliza más intensamente el gas en los hogares para calefacción. Puede haber un correlato entre esos valores y la intensidad del uso doméstico.