C2. Taller Práctico

El Servicio de Información Normativa es un conjunto de datos publicado por el Gobierno de la Ciudad Autónoma de Buenos Aires. Este dataset recopila las normativas sancionadas en el ámbito de la ciudad, publicadas tanto en el Boletín Municipal como en el Boletín Oficial desde el 6 de agosto de 1996.

data.buenosaires.gob.ar

library(tidyverse)
Warning: package 'tidyverse' was built under R version 4.3.3
Warning: package 'ggplot2' was built under R version 4.3.3
Warning: package 'readr' was built under R version 4.3.3
Warning: package 'dplyr' was built under R version 4.3.2
── Attaching core tidyverse packages ──────────────────────── tidyverse 2.0.0 ──
✔ dplyr     1.1.4     ✔ readr     2.1.5
✔ forcats   1.0.0     ✔ stringr   1.5.0
✔ ggplot2   3.5.1     ✔ tibble    3.2.1
✔ lubridate 1.9.3     ✔ tidyr     1.3.0
✔ purrr     1.0.2     
── Conflicts ────────────────────────────────────────── tidyverse_conflicts() ──
✖ dplyr::filter() masks stats::filter()
✖ dplyr::lag()    masks stats::lag()
ℹ Use the conflicted package (<http://conflicted.r-lib.org/>) to force all conflicts to become errors
library(janitor)
Warning: package 'janitor' was built under R version 4.3.3

Attaching package: 'janitor'

The following objects are masked from 'package:stats':

    chisq.test, fisher.test
df_normativa <- read_csv("https://cdn.buenosaires.gob.ar/datosabiertos/datasets/secretaria-legal-y-tecnica/servicio-informacion-normativa/normativa.csv") |> 
  clean_names()
Warning: One or more parsing issues, call `problems()` on your data frame for details,
e.g.:
  dat <- vroom(...)
  problems(dat)
Rows: 748671 Columns: 11
── Column specification ────────────────────────────────────────────────────────
Delimiter: ","
chr (7): norma_tipo, norma_organismo_emisor, norma_fecha_sancion, norma_fech...
dbl (4): norma_id, norma_numero, norma_anio_sancion, norma_anio_publicacion

ℹ Use `spec()` to retrieve the full column specification for this data.
ℹ Specify the column types or set `show_col_types = FALSE` to quiet this message.

Antes de empezar a trabajar con expresiones regulares vamos a analizar un poco la base

glimpse(df_normativa)
Rows: 748,671
Columns: 11
$ norma_id                <dbl> 78404, 78405, 78406, 78407, 78408, 78409, 7841…
$ norma_tipo              <chr> "DECRETO SINTETIZADO", "DECRETO SINTETIZADO", …
$ norma_numero            <dbl> 1570, 1574, 1576, 1577, 1579, 1591, 1596, 1597…
$ norma_anio_sancion      <dbl> 2005, 2005, 2005, 2005, 2005, 2005, 2005, 2005…
$ norma_anio_publicacion  <dbl> 2005, 2005, 2005, 2005, 2005, 2005, 2005, 2005…
$ norma_organismo_emisor  <chr> "GOBIERNO DE LA CIUDAD AUTONOMA DE BUENOS AIRE…
$ norma_fecha_sancion     <chr> "14/10/2005", "14/10/2005", "14/10/2005", "14/…
$ norma_fecha_publicacion <chr> "31/10/2005", "31/10/2005", "31/10/2005", "31/…
$ norma_alcance           <chr> "PARTICULAR", "PARTICULAR", "PARTICULAR", "PAR…
$ norma_gestion           <chr> "Aníbal Ibarra", "Aníbal Ibarra", "Aníbal Ibar…
$ norma_sintesis          <chr> "SECRETARÍA JEFE DE GABINETE - DESIGNA A GENOV…
summary(df_normativa)
    norma_id       norma_tipo         norma_numero       norma_anio_sancion
 Min.   :     1   Length:748671      Min.   :        0   Min.   :1858      
 1st Qu.:190912   Class :character   1st Qu.:      129   1st Qu.:2011      
 Median :380912   Mode  :character   Median :      427   Median :2017      
 Mean   :380335                      Mean   :   415450   Mean   :2015      
 3rd Qu.:570305                      3rd Qu.:     1511   3rd Qu.:2021      
 Max.   :757614                      Max.   :141182503   Max.   :2027      
                                     NA's   :2282        NA's   :412       
 norma_anio_publicacion norma_organismo_emisor norma_fecha_sancion
 Min.   :1882           Length:748671          Length:748671      
 1st Qu.:2012           Class :character       Class :character   
 Median :2017           Mode  :character       Mode  :character   
 Mean   :2016                                                     
 3rd Qu.:2021                                                     
 Max.   :2202                                                     
 NA's   :8834                                                     
 norma_fecha_publicacion norma_alcance      norma_gestion     
 Length:748671           Length:748671      Length:748671     
 Class :character        Class :character   Class :character  
 Mode  :character        Mode  :character   Mode  :character  
                                                              
                                                              
                                                              
                                                              
 norma_sintesis    
 Length:748671     
 Class :character  
 Mode  :character  
                   
                   
                   
                   

¿Qué tipos de normativa existen?

df_normativa |> 
  count(norma_tipo, sort = TRUE) |> 
  view()

df_normativa |> 
  count(norma_anio_sancion)
# A tibble: 148 × 2
   norma_anio_sancion     n
                <dbl> <int>
 1               1858     1
 2               1867     1
 3               1869     1
 4               1870     1
 5               1872     1
 6               1876     1
 7               1880     1
 8               1881     1
 9               1882     1
10               1883     1
# ℹ 138 more rows

Ejercicio 1: Filtrar normativas sobre Locaciones de Obras y Servicios (LOYS)

El objetivo es Filtrar todas las normativas referidas a contrataciones de locaciones de obras y servicios (LOYS).

patron_loys <- regex("\\bloys\\b|locaci.n ?de obras y servicios", T)
patron_baja_contrato <- regex("deja sin efecto|\\bbaja",T)
aumento <- regex("(aumenta|eleva|sube).{0,20} monto",T)

# Me quedo con todas normativas vinculadas a loys
loys <- df_normativa  |> 
  filter(str_detect(norma_sintesis, patron_loys))

loys |> 
  count(norma_anio_sancion)
# A tibble: 14 × 2
   norma_anio_sancion     n
                <dbl> <int>
 1               2006     1
 2               2011     4
 3               2012     3
 4               2013     6
 5               2014     6
 6               2015     6
 7               2016     6
 8               2018     8
 9               2019     8
10               2020    11
11               2021     9
12               2022     8
13               2023    18
14               2024    11

1.1 Clasificar las normativas LOYS

Ahora vamos a caracterizar las normativas LOYS según su tipo:

  • Alta: Contrataciones nuevas

  • Baja: Rescisión de contrato

  • Adenda: Aumento del monto del contrato

loys <- df_normativa  |> 
  filter(str_detect(norma_sintesis, patron_loys)) |> 
  mutate(tipo_normativa_loys = case_when(str_detect(norma_sintesis, patron_baja_contrato) ~ "Baja",
                                         str_detect(norma_sintesis, aumento) ~"Adenda",
                                                   T ~ "Alta"
                                         ))

# Grafico
loys |> 
  count(tipo_normativa_loys, sort = TRUE) |> 
  ggplot(aes(x = reorder(tipo_normativa_loys, n), y = n)) +
  geom_col(fill = "steelblue") +
  coord_flip() +
  labs(
    title = "Distribución de tipos de normativas en LOYS",
    x = "Tipo de normativa",
    y = "Cantidad"
  ) +
  theme_minimal()

Ejercicio 2: Filtrar designaciones y renuncias

Objetivo

Filtrar todas las normativas que mencionen designaciones y renuncias de personal.

Paso 1: Filtrar la base de datos por designaciones y renuncia

Completar los patrones regex

patron_renuncia <- regex("", T)  # 📝 Completar 
patron_designacion <- regex("" , T)  # 📝 Completar 

df_renuncias_y_designaciones <- df_normativa |> 
  # Filtro
  filter(str_detect(norma_sintesis, patron_renuncia) | str_detect(norma_sintesis, patron_renuncia))
Warning: There were 2 warnings in `filter()`.
The first warning was:
ℹ In argument: `|...`.
Caused by warning in `stri_detect_regex()`:
! empty search patterns are not supported
ℹ Run `dplyr::last_dplyr_warnings()` to see the 1 remaining warning.

Paso 2: Clasificar en renuncias o designaciones

 # 📝 Completar 
 # PISTA: Podes usar case_when() o ifelse()

Paso 3: Extraer el cargo

Usamos str_extract() para identificar el cargo mencionado en la normativa.

Ejemplo: se podrían extraer las gerencias, subgerencias y secretarías

# 📝 Completar

Paso 4: Analizar los resultados

¿Hay algún dato interesante? ¿Hubo diferencia por año?

# 📝 Completar