Through open data portals, governments and city councils provide data to citizens in a transparent and accesible format, so it can be reused for research, app development, and civic tech.
In this post, I will show how to retrieve data into R from an open data portal using the CKAN API technology, and structure it in tidy format with the tools of the tidyverse. Specifically, my aim is to retrieve Barcelona air quality data from the Open Data BCN portal.
I will be using the tidyverse for data reading, handling and plotting, janitor to clean column names and the ckanr package to interact with the CKAN API of the portal.
library(tidyverse)
library(janitor)
library(ckanr)
I need all the URLs of air quality data files. To get them, I set up the Open Data BCN portal with ckanr::ckanr_setup().
ckanr_setup(url = "https://opendata-ajuntament.barcelona.cat/data/")
The datasets available at a portal using CKAN are called packages. Let’s see the package list of the portal.
package_list(as = "table", limit = 1000)
## [1] "20170706-districtes-barris"
## [2] "accessibilitat-via-publica"
## [3] "accidents_causa_conductor_gu_bcn"
## [4] "accidents-causes-gu-bcn"
## [5] "accidents-gu-bcn"
## [6] "accidents-persones-gu-bcn"
## [7] "accidents-tipus-gu-bcn"
## [8] "accidents-vehicles-gu-bcn"
## [9] "accions-formatives-adrecades-al-personal"
## [10] "acollida-animals"
## [11] "administracio-autonomica"
## [12] "administracio-estatal"
## [13] "administracio-municipal"
## [14] "afectacions-turistiques"
## [15] "afectacions-turistiques-a-espais-verds"
## [16] "aforaments-descriptiu"
## [17] "aforaments-detall"
## [18] "aforament-tipus-equipament"
## [19] "agenda-activitats-esportives"
## [20] "agenda-cultural"
## [21] "agenda-diaria"
## [22] "agenda-publica-alcaldesa"
## [23] "agendes-publiques-comissionats"
## [24] "agendes-publiques-regidors"
## [25] "alcaldes-alcaldesses-bcn"
## [26] "allotjaments-altres"
## [27] "allotjaments-hotels"
## [28] "allotjaments-pensions"
## [29] "ampliacio-voreres-bici-bcn"
## [30] "aparcaments-bcn"
## [31] "aparcaments-servei-bicis"
## [32] "aparcaments-sota-superficie"
## [33] "arbrat-parcs"
## [34] "arbrat-viari"
## [35] "arbrat-zona"
## [36] "arbres-interes-local"
## [37] "arees-esbarjo-gossos-bcn"
## [38] "atles-biodiversitat-arbrat-especies"
## [39] "atles-biodiversitat-arbrat-geometries"
## [40] "atles-biodiversitat-arbrat-rel-geometria-especie"
## [41] "atles-biodiversitat-flora-especies"
## [42] "atles-biodiversitat-flora-geometries"
## [43] "atles-biodiversitat-flora-rel-geometria-especie"
## [44] "atles-renda-bruta-per-llar"
## [45] "atles-renda-bruta-per-persona"
## [46] "atles-renda-index-gini"
## [47] "atles-renda-mediana"
## [48] "atles-renda-mitjana"
## [49] "atles-renda-p80-p20-distribucio"
## [50] "autenticacions-punts-recarrega-electric"
## [51] "aut-terrasses-excep-decret-21-5"
## [52] "bancs-del-temps-bcn"
## [53] "barcelona-activa-projectes"
## [54] "benzineres"
## [55] "biblioteca_arus_bcnroc"
## [56] "bicicletes"
## [57] "bicing"
## [58] "calendari-festes-laborals"
## [59] "campanyes-publicitat-institucional"
## [60] "capacitat-mapa-estrategic-soroll"
## [61] "carrecs-electes-comissionats-i-gerents"
## [62] "carrerer"
## [63] "carrers-30-bcn"
## [64] "carrers-pacificats-bici-bcn"
## [65] "carrers-plataforma-unica-bcn"
## [66] "carrers-vianants-bcn"
## [67] "carril-bici"
## [68] "carrils-bici-en-construccio"
## [69] "carrils-bici-municipis"
## [70] "carta-arqueologica-barcelona"
## [71] "cataleg-bases-ajuts-subvencions-bcnroc"
## [72] "cataleg-bases-us-espai-public-bcnroc"
## [73] "cataleg-bcnroc"
## [74] "cataleg-cartes-de-serveis-i-politiques-de-qualitat-bcnroc"
## [75] "cataleg-cartobcn"
## [76] "cataleg-circulars-bcnroc"
## [77] "cataleg-comptes-bcnroc"
## [78] "cataleg-costos-bcnroc"
## [79] "cataleg-declaracions-institucionals-bcnroc"
## [80] "cataleg-decrets-alcaldia-bcnroc"
## [81] "cataleg-dictamens-bcnroc"
## [82] "cataleg-directrius-bcnroc"
## [83] "cataleg-documents-alcaldes-bcnroc"
## [84] "cataleg-documents-tecnics-bcnroc"
## [85] "cataleg-dossiers-notes-premsa-bcnroc"
## [86] "cataleg-enquestes-bcnroc"
## [87] "cataleg-estatuts-bcnroc"
## [88] "cataleg-fotografies-art-public-bcnroc"
## [89] "cataleg-fotografies-barcelona-general-bcnroc"
## [90] "cataleg-fotografies-cementiris-bcnroc"
## [91] "cataleg-fotografies-edificis-bcnroc"
## [92] "cataleg-fotografies-elements-urbans-bcnroc"
## [93] "cataleg-fotografies-projectes-urbans-bcnroc"
## [94] "cataleg_fotografies_temes_bcnroc"
## [95] "cataleg-havana-bcnroc"
## [96] "cataleg-informes-avaluacio-bcnroc"
## [97] "cataleg-informes-diversos-bcnroc"
## [98] "cataleg-informes-organs-govern-bcnroc"
## [99] "cataleg-instruccions-bcnroc"
## [100] "cataleg-laudes-bcnroc"
## [101] "cataleg-memories-bcnroc"
## [102] "cataleg-mesures-govern-bcnroc"
## [103] "cataleg-opendata"
## [104] "cataleg-ordenances-fiscals-preus-bcnroc"
## [105] "cataleg-ordenances-municipals-bcnroc"
## [106] "cataleg-plans-especials-bcnroc"
## [107] "cataleg-plans-estrategics-bcnroc"
## [108] "cataleg-premis-bcnroc"
## [109] "cataleg-pressupostos-bcnroc"
## [110] "cataleg-protocols-bcnroc"
## [111] "cataleg-publicacions-bcnroc"
## [112] "cataleg-reglaments-bcnroc"
## [113] "cataleg-rei-bcnroc"
## [114] "cataleg-revistes-bcnroc"
## [115] "cementiris"
## [116] "cens-activitats-economiques-class-bcn"
## [117] "cens-animals-companyia"
## [118] "cens-locals-planta-baixa-act-economica"
## [119] "centres-civics-activitatsdifusio"
## [120] "centres-civics-entitats"
## [121] "centres-civics-formacio"
## [122] "centres-civics-metres-quadrats"
## [123] "cinemes-dades-globals"
## [124] "cobertura-vegetal-ndvi"
## [125] "cohesio-social"
## [126] "colors-aparcaments-superficie"
## [127] "comissaries-policia"
## [128] "compatibilitats"
## [129] "compliment-objectius-estabilitat"
## [130] "comportament-energetic-edificis"
## [131] "confort-termic"
## [132] "consolats-bcn"
## [133] "consum-aigua"
## [134] "consum-electricitat-bcn"
## [135] "contaminacio-atmosferica"
## [136] "contaminants-estacions-mesura-qualitat-aire"
## [137] "contractes-menors"
## [138] "contractes-menors-a-generica"
## [139] "corredors-bici-bcn"
## [140] "culturailleure-bibliotequesimuseus"
## [141] "culturailleure-cinemesteatresauditoris"
## [142] "culturailleure-espaisinfantils"
## [143] "culturailleure-espaismusicacopes"
## [144] "culturailleure-espaisparticipaciociutadana"
## [145] "culturailleure-parcsjardins"
## [146] "dades-arts-esceniques"
## [147] "dades-arxius"
## [148] "dades-ateneus"
## [149] "dades-festes-ciutat"
## [150] "dades-festival-grec"
## [151] "dades-festivals"
## [152] "dades-globals-cultura"
## [153] "dades-grans-auditoris"
## [154] "dades-merce"
## [155] "dades-museus-exposicions"
## [156] "dades-projectes-fabriques-creacio"
## [157] "dades-sales-musica-viu-agrup-dimensions"
## [158] "dades-sindicals"
## [159] "dades-xarxa-biblioteques-catalunya"
## [160] "deficit-proximitat-espai-verd"
## [161] "densitat-activitats"
## [162] "densitat-huts"
## [163] "denuncies_sancions_transit_bcn_codis"
## [164] "denuncies_sancions_transit_bcn_conceptes_annex"
## [165] "denuncies_sancions_transit_bcn_detall"
## [166] "denuncies_sancions_transit_bcn_tip_vehicle"
## [167] "dutxes-platges"
## [168] "ebsib-bcn-enquesta-benestar-subjectiu-infancia"
## [169] "edificis-amics-de-la-bici-barcelona"
## [170] "educacio-ensenyament-infantil"
## [171] "educacio-ensenyament-no-reglat"
## [172] "educacio-ensenyament-reglat"
## [173] "enquesta-escletxa-digital"
## [174] "entitas-pacte-mobilitat"
## [175] "entitats"
## [176] "entitats-municipals"
## [177] "equipament-administracio"
## [178] "equipament-animals-i-plantes"
## [179] "equipament-associacions"
## [180] "equipament-cementiris-i-serveis-relacionats"
## [181] "equipament-centres-d-informacio"
## [182] "equipament-companyies-de-serveis"
## [183] "equipament-cultura-i-lleure"
## [184] "equipament-educacio"
## [185] "equipament-esports"
## [186] "equipament-medi-ambient-i-serveis-relacionats"
## [187] "equipament-mercats-i-centres-comercials"
## [188] "equipament-mitjans-de-comunicacio-i-serveis-relacionats"
## [189] "equipament-restaurants"
## [190] "equipament-sanitat"
## [191] "equipaments-culturals-icub"
## [192] "equipament-serveis-religiosos"
## [193] "equipament-serveis-socials"
## [194] "equipaments-i-parcs-refugi"
## [195] "equipaments-relacionats-amb-transports"
## [196] "equipament-transports-i-serveis-relacionats"
## [197] "escales-mecaniques"
## [198] "esm-bcn-evo"
## [199] "espais-creacio-activitats-difusio"
## [200] "espais-creacio-formacio-professionals"
## [201] "espais-creacio-metres-quadrats"
## [202] "espais-prioritaris-neteja-barcelona"
## [203] "espais-verds-publics"
## [204] "esports-equip"
## [205] "esports-individuals"
## [206] "esports-instal-lacions-esportives"
## [207] "estacionaments-dum"
## [208] "estacions-bus"
## [209] "estacions-maritimes"
## [210] "estat-estacions-bicing"
## [211] "estat-ports-recarrega-electric"
## [212] "est-cadastre-carrecs-quota-cadastral"
## [213] "est-cadastre-carrecs-tipus-propietari"
## [214] "est-cadastre-carrecs-us"
## [215] "est-cadastre-carrecs-valors-cadastrals"
## [216] "est-cadastre-edificacions-any-const"
## [217] "est-cadastre-edificacions-edat-mitjana"
## [218] "est-cadastre-edificacions-nombre-locals"
## [219] "est-cadastre-edificacions-superficie"
## [220] "est-cadastre-finques-regim-propietat"
## [221] "est-cadastre-finques-superficie"
## [222] "est-cadastre-habitatges-any-const"
## [223] "est-cadastre-habitatges-edat-mitjana"
## [224] "est-cadastre-habitatges-propietari"
## [225] "est-cadastre-habitatges-superficie"
## [226] "est-cadastre-habitatges-superficie-mitjana"
## [227] "est-cadastre-habitatges-valor-cadastral"
## [228] "est-cadastre-locals-prop"
## [229] "est-cadastre-locals-sup"
## [230] "est-cadastre-locals-us-desti"
## [231] "est-cadastre-locals-valors-total-unitaris"
## [232] "est-demo-taxa-migracio-interna"
## [233] "est-densitat"
## [234] "est-eleccions-autonomiques-seccio-censal"
## [235] "est-eleccions-europees-seccio-censal"
## [236] "est-eleccions-generals-seccio-censal"
## [237] "est-eleccions-locals-seccio-censal"
## [238] "est-social-discapacitats-grau"
## [239] "est-social-discapacitats-grups-edat"
## [240] "est-social-discapacitats-sexe"
## [241] "est-social-discapacitats-tipus"
## [242] "est-superficie"
## [243] "est-vehicles-amb-distintiu"
## [244] "est-vehicles-antiguitat-menys-un-any"
## [245] "est-vehicles-antiguitat-motos"
## [246] "est-vehicles-antiguitat-tipus"
## [247] "est-vehicles-antiguitat-turismes"
## [248] "est-vehicles-cilindrada-motos"
## [249] "est_vehicles_evolucio_total"
## [250] "est_vehicles_index_motor"
## [251] "est-vehicles-nacionalitat-propietari"
## [252] "est-vehicles-nacionalitat-propietari-motos"
## [253] "est-vehicles-potencia-fiscal-turismes"
## [254] "est_vehicles_propulsio"
## [255] "est_vehicles_servei"
## [256] "est-vehicles-tipologia-parc-vehicles"
## [257] "est-vehicles-tipus-propietari"
## [258] "est-vehicles-tipus-propietari-motos"
## [259] "evolucio-despeses-corrents-per-politiques"
## [260] "evolucio-despeses-per-capitols"
## [261] "evolucio-despeses-per-capitols-i-articles"
## [262] "evolucio-despeses-per-unitats-organiques"
## [263] "evolucio-deute"
## [264] "evolucio-ingressos-per-capitols"
## [265] "evolucio-ingressos-per-capitols-i-articles"
## [266] "evolucio-resultat-ingressos-i-despeses"
## [267] "exclusio-residencial"
## [268] "facanes-mapa-estrategic-soroll"
## [269] "factor-de-vulnerabilitat"
## [270] "fitxer_entitats"
## [271] "fitxes-ocupacionals"
## [272] "fonts"
## [273] "fonts-ornamentals"
## [274] "formacio-poblacio-insuficient"
## [275] "frase"
## [276] "funiculars"
## [277] "galeries-comercials"
## [278] "grans-centres-comercials"
## [279] "grans-establiments"
## [280] "gruamunicipalbcn-retirada-codis"
## [281] "gruamunicipalbcn-retirada-diposits"
## [282] "gruamunicipalbcn-retiradavehicles"
## [283] "h2mave-anualt1b"
## [284] "h2mave-anualt2b"
## [285] "h2mave-anualt3b"
## [286] "h2mave-semestralt1b"
## [287] "h2mave-semestralt2b"
## [288] "h2mave-semestralt3b"
## [289] "h2mave-totalt1b"
## [290] "h2mave-totalt2b"
## [291] "h2mave-totalt3b"
## [292] "h2mave-totalt4b"
## [293] "h2mave-totalt5b"
## [294] "habitatges-2na-ma"
## [295] "habitatges-us-turistic"
## [296] "habit-fam-dest-habit-segons-any-const"
## [297] "habit-fam-sit-edif-dest-habit-segons-tip"
## [298] "habit-ppal-segons-any-const"
## [299] "habit-ppal-segons-estat-conserv-edif"
## [300] "habit-ppal-segons-instal1-calef"
## [301] "habit-ppal-segons-instal2-aigua"
## [302] "habit-ppal-segons-instal3-telf-i-int"
## [303] "habit-ppal-segons-nombre-pers-viuen"
## [304] "habit-ppal-segons-nom-habit"
## [305] "habit-ppal-segons-regim-tin"
## [306] "habit-ppal-segons-sup-util"
## [307] "horaris-aparcaments-superficie"
## [308] "horts-urbans"
## [309] "immobles-quotes-padro-ibi"
## [310] "immo-edif-hab-segons-any-construccio"
## [311] "immo-edif-hab-segons-estat-conservacio"
## [312] "immo-edif-hab-segons-instalacions"
## [313] "immo-edif-hab-segons-num-plantes-sobre-rasant"
## [314] "immo-edif-hab-segons-num-plantes-sota-rasant"
## [315] "impacte-de-la-calor"
## [316] "incidents-gestionats-gub"
## [317] "indicadors-transparencia-pressupostaria"
## [318] "informacio-estacions-bicing"
## [319] "informacio-punts-recarrega-electric"
## [320] "informacio-rutes-autobus-estacio-del-nord"
## [321] "infraestructures-inventari-bancs"
## [322] "infraestructures-inventari-cameres"
## [323] "infraestructures-inventari-inscripcions"
## [324] "infraestructures-inventari-pas-vianants"
## [325] "infraestructures-inventari-pilones"
## [326] "infraestructures-inventari-reductors-velocitat"
## [327] "infraestructures-inventari-reserves"
## [328] "infraestructures-inventari-semafors"
## [329] "infraestructures-inventari-senyalitzacio"
## [330] "infraestructures-inventari-senyals"
## [331] "infraestructures-inventari-separa-carrils-bici"
## [332] "infraestructures-inventari-suports"
## [333] "infraestructures-tipologia-inscripcions"
## [334] "infraestructures-tipologia-pas-vianants"
## [335] "infraestructures-tipologia-semafors"
## [336] "infraestructures-tipologia-senyals"
## [337] "infraestructures-tipologia-suports-cameres"
## [338] "intensitat-activitat-turistica"
## [339] "iris"
## [340] "isofones-mapa-estrategic-soroll"
## [341] "itineraris"
## [342] "laterals-tallats-transit-bici-bcn"
## [343] "lavabos-publics"
## [344] "limits-municipals-districtes"
## [345] "llista-exposicions-temporals"
## [346] "llocs-culte"
## [347] "lloguer-de-vehicles"
## [348] "locve-evolucio"
## [349] "manteniment-lloguer"
## [350] "mapa-acustic-wms"
## [351] "mapa-ambits-urbanistics-wms"
## [352] "mapa-base-de-vialitat"
## [353] "mapa-base-guia"
## [354] "mapa-base-topografic"
## [355] "mapa-construccions-poblament-wms"
## [356] "mapa-de-la-malla-de-fulls-utm"
## [357] "mapa-de-retolacio-de-carrers"
## [358] "mapa-energia-teleco-wms"
## [359] "mapa-graf-viari-carrers-wms"
## [360] "mapa-hidrografia-obres-wms"
## [361] "mapa-orografia-relleu-wms"
## [362] "mapa-parcelari"
## [363] "mapa-peuat"
## [364] "mapa-planol-ciutat-bcn-wms"
## [365] "mapa-serveis-publics-wms"
## [366] "mapa-urbanistic"
## [367] "mapa-usos-sol-wms"
## [368] "mapa-vegetacio-wms"
## [369] "mapa-xarxa-topografica-municipal-wms"
## [370] "mapes-immissio-qualitat-aire"
## [371] "mediambient-contenidorssal"
## [372] "mediambient-puntsrecollidaarbresnadal"
## [373] "mediambient-puntsrobaamiga"
## [374] "mediambient-puntsverdsbarri"
## [375] "mediambient-puntsverdsmobils"
## [376] "mediambient-puntverdcolaborador"
## [377] "mercats-fires-carrer"
## [378] "mercats-municipals"
## [379] "mesures-estacions-meteorologiques"
## [380] "metadades-estacions-meteorologiques"
## [381] "metadades-variables-est-meteo"
## [382] "mobilitat-quotidiana"
## [383] "modificacions-credit-pressupost"
## [384] "modificacions-de-contractes"
## [385] "n-edif-hab-n-immo-edif"
## [386] "n-edif-hab-segons-any-construc"
## [387] "n-edif-hab-segons-estat-cons-edifici"
## [388] "n-edif-hab-segons-instal"
## [389] "n-edif-hab-segons-n-immo"
## [390] "n-edif-hab-segons-nombre-immo"
## [391] "n-edif-hab-segons-nombre-plantes"
## [392] "n-edif-hab-segons-nombre-plantes-sobre-rasant"
## [393] "n-edif-hab-segons-nombre-plantes-sota-rasant"
## [394] "n-edif-hab-segons-n-places-gar"
## [395] "n-edif-hab-segons-n-plantes-sobre-rasant"
## [396] "n-edif-hab-segons-n-plantes-sota-rasant"
## [397] "n-edif-hab-tipus-edif"
## [398] "nomenclator-bcn"
## [399] "np-asia-dipositsvehicles-bcn"
## [400] "np-circuits-caminar-correr"
## [401] "np-esculleres"
## [402] "np-espais-gimnastica"
## [403] "np-jardins-botanics"
## [404] "np-jardins-interiors-illa"
## [405] "np-molls"
## [406] "np-nasia-diposits-aigues-pluvials"
## [407] "np-nasia-fossars"
## [408] "np-nasia-miradors"
## [409] "np-piscines"
## [410] "np-plantes-depuradores"
## [411] "np-platges"
## [412] "np-quioscs-tramits"
## [413] "np-umbracles"
## [414] "obres"
## [415] "oferta-publica"
## [416] "ordenances-municipals"
## [417] "pad_alt_mdbas"
## [418] "pad_bai_mdbas"
## [419] "pad_cdo_b_barri-des"
## [420] "pad_def_mdbas"
## [421] "pad-dimensions"
## [422] "pad_dom_mdbas_dones"
## [423] "pad_dom_mdbas_edat-0018"
## [424] "pad_dom_mdbas_edat-1864"
## [425] "pad_dom_mdbas_edat-6599"
## [426] "pad_dom_mdbas_homes"
## [427] "pad_dom_mdbas_nacionalitat"
## [428] "pad_dom_mdbas_nacionalitat_edat"
## [429] "pad_dom_mdbas_n-persones"
## [430] "pad_dom_mdbas_tipus-domicili"
## [431] "pad_dom_mdbas_tipus-domicili_edat"
## [432] "pad_emi_mdbas"
## [433] "pad_emi_mdbas_nacionalitat-g"
## [434] "pad_imm_mdbas"
## [435] "pad_imm_mdbas_nacionalitat-g"
## [436] "pad_m_cognom"
## [437] "pad_mdbas"
## [438] "pad_mdbas_edat-1"
## [439] "pad_mdbas_edat-q"
## [440] "pad_mdba_sexe_edat-1"
## [441] "pad_mdba_sexe_edat-q"
## [442] "pad_mdbas_lloc-naix_sexe"
## [443] "pad_mdbas_nacionalitat-continent_sexe"
## [444] "pad_mdbas_nacionalitat-g_sexe"
## [445] "pad_mdbas_niv-educa-esta_sexe"
## [446] "pad_mdbas_sexe"
## [447] "pad_mdb_lloc-naix-continent_edat-q_sexe"
## [448] "pad_mdb_lloc-naix_edat-q_sexe"
## [449] "pad_mdb_lloc-naix-regio_sexe"
## [450] "pad_mdb_nacionalitat-contintent_edat-q_sexe"
## [451] "pad_mdb_nacionalitat-g_edat-q_sexe"
## [452] "pad_mdb_nacionalitat-regio_sexe"
## [453] "pad_mdb_niv-educa-esta_edat-lloc-naix"
## [454] "pad_mdb_niv-educa-esta_edat-q_sexe"
## [455] "pad_m_nom_decada_sexe"
## [456] "pad_m_nom_sexe"
## [457] "pad_nai_mdbas"
## [458] "pad_sol_mdb_sexe_edat-q"
## [459] "parades-de-taxi"
## [460] "patis-escolars"
## [461] "patrimoni-arquitectonic-protegit"
## [462] "pbd-cataleg-continguts"
## [463] "p-cons-inicials-segons-lgep-loepsf"
## [464] "perfil-contractant"
## [465] "piezometres_detall"
## [466] "piezometres_equipaments"
## [467] "plantilla-municipal"
## [468] "plaques-fotovoltaiques"
## [469] "plaques-fotovoltaiques-tipologia"
## [470] "poblacio-exposada-mapa-estrategic-soroll"
## [471] "poblacio_projectada"
## [472] "poblacio-vulnerable"
## [473] "precipitacio-hist-bcn"
## [474] "prediccio-meteorologica-del-barcelones"
## [475] "presencia-absencia-vegetacio"
## [476] "pressupost-despeses"
## [477] "pressupost-ingressos"
## [478] "prorrogues-de-contractes"
## [479] "provisio-promocio"
## [480] "proximitat-espais-verds"
## [481] "punts-ancoratge-bicicletes"
## [482] "punts-critics-neteja-barcelona"
## [483] "punts-informacio-turistica"
## [484] "punts-recarrega-vehicles-electrics"
## [485] "punts-verds"
## [486] "punts-wifi"
## [487] "qualificacions-elements-urbanistics"
## [488] "qualitat-aire-detall-bcn"
## [489] "qualitat-aire-estacions-bcn"
## [490] "rasters-mapa-estrategic-soroll"
## [491] "rebuts-quota-padro-iae"
## [492] "rebuts-quota-padro-vetlladors-terrasses"
## [493] "recintes-gran-aforament"
## [494] "registre-de-convenis"
## [495] "registre-estudis-i-informes"
## [496] "relacio-contractistes"
## [497] "renda-disponible-llars-bcn"
## [498] "renda-tributaria-per-persona-atlas-distribucio"
## [499] "renda-tributaria-unitat-consum-atlas-distribucio"
## [500] "resums-trimestrals-contractacio"
## [501] "risc-contaminacio-acustica"
## [502] "ronda-verda"
## [503] "sanitat-farmacies"
## [504] "sanitat-hospitals-atencio-primaria"
## [505] "sanitat-serveis-sanitaris"
## [506] "servei-cataleg-metadades-csw"
## [507] "serveissocials-centresdiagentgran"
## [508] "serveissocials-centresserveissocials"
## [509] "serveissocials-equipsatencioinfanciaadolescencia"
## [510] "serveissocials-habitatgestutelats"
## [511] "serveissocials-menjadorssocials"
## [512] "serveissocials-oficinesbenestarsocial"
## [513] "serveissocials-puntsassessoramentenergetic"
## [514] "serveissocials-puntsinformacioiatenciodones"
## [515] "serveissocials-residenciesgentgran"
## [516] "subvencions-a-ens-publics-no-integrats-cercador-post-2019"
## [517] "subvencions-atorgades-ajuntament-i-instituts"
## [518] "subvencions_entitats_nfge"
## [519] "subvencions-i-transferencies-a-ens-publics"
## [520] "subvencions-transferencies-cultura"
## [521] "tanatoris"
## [522] "tarifes-aparcament-superficie"
## [523] "taula-direle"
## [524] "taula-direle-sec-cens"
## [525] "taula-map-illa"
## [526] "taula-segimon"
## [527] "teleferics"
## [528] "temperatures-hist-bcn"
## [529] "terrasses-comercos-vigents"
## [530] "tramer-mapa-estrategic-soroll"
## [531] "trams"
## [532] "trams-aparcament-superficie"
## [533] "transferencies-encomanes-gestio"
## [534] "transitaeri_flightradar_ppal_aeroport"
## [535] "transitaeri_flightradar_ppal_comp_zona"
## [536] "transitaeri_flightradar_ppal_pais"
## [537] "transit-relacio-trams"
## [538] "transit-relacio-trams-per-itinerari"
## [539] "transports"
## [540] "transports-metropolitants-companyies-autocars-de-barcelona"
## [541] "us-del-servei-bicing"
## [542] "viatges-govern-bcn"
## [543] "vies-ciclables"
## [544] "xarxa-refugis-climatics"
## [545] "xarxasoroll-equipsmonitor-dades"
## [546] "xarxasoroll-equipsmonitor-instal"
## [547] "zbe-ambit"
## [548] "zones30-carrers"
## [549] "zones-carrega-descarrega"
## [550] "zones-estacionament-zona-bus"
For later use, I will need information about air quality stations:
st_package <- package_show("qualitat-aire-estacions-bcn")
The resources element of the package shows relevant information about each resource of the package:
st_package$resources[[1]]
## $cache_last_updated
## NULL
##
## $incorporated_in_cityos_res
## [1] "No"
##
## $token_type
## [1] ""
##
## $package_id
## [1] "4dff88b1-151b-48db-91c2-45007cd5d07a"
##
## $datastore_active
## [1] TRUE
##
## $id
## [1] "d1aa40d7-66f9-451b-85f8-955b765fdc2f"
##
## $api_access_number_absolute
## [1] "52"
##
## $token_name
## [1] ""
##
## $state
## [1] "active"
##
## $api_access_number
## [1] "22"
##
## $size
## [1] "8494"
##
## $token_required
## [1] "No"
##
## $hash
## [1] ""
##
## $description
## [1] ""
##
## $format
## [1] "CSV"
##
## $downloads
## [1] "166"
##
## $mimetype_inner
## NULL
##
## $url_type
## [1] "upload"
##
## $token_provider
## [1] ""
##
## $column_types
## [1] ""
##
## $hide_url
## [1] "No"
##
## $token_version
## [1] ""
##
## $mimetype
## NULL
##
## $cache_url
## NULL
##
## $name
## [1] "2025_qualitat_aire_estacions.csv"
##
## $created
## [1] "2025-02-12T09:21:21.936318"
##
## $url
## [1] "https://opendata-ajuntament.barcelona.cat/data/dataset/4dff88b1-151b-48db-91c2-45007cd5d07a/resource/d1aa40d7-66f9-451b-85f8-955b765fdc2f/download/2025_qualitat_aire_estacions.csv"
##
## $downloads_absolute
## [1] "670"
##
## $map_visualization_res
## [1] "data_explorer_map"
##
## $qa
## $qa$updated
## [1] "2025-07-27T02:12:17.690430"
##
## $qa$openness_score
## [1] 3
##
## $qa$archival_timestamp
## NULL
##
## $qa$format
## [1] "CSV"
##
## $qa$created
## [1] "2025-02-13T02:11:06.806242"
##
## $qa$resource_timestamp
## NULL
##
## $qa$openness_score_reason
## [1] "This file had not been downloaded at the time of scoring it. URL extension \"csv\" relates to format \"CSV\" and receives score: 3."
##
##
## $last_modified
## [1] "2025-02-12T09:21:21.669919"
##
## $position
## [1] 0
##
## $revision_id
## [1] "48b2f855-84a4-4dbb-8544-6ac1dcfc9236"
##
## $resource_type
## NULL
The url element contains an URL to read a .csv file. I am reading the file and transform it on the fly to obtain the stations table.
stations <- read_csv(st_package$resources[[1]]$url)
## Rows: 55 Columns: 15
## ── Column specification ────────────────────────────────────────────────────────
## Delimiter: ","
## chr (7): nom_cabina, codi_dtes, ubicacio, Nom_districte, Nom_barri, Clas_1, ...
## dbl (8): Estacio, zqa, codi_eoi, Longitud, Latitud, Codi_districte, Codi_bar...
##
## ℹ 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.
stations <- stations |>
clean_names() |>
mutate(nom_cabina = str_replace(nom_cabina, "Observatori", "Observ")) |>
select(estacio, nom_cabina) |>
distinct()
stations
## # A tibble: 8 × 2
## estacio nom_cabina
## <dbl> <chr>
## 1 4 Barcelona - Poblenou
## 2 42 Barcelona - Sants
## 3 43 Barcelona - Eixample
## 4 44 Barcelona - Gràcia
## 5 50 Barcelona - Ciutadella
## 6 54 Barcelona - Vall Hebron
## 7 57 Barcelona - Palau Reial
## 8 58 Barcelona - Observ Fabra
Air quality data are found at the qualitat-aire-detall-bcn package:
aq_package <- package_show("qualitat-aire-detall-bcn")
Let’s take a look at the resources content for this package:
aq_package$resources[[1]]
## $cache_last_updated
## NULL
##
## $package_id
## [1] "0582a266-ea06-4cc5-a219-913b22484e40"
##
## $datastore_active
## [1] FALSE
##
## $id
## [1] "c2032e7c-10ee-4c69-84d3-9e8caf9ca97a"
##
## $api_access_number_absolute
## [1] "6518"
##
## $state
## [1] "active"
##
## $api_access_number
## [1] "657"
##
## $size
## [1] "49176"
##
## $token_required
## [1] "No"
##
## $hash
## [1] ""
##
## $description
## [1] ""
##
## $format
## [1] "CSV"
##
## $downloads
## [1] "16568"
##
## $mimetype_inner
## NULL
##
## $url_type
## [1] ""
##
## $column_types
## [1] ""
##
## $file_volum
## [1] "little"
##
## $mimetype
## NULL
##
## $cache_url
## NULL
##
## $name
## [1] "Qualitat_Aire_Detall.csv"
##
## $created
## [1] "2018-05-23T15:10:28.678748"
##
## $url
## [1] "https://opendata-ajuntament.barcelona.cat/data/dataset/0582a266-ea06-4cc5-a219-913b22484e40/resource/c2032e7c-10ee-4c69-84d3-9e8caf9ca97a/download"
##
## $downloads_absolute
## [1] "647315"
##
## $map_visualization_res
## [1] "none"
##
## $qa
## $qa$updated
## [1] "2025-07-27T02:12:15.037481"
##
## $qa$openness_score
## [1] 3
##
## $qa$archival_timestamp
## NULL
##
## $qa$format
## [1] "CSV"
##
## $qa$created
## [1] "2018-05-24T02:07:27.871534"
##
## $qa$resource_timestamp
## NULL
##
## $qa$openness_score_reason
## [1] "This file had not been downloaded at the time of scoring it. URL extension \"csv\" relates to format \"CSV\" and receives score: 3."
##
##
## $last_modified
## [1] "2021-06-11T05:43:54"
##
## $position
## [1] 0
##
## $revision_id
## [1] "85fa0dd9-b217-45df-b586-0397afeac607"
##
## $resource_type
## NULL
Some tables are in .csv format and others in .7z format. We need only the .csv formats. To do so:
- The
is_csvlogical vector identifies which resources are.csvfiles. - The
urls_csvlist includes the URLs of the resouces that are.csvfiles.
is_csv <- map_lgl(aq_package$resources, ~ .$format == "CSV")
urls_csv <- map(aq_package$resources[which(is_csv)], ~ .$url) # urls de los 85 .csv
First Reading of Data
Let’s start reading all the .csv files of air quality data included in the package. Then, I will name each resource with the name of its file.
airqual_all <- map(urls_csv, read_csv)
## Rows: 280 Columns: 57
## ── Column specification ────────────────────────────────────────────────────────
## Delimiter: ","
## chr (29): CODI_PROVINCIA, PROVINCIA, CODI_MUNICIPI, MUNICIPI, ESTACIO, V01, ...
## dbl (28): CODI_CONTAMINANT, ANY, MES, DIA, H01, H02, H03, H04, H05, H06, H07...
##
## ℹ 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.
## Rows: 2170 Columns: 57
## ── Column specification ────────────────────────────────────────────────────────
## Delimiter: ","
## chr (26): PROVINCIA, MUNICIPI, V01, V02, V03, V04, V05, V06, V07, V08, V09, ...
## dbl (31): CODI_PROVINCIA, CODI_MUNICIPI, ESTACIO, CODI_CONTAMINANT, ANY, MES...
##
## ℹ 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.
## Rows: 1960 Columns: 57
## ── Column specification ────────────────────────────────────────────────────────
## Delimiter: ","
## chr (26): PROVINCIA, MUNICIPI, V01, V02, V03, V04, V05, V06, V07, V08, V09, ...
## dbl (31): CODI_PROVINCIA, CODI_MUNICIPI, ESTACIO, CODI_CONTAMINANT, ANY, MES...
##
## ℹ 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.
## Rows: 2170 Columns: 57
## ── Column specification ────────────────────────────────────────────────────────
## Delimiter: ","
## chr (26): PROVINCIA, MUNICIPI, V01, V02, V03, V04, V05, V06, V07, V08, V09, ...
## dbl (31): CODI_PROVINCIA, CODI_MUNICIPI, ESTACIO, CODI_CONTAMINANT, ANY, MES...
##
## ℹ 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.
## Rows: 2030 Columns: 57
## ── Column specification ────────────────────────────────────────────────────────
## Delimiter: ","
## chr (26): PROVINCIA, MUNICIPI, V01, V02, V03, V04, V05, V06, V07, V08, V09, ...
## dbl (31): CODI_PROVINCIA, CODI_MUNICIPI, ESTACIO, CODI_CONTAMINANT, ANY, MES...
##
## ℹ 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.
## Rows: 1750 Columns: 57
## ── Column specification ────────────────────────────────────────────────────────
## Delimiter: ","
## chr (26): PROVINCIA, MUNICIPI, V01, V02, V03, V04, V05, V06, V07, V08, V09, ...
## dbl (31): CODI_PROVINCIA, CODI_MUNICIPI, ESTACIO, CODI_CONTAMINANT, ANY, MES...
##
## ℹ 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.
## Rows: 1987 Columns: 57
## ── Column specification ────────────────────────────────────────────────────────
## Delimiter: ","
## chr (26): PROVINCIA, MUNICIPI, V01, V02, V03, V04, V05, V06, V07, V08, V09, ...
## dbl (31): CODI_PROVINCIA, CODI_MUNICIPI, ESTACIO, CODI_CONTAMINANT, ANY, MES...
##
## ℹ 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.
## Rows: 1856 Columns: 57
## ── Column specification ────────────────────────────────────────────────────────
## Delimiter: ","
## chr (26): PROVINCIA, MUNICIPI, V01, V02, V03, V04, V05, V06, V07, V08, V09, ...
## dbl (31): CODI_PROVINCIA, CODI_MUNICIPI, ESTACIO, CODI_CONTAMINANT, ANY, MES...
##
## ℹ 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.
## Rows: 1984 Columns: 57
## ── Column specification ────────────────────────────────────────────────────────
## Delimiter: ","
## chr (26): PROVINCIA, MUNICIPI, V01, V02, V03, V04, V05, V06, V07, V08, V09, ...
## dbl (31): CODI_PROVINCIA, CODI_MUNICIPI, ESTACIO, CODI_CONTAMINANT, ANY, MES...
##
## ℹ 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.
## Rows: 1920 Columns: 57
## ── Column specification ────────────────────────────────────────────────────────
## Delimiter: ","
## chr (26): PROVINCIA, MUNICIPI, V01, V02, V03, V04, V05, V06, V07, V08, V09, ...
## dbl (31): CODI_PROVINCIA, CODI_MUNICIPI, ESTACIO, CODI_CONTAMINANT, ANY, MES...
##
## ℹ 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.
## Rows: 1984 Columns: 57
## ── Column specification ────────────────────────────────────────────────────────
## Delimiter: ","
## chr (26): PROVINCIA, MUNICIPI, V01, V02, V03, V04, V05, V06, V07, V08, V09, ...
## dbl (31): CODI_PROVINCIA, CODI_MUNICIPI, ESTACIO, CODI_CONTAMINANT, ANY, MES...
##
## ℹ 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.
## Rows: 1870 Columns: 57
## ── Column specification ────────────────────────────────────────────────────────
## Delimiter: ","
## chr (26): PROVINCIA, MUNICIPI, V01, V02, V03, V04, V05, V06, V07, V08, V09, ...
## dbl (31): CODI_PROVINCIA, CODI_MUNICIPI, ESTACIO, CODI_CONTAMINANT, ANY, MES...
##
## ℹ 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.
## Rows: 2077 Columns: 57
## ── Column specification ────────────────────────────────────────────────────────
## Delimiter: ","
## chr (26): PROVINCIA, MUNICIPI, V01, V02, V03, V04, V05, V06, V07, V08, V09, ...
## dbl (31): CODI_PROVINCIA, CODI_MUNICIPI, ESTACIO, CODI_CONTAMINANT, ANY, MES...
##
## ℹ 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.
## Rows: 2077 Columns: 57
## ── Column specification ────────────────────────────────────────────────────────
## Delimiter: ","
## chr (26): PROVINCIA, MUNICIPI, V01, V02, V03, V04, V05, V06, V07, V08, V09, ...
## dbl (31): CODI_PROVINCIA, CODI_MUNICIPI, ESTACIO, CODI_CONTAMINANT, ANY, MES...
##
## ℹ 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.
## Rows: 2010 Columns: 57
## ── Column specification ────────────────────────────────────────────────────────
## Delimiter: ","
## chr (26): PROVINCIA, MUNICIPI, V01, V02, V03, V04, V05, V06, V07, V08, V09, ...
## dbl (31): CODI_PROVINCIA, CODI_MUNICIPI, ESTACIO, CODI_CONTAMINANT, ANY, MES...
##
## ℹ 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.
## Rows: 2077 Columns: 57
## ── Column specification ────────────────────────────────────────────────────────
## Delimiter: ","
## chr (26): PROVINCIA, MUNICIPI, V01, V02, V03, V04, V05, V06, V07, V08, V09, ...
## dbl (31): CODI_PROVINCIA, CODI_MUNICIPI, ESTACIO, CODI_CONTAMINANT, ANY, MES...
##
## ℹ 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.
## Rows: 2052 Columns: 57
## ── Column specification ────────────────────────────────────────────────────────
## Delimiter: ","
## chr (26): PROVINCIA, MUNICIPI, V01, V02, V03, V04, V05, V06, V07, V08, V09, ...
## dbl (31): CODI_PROVINCIA, CODI_MUNICIPI, ESTACIO, CODI_CONTAMINANT, ANY, MES...
##
## ℹ 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.
## Rows: 2170 Columns: 57
## ── Column specification ────────────────────────────────────────────────────────
## Delimiter: ","
## chr (26): PROVINCIA, MUNICIPI, V01, V02, V03, V04, V05, V06, V07, V08, V09, ...
## dbl (31): CODI_PROVINCIA, CODI_MUNICIPI, ESTACIO, CODI_CONTAMINANT, ANY, MES...
##
## ℹ 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.
## Rows: 2015 Columns: 57
## ── Column specification ────────────────────────────────────────────────────────
## Delimiter: ","
## chr (26): PROVINCIA, MUNICIPI, V01, V02, V03, V04, V05, V06, V07, V08, V09, ...
## dbl (31): CODI_PROVINCIA, CODI_MUNICIPI, ESTACIO, CODI_CONTAMINANT, ANY, MES...
##
## ℹ 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.
## Rows: 1820 Columns: 57
## ── Column specification ────────────────────────────────────────────────────────
## Delimiter: ","
## chr (26): PROVINCIA, MUNICIPI, V01, V02, V03, V04, V05, V06, V07, V08, V09, ...
## dbl (31): CODI_PROVINCIA, CODI_MUNICIPI, ESTACIO, CODI_CONTAMINANT, ANY, MES...
##
## ℹ 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.
## Rows: 2029 Columns: 57
## ── Column specification ────────────────────────────────────────────────────────
## Delimiter: ","
## chr (26): PROVINCIA, MUNICIPI, V01, V02, V03, V04, V05, V06, V07, V08, V09, ...
## dbl (31): CODI_PROVINCIA, CODI_MUNICIPI, ESTACIO, CODI_CONTAMINANT, ANY, MES...
##
## ℹ 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.
## Rows: 1980 Columns: 57
## ── Column specification ────────────────────────────────────────────────────────
## Delimiter: ","
## chr (26): PROVINCIA, MUNICIPI, V01, V02, V03, V04, V05, V06, V07, V08, V09, ...
## dbl (31): CODI_PROVINCIA, CODI_MUNICIPI, ESTACIO, CODI_CONTAMINANT, ANY, MES...
##
## ℹ 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.
## Rows: 2046 Columns: 57
## ── Column specification ────────────────────────────────────────────────────────
## Delimiter: ","
## chr (26): PROVINCIA, MUNICIPI, V01, V02, V03, V04, V05, V06, V07, V08, V09, ...
## dbl (31): CODI_PROVINCIA, CODI_MUNICIPI, ESTACIO, CODI_CONTAMINANT, ANY, MES...
##
## ℹ 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.
## Rows: 1980 Columns: 57
## ── Column specification ────────────────────────────────────────────────────────
## Delimiter: ","
## chr (26): PROVINCIA, MUNICIPI, V01, V02, V03, V04, V05, V06, V07, V08, V09, ...
## dbl (31): CODI_PROVINCIA, CODI_MUNICIPI, ESTACIO, CODI_CONTAMINANT, ANY, MES...
##
## ℹ 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.
## Rows: 2039 Columns: 57
## ── Column specification ────────────────────────────────────────────────────────
## Delimiter: ","
## chr (26): PROVINCIA, MUNICIPI, V01, V02, V03, V04, V05, V06, V07, V08, V09, ...
## dbl (31): CODI_PROVINCIA, CODI_MUNICIPI, ESTACIO, CODI_CONTAMINANT, ANY, MES...
##
## ℹ 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.
## Rows: 2015 Columns: 57
## ── Column specification ────────────────────────────────────────────────────────
## Delimiter: ","
## chr (26): PROVINCIA, MUNICIPI, V01, V02, V03, V04, V05, V06, V07, V08, V09, ...
## dbl (31): CODI_PROVINCIA, CODI_MUNICIPI, ESTACIO, CODI_CONTAMINANT, ANY, MES...
##
## ℹ 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.
## Rows: 1950 Columns: 57
## ── Column specification ────────────────────────────────────────────────────────
## Delimiter: ","
## chr (26): PROVINCIA, MUNICIPI, V01, V02, V03, V04, V05, V06, V07, V08, V09, ...
## dbl (31): CODI_PROVINCIA, CODI_MUNICIPI, ESTACIO, CODI_CONTAMINANT, ANY, MES...
##
## ℹ 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.
## Rows: 2015 Columns: 57
## ── Column specification ────────────────────────────────────────────────────────
## Delimiter: ","
## chr (26): PROVINCIA, MUNICIPI, V01, V02, V03, V04, V05, V06, V07, V08, V09, ...
## dbl (31): CODI_PROVINCIA, CODI_MUNICIPI, ESTACIO, CODI_CONTAMINANT, ANY, MES...
##
## ℹ 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.
## Rows: 1950 Columns: 57
## ── Column specification ────────────────────────────────────────────────────────
## Delimiter: ","
## chr (26): PROVINCIA, MUNICIPI, V01, V02, V03, V04, V05, V06, V07, V08, V09, ...
## dbl (31): CODI_PROVINCIA, CODI_MUNICIPI, ESTACIO, CODI_CONTAMINANT, ANY, MES...
##
## ℹ 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.
## Rows: 2015 Columns: 57
## ── Column specification ────────────────────────────────────────────────────────
## Delimiter: ","
## chr (26): PROVINCIA, MUNICIPI, V01, V02, V03, V04, V05, V06, V07, V08, V09, ...
## dbl (31): CODI_PROVINCIA, CODI_MUNICIPI, ESTACIO, CODI_CONTAMINANT, ANY, MES...
##
## ℹ 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.
## Rows: 1705 Columns: 57
## ── Column specification ────────────────────────────────────────────────────────
## Delimiter: ","
## chr (26): PROVINCIA, MUNICIPI, V01, V02, V03, V04, V05, V06, V07, V08, V09, ...
## dbl (31): CODI_PROVINCIA, CODI_MUNICIPI, ESTACIO, CODI_CONTAMINANT, ANY, MES...
##
## ℹ 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.
## Rows: 1562 Columns: 57
## ── Column specification ────────────────────────────────────────────────────────
## Delimiter: ","
## chr (26): PROVINCIA, MUNICIPI, V01, V02, V03, V04, V05, V06, V07, V08, V09, ...
## dbl (31): CODI_PROVINCIA, CODI_MUNICIPI, ESTACIO, CODI_CONTAMINANT, ANY, MES...
##
## ℹ 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.
## Rows: 1987 Columns: 57
## ── Column specification ────────────────────────────────────────────────────────
## Delimiter: ","
## chr (26): PROVINCIA, MUNICIPI, V01, V02, V03, V04, V05, V06, V07, V08, V09, ...
## dbl (31): CODI_PROVINCIA, CODI_MUNICIPI, ESTACIO, CODI_CONTAMINANT, ANY, MES...
##
## ℹ 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.
## Rows: 1950 Columns: 57
## ── Column specification ────────────────────────────────────────────────────────
## Delimiter: ","
## chr (26): PROVINCIA, MUNICIPI, V01, V02, V03, V04, V05, V06, V07, V08, V09, ...
## dbl (31): CODI_PROVINCIA, CODI_MUNICIPI, ESTACIO, CODI_CONTAMINANT, ANY, MES...
##
## ℹ 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.
## Rows: 2015 Columns: 57
## ── Column specification ────────────────────────────────────────────────────────
## Delimiter: ","
## chr (26): PROVINCIA, MUNICIPI, V01, V02, V03, V04, V05, V06, V07, V08, V09, ...
## dbl (31): CODI_PROVINCIA, CODI_MUNICIPI, ESTACIO, CODI_CONTAMINANT, ANY, MES...
##
## ℹ 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.
## Rows: 1950 Columns: 57
## ── Column specification ────────────────────────────────────────────────────────
## Delimiter: ","
## chr (26): PROVINCIA, MUNICIPI, V01, V02, V03, V04, V05, V06, V07, V08, V09, ...
## dbl (31): CODI_PROVINCIA, CODI_MUNICIPI, ESTACIO, CODI_CONTAMINANT, ANY, MES...
##
## ℹ 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.
## Rows: 2015 Columns: 57
## ── Column specification ────────────────────────────────────────────────────────
## Delimiter: ","
## chr (26): PROVINCIA, MUNICIPI, V01, V02, V03, V04, V05, V06, V07, V08, V09, ...
## dbl (31): CODI_PROVINCIA, CODI_MUNICIPI, ESTACIO, CODI_CONTAMINANT, ANY, MES...
##
## ℹ 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.
## Rows: 2015 Columns: 57
## ── Column specification ────────────────────────────────────────────────────────
## Delimiter: ","
## chr (26): PROVINCIA, MUNICIPI, V01, V02, V03, V04, V05, V06, V07, V08, V09, ...
## dbl (31): CODI_PROVINCIA, CODI_MUNICIPI, ESTACIO, CODI_CONTAMINANT, ANY, MES...
##
## ℹ 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.
## Rows: 1950 Columns: 57
## ── Column specification ────────────────────────────────────────────────────────
## Delimiter: ","
## chr (26): PROVINCIA, MUNICIPI, V01, V02, V03, V04, V05, V06, V07, V08, V09, ...
## dbl (31): CODI_PROVINCIA, CODI_MUNICIPI, ESTACIO, CODI_CONTAMINANT, ANY, MES...
##
## ℹ 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.
## Rows: 2015 Columns: 57
## ── Column specification ────────────────────────────────────────────────────────
## Delimiter: ","
## chr (26): PROVINCIA, MUNICIPI, V01, V02, V03, V04, V05, V06, V07, V08, V09, ...
## dbl (31): CODI_PROVINCIA, CODI_MUNICIPI, ESTACIO, CODI_CONTAMINANT, ANY, MES...
##
## ℹ 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.
## Rows: 1950 Columns: 57
## ── Column specification ────────────────────────────────────────────────────────
## Delimiter: ","
## chr (26): PROVINCIA, MUNICIPI, V01, V02, V03, V04, V05, V06, V07, V08, V09, ...
## dbl (31): CODI_PROVINCIA, CODI_MUNICIPI, ESTACIO, CODI_CONTAMINANT, ANY, MES...
##
## ℹ 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.
## Rows: 2015 Columns: 57
## ── Column specification ────────────────────────────────────────────────────────
## Delimiter: ","
## chr (26): PROVINCIA, MUNICIPI, V01, V02, V03, V04, V05, V06, V07, V08, V09, ...
## dbl (31): CODI_PROVINCIA, CODI_MUNICIPI, ESTACIO, CODI_CONTAMINANT, ANY, MES...
##
## ℹ 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.
## Rows: 1519 Columns: 57
## ── Column specification ────────────────────────────────────────────────────────
## Delimiter: ","
## chr (26): PROVINCIA, MUNICIPI, V01, V02, V03, V04, V05, V06, V07, V08, V09, ...
## dbl (31): CODI_PROVINCIA, CODI_MUNICIPI, ESTACIO, CODI_CONTAMINANT, ANY, MES...
##
## ℹ 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.
## Rows: 1372 Columns: 57
## ── Column specification ────────────────────────────────────────────────────────
## Delimiter: ","
## chr (26): PROVINCIA, MUNICIPI, V01, V02, V03, V04, V05, V06, V07, V08, V09, ...
## dbl (31): CODI_PROVINCIA, CODI_MUNICIPI, ESTACIO, CODI_CONTAMINANT, ANY, MES...
##
## ℹ 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.
## Rows: 1519 Columns: 57
## ── Column specification ────────────────────────────────────────────────────────
## Delimiter: ","
## chr (26): PROVINCIA, MUNICIPI, V01, V02, V03, V04, V05, V06, V07, V08, V09, ...
## dbl (31): CODI_PROVINCIA, CODI_MUNICIPI, ESTACIO, CODI_CONTAMINANT, ANY, MES...
##
## ℹ 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.
## Rows: 1480 Columns: 57
## ── Column specification ────────────────────────────────────────────────────────
## Delimiter: ","
## chr (26): PROVINCIA, MUNICIPI, V01, V02, V03, V04, V05, V06, V07, V08, V09, ...
## dbl (31): CODI_PROVINCIA, CODI_MUNICIPI, ESTACIO, CODI_CONTAMINANT, ANY, MES...
##
## ℹ 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.
## Rows: 1674 Columns: 57
## ── Column specification ────────────────────────────────────────────────────────
## Delimiter: ","
## chr (26): PROVINCIA, MUNICIPI, V01, V02, V03, V04, V05, V06, V07, V08, V09, ...
## dbl (31): CODI_PROVINCIA, CODI_MUNICIPI, ESTACIO, CODI_CONTAMINANT, ANY, MES...
##
## ℹ 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.
## Rows: 1620 Columns: 57
## ── Column specification ────────────────────────────────────────────────────────
## Delimiter: ","
## chr (26): PROVINCIA, MUNICIPI, V01, V02, V03, V04, V05, V06, V07, V08, V09, ...
## dbl (31): CODI_PROVINCIA, CODI_MUNICIPI, ESTACIO, CODI_CONTAMINANT, ANY, MES...
##
## ℹ 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.
## Rows: 1674 Columns: 57
## ── Column specification ────────────────────────────────────────────────────────
## Delimiter: ","
## chr (26): PROVINCIA, MUNICIPI, V01, V02, V03, V04, V05, V06, V07, V08, V09, ...
## dbl (31): CODI_PROVINCIA, CODI_MUNICIPI, ESTACIO, CODI_CONTAMINANT, ANY, MES...
##
## ℹ 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.
## Rows: 1674 Columns: 57
## ── Column specification ────────────────────────────────────────────────────────
## Delimiter: ","
## chr (26): PROVINCIA, MUNICIPI, V01, V02, V03, V04, V05, V06, V07, V08, V09, ...
## dbl (31): CODI_PROVINCIA, CODI_MUNICIPI, ESTACIO, CODI_CONTAMINANT, ANY, MES...
##
## ℹ 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.
## Rows: 1620 Columns: 57
## ── Column specification ────────────────────────────────────────────────────────
## Delimiter: ","
## chr (26): PROVINCIA, MUNICIPI, V01, V02, V03, V04, V05, V06, V07, V08, V09, ...
## dbl (31): CODI_PROVINCIA, CODI_MUNICIPI, ESTACIO, CODI_CONTAMINANT, ANY, MES...
##
## ℹ 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.
## Rows: 1674 Columns: 57
## ── Column specification ────────────────────────────────────────────────────────
## Delimiter: ","
## chr (26): PROVINCIA, MUNICIPI, V01, V02, V03, V04, V05, V06, V07, V08, V09, ...
## dbl (31): CODI_PROVINCIA, CODI_MUNICIPI, ESTACIO, CODI_CONTAMINANT, ANY, MES...
##
## ℹ 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.
## Rows: 1587 Columns: 57
## ── Column specification ────────────────────────────────────────────────────────
## Delimiter: ","
## chr (26): PROVINCIA, MUNICIPI, V01, V02, V03, V04, V05, V06, V07, V08, V09, ...
## dbl (31): CODI_PROVINCIA, CODI_MUNICIPI, ESTACIO, CODI_CONTAMINANT, ANY, MES...
##
## ℹ 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.
## Rows: 1705 Columns: 57
## ── Column specification ────────────────────────────────────────────────────────
## Delimiter: ","
## chr (26): PROVINCIA, MUNICIPI, V01, V02, V03, V04, V05, V06, V07, V08, V09, ...
## dbl (31): CODI_PROVINCIA, CODI_MUNICIPI, ESTACIO, CODI_CONTAMINANT, ANY, MES...
##
## ℹ 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.
## Rows: 1279 Columns: 57
## ── Column specification ────────────────────────────────────────────────────────
## Delimiter: ","
## chr (26): PROVINCIA, MUNICIPI, V01, V02, V03, V04, V05, V06, V07, V08, V09, ...
## dbl (31): CODI_PROVINCIA, CODI_MUNICIPI, ESTACIO, CODI_CONTAMINANT, ANY, MES...
##
## ℹ 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.
## Rows: 1305 Columns: 57
## ── Column specification ────────────────────────────────────────────────────────
## Delimiter: ","
## chr (26): PROVINCIA, MUNICIPI, V01, V02, V03, V04, V05, V06, V07, V08, V09, ...
## dbl (31): CODI_PROVINCIA, CODI_MUNICIPI, ESTACIO, CODI_CONTAMINANT, ANY, MES...
##
## ℹ 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.
## Rows: 1395 Columns: 57
## ── Column specification ────────────────────────────────────────────────────────
## Delimiter: ","
## chr (26): PROVINCIA, MUNICIPI, V01, V02, V03, V04, V05, V06, V07, V08, V09, ...
## dbl (31): CODI_PROVINCIA, CODI_MUNICIPI, ESTACIO, CODI_CONTAMINANT, ANY, MES...
##
## ℹ 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.
## Rows: 1378 Columns: 57
## ── Column specification ────────────────────────────────────────────────────────
## Delimiter: ","
## chr (26): PROVINCIA, MUNICIPI, V01, V02, V03, V04, V05, V06, V07, V08, V09, ...
## dbl (31): CODI_PROVINCIA, CODI_MUNICIPI, ESTACIO, CODI_CONTAMINANT, ANY, MES...
##
## ℹ 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.
## Rows: 1519 Columns: 57
## ── Column specification ────────────────────────────────────────────────────────
## Delimiter: ","
## chr (26): PROVINCIA, MUNICIPI, V01, V02, V03, V04, V05, V06, V07, V08, V09, ...
## dbl (31): CODI_PROVINCIA, CODI_MUNICIPI, ESTACIO, CODI_CONTAMINANT, ANY, MES...
##
## ℹ 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.
## Rows: 1470 Columns: 57
## ── Column specification ────────────────────────────────────────────────────────
## Delimiter: ","
## chr (26): PROVINCIA, MUNICIPI, V01, V02, V03, V04, V05, V06, V07, V08, V09, ...
## dbl (31): CODI_PROVINCIA, CODI_MUNICIPI, ESTACIO, CODI_CONTAMINANT, ANY, MES...
##
## ℹ 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.
## Rows: 1519 Columns: 57
## ── Column specification ────────────────────────────────────────────────────────
## Delimiter: ","
## chr (26): PROVINCIA, MUNICIPI, V01, V02, V03, V04, V05, V06, V07, V08, V09, ...
## dbl (31): CODI_PROVINCIA, CODI_MUNICIPI, ESTACIO, CODI_CONTAMINANT, ANY, MES...
##
## ℹ 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.
## Rows: 1372 Columns: 57
## ── Column specification ────────────────────────────────────────────────────────
## Delimiter: ","
## chr (26): PROVINCIA, MUNICIPI, V01, V02, V03, V04, V05, V06, V07, V08, V09, ...
## dbl (31): CODI_PROVINCIA, CODI_MUNICIPI, ESTACIO, CODI_CONTAMINANT, ANY, MES...
##
## ℹ 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.
## Rows: 1470 Columns: 57
## ── Column specification ────────────────────────────────────────────────────────
## Delimiter: ","
## chr (26): PROVINCIA, MUNICIPI, V01, V02, V03, V04, V05, V06, V07, V08, V09, ...
## dbl (31): CODI_PROVINCIA, CODI_MUNICIPI, ESTACIO, CODI_CONTAMINANT, ANY, MES...
##
## ℹ 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.
## Rows: 1519 Columns: 57
## ── Column specification ────────────────────────────────────────────────────────
## Delimiter: ","
## chr (26): PROVINCIA, MUNICIPI, V01, V02, V03, V04, V05, V06, V07, V08, V09, ...
## dbl (31): CODI_PROVINCIA, CODI_MUNICIPI, ESTACIO, CODI_CONTAMINANT, ANY, MES...
##
## ℹ 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.
## Rows: 1274 Columns: 57
## ── Column specification ────────────────────────────────────────────────────────
## Delimiter: ","
## chr (26): PROVINCIA, MUNICIPI, V01, V02, V03, V04, V05, V06, V07, V08, V09, ...
## dbl (31): CODI_PROVINCIA, CODI_MUNICIPI, ESTACIO, CODI_CONTAMINANT, ANY, MES...
##
## ℹ 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.
## Rows: 1519 Columns: 57
## ── Column specification ────────────────────────────────────────────────────────
## Delimiter: ","
## chr (26): PROVINCIA, MUNICIPI, V01, V02, V03, V04, V05, V06, V07, V08, V09, ...
## dbl (31): CODI_PROVINCIA, CODI_MUNICIPI, ESTACIO, CODI_CONTAMINANT, ANY, MES...
##
## ℹ 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.
## Rows: 5904 Columns: 18
## ── Column specification ────────────────────────────────────────────────────────
## Delimiter: ","
## chr (15): nom_cabina, qualitat_aire, codi_dtes, zqa, codi_eoi, hora_o3, qual...
## dbl (3): longitud, latitud, dateTime
##
## ℹ 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.
## Rows: 5376 Columns: 18
## ── Column specification ────────────────────────────────────────────────────────
## Delimiter: ","
## chr (15): nom_cabina, qualitat_aire, codi_dtes, zqa, codi_eoi, hora_o3, qual...
## dbl (3): longitud, latitud, dateTime
##
## ℹ 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.
## Rows: 5928 Columns: 18
## ── Column specification ────────────────────────────────────────────────────────
## Delimiter: ","
## chr (9): nom_cabina, qualitat_aire, codi_dtes, zqa, codi_eoi, hora_pm10, qua...
## dbl (3): longitud, latitud, dateTime
## lgl (6): hora_o3, qualitat_o3, valor_o3, hora_no2, qualitat_no2, valor_no2
##
## ℹ 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.
## Rows: 1131 Columns: 57
## ── Column specification ────────────────────────────────────────────────────────
## Delimiter: ","
## chr (28): CODI_PROVINCIA, PROVINCIA, CODI_MUNICIPI, MUNICIPI, V01, V02, V03,...
## dbl (29): ESTACIO, CODI_CONTAMINANT, ANY, MES, DIA, H01, H02, H03, H04, H05,...
##
## ℹ 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.
## Rows: 1092 Columns: 57
## ── Column specification ────────────────────────────────────────────────────────
## Delimiter: ","
## chr (28): CODI_PROVINCIA, PROVINCIA, CODI_MUNICIPI, MUNICIPI, V01, V02, V03,...
## dbl (29): ESTACIO, CODI_CONTAMINANT, ANY, MES, DIA, H01, H02, H03, H04, H05,...
##
## ℹ 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.
## Rows: 1164 Columns: 1
## ── Column specification ────────────────────────────────────────────────────────
## Delimiter: ","
## chr (1): CODI_PROVINCIA;PROVINCIA;CODI_MUNICIPI;MUNICIPI;ESTACIO;CODI_CONTAM...
##
## ℹ 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.
## Rows: 1053 Columns: 1
## ── Column specification ────────────────────────────────────────────────────────
## Delimiter: ","
## chr (1): CODI_PROVINCIA;PROVINCIA;CODI_MUNICIPI;MUNICIPI;ESTACIO;CODI_CONTAM...
##
## ℹ 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.
## Rows: 1209 Columns: 57
## ── Column specification ────────────────────────────────────────────────────────
## Delimiter: ","
## chr (26): PROVINCIA, MUNICIPI, V01, V02, V03, V04, V05, V06, V07, V08, V09, ...
## dbl (31): CODI_PROVINCIA, CODI_MUNICIPI, ESTACIO, CODI_CONTAMINANT, ANY, MES...
##
## ℹ 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.
## Rows: 1131 Columns: 57
## ── Column specification ────────────────────────────────────────────────────────
## Delimiter: ","
## chr (26): PROVINCIA, MUNICIPI, V01, V02, V03, V04, V05, V06, V07, V08, V09, ...
## dbl (31): CODI_PROVINCIA, CODI_MUNICIPI, ESTACIO, CODI_CONTAMINANT, ANY, MES...
##
## ℹ 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.
## Rows: 1209 Columns: 57
## ── Column specification ────────────────────────────────────────────────────────
## Delimiter: ","
## chr (26): PROVINCIA, MUNICIPI, V01, V02, V03, V04, V05, V06, V07, V08, V09, ...
## dbl (31): CODI_PROVINCIA, CODI_MUNICIPI, ESTACIO, CODI_CONTAMINANT, ANY, MES...
##
## ℹ 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.
## Rows: 1215 Columns: 57
## ── Column specification ────────────────────────────────────────────────────────
## Delimiter: ","
## chr (26): PROVINCIA, MUNICIPI, V01, V02, V03, V04, V05, V06, V07, V08, V09, ...
## dbl (31): CODI_PROVINCIA, CODI_MUNICIPI, ESTACIO, CODI_CONTAMINANT, ANY, MES...
##
## ℹ 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.
## Rows: 1276 Columns: 57
## ── Column specification ────────────────────────────────────────────────────────
## Delimiter: ","
## chr (26): PROVINCIA, MUNICIPI, V01, V02, V03, V04, V05, V06, V07, V08, V09, ...
## dbl (31): CODI_PROVINCIA, CODI_MUNICIPI, ESTACIO, CODI_CONTAMINANT, ANY, MES...
##
## ℹ 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.
## Rows: 3262 Columns: 18
## ── Column specification ────────────────────────────────────────────────────────
## Delimiter: ","
## chr (15): nom_cabina, qualitat_aire, codi_dtes, zqa, codi_eoi, hora_o3, qual...
## dbl (3): longitud, latitud, dateTime
##
## ℹ 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.
## Rows: 3649 Columns: 18
## ── Column specification ────────────────────────────────────────────────────────
## Delimiter: ","
## chr (15): nom_cabina, qualitat_aire, codi_dtes, zqa, codi_eoi, hora_o3, qual...
## dbl (3): longitud, latitud, dateTime
##
## ℹ 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.
## Rows: 5800 Columns: 18
## ── Column specification ────────────────────────────────────────────────────────
## Delimiter: ","
## chr (15): nom_cabina, qualitat_aire, codi_dtes, zqa, codi_eoi, hora_o3, qual...
## dbl (3): longitud, latitud, dateTime
##
## ℹ 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.
## Rows: 5736 Columns: 18
## ── Column specification ────────────────────────────────────────────────────────
## Delimiter: ","
## chr (15): nom_cabina, qualitat_aire, codi_dtes, zqa, codi_eoi, hora_o3, qual...
## dbl (3): longitud, latitud, dateTime
##
## ℹ 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.
## Rows: 5944 Columns: 18
## ── Column specification ────────────────────────────────────────────────────────
## Delimiter: ","
## chr (15): nom_cabina, qualitat_aire, codi_dtes, zqa, codi_eoi, hora_o3, qual...
## dbl (3): longitud, latitud, dateTime
##
## ℹ 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.
## Rows: 5744 Columns: 18
## ── Column specification ────────────────────────────────────────────────────────
## Delimiter: ","
## chr (15): nom_cabina, qualitat_aire, codi_dtes, zqa, codi_eoi, hora_o3, qual...
## dbl (3): longitud, latitud, dateTime
##
## ℹ 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.
## Rows: 5848 Columns: 18
## ── Column specification ────────────────────────────────────────────────────────
## Delimiter: ","
## chr (15): nom_cabina, qualitat_aire, codi_dtes, zqa, codi_eoi, hora_o3, qual...
## dbl (3): longitud, latitud, dateTime
##
## ℹ 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.
names(airqual_all) <- map_chr(aq_package$resources[which(is_csv)], ~ .$name)
The output of readr::read:csv() shows that tables are presented in different structures. To detect the differeet tipologies, I have examined how many columns has the table of each resource.
columns <- map_int(airqual_all, ncol)
columns
## Qualitat_Aire_Detall.csv 2025_01_Gener_qualitat_aire_BCN.csv
## 57 57
## 2025_02_Febrer_qualitat_aire_BCN.csv 2025_03_Marc_qualitat_aire_BCN.csv
## 57 57
## 2025_04_Abril_qualitat_aire_BCN.csv 2025_06_Juny_qualitat_aire_BCN.csv
## 57 57
## 2024_01_Gener_qualitat_aire_BCN.csv 2024_02_Febrer_qualitat_aire_BCN.csv
## 57 57
## 2024_03_Marc_qualitat_aire_BCN.csv 2024_04_Abril_qualitat_aire_BCN.csv
## 57 57
## 2024_05_Maig_qualitat_aire_BCN.csv 2024_06_Juny_qualitat_aire_BCN.csv
## 57 57
## 2024_07_Juliol_qualitat_aire_BCN.csv 2024_08_Agost_qualitat_aire_BCN.csv
## 57 57
## 2024_09_Setembre_qualitat_aire_BCN.csv 2024_10_Octubre_qualitat_aire_BCN.csv
## 57 57
## 2024_11_Novembre_qualitat_aire_BCN.csv 2024_12_Desembre_qualitat_aire_BCN.csv
## 57 57
## 2023_01_Gener_qualitat_aire_BCN.csv 2023_02_Febrer_qualitat_aire_BCN.csv
## 57 57
## 2023_03_Marc_qualitat_aire_BCN.csv 2023_04_Abril_qualitat_aire_BCN.csv
## 57 57
## 2023_05_Maig_qualitat_aire_BCN.csv 2023_06_Juny_qualitat_aire_BCN.csv
## 57 57
## 2023_07_Juliol_qualitat_aire_BCN.csv 2023_08_Agost_qualitat_aire_BCN.csv
## 57 57
## 2023_09_Setembre_qualitat_aire_BCN.csv 2023_10_Octubre_qualitat_aire_BCN.csv
## 57 57
## 2023_11_Novembre_qualitat_aire_BCN.csv 2023_12_Desembre_qualitat_aire_BCN.csv
## 57 57
## 2022_01_Gener_qualitat_aire_BCN.csv 2022_02_Febrer_qualitat_aire_BCN.csv
## 57 57
## 2022_03_Marc_qualitat_aire_BCN.csv 2022_04_Abril_qualitat_aire_BCN.csv
## 57 57
## 2022_05_Maig_qualitat_aire_BCN.csv 2022_06_Juny_qualitat_aire_BCN.csv
## 57 57
## 2022_07_Juliol_qualitat_aire_BCN.csv 2022_08_Agost_qualitat_aire_BCN.csv
## 57 57
## 2022_09_Setembre_qualitat_aire_BCN.csv 2022_10_Octubre_qualitat_aire_BCN.csv
## 57 57
## 2022_11_Novembre_qualitat_aire_BCN.csv 2022_12_Desembre_qualitat_aire_BCN.csv
## 57 57
## 2021_01_Gener_qualitat_aire_BCN.csv 2021_02_Febrer_qualitat_aire_BCN.csv
## 57 57
## 2021_03_Marc_qualitat_aire_BCN.csv 2021_04_Abril_qualitat_aire_BCN.csv
## 57 57
## 2021_05_Maig_qualitat_aire_BCN.csv 2021_06_Juny_qualitat_aire_BCN.csv
## 57 57
## 2021_07_Juliol_qualitat_aire_BCN.csv 2021_08_Agost_qualitat_aire_BCN.csv
## 57 57
## 2021_09_Setembre_qualitat_aire_BCN.csv 2021_10_Octubre_qualitat_aire_BCN.csv
## 57 57
## 2021_11_Novembre_qualitat_aire_BCN.csv 2021_12_Desembre_qualitat_aire_BCN.csv
## 57 57
## 2020_01_Gener_qualitat_aire_BCN.csv 2020_02_Febrer_qualitat_aire_BCN.csv
## 57 57
## 2020_03_Marc_qualitat_aire_BCN.csv 2020_04_Abril_qualitat_aire_BCN.csv
## 57 57
## 2020_05_Maig_qualitat_aire_BCN.csv 2020_06_Juny_qualitat_aire_BCN.csv
## 57 57
## 2020_07_Juliol_qualitat_aire_BCN.csv 2020_08_Agost_qualitat_aire_BCN.csv
## 57 57
## 2020_09_Setembre_qualitat_aire_BCN.csv 2020_10_Octubre_qualitat_aire_BCN.csv
## 57 57
## 2020_11_Novembre_qualitat_aire_BCN.csv 2020_12_Desembre_qualitat_aire_BCN.csv
## 57 57
## 2019_01_Gener_qualitat_aire_BCN.csv 2019_02_Febrer_qualitat_aire_BCN.csv
## 18 18
## 2019_03_Marc_qualitat_aire_BCN.csv 2019_04_Abril_qualitat_aire_BCN.csv
## 18 57
## 2019_05_Maig_qualitat_aire_BCN.csv 2019_06_Juny_qualitat_aire_BCN.csv
## 57 1
## 2019_07_Juliol_qualitat_aire_BCN.csv 2019_08_Agost_qualitat_aire_BCN.csv
## 1 57
## 2019_09_Setembre_qualitat_aire_BCN.csv 2019_10_Octubre_qualitat_aire_BCN.csv
## 57 57
## 2019_11_Novembre_qualitat_aire_BCN.csv 2019_12_Desembre_qualitat_aire_BCN.csv
## 57 57
## 2018_06_Juny_qualitat_aire_BCN.csv 2018_07_Juliol_qualitat_aire_BCN.csv
## 18 18
## 2018_08_Agost_qualitat_aire_BCN.csv 2018_09_Setembre_qualitat_aire_BCN.csv
## 18 18
## 2018_10_Octubre_qualitat_aire_BCN.csv 2018_11_Novembre_qualitat_aire_BCN.csv
## 18 18
## 2018_12_Desembre_qualitat_aire_BCN.csv
## 18
We can detect three different tipologies:
- The most common has 57 columns, and has been maintained since 2020.
- The tables of June and July 2019 have only one column. This suggests that the separators of the
.csvare the semicolon rather than comma. - Early versions of the dataset have a configuration of 18 columns.
Furthermore, the table of May 2025 is not present in the resource for some reason at the present date. This table is also not available in the website.
I start storing the datasets of 57 columns in the airqual_csv list
airqual_csv <- airqual_all[which(columns == 57)]
Let’s examine one of the datasets with one column:
airqual_all$`2019_07_Juliol_qualitat_aire_BCN.csv`
## # A tibble: 1,053 × 1
## CODI_PROVINCIA;PROVINCIA;CODI_MUNICIPI;MUNICIPI;ESTACIO;CODI_CONTAMINANT;AN…¹
## <chr>
## 1 08;Barcelona;019;Barcelona;4;7;2019;7;1;1;V;1;V;1;V;1;V;1;V;2;V;5;V;23;V;23;…
## 2 08;Barcelona;019;Barcelona;4;7;2019;7;2;2;V;3;V;3;V;2;V;4;V;6;V;6;V;29;V;24;…
## 3 08;Barcelona;019;Barcelona;4;7;2019;7;3;2;V;2;V;4;V;6;V;5;V;6;V;15;V;40;V;40…
## 4 08;Barcelona;019;Barcelona;4;7;2019;7;4;7;V;4;V;4;V;2;V;2;V;3;V;6;V;16;V;31;…
## 5 08;Barcelona;019;Barcelona;4;7;2019;7;5;1;V;1;V;1;V;2;V;3;V;5;V;11;V;23;V;36…
## 6 08;Barcelona;019;Barcelona;4;7;2019;7;6;3;V;2;V;3;V;3;V;2;V;3;V;4;V;5;V;9;V;…
## 7 08;Barcelona;019;Barcelona;4;7;2019;7;7;12;V;4;V;2;V;1;V;2;V;10;V;11;V;12;V;…
## 8 08;Barcelona;019;Barcelona;4;7;2019;7;8;2;V;2;V;4;V;2;V;1;V;3;V;3;V;21;V;48;…
## 9 08;Barcelona;019;Barcelona;4;7;2019;7;9;9;V;7;V;3;V;2;V;1;V;1;V;2;V;3;V;4;V;…
## 10 08;Barcelona;019;Barcelona;4;7;2019;7;10;2;V;2;V;1;V;1;V;2;V;3;V;2;V;5;V;9;V…
## # ℹ 1,043 more rows
## # ℹ abbreviated name:
## # ¹`CODI_PROVINCIA;PROVINCIA;CODI_MUNICIPI;MUNICIPI;ESTACIO;CODI_CONTAMINANT;ANY;MES;DIA;H01;V01;H02;V02;H03;V03;H04;V04;H05;V05;H06;V06;H07;V07;H08;V08;H09;V09;H10;V10;H11;V11;H12;V12;H13;V13;H14;V14;H15;V15;H16;V16;H17;V17;H18;V18;H19;V19;H20;V20;H21;V21;H22;V22;H23;V23;H24;V24`
We confirm that this dataset is quite similar to the 57 columns, but it really uses semicolon as separator. It is enough with reading them with readr::read_csv2(). The result is stored in the airqual_csv2 list.
urls_csv2 <- urls_csv[which(columns == 1)]
airqual_csv2 <- map(urls_csv2, read_csv2)
## ℹ Using "','" as decimal and "'.'" as grouping mark. Use `read_delim()` for more control.
## Rows: 1164 Columns: 57
## ── Column specification ────────────────────────────────────────────────────────
## Delimiter: ";"
## chr (52): CODI_PROVINCIA, PROVINCIA, CODI_MUNICIPI, MUNICIPI, H01, V01, H02,...
## dbl (5): ESTACIO, CODI_CONTAMINANT, ANY, MES, DIA
##
## ℹ 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.
## ℹ Using "','" as decimal and "'.'" as grouping mark. Use `read_delim()` for more control.
##
## Rows: 1053 Columns: 57
## ── Column specification ────────────────────────────────────────────────────────
## Delimiter: ";"
## chr (52): CODI_PROVINCIA, PROVINCIA, CODI_MUNICIPI, MUNICIPI, H01, V01, H02,...
## dbl (5): ESTACIO, CODI_CONTAMINANT, ANY, MES, DIA
##
## ℹ 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.
names(airqual_csv2) <- names(airqual_csv[which(columns == 1)])
The tables with 18 columns have a completely different structure.
airqual_all$`2019_02_Febrer_qualitat_aire_BCN.csv`
## # A tibble: 5,376 × 18
## nom_cabina qualitat_aire codi_dtes zqa codi_eoi longitud latitud hora_o3
## <chr> <chr> <chr> <chr> <chr> <dbl> <dbl> <chr>
## 1 Barcelona - … -- ID 01 08019042 2.13 41.4 <NA>
## 2 Barcelona - … -- IH 01 08019043 2.15 41.4 <NA>
## 3 Barcelona - … -- IJ 01 08019044 2.15 41.4 <NA>
## 4 Barcelona - … -- IL 01 08019050 2.19 41.4 <NA>
## 5 Barcelona - … -- IN 01 08019054 2.15 41.4 <NA>
## 6 Barcelona - … -- IZ 01 08019057 2.12 41.4 <NA>
## 7 Barcelona - … -- I2 01 08019004 2.20 41.4 <NA>
## 8 Barcelona - … -- OF 01 08019058 2.12 41.4 <NA>
## 9 Barcelona - … Bona ID 01 08019042 2.13 41.4 <NA>
## 10 Barcelona - … Bona IH 01 08019043 2.15 41.4 0h
## # ℹ 5,366 more rows
## # ℹ 10 more variables: qualitat_o3 <chr>, valor_o3 <chr>, hora_no2 <chr>,
## # qualitat_no2 <chr>, valor_no2 <chr>, hora_pm10 <chr>, qualitat_pm10 <chr>,
## # valor_pm10 <chr>, generat <chr>, dateTime <dbl>
They will require being treated separatedly so they are stored in the airqual_long dataset.
airqual_long <- airqual_all[which(columns == 18)]
To summarise, we have now three different sets of tables:
airqual_csv, including the most common structure of 57 columns and obtained from a comma-separated file.airqual_csv2, including tables with a similar structure of 57 columns, obtained form a semicolon-separated file.airqual_long, including the tables with the old standard of 18 columns.
Table Cleaning
Now we need to tidy the three diferents sets of tables, so they have the same columns and can be integrated in a single dataset.
I presented how to deal with airqual_csv tables in a previous post. There I defined a clean_aq_table function to transform the table in tidy format.
clean_aq_table <- function(table){
t <- table |>
clean_names() |>
select(c(estacio:dia, starts_with("h"))) |>
mutate(estacio = as.numeric(estacio)) |>
pivot_longer(-c(estacio:dia), names_prefix = "h",
names_to = "hora", values_to = "value") |>
mutate(hora = as.numeric(hora)) |>
mutate(datetime = make_datetime(year = any, month = mes, day = dia, hour = hora)) |>
relocate(datetime, .after = codi_contaminant)
return(t)
}
I am applying the function to all the tables of airqual_csv and wrapping all together in a single table using purrr::map_dfr().
airqual_csv_table <- map_dfr(airqual_csv, clean_aq_table)
Here is the resulting table:
airqual_csv_table
## # A tibble: 3,019,368 × 8
## estacio codi_contaminant datetime any mes dia hora value
## <dbl> <dbl> <dttm> <dbl> <dbl> <dbl> <dbl> <dbl>
## 1 43 999 2025-07-24 01:00:00 2025 7 24 1 16.2
## 2 43 999 2025-07-24 02:00:00 2025 7 24 2 17.1
## 3 43 999 2025-07-24 03:00:00 2025 7 24 3 16.8
## 4 43 999 2025-07-24 04:00:00 2025 7 24 4 16.4
## 5 43 999 2025-07-24 05:00:00 2025 7 24 5 18.8
## 6 43 999 2025-07-24 06:00:00 2025 7 24 6 15.8
## 7 43 999 2025-07-24 07:00:00 2025 7 24 7 13.6
## 8 43 999 2025-07-24 08:00:00 2025 7 24 8 12.8
## 9 43 999 2025-07-24 09:00:00 2025 7 24 9 16.1
## 10 43 999 2025-07-24 10:00:00 2025 7 24 10 15.5
## # ℹ 3,019,358 more rows
The airqual_csv2 tables have a slightly different structure regarding the data types of the estacio and value columns, so here is a clean_aq_table2 specific for them:
clean_aq_table2 <- function(table){
table |>
clean_names() |>
select(c(estacio:dia, starts_with("h"))) |>
pivot_longer(-c(estacio:dia), names_prefix = "h",
names_to = "hora", values_to = "value") |>
mutate(hora = as.numeric(hora)) |>
mutate(datetime = make_datetime(year = any, month = mes, day = dia, hour = hora)) |>
mutate(value = as.numeric(value)) |>
relocate(datetime, .after = codi_contaminant)
}
Here is the result of the data cleaning. The column names and types are the same as the airqual_csv_table.
airqual_csv2_table <- map_dfr(airqual_csv2, clean_aq_table2)
airqual_csv2_table
## # A tibble: 53,208 × 8
## estacio codi_contaminant datetime any mes dia hora value
## <dbl> <dbl> <dttm> <dbl> <dbl> <dbl> <dbl> <dbl>
## 1 4 7 2019-06-01 01:00:00 2019 6 1 1 7
## 2 4 7 2019-06-01 02:00:00 2019 6 1 2 15
## 3 4 7 2019-06-01 03:00:00 2019 6 1 3 5
## 4 4 7 2019-06-01 04:00:00 2019 6 1 4 28
## 5 4 7 2019-06-01 05:00:00 2019 6 1 5 14
## 6 4 7 2019-06-01 06:00:00 2019 6 1 6 7
## 7 4 7 2019-06-01 07:00:00 2019 6 1 7 9
## 8 4 7 2019-06-01 08:00:00 2019 6 1 8 12
## 9 4 7 2019-06-01 09:00:00 2019 6 1 9 17
## 10 4 7 2019-06-01 10:00:00 2019 6 1 10 32
## # ℹ 53,198 more rows
The elements of airqual_long are harder to tidy:
airqual_long[[1]]
## # A tibble: 5,904 × 18
## nom_cabina qualitat_aire codi_dtes zqa codi_eoi longitud latitud hora_o3
## <chr> <chr> <chr> <chr> <chr> <dbl> <dbl> <chr>
## 1 Barcelona - … Bona ID 01 08019042 2.13 41.4 <NA>
## 2 Barcelona - … Regular IH 01 08019043 2.15 41.4 23h
## 3 Barcelona - … Regular IJ 01 08019044 2.15 41.4 23h
## 4 Barcelona - … Bona IL 01 08019050 2.19 41.4 23h
## 5 Barcelona - … Bona IN 01 08019054 2.15 41.4 23h
## 6 Barcelona - … Bona IZ 01 08019057 2.12 41.4 0h
## 7 Barcelona - … Bona I2 01 08019004 2.20 41.4 <NA>
## 8 Barcelona - … Bona OF 01 08019058 2.12 41.4 0h
## 9 Barcelona - … Regular ID 01 08019042 2.13 41.4 <NA>
## 10 Barcelona - … Regular IH 01 08019043 2.15 41.4 0h
## # ℹ 5,894 more rows
## # ℹ 10 more variables: qualitat_o3 <chr>, valor_o3 <chr>, hora_no2 <chr>,
## # qualitat_no2 <chr>, valor_no2 <chr>, hora_pm10 <chr>, qualitat_pm10 <chr>,
## # valor_pm10 <chr>, generat <chr>, dateTime <dbl>
The function tidying these datasets is clean_aq_table(), presented below. The measurement stations and pollutants are presented with their names, and not with their code. That’s why I have defined the stations table at the beginning. These tables include only three pollutants. Their codes are presented in the conts table inside the function.
clean_aq_long <- function(table){
table0 <- table |>
select(nom_cabina, starts_with("hora"), starts_with("valor"), generat) |>
mutate(across(starts_with("valor"), ~ str_replace(., " µg/m³", ""))) |>
mutate(across(starts_with("valor"), ~ str_replace(., "--", ""))) |>
mutate(across(starts_with("valor"), ~ ifelse(. == "", NA, .))) |>
mutate(datetime = dmy_hm(generat)) |>
select(nom_cabina, datetime, starts_with("valor"))
new_table <- map_dfr(c("o3", "no2", "pm10"), ~ table0 |>
select(nom_cabina, datetime, ends_with(.)) |>
mutate(contaminant = .) |>
mutate(across(starts_with("valor"), ~ as.numeric(.))) |>
rename(c("value" = paste0("valor_", .))))
conts <- tibble(contaminant = c("o3", "no2", "pm10"),
codi_contaminant = c(14, 8, 10))
new_table <- new_table |>
left_join(conts, by = "contaminant")
new_table <- new_table |>
left_join(stations |> select(estacio, nom_cabina), by = "nom_cabina")
new_table <- new_table |>
mutate(any = year(datetime), mes = month(datetime),
dia = day(datetime), hora = hour(datetime)) |>
select(estacio, codi_contaminant, datetime, any, mes, dia, hora, value)
return(new_table)
}
The table of February 2019 was totally empty of data, so it has been excluded from treatment. When applying clean_aq_long() some warnings appeared resulting from applying as.numeric() to the column of values, indicating that non-numeric strings have been turned into NA by coertion.
airqual_long_table <- map_dfr(airqual_long[c(1, 4:10)], clean_aq_long)
airqual_long_table
## # A tibble: 125,661 × 8
## estacio codi_contaminant datetime any mes dia hora value
## <dbl> <dbl> <dttm> <dbl> <dbl> <int> <int> <dbl>
## 1 42 14 2019-01-01 00:00:00 2019 1 1 0 NA
## 2 43 14 2019-01-01 00:00:00 2019 1 1 0 3
## 3 44 14 2019-01-01 00:00:00 2019 1 1 0 3
## 4 50 14 2019-01-01 00:00:00 2019 1 1 0 2
## 5 54 14 2019-01-01 00:00:00 2019 1 1 0 10
## 6 57 14 2019-01-01 00:00:00 2019 1 1 0 1
## 7 4 14 2019-01-01 00:00:00 2019 1 1 0 NA
## 8 58 14 2019-01-01 00:00:00 2019 1 1 0 86
## 9 42 14 2019-01-01 01:00:00 2019 1 1 1 NA
## 10 43 14 2019-01-01 01:00:00 2019 1 1 1 4
## # ℹ 125,651 more rows
Wrapping It All Together
Now that we have the three sets of tables turned into a single dataset, it is time to wrap them up with the dplyr::bind_rows() function. It has worked properly because similar data has the same column name and data type in the three tables.
airqual <- bind_rows(airqual_csv_table, airqual_csv2_table, airqual_long_table)
Finally, I am renaming columns so that they are presented in the same language.
airqual <- airqual |>
rename(station = estacio, pollutant = codi_contaminant, year = any, month = mes, day = dia, hour = hora)
This is the resulting dataset, including air quality data from 2018 to mid 2025.
airqual
## # A tibble: 3,198,237 × 8
## station pollutant datetime year month day hour value
## <dbl> <dbl> <dttm> <dbl> <dbl> <dbl> <dbl> <dbl>
## 1 43 999 2025-07-24 01:00:00 2025 7 24 1 16.2
## 2 43 999 2025-07-24 02:00:00 2025 7 24 2 17.1
## 3 43 999 2025-07-24 03:00:00 2025 7 24 3 16.8
## 4 43 999 2025-07-24 04:00:00 2025 7 24 4 16.4
## 5 43 999 2025-07-24 05:00:00 2025 7 24 5 18.8
## 6 43 999 2025-07-24 06:00:00 2025 7 24 6 15.8
## 7 43 999 2025-07-24 07:00:00 2025 7 24 7 13.6
## 8 43 999 2025-07-24 08:00:00 2025 7 24 8 12.8
## 9 43 999 2025-07-24 09:00:00 2025 7 24 9 16.1
## 10 43 999 2025-07-24 10:00:00 2025 7 24 10 15.5
## # ℹ 3,198,227 more rows
Evolution of PM10 at the Eixample Station
Now that we have all data into a single table, we can examine some of the results. For instance, here is the evolution of the PM10 pollutant in the Eixample air quality measurement station (code 43).
airqual |>
filter(station == 43, pollutant == 10) |>
mutate(date = as_date(datetime)) |>
group_by(date) |>
summarise(pm10 = mean(value, na.rm = TRUE), .groups = "drop") |>
ggplot(aes(date, pm10)) +
geom_line(linewidth = 0.5) +
theme_minimal() +
labs(title = "Evolution of PM10 at Eixample Station (2018-2025)", x = NULL, y = NULL)
## Warning: Removed 1 row containing missing values or values outside the scale range
## (`geom_line()`).

