ANALISIS DE LA ACTIVIDAD COMERCIAL DE BARCELONA (2019 VS 2024)

Proyecto de Modelos y herramientas de decisión 2025

INTEGRANTES:

1 INTRODUCCION

La actividad comercial constituye uno de los pilares fundamentales del dinamismo económico y social de las ciudades. En el caso de Barcelona, su red de comercios distribuidos a lo largo de los distritos y barrios no solo influye en la economía local, sino también en la calidad de vida de sus habitantes y la configuración del espacio urbano. En este contexto, el presente informe tiene como objetivo analizar la evolución de la actividad comercial en Barcelona, tomando como base los años 2019 y 2024, con especial atención a los efectos provocados por la pandemia de COVID-19 en la configuración del comercio urbano.

OBJETIVOS

Este informe se estructura en torno a tres objetivos principales:

  • Objetivo 1: Evaluar las actividades más relevantes de los comercios de Barcelona en 2024, señalando las diferencias existentes entre los diferentes distritos.
  • Objetivo 2: Analizar la evolución de los espacios de concentración comercial —como centros comerciales, mercados, ejes y galerías— entre 2019 y 2024.
  • Objetivo 3: Detectar las zonas de alta y baja densidad comercial en Barcelona en el año 2024, con el fin de identificar patrones de concentración o vaciamiento comercial.

2 METODOLOGIA

Para llevar a cabo el análisis de la actividad comercial de Barcelona, se ha seguido una metodología estructurada en varias etapas: recolección de datos, tratamiento y limpieza, análisis exploratorio y visualización. Como se vera acontinuacion:

2.1 Recoleccion de datos

Los datos utilizados en este estudio provienen del portal de datos abiertos del Ayuntamiento de Barcelona (Barcelona Open Data):

  • Censo de locales en planta baja destinados a actividad económica
  • Organización administrativa de Barcelona

2.2 Herramientas utilizadas

El análisis de los datos se ha realizado utilizando el lenguaje de programación (R), con el soporte de los siguientes paquetes:

  • tidyverse: para manipulación y análisis de datos.
  • sf: para manejo de datos espaciales.
  • ggspatial: para la inclusión de elementos cartográficos (como escalas y flechas de norte) en los mapas.
  • janitor: para la lectura y limpieza inicial de los datos.

2.3 Proceso de análisis

Para el desarrollo del analisis se considero el siguiente procedimiento:

2.3.1 Lectura y exploración inicial de los datos:

  • Importación de los datasets correspondientes a 2019 y 2024.

  • Revisión de las variables disponibles (tipo de actividad, estado del local, coordenadas geográficas, distrito, etc.).

2.3.2 Limpieza y preparación:

  • Estandarización de los nombres de columnas mediante el paquete janitor.

  • Eliminación de registros duplicados o con datos faltantes relevantes.

  • Conversión de tipos de datos a formatos adecuados (fechas, factores, coordenadas, etc.).

2.3.3 Clasificación de locales comerciales:

  • Agrupación de locales según su sector o grupo de actividad.

  • Filtrado de locales sin actividad económica (código de actividad igual a 0).

  • Categorización por tipo de espacio de concentración comercial: mercados, centros comerciales, galerías y ejes.

2.3.4 Comparación temporal (2019 vs 2024):

  • Cálculo y comparación del número de establecimientos por tipo de concentración comercial.

  • Evaluación de cambios en la presencia de los diferentes formatos comerciales entre ambos años.

2.3.5 Análisis geoespacial:

  • Conversión de los datasets en objetos sf para el manejo de información geográfica.

  • Conversión de los datasets en objetos sf para el manejo de información geográfica (st_join).

  • Cálculo de densidades comerciales por kilómetro cuadrado y por habitante, utilizando datos de población y superficie.

2.3.6 Visualización de datos:

  • Generación de mapas temáticos de densidad, distribución y concentración utilizando ggplot2y ggspatial.

  • Creación de gráficos comparativos y tablas resumen para facilitar la interpretación.

  • Elaboración de mapas de calor y mallas de cuadrícula para analizar la distribución microespacial de la actividad comercial.

3 Resultados

3.1 Actividad comercial por distritos (2024)

library(tidyverse)
library(janitor)
Warning: package 'janitor' was built under R version 4.4.3
library(dplyr)
library(ggplot2)
library(sf)
Warning: package 'sf' was built under R version 4.4.3
library(ggspatial)
Warning: package 'ggspatial' was built under R version 4.4.3

Consolidamos la data de los comercios del 2019 y 2024, usamos el comando “clean_names” para evitar posibles problemas al comparar datos a futuro.

comercios_24<-read_csv("241021_censcomercialbcn_opendata_2024_v5.csv")
Warning: One or more parsing issues, call `problems()` on your data frame for details,
e.g.:
  dat <- vroom(...)
  problems(dat)
comercios_24<-clean_names(comercios_24)
comercios_19<-read_csv("2019_censcomercialbcn_detall.csv")
Warning: One or more parsing issues, call `problems()` on your data frame for details,
e.g.:
  dat <- vroom(...)
  problems(dat)
comercios_19<-clean_names(comercios_19)

Obtenemos cual es el comercio más relevante de Barcelona el año 2024, obtenemos ésto viendo cual tiene más cantidad de locales. primero filtramos el campo codi_principal_activitat, tomando los valores iguales a 1. Esto debido a los que tienen valor 0 son locales sin actividad económica. Las actividades más importantes son, los restaurantes, Bares/cibercafés, Servicios a empresas y oficinas, Peluquerías y Tiendas de vestir.

comercios_24|>
  filter(codi_principal_activitat==1)|>
  count(nom_activitat)|>
  arrange(-n)|>
  slice(1:5)|>
  ggplot(aes(x=nom_activitat,y=n))+geom_bar(stat="identity",fill="steelblue")+coord_flip()

Asimismo podemos obtener cual es el distrito de mayor actividad comercial, es el distrito de Eixample, seguido por Sant Martí y Ciutat Vella.

comercios_24|>
  filter(codi_principal_activitat==1)|>
  ggplot(aes(nom_districte))+geom_bar(fill="steelblue")+coord_flip()

Comparemos como las actividades más relevantes se comparan por distritos.

comercios_24 |>
  filter(codi_principal_activitat == 1,nom_activitat %in% c("Restaurants", "Bars   / CIBERCAFÈ", "Serveis a les empreses i oficines"))|>
  group_by(nom_districte,nom_activitat)|>
  count()|>
  ggplot(aes(x=nom_districte,y=n,fill= nom_activitat))+geom_col(position ="dodge")+coord_flip()

3.2 Evolución de espacios de concentración comercial (2019–2024)

Como primer paso se realizara la LECTURA DE LOS DATOS

Leemos el data frame con la información de las fuentes obtenido de: https://opendata-ajuntament.barcelona.cat/data/es/dataset/cens-locals-planta-baixa-act-economica

comercios_2019 <- read_csv("2019_censcomercialbcn_detall.csv")
Warning: One or more parsing issues, call `problems()` on your data frame for details,
e.g.:
  dat <- vroom(...)
  problems(dat)
