En este taller seguiremos trabajando con indicadores descriptivos del análisis regional con información limitada utilizando información del PIB regional de Chile. De esta manera, los objetivos del taller serán los siguientes:
# Una sola vez, en la consola:
install.packages("REAT") # indicadores de economía regional
install.packages("sf") # datos espaciales
install.packages("ggplot2") # gráficos y mapas
# En cada sesión, al principio del script:
library(REAT)
library(sf)
library(ggplot2)
PIB regional por actividad económica, 2023, precios corrientes, series empalmadas, referencia 2018, en miles de millones de pesos. Los datos son del Banco Central de Chile, y se han obtenido vía el buscador de Estadísticas Territoriales de la Biblioteca del Congreso Nacional. La información representa a 13 actividades y 16 regiones.
d <- read.csv("pib_regional_chile_largo.csv",
encoding = "UTF-8",
colClasses = c(codigo_region = "character"))
str(d) # estructura del objeto: qué columnas tiene y de qué tipo
#> 'data.frame': 416 obs. of 5 variables:
#> $ codigo_region: chr "15" "01" "02" "03" ...
#> $ region : chr "Arica y Parinacota" "Tarapacá" "Antofagasta" "Atacama" ...
#> $ sector : chr "Agropecuario-Silvícola" "Agropecuario-Silvícola" "Agropecuario-Silvícola" "Agropecuario-Silvícola" ...
#> $ anio : int 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 ...
#> $ valor : num 42.27 3.48 2.47 73.61 237.41 ...
d23 <- subset(d, anio == 2023) # subset() filtra filas según una condición. Trabajaremos para con el año 2023.
regiones <- unique(d$region) # unique() devuelve los valores sin repetir
sectores <- unique(d$sector) # y el signo $ extrae una columna. Identificamos sectores y regiones.
V <- matrix(0, nrow = length(sectores), ncol = length(regiones), # Creamos una matriz: filas son sectores, columnas: regiones.
dimnames = list(sectores, regiones)) # Se indican los nombres a las filas y las columnas.
for (k in seq_len(nrow(d23))) V[d23$sector[k], d23$region[k]] <- d23$valor[k] # Contando las observaciones (valores) que tiene d23, busca para cada fila el sector de esa observación y la región de esa observación. Finalmente, el código asigna el valor que queremos colocar en la matriz, que es el valor correspondiente al sector i en la región j.
dim(V) # dimensión filas y columnas
#> [1] 13 16
NOTA: El bucle for recorre las 416
filas del archivo y va colocando cada valor en la casilla que le
corresponde. Es la manera más fácil de pasar de formato largo a matriz y
nos permite ver lo que está ocurriendo (lo que hace).
tot_sector <- rowSums(V) # suma de cada FILA: total de cada sector
tot_region <- colSums(V) # suma de cada COLUMNA: total de cada región
total <- sum(V)
n <- nrow(V); m <- ncol(V) # 13 sectores, 16 regiones
p_ij <- sweep(V, 2, tot_region, "/") # participación del sector dentro de la REGIÓN
p_i <- tot_sector / total # participación del sector en el nacional
q_ij <- sweep(V, 1, tot_sector, "/") # peso de la región dentro del SECTOR
t_j <- tot_region / total # peso de la región en la economía
NOTA: La función sweep() divide toda
una matriz por un vector. El segundo argumento dice en qué dirección se
utiliza la matriz en el cáluclo: 1 recorre las filas y
2 recorre las columnas.
Representamos el peso de cada región en el PIB nacional, para explorar, de manera básica, la distribución regional de la economía chilena.
kable(data.frame(Región = names(t_j),
`t_j` = round(as.numeric(t_j), 4),
`% del PIB` = round(100 * as.numeric(t_j), 2),
check.names = FALSE),
align = "c", row.names = FALSE,
caption = "Peso de cada región en el PIB nacional, 2023.")
| Región | t_j | % del PIB |
|---|---|---|
| Arica y Parinacota | 0.0085 | 0.85 |
| Tarapacá | 0.0311 | 3.11 |
| Antofagasta | 0.1233 | 12.33 |
| Atacama | 0.0237 | 2.37 |
| Coquimbo | 0.0361 | 3.61 |
| Valparaíso | 0.0799 | 7.99 |
| Metropolitana | 0.4300 | 43.00 |
| O’Higgins | 0.0469 | 4.69 |
| Maule | 0.0408 | 4.08 |
| Ñuble | 0.0162 | 1.62 |
| Biobío | 0.0659 | 6.59 |
| Araucanía | 0.0305 | 3.05 |
| Los Ríos | 0.0140 | 1.40 |
| Los Lagos | 0.0372 | 3.72 |
| Aysén | 0.0062 | 0.62 |
| Magallanes | 0.0098 | 0.98 |
| Qué compara | La participación del sector \(i\) dentro de la región \(j\) frente a su participación en el país |
| Fórmula | \(Q_{ij} = \dfrac{p_{ij}}{p_i} = \dfrac{V_{ij} / \sum_i V_{ij}}{\sum_j V_{ij} / \sum_i \sum_j V_{ij}}\) |
| Qué devuelve | Un número por cada casilla: 13 × 16 = 208 valores |
| Recorrido | \([0, \infty)\), sin tope superior |
Interpretación \(Q = 1\) significa que el sector pesa en la región exactamente lo mismo que en el país. \(Q > 1\), que el sector pesa más en la región en comparación al país; \(Q < 1\), que el sector pesa menos en la región en comparación al país. La especialización relativa de una región en un sector se asociaría a un cociente de localización mayor que 1.
Q <- sweep(p_ij, 1, p_i, "/")
round(Q[, c("Antofagasta", "Metropolitana", "Aysén")], 3) # Seleccionamos tres casos (regiones) para analizar
#> Antofagasta Metropolitana Aysén
#> Agropecuario-Silvícola 0.004 0.273 0.376
#> Pesca 0.067 0.000 48.506
#> Minería 5.181 0.083 0.138
#> Industria Manufacturera 0.245 1.054 0.707
#> Electricidad, gas, agua y gestión de desechos 0.844 0.673 0.470
#> Construcción 0.892 0.820 0.669
#> Comercio 0.264 1.433 0.566
#> Restaurantes y hoteles 0.496 1.122 0.696
#> Transporte, información y comunicaciones 0.451 1.343 0.734
#> Servicios financieros y empresariales 0.385 1.512 0.281
#> Servicios de vivienda e inmobiliarios 0.257 1.055 0.814
#> Servicios personales 0.281 1.095 1.089
#> Administración pública 0.254 1.022 3.568
El paquete REAT ofrece la función
locq(e_ij, e_j, e_i, e)para obtener el cociente de
localización. La función necesita 4 insumos: el valor de la celda en la
matriz SECRE, el total de la región, el total del sector y el total
general, en ese orden.
# Un caso: la minería en Antofagasta
REAT::locq(V["Minería", "Antofagasta"], tot_region["Antofagasta"],
tot_sector["Minería"], total)
#> Minería
#> 5.180708
Q["Minería","Antofagasta"] #Verificamos que sea el mismo que hemos calculado.
#> [1] 5.180708
# Podemos usar la matriz completa, aplicando la función a cada casilla
Q_reat <- outer(seq_len(n), seq_len(m), #se genera una secuencia -> n: sectores y m: regiones. Outer toma dos vectores y aplica una función a todas las posibles combinaciones entre sus elementos. Organiza los resultados en una matriz.
Vectorize(function(i, j) # Se declara la función que se aplicará a todas las combinaciones sector-región. En este caso, locq.
REAT::locq(V[i, j], tot_region[j], tot_sector[i], total)))
all.equal(as.numeric(Q), as.numeric(Q_reat)) # Comparamos ambos cálculos. Si ambos son iguales, el resultado debe ser igual a TRUE.
#> [1] TRUE
w <- which(Q > 2.5, arr.ind = TRUE) # Identificar todos los cocientes mayores que 2,5
tab <- data.frame(Sector = rownames(Q)[w[, 1]], Región = colnames(Q)[w[, 2]], # se construye la tabla
`Q_ij` = round(Q[w], 2), check.names = FALSE)
kable(tab[order(-tab$Q_ij), ], row.names = FALSE, align = "c",
caption = "Todos los cocientes superiores a 2,5.") # Formato.
| Sector | Región | Q_ij |
|---|---|---|
| Pesca | Aysén | 48.51 |
| Pesca | Los Lagos | 11.22 |
| Pesca | Magallanes | 6.96 |
| Minería | Antofagasta | 5.18 |
| Agropecuario-Silvícola | Maule | 4.56 |
| Agropecuario-Silvícola | O’Higgins | 4.47 |
| Administración pública | Aysén | 3.57 |
| Agropecuario-Silvícola | Ñuble | 3.38 |
| Minería | Atacama | 3.11 |
| Administración pública | Magallanes | 2.92 |
| Agropecuario-Silvícola | Los Ríos | 2.89 |
| Minería | Tarapacá | 2.86 |
| Administración pública | Arica y Parinacota | 2.71 |
| Electricidad, gas, agua y gestión de desechos | Atacama | 2.59 |
| Qué compara | La estructura sectorial completa de la región frente a la del país |
| Fórmula | \(Q^{R}_{j} = \tfrac{1}{2} \sum_i \left| p_{ij} - p_i \right|\) |
| Qué devuelve | Un número por región: 16 valores |
| Recorrido | \([0, 1]\) |
ruta_positivas <- function(x) sum(x[x > 0]) # Creamos función para sumar solo valores positivos
ruta_absolutos <- function(x) sum(abs(x)) / 2 # Creamos función para sumar valores absolutos y dividimos por dos
dif_p <- sweep(p_ij, 1, p_i, "-")
QR_pos <- apply(dif_p, 2, ruta_positivas) # Aplica función por columna.
QR <- apply(dif_p, 2, ruta_absolutos)
all.equal(QR_pos, QR)
#> [1] TRUE
kable(data.frame(Región = names(sort(QR, decreasing = TRUE)), # Creamos una tabla para guardar los resultados
`Q^R_j` = round(as.numeric(sort(QR, decreasing = TRUE)), 4),
check.names = FALSE),
align = "c", row.names = FALSE,
caption = "Coeficiente de especialización por región, 2023.")
| Región | Q^R_j |
|---|---|
| Antofagasta | 0.5530 |
| Aysén | 0.3940 |
| Atacama | 0.3621 |
| Tarapacá | 0.3400 |
| Maule | 0.2532 |
| Los Ríos | 0.2446 |
| Araucanía | 0.2298 |
| Ñuble | 0.2295 |
| Los Lagos | 0.2258 |
| Arica y Parinacota | 0.2164 |
| Biobío | 0.2011 |
| Magallanes | 0.1746 |
| Metropolitana | 0.1729 |
| O’Higgins | 0.1530 |
| Coquimbo | 0.1482 |
| Valparaíso | 0.1111 |
El paquete REAT no provee el indicador que hemos calculado previamente, sino que devuelve el índice de Krugman. El índice de Krugman, \(K = \sum_i |s_{ij} - s_{il}|\), es la misma distancia que se busca medir en el indicador anterior, sin dividir por dos. Por eso su recorrido está entre \([0, 2]\).
NOTA: En estricto rigor, el índice de krugman busca medir el coeficiente de especialización comparando la participación del sector i en la región j, utilizando como patrón de comparación la participación del sector i en la región l. Generalmente, la variable de interés utilizada para calcular esta participación es a través del empleo. En nuestro caso, utilizaremos como patrón de comparación la participación del sector i a nivel nacional.
#Evaluamos lo que ocurre con el caso de Antofagasta
QR_reat <- REAT::krugman.spec(V[, "Antofagasta"], tot_sector)
QR_reat
#> [1] 1.106057
#Podemos obtener el coeficiente de especialización a la Boisier dividiendo el índice de krugman por 2.
QR_reat_boisier <- REAT::krugman.spec(V[, "Antofagasta"], tot_sector)/2
QR_reat_boisier
#> [1] 0.5530284
QR["Antofagasta"]
#> Antofagasta
#> 0.5530284
El coeficiente de especialización siempre necesita un patrón de comparación, lo que dificulta su interpretación a la hora de determinar si una unidad territorial es especializada o diversificada. Es decir, para determinar si una región es más especializada o diversificada, dependerá del supuesto de que la distribución de referencia sea diversificada o especializada en términos relativos.
En cambio, el índice de Herfindahl-Hirschman no lo necesita: mide la concentración de la estructura regional en términos absolutos, y por eso responde justamente lo que el anterior no puede hacer.
| Qué mide | Concentración de la estructura productiva de la región, sin patrón de comparación |
| Fórmula | \(HHI_j = \sum_i p_{ij}^2\) |
| Qué devuelve | Un número por región |
| Recorrido | \([1/n,\ 1]\) |
| Lectura auxiliar | \(1/HHI_j\) = número equivalente de sectores |
Un HHI alto indica que una parte importante de la actividad económica de la región se concentra en pocos sectores, mientras que un HHI bajo indica que la región presenta una estructura más diversificada.
HHI <- sapply(seq_len(m), function(j) REAT::herf(V[, j]))
names(HHI) <- colnames(V)
# El número equivalente: a cuántos sectores de igual tamaño equivale la estructura
equivalente <- sapply(seq_len(m), function(j) REAT::herf(V[, j], output = "eq"))
names(equivalente) <- colnames(V)
kable(data.frame(Región = names(sort(HHI, decreasing = TRUE)),
`HHI` = round(as.numeric(sort(HHI, decreasing = TRUE)), 4),
`Equivalente`= round(equivalente[names(sort(HHI, decreasing = TRUE))], 4),
check.names = FALSE),
align = "c", row.names = FALSE,
caption = "Herfindahl-Hirschman por región, 2023.")
| Región | HHI | Equivalente |
|---|---|---|
| Antofagasta | 0.4817 | 2.0759 |
| Atacama | 0.2090 | 4.7838 |
| Tarapacá | 0.1955 | 5.1160 |
| Aysén | 0.1445 | 6.9228 |
| Metropolitana | 0.1306 | 7.6552 |
| Los Lagos | 0.1207 | 8.2865 |
| Los Ríos | 0.1194 | 8.3783 |
| Araucanía | 0.1191 | 8.3984 |
| Biobío | 0.1174 | 8.5178 |
| Ñuble | 0.1162 | 8.6044 |
| Maule | 0.1148 | 8.7092 |
| Coquimbo | 0.1108 | 9.0264 |
| O’Higgins | 0.1070 | 9.3465 |
| Arica y Parinacota | 0.1052 | 9.5044 |
| Valparaíso | 0.1006 | 9.9427 |
| Magallanes | 0.0989 | 10.1130 |
| Qué compara | La distribución territorial del sector \(i\) frente a la del total de la economía |
| Fórmula | \(CL_{i} = \tfrac{1}{2} \sum_j \left| q_{ij} - t_j \right|\) |
| Qué devuelve | Un número por sector: 13 valores |
| Recorrido | \([0, 1]\) |
El coeficiente de localización se utiliza como medida de concentración geográfica, donde el grado de concentración se asociaría a la ubicación en el rango \([0, 1]\).
Si bien, un coeficiente cercano a \(1\) indicaría representaría un alto grado de concentración, en estricto rigor solo estaría indicando una distribución del sector muy diferente al patrón de referencia. Por tanto, siempre debemos considerar esta medida como un indicador de concentración relativo.
dif_q <- sweep(q_ij, 2, t_j, "-")
CL <- apply(dif_q, 1, ruta_absolutos) # apply aplica la función por filas.
kable(data.frame(Sector = names(sort(CL, decreasing = TRUE)),
`CL_i` = round(as.numeric(sort(CL, decreasing = TRUE)), 4),
check.names = FALSE),
align = "c", row.names = FALSE,
caption = "Coeficiente de localización por actividad, 2023.")
| Sector | CL_i |
|---|---|
| Pesca | 0.8134 |
| Minería | 0.6475 |
| Agropecuario-Silvícola | 0.4851 |
| Servicios financieros y empresariales | 0.2200 |
| Electricidad, gas, agua y gestión de desechos | 0.1946 |
| Comercio | 0.1861 |
| Transporte, información y comunicaciones | 0.1637 |
| Industria Manufacturera | 0.1628 |
| Administración pública | 0.1257 |
| Servicios personales | 0.1168 |
| Servicios de vivienda e inmobiliarios | 0.1159 |
| Construcción | 0.1082 |
| Restaurantes y hoteles | 0.0969 |
El paquete REAT ofrece la función hoover(). Esta función
compara dos distribuciones: la del sector, que va en x, y
la de referencia, que va en ref. Con la distribución del
PIB regional como referencia, la función devuelve exactamente el
coeficiente de localización:
\[HC \;=\; \tfrac{1}{2} \sum_j \left| \frac{x_j}{\sum x} - \frac{r_j}{\sum r} \right|\]
REAT::hoover(V["Pesca", ], ref = tot_region) # con REAT
#> [1] 0.8134488
CL["Pesca"] # cálculo propio
#> Pesca
#> 0.8134488
REAT::hoover(V["Minería", ], ref = tot_region) # con REAT
#> [1] 0.6474534
CL["Minería"] # cálculo propio
#> Minería
#> 0.6474534
La capa que utilizaremos para esta sección está alojada en la carpeta
cartografía. El archivo principal se llama
regiones_chile.shp y viene acompañado de
los archivos auxiliares que el shapefile necesita:
.dbf con la tabla de atributos, .shx con el
índice, .prj con el sistema de referencia y
.CPG con la codificación. Se lee el .shp, pero
sin los otros la lectura falla o pierde información.
| Campo | Contenido |
|---|---|
cut |
Código único territorial, texto de dos dígitos |
region |
Nombre de la región |
codregion |
El mismo código como número, por si se necesita |
regiones_sf <- sf::st_read("cartografia/regiones_chile.shp", quiet = TRUE)
nrow(regiones_sf)
#> [1] 16
names(regiones_sf)
#> [1] "cut" "region" "codregion" "geometry"
sf::st_crs(regiones_sf)$input
#> [1] "WGS 84"
cut_datos <- unique(d23[, c("codigo_region", "region")])
cut_datos$Q_mineria <- as.numeric(Q["Minería", cut_datos$region]) # Unimos cociente de localización de minería
cut_datos$QR <- as.numeric(QR[cut_datos$region]) # Unimos coeficiente de especialización
mapa <- merge(regiones_sf, cut_datos,
by.x = "cut", by.y = "codigo_region", all.x = TRUE) # Unimos datos a mapa y generamos uno nuevo
Un detalle importante del shapefile utilizado en este taller es que contiene los territorios insulares de Chile, ya que pertenecen a regiones administrativas continentales. Por tanto, podríamos tomar dos decisiones: eliminarlas del análisis, o limitando/recortando la vista del análisis a Chile continental. En este caso, optaremos por el segundo camino.
sf::st_bbox(mapa)
#> xmin ymin xmax ymax
#> -109.44986 -55.97970 -66.41851 -17.49840
lim_x <- c(-76.5, -66.0) # Chile continental; deja fuera Rapa Nui
lim_y <- c(-56.5, -17.0)
library(ggplot2)
cortes <- c(1/32, 1/8, 1/2, 1, 2, 4) # Son los cocientes de localización que se buscan destacar, pasando desde una interpretación que represente un peso relativo extremadamente bajo a un extremo que represente un peso relativo cuatro veces el peso nacional.
ggplot(mapa) +
geom_sf(aes(fill = log2(Q_mineria)), colour = "white", linewidth = 0.15) + # Aquí dibujamos el logaritmo en base 2, no el cociente directamente.
coord_sf(xlim = lim_x, ylim = lim_y, expand = FALSE) +
scale_fill_gradient2(
low = "#2a78d6", mid = "#f0efec", high = "#e34948", midpoint = 0,
breaks = log2(cortes), labels = c("1/32", "1/8", "1/2", "1", "2", "4"),
name = expression(Q[ij])) +
labs(title = "Cociente de localización de la minería, 2023",
subtitle = "Azul: pesa menos que en el país · Gris: igual · Rojo: pesa más",
caption = "Datos: Banco Central de Chile. Cartografía: BCN.\nSe omite Rapa Nui, parte de la Región de Valparaíso.") +
theme_void(base_size = 11)
NOTA: Aquí no utilizamos directamente el cociente de
localización, sino que lo transformamos a un \(log_{2}\). Esto lo hacemos para que cuando
el cociente de localización sea menor que 1 represente valores
negativos, cuando sea igual a 1 produzca un valor igual a 0, y si el
cociente de localización es mayor que 1 produzca valores positivos.
Aquí la magnitud recorre \([0, 1]\) desde un cero con significado, de modo que corresponde una escala secuencial de un solo tono, de claro a oscuro.
ggplot(mapa) +
geom_sf(aes(fill = QR), colour = "white", linewidth = 0.15) + #Aquí usamos directamente el coeficiente.
coord_sf(xlim = lim_x, ylim = lim_y, expand = FALSE) +
scale_fill_gradient(low = "#cde2fb", high = "#0d366b",
limits = c(0, max(mapa$QR, na.rm = TRUE)),
name = expression(Q[j]^R)) +
labs(title = "Coeficiente de especialización por región, 2023",
subtitle = "Distancia entre la estructura de la región y la del país",
caption = "Datos: Banco Central de Chile. Cartografía: BCN.\nSe omite Rapa Nui, parte de la Región de Valparaíso.") +
theme_void(base_size = 11)
library(ggplot2)
cl_df <- data.frame(sector = names(CL), cl = as.numeric(CL))
cl_df$sector <- factor(cl_df$sector, levels = cl_df$sector[order(cl_df$cl)])
ggplot(cl_df, aes(x = cl, y = sector)) +
geom_col(fill = "#2a78d6", width = 0.6) +
geom_text(aes(label = format(round(cl, 3), decimal.mark = ",")),
hjust = -0.15, size = 3.2, colour = "#52514e") +
scale_x_continuous(limits = c(0, 0.95), expand = c(0, 0)) +
labs(title = "Coeficiente de localización por actividad, 2023",
subtitle = "0 = se reparte como el conjunto de la economía · 1 = concentración máxima",
x = NULL, y = NULL, caption = "Datos: Banco Central de Chile.") +
theme_minimal(base_size = 11) +
theme(panel.grid.major.y = element_blank(),
panel.grid.minor = element_blank())
El archivo de datos trae también el año 2013. Cuatro extensiones, en orden de dificultad:
anio y comparar los ordenamientos.Boisier, S. (1980). Técnicas de análisis regional con información limitada. Cuaderno del ILPES N.º 27. Santiago.
Wieland, T. (2018). REAT: Regional Economic Analysis
Toolbox. Versión 2.0.0, manual de referencia. La versión actual en
CRAN es la 3.0.3 (2021); ver la nota sobre hoover() en el
bloque 4.
Banco Central de Chile. PIB regional por actividad económica, series empalmadas, referencia 2018. Vía Biblioteca del Congreso Nacional, Estadísticas Territoriales.
Biblioteca del Congreso Nacional de Chile. Mapas vectoriales, división político-administrativa.