As the year 2022 had high values of PM10, we can observe it closely:
airqual |>
filter(station == 43, pollutant == 10, year == 2022) |>
mutate(date = as_date(datetime)) |>
group_by(date) |>
summarise(pm10 = mean(value, na.rm = TRUE), .groups = "drop") |>
ggplot(aes(date, pm10)) +
geom_line(linewidth = 0.5) +
geom_hline(yintercept = 50, color = "red", linetype = "dashed") +
theme_minimal() +
labs(title = "Evolution of PM10 at Eixample Station (2022)", x = NULL, y = NULL)

Episodes of PM10 Pollution
One of the ways of defining an episode of PM10 pollution is to observe daily average values of PM10 above 50 in two or more station. Let’s see the days when one of these episodes occurred.
pm10_episodes <- airqual |>
filter(pollutant == 10) |>
mutate(date = as_date(datetime)) |>
group_by(date, station) |>
summarise(pm10 = mean(value, na.rm = TRUE), .groups = "drop") |>
filter(pm10 >= 50) |>
group_by(date) |>
summarise(n = n()) |>
filter(n > 1) |>
arrange(-n)
pm10_episodes
## # A tibble: 46 × 2
## date n
## <date> <int>
## 1 2019-12-17 6
## 2 2019-12-18 6
## 3 2020-02-29 6
## 4 2020-10-22 6
## 5 2021-02-06 6
## 6 2021-08-14 6
## 7 2023-07-11 6
## 8 2019-06-28 5
## 9 2020-01-24 5
## 10 2020-10-21 5
## # ℹ 36 more rows
There have been 46 episodes of PM10 pollution registered since 2018. If we count episodes by month we have:
pm10_episodes |>
mutate(month = month(date)) |>
mutate(month = factor(month)) |>
ggplot(aes(month)) +
geom_bar() +
theme_minimal() +
labs(x = NULL, y = NULL, title = "Episodes of PM10 Pollution in Barcelona (2018-2025)")