comercios_2019 <- clean_names(comercios_2019)
comercios_2019
# A tibble: 80,554 × 49
   id_bcn_2019 id_bcn_2016 codi_principal_activitat nom_principal_activitat
         <dbl>       <dbl>                    <dbl> <chr>                  
 1     1075454          NA                        1 Actiu                  
 2     1075453          NA                        1 Actiu                  
 3     1075451          NA                        1 Actiu                  
 4     1075449          NA                        1 Actiu                  
 5     1075448          NA                        1 Actiu                  
 6     1075447          NA                        1 Actiu                  
 7     1075446          NA                        1 Actiu                  
 8     1069815          NA                        1 Actiu                  
 9     1074351          NA                        1 Actiu                  
10     1074376          NA                        1 Actiu                  
# ℹ 80,544 more rows
# ℹ 45 more variables: codi_sector_activitat <dbl>, nom_sector_activitat <chr>,
#   codi_grup_activitat <dbl>, nom_grup_activitat <chr>,
#   codi_activitat_2019 <dbl>, nom_activitat <chr>, codi_activitat_2016 <chr>,
#   nom_local <chr>, sn_oci_nocturn <dbl>, sn_coworking <dbl>,
#   sn_servei_degustacio <dbl>, sn_obert24h <dbl>, sn_mixtura <dbl>,
#   sn_carrer <dbl>, sn_mercat <dbl>, nom_mercat <chr>, sn_galeria <dbl>, …

Leemos el data frame con la información de las fuentes obtenido de: https://opendata-ajuntament.barcelona.cat/data/es/dataset/cens-locals-planta-baixa-act-economica

comercios_2024 <- read_csv("241021_censcomercialbcn_opendata_2024_v5.csv")
Warning: One or more parsing issues, call `problems()` on your data frame for details,
e.g.:
  dat <- vroom(...)
  problems(dat)
comercios_2024 <- clean_names(comercios_2024)
comercios_2024
# A tibble: 68,024 × 49
   id_global           id_bcn_2016 codi_principal_activ…¹ nom_principal_activi…²
   <chr>                     <dbl>                  <dbl> <chr>                 
 1 5f158100-c0b8-45e2…       45538                      0 Sense activitat Econò…
 2 03a89603-7bb5-423f…       16649                      0 Sense activitat Econò…
 3 aad63dad-4969-4eff…       23980                      0 Sense activitat Econò…
 4 59832baf-4dd3-4fa4…          NA                      0 Sense activitat Econò…
 5 e3794cd9-8191-4cb3…       26849                      0 Sense activitat Econò…
 6 3db1bda1-f434-4297…       29639                      0 Sense activitat Econò…
 7 510e1364-689f-4651…          NA                      0 Sense activitat Econò…
 8 eafd6ba7-50a9-4da8…       26544                      0 Sense activitat Econò…
 9 d84dd3e6-8e8b-456b…       22661                      0 Sense activitat Econò…
10 ac650075-b5f6-4d6d…       44615                      0 Sense activitat Econò…
# ℹ 68,014 more rows
# ℹ abbreviated names: ¹​codi_principal_activitat, ²​nom_principal_activitat
# ℹ 45 more variables: codi_sector_activitat <dbl>, nom_sector_activitat <chr>,
#   codi_grup_activitat <dbl>, nom_grup_activitat <chr>,
#   codi_activitat_2022 <dbl>, nom_activitat <chr>, codi_activitat_2016 <chr>,
#   nom_local <chr>, sn_oci_nocturn <chr>, sn_coworking <chr>,
#   sn_servei_degustacio <chr>, sn_obert24h <chr>, sn_mixtura <chr>, …

seguidamente tendremos la Tabla de comercios 2019 en concentracion comercial con el cual podremos contar el número de comercios del 2019 de cada concentracion comercial con actividad con summarise() y filter() sobre comercio2019, y guardamos el resultado en num_comercios_CC_2019.Tambien lo pasamos a una tabla larga para poder graficarlo despues.

Tabla de comercios 2019 en concentracion comercial

num_comercios_CC_2019 <- comercios_2019 |>
  filter(codi_principal_activitat ==1)|>
  summarise(
    Mercados = sum(!is.na(nom_mercat) & nom_mercat != ""),
    Galerias = sum(!is.na(nom_galeria) & nom_galeria != ""),
    Centros_Comerciales = sum(!is.na(nom_c_comercial) & nom_c_comercial != ""),
    Ejes_Comerciales = sum(!is.na(nom_eix) & nom_eix != "")) 
num_comercios_CC_2019_largo <- num_comercios_CC_2019 |>
  pivot_longer(cols = everything(), names_to = "tipo",values_to = "cantidad")

Para despues realizar el grafico de barras de comercios 2019 en concentracion comercial, por lo que graficaremos la tabla anterior, un grafico de barras ayudaria “num_comercios_CC_2019_largo”

Grafico de barras de comercios 2019 en concentracion comercial

ggplot(num_comercios_CC_2019_largo, aes(x = tipo, y = cantidad)) +
  geom_bar(stat = "identity", fill = "steelblue") +
  geom_text(aes(label = cantidad), vjust = -0.5, size = 4) +
  labs(
    title = "Cantidad de establecimientos en el año 2019",
    x = "Tipo de establecimiento",
    y = "Cantidad"
  ) +
  theme_minimal()

a continuacion desarrollaremos la tabla de comercios 2024 en concentracion comercial, que nos permitira contar el número de comercios del 2024 de cada concentracion comercial con actividad con summarise() y filter() sobre comercio2019, y guardamos el resultado en num_comercios_CC_2024.Tambien lo pasamos a una tabla larga para poder graficarlo despues.

Grafico de tabla de Comercios 2024 en concentracion comercial

num_comercios_CC_2024 <- comercios_2024 |>
  filter(codi_principal_activitat ==1)|>
  summarise(
    Mercados = sum(!is.na(nom_mercat) & nom_mercat != ""),
    Galerias = sum(!is.na(nom_galeria) & nom_galeria != ""),
    Centros_Comerciales = sum(!is.na(nom_c_comercial) & nom_c_comercial != ""),
    Ejes_Comerciales = sum(!is.na(nom_eix) & nom_eix != "")) 
num_comercios_CC_2024_largo <- num_comercios_CC_2024 |>
  pivot_longer(cols = everything(), names_to = "tipo",values_to = "cantidad")

Para desarrollar el objetivo deberemos graficar las barras de comercios 2024 en concentracion comercial, por ello graficaremos la tabla anterior, un grafico de barras ayudaria “num_comercios_CC_2024_largo”

Graficar las barras de comercios 2024 en concentracion comercial

ggplot(num_comercios_CC_2024_largo, aes(x = tipo, y = cantidad)) +
  geom_bar(stat = "identity", fill = "steelblue") +
  geom_text(aes(label = cantidad), vjust = -0.5, size = 4) +
  labs(
    title = "Cantidad de establecimientos en el año 2019",
    x = "Tipo de establecimiento",
    y = "Cantidad"
  ) +
  theme_minimal()

Para finalizar realizaremos el grafico de barras de comercios 2019 y 2024 en concentracion comercial, el cual vendra de la tabla anterior, un grafico de barras ayudaria “num_comercios_CC_2024_largo”

Grafico de barras de comercios 2019 y 2024 en concentracion comercial

num_comercios_CC_2019_largo_año <- num_comercios_CC_2019_largo |>
  mutate(año = "2019")
num_comercios_CC_2024_largo_año <- num_comercios_CC_2024_largo |>
  mutate(año = "2024")
