library(httr2) # comunicació amb l'API
library(purrr) # paralelització
library(dplyr) # manipulació de dades
library(janitor) # neteja noms de dades
library(ggplot2) # visualitzacions
library(knitr) # taules
Preus de benzina - Geoportal
Context
Preus de benzina a Espanya, sèries temporals (freqüència diària) desagregades a nivell de gasolinera. El Ministerio de transición ecológica ens ofereix l’informació a través d’una API 1 que es diu Geoportal.
Delimitació de la població
Tenim moltes dades, per simplicitat comencem considerant un subconjunt de la població. Ens interessem pels preus de cert producte a les benzineres (estacions terrestres) 2 ubicades en un llistat de municipis en cert hortitzó temporal. Per exemple:
Municipis | Horitzó | Producte |
---|---|---|
Cardedeu | 01/01/2022 - … | Benzina 95 |
Llinars del Vallès | ||
Sant Antoni de Vilamajor | ||
Sant Celoni | ||
Santa Maria de Palautordera |
Obtenció de les dades
A l’apartat de descàrregues del Geoportal trobarem les consultes que necessitem sota la secció preus. Podem accedir a l’informació de diferents formes, utilitzarem R
per comoditat. Per comunicar-nos amb l’API, agrupar, netejar i guardar les dades farem servir les següents llibreries:
Per fer una consulta cal seguir els següents passos:
- Decidir quina és la consulta
- Parametritzar la consulta (si cal)
- Petició i resposta de l’API
Quina és la consulta?
Disposem d’unes 20 consultes diferents que ens permeten descarregar informació sota diferents filtres. Cadascuna consta d’una descripció, una url i un exemple:
Parametrització de la consulta
Algunes consultes no requereixen cap paràmetre, són una mena de llista informativa. Altres requereixen delimitar l’informació que es demana. La data del calendari, el tipus de producte o la regió son els paràmetres més freqüents.
Una forma d’obtenir els preus dins de la zona i horitzó que considerem és utilitzant els codis municipals. Primer trobarem el codi de la provincia de Barcelona i l’utilitzarem per trobar els codis dels municipis desitjats.
Amb els codis municipals, el codi de producte petrolífer i un l’horitzó temporal delimitat podrem descarregar els preus de benzina per l’interval i la zona que sigui necessari.
Petició i resposta de l’API
Primer ens ocuparem del llistat de províncies i del producte. Busquem els identificadors de la benzina 95 e5 i la provincia de Barcelona.
# base url
<- "https://sedeaplicaciones.minetur.gob.es/ServiciosRESTCarburantes/PreciosCarburantes"
url
# endpoints without params
<- paste0(url, c(
dict "/Listados/Provincias/", "/Listados/ProductosPetroliferos/"
%>%
)) set_names(c("prov", "prod")) %>%
map(\(x){
request(x) %>%
req_perform() %>%
resp_body_json() %>%
map(\(json) as_tibble(list_flatten(json))) %>%
bind_rows() %>%
clean_names()
})
# province and product id
<- dict$prov %>%
id_prov filter(grepl("barcelona", provincia, ignore.case = TRUE)) %>%
with(set_names(id_povincia, provincia)); id_prov # tenen el nom mal escrit...
BARCELONA
"08"
<- dict$prod %>%
id_prod filter(grepl("gasolina 95 e5$", nombre_producto, ignore.case = TRUE)) %>%
with(set_names(id_producto, nombre_producto_abreviatura)); id_prod
G95E5
"1"
Ara farem una consulta per obtenir els codis dels municipis d’interès a partir del codi de província de Barcelona.
# municipalities id
<- paste0(url, "/Listados/MunicipiosPorProvincia/", id_prov) %>%
muns request() %>%
req_perform() %>%
resp_body_json() %>%
bind_rows() %>%
filter(grepl(
pattern = "^Llinars|Cardedeu|Vilamajor|Palautordera|Sant Celoni",
x = Municipio, ignore.case = TRUE
%>%
)) distinct(IDMunicipio, Municipio) %>%
with(set_names(IDMunicipio, Municipio)); muns
Cardedeu Llinars del Vallès
"908" "973"
Sant Antoni de Vilamajor Sant Celoni
"1060" "1065"
Sant Esteve de Palautordera Sant Pere de Vilamajor
"1069" "1095"
Santa Maria de Palautordera
"1123"
Ja tenim tots els paràmetres necessaris per fer la nostra consulta. Només ens falta definir l’horitzó temporal i executar la consulta.
<- format(seq.Date(as.Date("2010/01/01"), Sys.Date() - 1, "day"), "%d-%m-%Y")
horitzo <- Sys.time()
t <- expand.grid(dia = horitzo, mun = muns) %>%
preu pmap(\(dia, mun){
%>%
url paste0("/EstacionesTerrestresHist/FiltroMunicipioProducto/") %>%
paste0(dia, "/", mun, "/", id_prod) %>%
request() %>%
req_perform() %>%
resp_body_json() %>%
"ListaEESSPrecio"]] %>%
.[[lapply(as_tibble) %>%
bind_rows() %>%
mutate(dia = dia)
%>%
}) bind_rows() %>%
clean_names()
#write.csv2(preu, "data/preu.csv")
Sys.time() - t
No l’evaluarem si no és necessari ja que tarda uns minuts, utilitzarem una versió recent.
Rows: 77,476
Columns: 19
$ c_p <int> 8440, 8440, 8440, 8440, 8440, 8440, 8440, 8440, 8440, …
$ direccion <chr> "CARRETERA C-251 KM. 5,5", "CARRETERA C-251 KM. 5,5", …
$ horario <chr> "L-D: 06:00-22:00", "L-D: 06:00-22:00", "L-D: 06:00-22…
$ latitud <dbl> 41.63481, 41.63522, 41.63481, 41.63522, 41.63481, 41.6…
$ localidad <chr> "CARDEDEU ", "CARDEDEU …
$ longitud_wgs84 <dbl> 2.340139, 2.339722, 2.340139, 2.339722, 2.340139, 2.33…
$ margen <chr> "D", "I", "D", "I", "D", "I", "D", "I", "D", "I", "D",…
$ municipio <chr> "Cardedeu", "Cardedeu", "Cardedeu", "Cardedeu", "Carde…
$ precio_producto <dbl> 1.108, 1.108, 1.108, 1.108, 1.108, 1.108, 1.108, 1.108…
$ provincia <chr> "BARCELONA", "BARCELONA", "BARCELONA", "BARCELONA", "B…
$ remision <chr> "OM", "OM", "OM", "OM", "OM", "OM", "OM", "OM", "OM", …
$ rotulo <chr> "REPSOL", "REPSOL", "REPSOL", "REPSOL", "REPSOL", "REP…
$ tipo_venta <chr> "P", "P", "P", "P", "P", "P", "P", "P", "P", "P", "P",…
$ ideess <int> 2509, 2510, 2509, 2510, 2509, 2510, 2509, 2510, 2509, …
$ id_municipio <int> 908, 908, 908, 908, 908, 908, 908, 908, 908, 908, 908,…
$ id_provincia <int> 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, …
$ idccaa <int> 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, …
$ dia <date> 2010-01-01, 2010-01-01, 2010-01-02, 2010-01-02, 2010-…
$ preu <dbl> 1.108, 1.108, 1.108, 1.108, 1.108, 1.108, 1.108, 1.108…
Conté informació sobre el preu de G95E5 en 0 municipis de la provincia de .
Descriptiva
Fem una ullada a les nostres dades. Plantegem qüestións d’interès a primera vista.
- Comparació de grups (municipis, estacions, codis postals…)
- Mapa de les gasolineres
- Quantitats d’interès (i.e mean(preu) - median(preu))
- Sèries estacionàries? Cointegrables? VAR?