We observe that the highest value of pollution episodes is during June, and the lowest in March and April.
Reading and Tidying Data from Open Data Portals
Although open data portals are supposed to provide data in a structured and reusable way, using this kind of data may require extensive tidying and cleaning, pretty much like any other dataset. Turning a dataset into R tidy data can require some effort, but the resulting dataset can be very useful for exploratory data analysis jobs.
References
- Air quality data from the measure stations of the city of Barcelona https://opendata-ajuntament.barcelona.cat/data/en/dataset/qualitat-aire-detall-bcn
- Air quality measure stations of the city of Barcelona https://opendata-ajuntament.barcelona.cat/data/en/dataset/qualitat-aire-estacions-bcn
- Measured air pollutants by the air quality measurement stations of the city of Barcelona https://opendata-ajuntament.barcelona.cat/data/en/dataset/contaminants-estacions-mesura-qualitat-aire
ckanrpackage https://docs.ropensci.org/ckanr/- Cleaning Barcelona Air Quality Data https://jmsallan.netlify.app/blog/cleaning-barcelona-air-quality-data/
All websites checked on 21 July 2025.
Session Info
## R version 4.5.1 (2025-06-13)
## Platform: x86_64-pc-linux-gnu
## Running under: Linux Mint 21.1
##
## Matrix products: default
## BLAS: /usr/lib/x86_64-linux-gnu/blas/libblas.so.3.10.0
## LAPACK: /usr/lib/x86_64-linux-gnu/lapack/liblapack.so.3.10.0 LAPACK version 3.10.0
##
## locale:
## [1] LC_CTYPE=es_ES.UTF-8 LC_NUMERIC=C
## [3] LC_TIME=es_ES.UTF-8 LC_COLLATE=es_ES.UTF-8
## [5] LC_MONETARY=es_ES.UTF-8 LC_MESSAGES=es_ES.UTF-8
## [7] LC_PAPER=es_ES.UTF-8 LC_NAME=C
## [9] LC_ADDRESS=C LC_TELEPHONE=C
## [11] LC_MEASUREMENT=es_ES.UTF-8 LC_IDENTIFICATION=C
##
## time zone: Europe/Madrid
## tzcode source: system (glibc)
##
## attached base packages:
## [1] stats graphics grDevices utils datasets methods base
##
## other attached packages:
## [1] ckanr_0.7.0 DBI_1.2.3 janitor_2.2.1 lubridate_1.9.4
## [5] forcats_1.0.0 stringr_1.5.1 dplyr_1.1.4 purrr_1.0.4
## [9] readr_2.1.5 tidyr_1.3.1 tibble_3.2.1 ggplot2_3.5.2
## [13] tidyverse_2.0.0
##
## loaded via a namespace (and not attached):
## [1] utf8_1.2.4 sass_0.4.10 generics_0.1.3 blogdown_1.21
## [5] stringi_1.8.7 httpcode_0.3.0 hms_1.1.3 digest_0.6.37
## [9] magrittr_2.0.3 evaluate_1.0.3 grid_4.5.1 timechange_0.3.0
## [13] bookdown_0.43 fastmap_1.2.0 jsonlite_2.0.0 crul_1.5.0
## [17] urltools_1.7.3.1 scales_1.3.0 jquerylib_0.1.4 cli_3.6.4
## [21] crayon_1.5.3 rlang_1.1.6 triebeard_0.4.1 dbplyr_2.5.0
## [25] bit64_4.6.0-1 munsell_0.5.1 withr_3.0.2 cachem_1.1.0
## [29] yaml_2.3.10 parallel_4.5.1 tools_4.5.1 tzdb_0.5.0
## [33] colorspace_2.1-1 curl_6.2.2 vctrs_0.6.5 R6_2.6.1
## [37] lifecycle_1.0.4 snakecase_0.11.1 bit_4.6.0 vroom_1.6.5
## [41] pkgconfig_2.0.3 pillar_1.10.2 bslib_0.9.0 gtable_0.3.6
## [45] Rcpp_1.0.14 glue_1.8.0 xfun_0.52 tidyselect_1.2.1
## [49] rstudioapi_0.17.1 knitr_1.50 farver_2.1.2 htmltools_0.5.8.1
## [53] labeling_0.4.3 rmarkdown_2.29 compiler_4.5.1