Code
library(tidyverse)
library(janitor)
library(skimr)
library(stringr)
library(tidyverse)
library(janitor)
library(skimr)
library(stringr)
# Si tu archivo está en la misma carpeta que este .qmd:
<- "datos.csv"
ruta
# RUPE viene con separador ';'
<- readr::read_csv2(ruta, locale = locale(encoding = "UTF-8"),
df show_col_types = FALSE, guess_max = 100000) |>
clean_names()
# Confirmar estructura esperada
stopifnot(all(c("pais_prov","identificacion_prov","denominacion_social_prov",
"domicilio_fiscal","localidad_prov","departamento_prov",
"estado_prov") %in% names(df)))
::skim(df) skimr
Name | df |
Number of rows | 110747 |
Number of columns | 7 |
_______________________ | |
Column type frequency: | |
character | 7 |
________________________ | |
Group variables | None |
Variable type: character
skim_variable | n_missing | complete_rate | min | max | empty | n_unique | whitespace |
---|---|---|---|---|---|---|---|
pais_prov | 0 | 1 | 4 | 78 | 0 | 79 | 0 |
identificacion_prov | 0 | 1 | 4 | 34 | 0 | 110739 | 0 |
denominacion_social_prov | 0 | 1 | 2 | 140 | 0 | 110627 | 0 |
domicilio_fiscal | 0 | 1 | 1 | 366 | 0 | 82462 | 0 |
localidad_prov | 0 | 1 | 4 | 29 | 0 | 991 | 0 |
departamento_prov | 0 | 1 | 5 | 14 | 0 | 20 | 0 |
estado_prov | 0 | 1 | 6 | 15 | 0 | 4 | 0 |
names(df)
[1] "pais_prov" "identificacion_prov"
[3] "denominacion_social_prov" "domicilio_fiscal"
[5] "localidad_prov" "departamento_prov"
[7] "estado_prov"
head(df, 3)
# A tibble: 3 × 7
pais_prov identificacion_prov denominacion_social_prov domicilio_fiscal
<chr> <chr> <chr> <chr>
1 URUGUAY 080192190014 GIMENEZ VAZQUEZ ROBERT ALBERTO MELENDEZ, MANUEL…
2 URUGUAY 216684990015 PACHECO TROISI MARIANGEL CARAGUATAY 2080
3 URUGUAY 100789580019 MOORINGMEN SRL FRANCIA 0 20100 …
# ℹ 3 more variables: localidad_prov <chr>, departamento_prov <chr>,
# estado_prov <chr>
<- df |>
df mutate(across(c(pais_prov, denominacion_social_prov, domicilio_fiscal,
localidad_prov, departamento_prov, estado_prov),~ str_squish(as.character(.)))) |>
distinct()
nrow(df)
[1] 110747
|>
df summarise(duplicados_por_id = n() - n_distinct(identificacion_prov))
# A tibble: 1 × 1
duplicados_por_id
<int>
1 8
# Conteo por estado
<- df |>
por_estado count(estado_prov, name = "proveedores") |>
arrange(desc(proveedores))
por_estado
# A tibble: 4 × 2
estado_prov proveedores
<chr> <int>
1 ACTIVO 54540
2 EN INGRESO 37546
3 BAJA DGI 18620
4 BAJA VOLUNTARIA 41
# Conteo por departamento
<- df |>
por_depto count(departamento_prov, name = "proveedores") |>
arrange(desc(proveedores))
|> head(15) por_depto
# A tibble: 15 × 2
departamento_prov proveedores
<chr> <int>
1 Montevideo 41853
2 Sin dato 31973
3 Canelones 8312
4 Maldonado 3481
5 Colonia 3250
6 Paysandú 2283
7 Salto 2240
8 San José 2240
9 Soriano 1952
10 Tacuarembó 1710
11 Florida 1555
12 Rocha 1366
13 Rivera 1264
14 Cerro Largo 1234
15 Lavalleja 1192
# Buscamos en TODAS las columnas texto (nombre, domicilio, etc.)
<- "(software|inform[aá]tica|tecnolog[ií]a|datos|anal[ií]tica|inteligencia artificial|machine learning|cloud|telecom|data\\b|bi\\b)"
keywords
<- df |>
ti mutate(across(where(is.character), str_to_lower)) |>
filter(if_any(where(is.character), ~ str_detect(., keywords)))
list(
total_registros = nrow(df),
empresas_ti_detectadas = nrow(ti),
porcentaje = round(100 * nrow(ti) / nrow(df), 2)
)
$total_registros
[1] 110747
$empresas_ti_detectadas
[1] 455
$porcentaje
[1] 0.41
|> select(identificacion_prov, denominacion_social_prov,
ti |> slice_head(n = 20) departamento_prov, estado_prov)
# A tibble: 20 × 4
identificacion_prov denominacion_social_prov departamento_prov estado_prov
<chr> <chr> <chr> <chr>
1 213958790013 colombi strazzarino juan j… montevideo en ingreso
2 040408860013 telecomunicaciones opticas… colonia en ingreso
3 217056790012 rosendorff bianco guillerm… montevideo en ingreso
4 b86694528 melcox telecomunicaciones … sin dato activo
5 219151900012 sarubbi salles maximiliano… montevideo en ingreso
6 216724890016 asociacion civil red espec… montevideo activo
7 140096110010 data control informatica l… sin dato baja dgi
8 215224720016 informatica elabir socieda… montevideo baja dgi
9 214705590014 ingeniero ruben tomasco - … montevideo baja dgi
10 213679380013 madakei ltda. montevideo en ingreso
11 050000630019 abi rached hnos ltda durazno baja dgi
12 214276020017 capacitacion profesional e… montevideo baja dgi
13 214721410017 estudios y datos s r l montevideo baja dgi
14 213826390018 tecnologia informatica s.r… montevideo baja dgi
15 213981800011 tecnologia termodinamica s… montevideo baja dgi
16 213786140016 wingate informatica ltda sin dato baja dgi
17 160002460017 balbi y lopez s r l salto baja dgi
18 213384480017 ecodata s r l montevideo en ingreso
19 213359420014 informatica vandos ltda. sin dato baja dgi
20 216106540016 foresagro sur ltda montevideo en ingreso
library(ggplot2)
ggplot(por_estado, aes(x = reorder(estado_prov, proveedores), y = proveedores)) +
geom_col() +
coord_flip() +
labs(title = "Proveedores por estado RUPE (stock agosto 2025)",
x = "Estado", y = "Cantidad")
ggplot(por_depto |> slice_max(order_by = proveedores, n = 15),
aes(x = reorder(departamento_prov, proveedores), y = proveedores)) +
geom_col() +
coord_flip() +
labs(title = "Top 15 departamentos por cantidad de proveedores",
x = "Departamento", y = "Cantidad")
# Proxy TI por departamento (top)
<- ti |>
ti_por_depto count(departamento_prov, name = "proveedores_ti") |>
arrange(desc(proveedores_ti))
ggplot(ti_por_depto |> slice_max(order_by = proveedores_ti, n = 15),
aes(x = reorder(departamento_prov, proveedores_ti), y = proveedores_ti)) +
geom_col() +
coord_flip() +
labs(title = "Top 15 departamentos — proveedores TI (proxy keywords)",
x = "Departamento", y = "Cantidad")
Texto: este CSV de RUPE no incluye fecha de alta/inscripción. El análisis es de stock al mes publicado.
Para medir incremento/altas, descargar dos meses distintos, cargarlos como df_agosto
y df_julio
, y comparar por identificacion_prov
:
# Ejemplo (si tuvieras otro CSV):
# df_julio <- read_csv2("rupe-julio-2025.csv") |> clean_names()
# nuevas_altas <- anti_join(df_agosto, df_julio, by = "identificacion_prov")
# nrow(nuevas_altas)