conteo_comparado <- bind_rows(num_comercios_CC_2019_largo_año, num_comercios_CC_2024_largo_año)
ggplot(conteo_comparado, aes(x = tipo, y = cantidad, fill = año)) +
  geom_bar(stat = "identity", position = position_dodge(width = 0.8)) +
  geom_text(
    aes(label = cantidad),
    position = position_dodge(width = 0.8),
    vjust = -0.3,
    size = 3.5
  ) +
  labs(
    title = "Comparación de Establecimientos (2019 vs 2024)",
    x = "Tipo de Establecimiento",
    y = "Cantidad",
    fill = "Año"
  ) +
  theme_minimal()

3.3 Distribución geográfica de la actividad comercial (2024)

Empezamos creando un mapa de comercios de Barcelona. Para ello necesitamos:

  • Obtener un objeto sf con una columna geom con la posición de las fuentes.
  • A partir de este objeto, y del mapa bcn_districts, mostrar las fuentes de cada distrito.

Después mostraremos las fuentes de un distrito, identificando las fuentes que hay dentro de éste.

Creando datos geográficos

Empezamos leyendo el archivo con datos geográficos de los distritos de Barcelona:

bcn_districts <- readRDS("bcn_districts.RDS")
bcn_districts <- bcn_districts |> select(area:coord_y)
bcn_districts
Simple feature collection with 10 features and 9 fields
Geometry type: MULTIPOLYGON
Dimension:     XY
Bounding box:  xmin: 2.052451 ymin: 41.31692 xmax: 2.229203 ymax: 41.46825
Geodetic CRS:  WGS 84
       area c_distri            n_distri  homes  dones cartodb_id    perim
1  20092803        5 Sarrià-Sant Gervasi  67799  80113          5 37563.64
2  11947078        7      Horta-Guinardó  79017  89075          7 20413.19
3   4368465        1        Ciutat Vella  53968  48379          1 21035.21
4   7476392        2            Eixample 123571 142906          2 13902.57
5  22940419        3      Sants-Montjuïc  87877  95243          3 47125.93
6   6017532        4           Les Corts  38331  43939          4 12481.47
7   4185517        6              Gràcia  55611  65891          6 12280.06
8   8041439        8          Nou Barris  78448  87862          8 14698.41
9   6565322        9         Sant Andreu  70151  77581          9 15132.45
10 10523762       10          Sant Martí 113572 122147         10 20736.53
    coord_x  coord_y                       geometry
1  2.106121 41.41277 MULTIPOLYGON (((2.072115 41...
2  2.150531 41.42914 MULTIPOLYGON (((2.176161 41...
3  2.181049 41.38084 MULTIPOLYGON (((2.18239 41....
4  2.164488 41.39162 MULTIPOLYGON (((2.18239 41....
5  2.144933 41.34995 MULTIPOLYGON (((2.167847 41...
6  2.118214 41.38697 MULTIPOLYGON (((2.102914 41...
7  2.152398 41.41015 MULTIPOLYGON (((2.168652 41...
8  2.175060 41.44624 MULTIPOLYGON (((2.187454 41...
9  2.193309 41.43505 MULTIPOLYGON (((2.207194 41...
10 2.201221 41.40761 MULTIPOLYGON (((2.207194 41...

Para transformar las coordenadas de los comercios en un objeto geográfico usaremos st_as_sf(). Luego le asignaremos la proyección compatible con los mapas que tenemos disponibles usando st_set_crs().

comercios_2024_sf <- st_as_sf(comercios_2024, coords = c("longitud", "latitud"))
comercios_2024_sf <- st_set_crs(comercios_2024_sf, "EPSG:4326")
comercios_2024_sf
Simple feature collection with 68024 features and 47 fields
Geometry type: POINT
Dimension:     XY
Bounding box:  xmin: 2.088023 ymin: 41.34512 xmax: 2.220819 ymax: 41.46653
Geodetic CRS:  WGS 84
# A tibble: 68,024 × 48
   id_global           id_bcn_2016 codi_principal_activ…¹ nom_principal_activi…²
 * <chr>                     <dbl>                  <dbl> <chr>                 
 1 5f158100-c0b8-45e2…       45538                      0 Sense activitat Econò…
 2 03a89603-7bb5-423f…       16649                      0 Sense activitat Econò…
 3 aad63dad-4969-4eff…       23980                      0 Sense activitat Econò…
 4 59832baf-4dd3-4fa4…          NA                      0 Sense activitat Econò…
 5 e3794cd9-8191-4cb3…       26849                      0 Sense activitat Econò…
 6 3db1bda1-f434-4297…       29639                      0 Sense activitat Econò…
 7 510e1364-689f-4651…          NA                      0 Sense activitat Econò…
 8 eafd6ba7-50a9-4da8…       26544                      0 Sense activitat Econò…
 9 d84dd3e6-8e8b-456b…       22661                      0 Sense activitat Econò…
10 ac650075-b5f6-4d6d…       44615                      0 Sense activitat Econò…
# ℹ 68,014 more rows
# ℹ abbreviated names: ¹​codi_principal_activitat, ²​nom_principal_activitat
# ℹ 44 more variables: codi_sector_activitat <dbl>, nom_sector_activitat <chr>,
#   codi_grup_activitat <dbl>, nom_grup_activitat <chr>,
#   codi_activitat_2022 <dbl>, nom_activitat <chr>, codi_activitat_2016 <chr>,
#   nom_local <chr>, sn_oci_nocturn <chr>, sn_coworking <chr>,
#   sn_servei_degustacio <chr>, sn_obert24h <chr>, sn_mixtura <chr>, …

Mapa de establecimientos 2024

Obtenemos el mapa de comercios 2024 creando primero el mapa de Barcelona y luego dibujando los puntos. El orden importa si queremos que se vean los puntos. En los dos casos usamos geom_sf(), pero con datos distintos.Aqui hay los comercios con actividad.

bcn_districts |>
  ggplot() +
  geom_sf(fill = "white") +
  geom_sf(data = filter(comercios_2024_sf, codi_principal_activitat == 1), size = 0.5) + theme_void()

Comercios de Barcelona 2024

Comercios de cada distrito

Si queremos saber el distrito en que está cada comercio 2024, hemos de hacer un join espacial con st_join(). En este caso, queremos llevar la columna n_distri de bcn_districts a comercios_2024_sf, guardando el resultado en comercio2024_distrito.

comercio2024_distrito <- st_join(filter(comercios_2024_sf, codi_principal_activitat == 1), 
                            bcn_districts |> select(n_distri), 
                            join = st_intersects)
comercio2024_distrito
Simple feature collection with 61875 features and 48 fields
Geometry type: POINT
Dimension:     XY
Bounding box:  xmin: 2.088023 ymin: 41.34512 xmax: 2.220819 ymax: 41.46653
Geodetic CRS:  WGS 84
# A tibble: 61,875 × 49
   id_global           id_bcn_2016 codi_principal_activ…¹ nom_principal_activi…²
 * <chr>                     <dbl>                  <dbl> <chr>                 
 1 3e40cf2c-3b94-4977…          NA                      1 Actiu                 
 2 6a8c18de-61f6-44ec…          NA                      1 Actiu                 
 3 36078b21-940f-4f7b…          NA                      1 Actiu                 
 4 d3c44b8e-94ec-49d3…          NA                      1 Actiu                 
 5 c3e95f02-d377-485f…          NA                      1 Actiu                 
 6 725e272c-3159-4217…       50747                      1 Actiu                 
 7 21bdd67d-6848-4ccf…       48481                      1 Actiu                 
 8 1b025b69-8a76-4a82…       47652                      1 Actiu                 
 9 d9ce997d-9a39-440b…          NA                      1 Actiu                 
10 2306209a-67ec-4cf2…       50357                      1 Actiu                 
# ℹ 61,865 more rows
# ℹ abbreviated names: ¹​codi_principal_activitat, ²​nom_principal_activitat
# ℹ 45 more variables: codi_sector_activitat <dbl>, nom_sector_activitat <chr>,
#   codi_grup_activitat <dbl>, nom_grup_activitat <chr>,
#   codi_activitat_2022 <dbl>, nom_activitat <chr>, codi_activitat_2016 <chr>,
#   nom_local <chr>, sn_oci_nocturn <chr>, sn_coworking <chr>,
#   sn_servei_degustacio <chr>, sn_obert24h <chr>, sn_mixtura <chr>, …

Podemos usar la nueva columna n_distri como argumento de color en el mapping aes() para mostrar los comercios con actividad de cada distrito de un color diferente.

bcn_districts |>
  ggplot() +
  geom_sf(fill = "white") +
  geom_sf(data = comercio2024_distrito, aes(color = n_distri), size = 0.5) + 
  theme_void() +
  theme(legend.position = "none")

Comercios 2024 de cada distrito

Indicadores de comercios 2024 por distrito

Podemos usar la información de comercio2024_distrito para obtener indicadores del comercio en cada distrito. El número absoluto de comercio se puede escalar a partir de:

  • El área de cada distrito, que podemos obatener con st_area() (aunque el mapa de Barcelona ya tiene esa información).
  • La población de cada distrito, obtenida como suma de las columnas homes y dones.

Comercios 2024 por kilómetro cuadrado

Contamos el número de comercios del 2024 de cada distrito(con actividad) con group_by() y count() sobre comercio2024_distrito, y guardamos el resultado en num_comercios_2024.

num_comercios_2024 <- comercio2024_distrito |>
  group_by(n_distri,) |>
  count() |>
  rename(n_comercios = n) |>
  st_drop_geometry() # elimino la columna geometry

Ahora podemos añadir esta información al mapa de Barcelona con un left_join().

bcn_districts <- left_join(bcn_districts,
          num_comercios_2024,
          by = "n_distri")
bcn_districts
Simple feature collection with 10 features and 10 fields
Geometry type: MULTIPOLYGON
Dimension:     XY
Bounding box:  xmin: 2.052451 ymin: 41.31692 xmax: 2.229203 ymax: 41.46825
Geodetic CRS:  WGS 84
       area c_distri            n_distri  homes  dones cartodb_id    perim
1  20092803        5 Sarrià-Sant Gervasi  67799  80113          5 37563.64
2  11947078        7      Horta-Guinardó  79017  89075          7 20413.19
3   4368465        1        Ciutat Vella  53968  48379          1 21035.21
4   7476392        2            Eixample 123571 142906          2 13902.57
5  22940419        3      Sants-Montjuïc  87877  95243          3 47125.93
6   6017532        4           Les Corts  38331  43939          4 12481.47
7   4185517        6              Gràcia  55611  65891          6 12280.06
8   8041439        8          Nou Barris  78448  87862          8 14698.41
9   6565322        9         Sant Andreu  70151  77581          9 15132.45
10 10523762       10          Sant Martí 113572 122147         10 20736.53
    coord_x  coord_y n_comercios                       geometry
1  2.106121 41.41277        6285 MULTIPOLYGON (((2.072115 41...
2  2.150531 41.42914        4156 MULTIPOLYGON (((2.176161 41...
3  2.181049 41.38084        6624 MULTIPOLYGON (((2.18239 41....
4  2.164488 41.39162       13559 MULTIPOLYGON (((2.18239 41....
5  2.144933 41.34995        5813 MULTIPOLYGON (((2.167847 41...
6  2.118214 41.38697        2957 MULTIPOLYGON (((2.102914 41...
7  2.152398 41.41015        5529 MULTIPOLYGON (((2.168652 41...
8  2.175060 41.44624        4398 MULTIPOLYGON (((2.187454 41...
9  2.193309 41.43505        4719 MULTIPOLYGON (((2.207194 41...
10 2.201221 41.40761        7835 MULTIPOLYGON (((2.207194 41...

Definiendo indicadores

Una vez obtenido el número de comercios por distritos, podemos obtener:

  • Los comercios por kilómetro cuadrado comercios_2024_km2.
  • Los comercios por habitante comercios_2024_hab.
  • La densidad de población.

Para obtener un mapa con cuatro colores, usamos cut() sobre cada una de las variables creadas.

bcn_districts <- bcn_districts |>
  mutate(comercios_2024_km2 = n_comercios*1000000/area,
         comercios_2024_hab = n_comercios * 10000/(homes + dones),
         densidad = (homes+dones)*1000000/area,
         densidad_cut = cut(densidad, 4),
         comercios_2024_km2_cut = cut(comercios_2024_km2, 4),
         comercios_2024_hab_cut = cut(comercios_2024_hab, 4))
bcn_districts
Simple feature collection with 10 features and 16 fields
Geometry type: MULTIPOLYGON
Dimension:     XY
Bounding box:  xmin: 2.052451 ymin: 41.31692 xmax: 2.229203 ymax: 41.46825
Geodetic CRS:  WGS 84
       area c_distri            n_distri  homes  dones cartodb_id    perim
1  20092803        5 Sarrià-Sant Gervasi  67799  80113          5 37563.64
2  11947078        7      Horta-Guinardó  79017  89075          7 20413.19
3   4368465        1        Ciutat Vella  53968  48379          1 21035.21
4   7476392        2            Eixample 123571 142906          2 13902.57
5  22940419        3      Sants-Montjuïc  87877  95243          3 47125.93
6   6017532        4           Les Corts  38331  43939          4 12481.47
7   4185517        6              Gràcia  55611  65891          6 12280.06
8   8041439        8          Nou Barris  78448  87862          8 14698.41
9   6565322        9         Sant Andreu  70151  77581          9 15132.45
10 10523762       10          Sant Martí 113572 122147         10 20736.53
    coord_x  coord_y n_comercios                       geometry
1  2.106121 41.41277        6285 MULTIPOLYGON (((2.072115 41...
2  2.150531 41.42914        4156 MULTIPOLYGON (((2.176161 41...
3  2.181049 41.38084        6624 MULTIPOLYGON (((2.18239 41....
4  2.164488 41.39162       13559 MULTIPOLYGON (((2.18239 41....
5  2.144933 41.34995        5813 MULTIPOLYGON (((2.167847 41...
6  2.118214 41.38697        2957 MULTIPOLYGON (((2.102914 41...
7  2.152398 41.41015        5529 MULTIPOLYGON (((2.168652 41...
8  2.175060 41.44624        4398 MULTIPOLYGON (((2.187454 41...
9  2.193309 41.43505        4719 MULTIPOLYGON (((2.207194 41...
10 2.201221 41.40761        7835 MULTIPOLYGON (((2.207194 41...
   comercios_2024_km2 comercios_2024_hab  densidad        densidad_cut
1            312.7986           424.9148  7361.442 (7.33e+03,1.44e+04]
2            347.8675           247.2456 14069.717 (7.33e+03,1.44e+04]
3           1516.3222           647.2100 23428.597 (2.15e+04,2.86e+04]
4           1813.5754           508.8244 35642.462 (2.86e+04,3.57e+04]
5            253.3955           317.4421  7982.417 (7.33e+03,1.44e+04]
6            491.3975           359.4263 13671.718 (7.33e+03,1.44e+04]
7           1320.9839           455.0542 29029.152 (2.86e+04,3.57e+04]
8            546.9171           264.4459 20681.622 (1.44e+04,2.15e+04]
9            718.7767           319.4298 22501.868 (2.15e+04,2.86e+04]
10           744.5056           332.3873 22398.740 (2.15e+04,2.86e+04]
   comercios_2024_km2_cut comercios_2024_hab_cut
1               (252,643]              (347,447]
2               (252,643]              (247,347]
3     (1.42e+03,1.82e+03]              (547,648]
4     (1.42e+03,1.82e+03]              (447,547]
5               (252,643]              (247,347]
6               (252,643]              (347,447]
7     (1.03e+03,1.42e+03]              (447,547]
8               (252,643]              (247,347]
9          (643,1.03e+03]              (247,347]
10         (643,1.03e+03]              (247,347]

Mapas con indicadores de densidad

Ya podemos obtener cada uno de los mapas. He definido los colores a mostrar con diferentes paletas de scale_fill_brewer() y he usado annotation_scale() y annotation_north_arrow() para añadir contexto al mapa.

ggplot(bcn_districts) + 
  geom_sf(aes(fill = comercios_2024_km2_cut)) +
  scale_fill_brewer(palette = "Greens") +
  theme_void(base_size = 12) +
  theme(legend.position = "none") +
  labs(title = "Comercios 2024 por Km2", caption = "Fuente: OpenData BCN") +
  annotation_scale() +
  annotation_north_arrow(location = "tr", height = unit(1, "cm"),
  width = unit(1, "cm"))

Densidad de comercios 2024

El mapa de comercios por habitante:

ggplot(bcn_districts) + 
  geom_sf(aes(fill = comercios_2024_hab_cut)) +
  scale_fill_brewer(palette = "YlOrRd") +
  theme_void(base_size = 12) +
  theme(legend.position = "none") +
  labs(title = "Comercios por habitante", caption = "Fuente: OpenData BCN") +
  annotation_scale() +
  annotation_north_arrow(location = "tr", height = unit(1, "cm"),
  width = unit(1, "cm"))

Comercios por habitante

Y el de densidad de población:

ggplot(bcn_districts) + 
  geom_sf(aes(fill = densidad_cut)) +
  scale_fill_brewer(palette = "YlOrBr") +
  theme_void(base_size = 12) +
  theme(legend.position = "none") +
  labs(title = "Densidad de población (distritos)", caption = "Fuente: OpenData BCN") +
  annotation_scale() +
  annotation_north_arrow(location = "tr", height = unit(1, "cm"),
  width = unit(1, "cm"))

Densidad de distritos

Malla de Barcelona

En vez de mostrar número de comercios por distrito, podemos mostrar este número de comercios en una malla sobre la ciudad de Barcelona.

Grid de Barcelona

La función st_make_grid() crea una malla bcn_grid sobre Barcelona de 30 celdas por 30 (900 celdas). El resultado es una simple feature collection.

bcn_grid <- st_make_grid(bcn_districts, n = c(30, 30))
bcn_grid
Geometry set for 900 features 
Geometry type: POLYGON
Dimension:     XY
Bounding box:  xmin: 2.052451 ymin: 41.31692 xmax: 2.229203 ymax: 41.46825
Geodetic CRS:  WGS 84
First 5 geometries:
POLYGON ((2.052451 41.31692, 2.058343 41.31692,...
POLYGON ((2.058343 41.31692, 2.064235 41.31692,...
POLYGON ((2.064235 41.31692, 2.070126 41.31692,...
POLYGON ((2.070126 41.31692, 2.076018 41.31692,...
POLYGON ((2.076018 41.31692, 2.08191 41.31692, ...

Creamos un sf de la malla bcn_grid_sf con st_sf() y añadimos una columna de id numérica.

bcn_grid_sf <- st_sf(bcn_grid) |>
  mutate(grid_id = 1:n())
bcn_grid_sf
Simple feature collection with 900 features and 1 field
Geometry type: POLYGON
Dimension:     XY
Bounding box:  xmin: 2.052451 ymin: 41.31692 xmax: 2.229203 ymax: 41.46825
Geodetic CRS:  WGS 84
First 10 features:
                         bcn_grid grid_id
1  POLYGON ((2.052451 41.31692...       1
2  POLYGON ((2.058343 41.31692...       2
3  POLYGON ((2.064235 41.31692...       3
4  POLYGON ((2.070126 41.31692...       4
5  POLYGON ((2.076018 41.31692...       5
6  POLYGON ((2.08191 41.31692,...       6
7  POLYGON ((2.087802 41.31692...       7
8  POLYGON ((2.093693 41.31692...       8
9  POLYGON ((2.099585 41.31692...       9
10 POLYGON ((2.105477 41.31692...      10

Ahora ya podemos representar la malla. Como es un conjunto de polígonos, le hemos asignado una transparencia alpha baja para que pueda verse el mapa de Barcelona bajo la malla.

bcn_districts |>
  ggplot() +
  geom_sf() +
  geom_sf(data = bcn_grid_sf, alpha = 0.1) + theme_void()

Grid de Barcelona

Número de comercios en cada celda

Ya podemos ver cuántos comercios hay en cada malla. Primero obtenemos el id de malla de cada comercios con st_join().

comercios_grid <- st_join(filter(comercios_2024_sf, codi_principal_activitat == 1), bcn_grid_sf, join = st_intersects)

Luego contamos cuántos comercios hay en cada área de la malla…

comercios_grid_num <- comercios_grid |>
  group_by(grid_id) |>
  count() |>
  st_drop_geometry()

comercios_grid_num |>
  arrange(-n) |>
  slice(1:10)
# A tibble: 10 × 2
   grid_id     n
     <int> <int>
 1     381  1089
 2     412  1018
 3     498   972
 4     379   793
 5     466   780
 6     411   744
 7     499   737
 8     380   724
 9     438   712
10     529   667

… y llevamos el resultado a la malla, obteniedo bcn_grid_sf_color.

bcn_grid_sf_color <- left_join(bcn_grid_sf, 
                               comercios_grid_num, by = "grid_id") |>
            mutate(n = ifelse(is.na(n), 0, n))

Aquí podemos ver algunos de los elementos de la malla con más comercios.

bcn_grid_sf_color |>
  arrange(-n) |>
  select(grid_id, n) |>
  slice(1:10)
Simple feature collection with 10 features and 2 fields
Geometry type: POLYGON
Dimension:     XY
Bounding box:  xmin: 2.140827 ymin: 41.37745 xmax: 2.182069 ymax: 41.40772
Geodetic CRS:  WGS 84
   grid_id    n                       bcn_grid
1      381 1089 POLYGON ((2.170286 41.37745...
2      412 1018 POLYGON ((2.176177 41.3825,...
3      498  972 POLYGON ((2.152611 41.39763...
4      379  793 POLYGON ((2.158502 41.37745...
5      466  780 POLYGON ((2.140827 41.39259...
6      411  744 POLYGON ((2.170286 41.3825,...
7      499  737 POLYGON ((2.158502 41.39763...
8      380  724 POLYGON ((2.164394 41.37745...
9      438  712 POLYGON ((2.152611 41.38754...
10     529  667 POLYGON ((2.158502 41.40268...

Mapa de la grid de comercios

Ahora ya podemos usar el número de comercios n como fill del aes() en la malla. Cada cuadrado de la malla tendrá un color definido por el número de comercios que hay en él.

Usamos una escala de gradiente scale_fill_gradient() definiendo el blanco como color para cero restaurants y el verde para el máximo número de comercios.

bcn_grid_sf_color |>
  ggplot() +
  geom_sf(aes(fill = n), color = "white") + 
  theme_void() +
  scale_fill_gradient(low = "#FFFFFF", high = "#00FF00") +
  geom_sf(data = bcn_districts, alpha = 0.1, linewidth = 0.5) +
  theme(legend.position = "none") +
  annotation_scale()

Comercios de Barcelona

Mapa del contorno de Barcelona

En el mapa de arriba, podemos querer eliminar los distritos, y mostrar sólo el contorno de Barcelona. Podemos hacer esto con st_union()

bcn_unico_sfc <- st_union(bcn_districts)
bcn_unico_sfc
Geometry set for 1 feature 
Geometry type: MULTIPOLYGON
Dimension:     XY
Bounding box:  xmin: 2.052451 ymin: 41.31692 xmax: 2.229203 ymax: 41.46825
Geodetic CRS:  WGS 84
MULTIPOLYGON (((2.102914 41.40109, 2.102839 41....

El sf resultante es bcn_unico.

bcn_unico <- st_as_sf(bcn_unico_sfc)
bcn_unico
Simple feature collection with 1 feature and 0 fields
Geometry type: MULTIPOLYGON
Dimension:     XY
Bounding box:  xmin: 2.052451 ymin: 41.31692 xmax: 2.229203 ymax: 41.46825
Geodetic CRS:  WGS 84
                               x
1 MULTIPOLYGON (((2.102914 41...

Este es el resultado con el nuevo mapa:

bcn_grid_sf_color |>
  ggplot() +
  geom_sf(aes(fill = n), color = "white") + 
  theme_void() +
  scale_fill_gradient(low = "#FFFFFF", high = "#00FF00") +
  geom_sf(data = bcn_unico, alpha = 0.1, linewidth = 0.5) +
  theme(legend.position = "none") +
  annotation_scale()

Comercios de Barcelona

Mapa de distribucion de Restaurants 2024

Obtenemos el mapa de restaurants 2024 creando primero el mapa de Barcelona y luego dibujando los puntos. El orden importa si queremos que se vean los puntos. En los dos casos usamos geom_sf(), pero con datos distintos.Aqui hay los comercios con actividad.

bcn_districts |>
  ggplot() +
  geom_sf(fill = "white") +
  geom_sf(data = filter(comercios_2024_sf, codi_principal_activitat == 1, nom_activitat == "Restaurants"), size = 0.5) + theme_void()

Restaurants de Barcelona 2024

Restaurants de cada distrito

Si queremos saber el distrito en que está cada restaurant 2024, hemos de hacer un join espacial con st_join(). En este caso, queremos llevar la columna n_distri de bcn_districts a comercios_2024_sf, guardando el resultado en comercio2024_distrito.

restaurants2024_distrito <- st_join(filter(comercios_2024_sf, codi_principal_activitat == 1, nom_activitat == "Restaurants"), 
                            bcn_districts |> select(n_distri), 
                            join = st_intersects)
restaurants2024_distrito
Simple feature collection with 4430 features and 48 fields
Geometry type: POINT
Dimension:     XY
Bounding box:  xmin: 2.088023 ymin: 41.35142 xmax: 2.220413 ymax: 41.46628
Geodetic CRS:  WGS 84
# A tibble: 4,430 × 49
   id_global           id_bcn_2016 codi_principal_activ…¹ nom_principal_activi…²
 * <chr>                     <dbl>                  <dbl> <chr>                 
 1 6a8c18de-61f6-44ec…          NA                      1 Actiu                 
 2 8395faa6-c4e2-465b…       69653                      1 Actiu                 
 3 bf8b59ac-60b3-480e…       68794                      1 Actiu                 
 4 5f16c65a-22fa-4eca…       63927                      1 Actiu                 
 5 c6fecb80-4ff9-43cd…       71166                      1 Actiu                 
 6 e0e67cec-5bca-4ff4…       42221                      1 Actiu                 
 7 ac4498a8-0630-4794…       42713                      1 Actiu                 
 8 e9651eba-8816-4244…       66513                      1 Actiu                 
 9 c15aea6a-5089-464a…       21262                      1 Actiu                 
10 8be7a99d-eb21-4b45…       51269                      1 Actiu                 
# ℹ 4,420 more rows
# ℹ abbreviated names: ¹​codi_principal_activitat, ²​nom_principal_activitat
# ℹ 45 more variables: codi_sector_activitat <dbl>, nom_sector_activitat <chr>,
#   codi_grup_activitat <dbl>, nom_grup_activitat <chr>,
#   codi_activitat_2022 <dbl>, nom_activitat <chr>, codi_activitat_2016 <chr>,
#   nom_local <chr>, sn_oci_nocturn <chr>, sn_coworking <chr>,
#   sn_servei_degustacio <chr>, sn_obert24h <chr>, sn_mixtura <chr>, …

Podemos usar la nueva columna n_distri como argumento de color en el mapping aes() para mostrar los restaurants con actividad de cada distrito de un color diferente.

bcn_districts |>
  ggplot() +
  geom_sf(fill = "white") +
  geom_sf(data = restaurants2024_distrito, aes(color = n_distri), size = 0.5) + 
  theme_void() +
  theme(legend.position = "none")

Restaurants 2024 de cada distrito

Indicadores de restaurants 2024 por distrito

Podemos usar la información de restaurants2024_distrito para obtener indicadores del comercio en cada distrito. El número absoluto de comercio se puede escalar a partir de:

  • El área de cada distrito, que podemos obatener con st_area() (aunque el mapa de Barcelona ya tiene esa información).
  • La población de cada distrito, obtenida como suma de las columnas homes y dones.

Comercios 2024 por kilómetro cuadrado

Contamos el número de comercios del 2024 de cada distrito(con actividad) con group_by() y count() sobre comercio2024_distrito, y guardamos el resultado en num_comercios_2024.

num_restaurants_2024 <- restaurants2024_distrito |>
  group_by(n_distri,) |>
  count() |>
  rename(n_restaurants = n) |>
  st_drop_geometry() # elimino la columna geometry

Ahora podemos añadir esta información al mapa de Barcelona con un left_join().

bcn_districts <- left_join(bcn_districts,
          num_restaurants_2024,
          by = "n_distri")
bcn_districts
Simple feature collection with 10 features and 17 fields
Geometry type: MULTIPOLYGON
Dimension:     XY
Bounding box:  xmin: 2.052451 ymin: 41.31692 xmax: 2.229203 ymax: 41.46825
Geodetic CRS:  WGS 84
       area c_distri            n_distri  homes  dones cartodb_id    perim
1  20092803        5 Sarrià-Sant Gervasi  67799  80113          5 37563.64
2  11947078        7      Horta-Guinardó  79017  89075          7 20413.19
3   4368465        1        Ciutat Vella  53968  48379          1 21035.21
4   7476392        2            Eixample 123571 142906          2 13902.57
5  22940419        3      Sants-Montjuïc  87877  95243          3 47125.93
6   6017532        4           Les Corts  38331  43939          4 12481.47
7   4185517        6              Gràcia  55611  65891          6 12280.06
8   8041439        8          Nou Barris  78448  87862          8 14698.41
9   6565322        9         Sant Andreu  70151  77581          9 15132.45
10 10523762       10          Sant Martí 113572 122147         10 20736.53
    coord_x  coord_y n_comercios comercios_2024_km2 comercios_2024_hab
1  2.106121 41.41277        6285           312.7986           424.9148
2  2.150531 41.42914        4156           347.8675           247.2456
3  2.181049 41.38084        6624          1516.3222           647.2100
4  2.164488 41.39162       13559          1813.5754           508.8244
5  2.144933 41.34995        5813           253.3955           317.4421
6  2.118214 41.38697        2957           491.3975           359.4263
7  2.152398 41.41015        5529          1320.9839           455.0542
8  2.175060 41.44624        4398           546.9171           264.4459
9  2.193309 41.43505        4719           718.7767           319.4298
10 2.201221 41.40761        7835           744.5056           332.3873
    densidad        densidad_cut comercios_2024_km2_cut comercios_2024_hab_cut
1   7361.442 (7.33e+03,1.44e+04]              (252,643]              (347,447]
2  14069.717 (7.33e+03,1.44e+04]              (252,643]              (247,347]
3  23428.597 (2.15e+04,2.86e+04]    (1.42e+03,1.82e+03]              (547,648]
4  35642.462 (2.86e+04,3.57e+04]    (1.42e+03,1.82e+03]              (447,547]
5   7982.417 (7.33e+03,1.44e+04]              (252,643]              (247,347]
6  13671.718 (7.33e+03,1.44e+04]              (252,643]              (347,447]
7  29029.152 (2.86e+04,3.57e+04]    (1.03e+03,1.42e+03]              (447,547]
8  20681.622 (1.44e+04,2.15e+04]              (252,643]              (247,347]
9  22501.868 (2.15e+04,2.86e+04]         (643,1.03e+03]              (247,347]
10 22398.740 (2.15e+04,2.86e+04]         (643,1.03e+03]              (247,347]
   n_restaurants                       geometry
1            365 MULTIPOLYGON (((2.072115 41...
2            136 MULTIPOLYGON (((2.176161 41...
3            660 MULTIPOLYGON (((2.18239 41....
4           1432 MULTIPOLYGON (((2.18239 41....
5            414 MULTIPOLYGON (((2.167847 41...
6            241 MULTIPOLYGON (((2.102914 41...
7            289 MULTIPOLYGON (((2.168652 41...
8            173 MULTIPOLYGON (((2.187454 41...
9            222 MULTIPOLYGON (((2.207194 41...
10           498 MULTIPOLYGON (((2.207194 41...

Definiendo indicadores

Una vez obtenido el número de restaurants por distritos, podemos obtener:

  • Los restaurants por kilómetro cuadrado restaurants_2024_km2`.
  • Los restaurants por habitante restaurants_2024_hab`.

Para obtener un mapa con cuatro colores, usamos cut() sobre cada una de las variables creadas.

bcn_districts <- bcn_districts |>
  mutate(restaurants_2024_km2 = n_restaurants*1000000/area,
         restaurants_2024_hab = n_restaurants * 10000/(homes + dones),
         restaurants_2024_km2_cut = cut(restaurants_2024_km2, 4),
         restaurants_2024_hab_cut = cut(restaurants_2024_hab, 4))
bcn_districts
Simple feature collection with 10 features and 21 fields
Geometry type: MULTIPOLYGON
Dimension:     XY
Bounding box:  xmin: 2.052451 ymin: 41.31692 xmax: 2.229203 ymax: 41.46825
Geodetic CRS:  WGS 84
       area c_distri            n_distri  homes  dones cartodb_id    perim
1  20092803        5 Sarrià-Sant Gervasi  67799  80113          5 37563.64
2  11947078        7      Horta-Guinardó  79017  89075          7 20413.19
3   4368465        1        Ciutat Vella  53968  48379          1 21035.21
4   7476392        2            Eixample 123571 142906          2 13902.57
5  22940419        3      Sants-Montjuïc  87877  95243          3 47125.93
6   6017532        4           Les Corts  38331  43939          4 12481.47
7   4185517        6              Gràcia  55611  65891          6 12280.06
8   8041439        8          Nou Barris  78448  87862          8 14698.41
9   6565322        9         Sant Andreu  70151  77581          9 15132.45
10 10523762       10          Sant Martí 113572 122147         10 20736.53
    coord_x  coord_y n_comercios comercios_2024_km2 comercios_2024_hab
1  2.106121 41.41277        6285           312.7986           424.9148
2  2.150531 41.42914        4156           347.8675           247.2456
3  2.181049 41.38084        6624          1516.3222           647.2100
4  2.164488 41.39162       13559          1813.5754           508.8244
5  2.144933 41.34995        5813           253.3955           317.4421
6  2.118214 41.38697        2957           491.3975           359.4263
7  2.152398 41.41015        5529          1320.9839           455.0542
8  2.175060 41.44624        4398           546.9171           264.4459
9  2.193309 41.43505        4719           718.7767           319.4298
10 2.201221 41.40761        7835           744.5056           332.3873
    densidad        densidad_cut comercios_2024_km2_cut comercios_2024_hab_cut
1   7361.442 (7.33e+03,1.44e+04]              (252,643]              (347,447]
2  14069.717 (7.33e+03,1.44e+04]              (252,643]              (247,347]
3  23428.597 (2.15e+04,2.86e+04]    (1.42e+03,1.82e+03]              (547,648]
4  35642.462 (2.86e+04,3.57e+04]    (1.42e+03,1.82e+03]              (447,547]
5   7982.417 (7.33e+03,1.44e+04]              (252,643]              (247,347]
6  13671.718 (7.33e+03,1.44e+04]              (252,643]              (347,447]
7  29029.152 (2.86e+04,3.57e+04]    (1.03e+03,1.42e+03]              (447,547]
8  20681.622 (1.44e+04,2.15e+04]              (252,643]              (247,347]
9  22501.868 (2.15e+04,2.86e+04]         (643,1.03e+03]              (247,347]
10 22398.740 (2.15e+04,2.86e+04]         (643,1.03e+03]              (247,347]
   n_restaurants                       geometry restaurants_2024_km2
1            365 MULTIPOLYGON (((2.072115 41...             18.16571
2            136 MULTIPOLYGON (((2.176161 41...             11.38354
3            660 MULTIPOLYGON (((2.18239 41....            151.08282
4           1432 MULTIPOLYGON (((2.18239 41....            191.53625
5            414 MULTIPOLYGON (((2.167847 41...             18.04675
6            241 MULTIPOLYGON (((2.102914 41...             40.04964
7            289 MULTIPOLYGON (((2.168652 41...             69.04763
8            173 MULTIPOLYGON (((2.187454 41...             21.51356
9            222 MULTIPOLYGON (((2.207194 41...             33.81403
10           498 MULTIPOLYGON (((2.207194 41...             47.32148
   restaurants_2024_hab restaurants_2024_km2_cut restaurants_2024_hab_cut
1             24.676835              (11.2,56.4]              (22.2,36.3]
2              8.090807              (11.2,56.4]              (8.03,22.2]
3             64.486502                (146,192]              (50.4,64.5]
4             53.738221                (146,192]              (50.4,64.5]
5             22.608126              (11.2,56.4]              (22.2,36.3]
6             29.293789              (11.2,56.4]              (22.2,36.3]
7             23.785617               (56.4,101]              (22.2,36.3]
8             10.402261              (11.2,56.4]              (8.03,22.2]
9             15.027211              (11.2,56.4]              (8.03,22.2]
10            21.126850              (11.2,56.4]              (8.03,22.2]

Mapas con indicadores de densidad

Ya podemos obtener cada uno de los mapas. He definido los colores a mostrar con diferentes paletas de scale_fill_brewer() y he usado annotation_scale() y annotation_north_arrow() para añadir contexto al mapa.

ggplot(bcn_districts) + 
  geom_sf(aes(fill = restaurants_2024_km2_cut)) +
  scale_fill_brewer(palette = "Greens") +
  theme_void(base_size = 12) +
  theme(legend.position = "none") +
  labs(title = "Restaurants 2024 por Km2", caption = "Fuente: OpenData BCN") +
  annotation_scale() +
  annotation_north_arrow(location = "tr", height = unit(1, "cm"),
  width = unit(1, "cm"))

Densidad de restaurants 2024

El mapa de restaurants por habitante:

ggplot(bcn_districts) + 
  geom_sf(aes(fill = restaurants_2024_hab_cut)) +
  scale_fill_brewer(palette = "YlOrRd") +
  theme_void(base_size = 12) +
  theme(legend.position = "none") +
  labs(title = "Restaurants por habitante", caption = "Fuente: OpenData BCN") +
  annotation_scale() +
  annotation_north_arrow(location = "tr", height = unit(1, "cm"),
  width = unit(1, "cm"))

Restaurants por habitante

Número de restaurants en cada celda

Ya podemos ver cuántos restaurants hay en cada malla. Primero obtenemos el id de malla de cada restaurant con st_join().

restaurants_grid <- st_join(filter(comercios_2024_sf, codi_principal_activitat == 1, nom_activitat == "Restaurants"), bcn_grid_sf, join = st_intersects)

Luego contamos cuántos restaurants hay en cada área de la malla…

restaurants_grid_num <- restaurants_grid |>
  group_by(grid_id) |>
  count() |>
  st_drop_geometry()

restaurants_grid_num |>
  arrange(-n) |>
  slice(1:10)
# A tibble: 10 × 2
   grid_id     n
     <int> <int>
 1     438   103
 2     439    98
 3     381    87
 4     382    83
 5     467    80
 6     468    73
 7     412    72
 8     409    71
 9     350    67
10     349    65

… y llevamos el resultado a la malla, obteniedo bcn_grid_sf_color.

bcn_grid_sf_color <- left_join(bcn_grid_sf, 
                               restaurants_grid_num, by = "grid_id") |>
            mutate(n = ifelse(is.na(n), 0, n))

Aquí podemos ver algunos de los elementos de la malla con más restaurants.

bcn_grid_sf_color |>
  arrange(-n) |>
  select(grid_id, n) |>
  slice(1:10)
Simple feature collection with 10 features and 2 fields
Geometry type: POLYGON
Dimension:     XY
Bounding box:  xmin: 2.146719 ymin: 41.37241 xmax: 2.182069 ymax: 41.39763
Geodetic CRS:  WGS 84
   grid_id   n                       bcn_grid
1      438 103 POLYGON ((2.152611 41.38754...
2      439  98 POLYGON ((2.158502 41.38754...
3      381  87 POLYGON ((2.170286 41.37745...
4      382  83 POLYGON ((2.176177 41.37745...
5      467  80 POLYGON ((2.146719 41.39259...
6      468  73 POLYGON ((2.152611 41.39259...
7      412  72 POLYGON ((2.176177 41.3825,...
8      409  71 POLYGON ((2.158502 41.3825,...
9      350  67 POLYGON ((2.164394 41.37241...
10     349  65 POLYGON ((2.158502 41.37241...

Mapa de la grid de restaurants

Ahora ya podemos usar el número de restaurants n como fill del aes() en la malla. Cada cuadrado de la malla tendrá un color definido por el número de restaurants que hay en él.

Usamos una escala de gradiente scale_fill_gradient() definiendo el blanco como color para cero restaurants y el verde para el máximo número de restaurants.

bcn_grid_sf_color |>
  ggplot() +
  geom_sf(aes(fill = n), color = "white") + 
  theme_void() +
  scale_fill_gradient(low = "#FFFFFF", high = "#00FF00") +
  geom_sf(data = bcn_districts, alpha = 0.1, linewidth = 0.5) +
  theme(legend.position = "none") +
  annotation_scale()

Restaurants de Barcelona

Mapa del contorno de Barcelona

En el mapa de arriba, podemos querer eliminar los distritos, y mostrar sólo el contorno de Barcelona. Podemos hacer esto con st_union()

bcn_unico_sfc <- st_union(bcn_districts)
bcn_unico_sfc
Geometry set for 1 feature 
Geometry type: MULTIPOLYGON
Dimension:     XY
Bounding box:  xmin: 2.052451 ymin: 41.31692 xmax: 2.229203 ymax: 41.46825
Geodetic CRS:  WGS 84
MULTIPOLYGON (((2.102914 41.40109, 2.102839 41....

El sf resultante es bcn_unico.

bcn_unico <- st_as_sf(bcn_unico_sfc)
bcn_unico
Simple feature collection with 1 feature and 0 fields
Geometry type: MULTIPOLYGON
Dimension:     XY
Bounding box:  xmin: 2.052451 ymin: 41.31692 xmax: 2.229203 ymax: 41.46825
Geodetic CRS:  WGS 84
                               x
1 MULTIPOLYGON (((2.102914 41...

Este es el resultado con el nuevo mapa:

bcn_grid_sf_color |>
  ggplot() +
  geom_sf(aes(fill = n), color = "white") + 
  theme_void() +
  scale_fill_gradient(low = "#FFFFFF", high = "#00FF00") +
  geom_sf(data = bcn_unico, alpha = 0.1, linewidth = 0.5) +
  theme(legend.position = "none") +
  annotation_scale()

Restaurants de Barcelona

4 Conclusiones

  • En el año 2024, se identificó que las actividades comerciales más representativas en Barcelona son los restaurants, bares/cibercafés, y los servicios a empresas y oficinas. Estas actividades presentan una mayor concentración en distritos como Eixample, Sant Martí y Ciutat Vella, lo que evidencia una fuerte centralización de la actividad económica en zonas urbanas de alta densidad y flujo poblacional.

  • Entre 2019 y 2024 se observa una disminución general en el número de establecimientos en espacios de concentración comercial, con especial impacto en las galerías y centros comerciales, probablemente como consecuencia de la pandemia. Sin embargo, algunos mercados y ejes comerciales han mostrado resiliencia, manteniendo o incluso aumentando su actividad, lo cual sugiere una adaptación más ágil a los cambios del entorno.

  • El análisis geoespacial muestra que las zonas de mayor densidad comercial en 2024 se concentran principalmente en el centro de la ciudad, especialmente en distritos como Eixample y Ciutat Vella. En contraste, las áreas periféricas presentan una menor densidad, lo que revela una desigual distribución territorial del comercio y pone en evidencia la necesidad de políticas que fomenten una mayor descentralización de la actividad comercial.