3 Procesado de datos

Instalación/carga librerías utilizadas

if (!require(openxlsx)) install.packages('openxlsx') 
library(openxlsx)
if (!require(pxR)) install.packages('pxR') 
library(pxR)
if (!require(tidyverse)) install.packages('tidyverse') 
library(tidyverse)

Rara vez nos encontramos los datos organizados en la forma que necesitamos para el objetivo de nuestro análisis. De hecho, con frecuencia, el trabajo más complejo de nuestra exploración de datos es localizar, extraer y entender como están organizados los datos. Por ello, la primera tarea de cualquier análisis de datos es procesarlos hasta tenerlos en la forma y estructura que nosotros queremos. Por ello vamos a dedicar en el curso cierta atención a la manipulación de datos.

En primer lugar hablaremos de las bases de datos principales que usaremos en el curso. Como se verá a continuación se utilizarán principalmente bases de datos actuales sobre temas de interés general que pueden ser más atractivas que las bases de datos incluidas por defecto en R que se suelen usar en los cursos de análisis de datos.

3.1 Bases de datos

Las fuentes principales de información que vamos a usar para ilustrar los contenidos del curso son las siguientes bases de datos de interés general:

  • OWID: base de datos a nivel mundial sobre temas de actualidad

  • UNdata: base de datos de la organización de las Naciones Unidas.

  • INE: base de datos del Instituto Nacional de Estadística.

  • ISTAC : base de datos del Instituto Canario de Estadística

  • UNICEF : base de datos de UNICEF

  • Organización mundial de la salud. : base de datos de la Organización mundial de la salud

En este libro también utilizaremos algunas bases de datos almacenadas en un repositorio local de datos llamado data. Los ficheros referenciados en este libro a este repositorio se pueden localizar en la dirección https://ctim.es/AEDV/data/. Estas bases de datos locales, en general, se han extraído de las bases de datos anteriores y por comodidad se han puesto en un repositorio local.

Además de estas bases de datos, R tiene una amplia colección de bases de datos de ejemplo directamente accesibles. Por ejemplo la base de datos con información de coches mtcars se utiliza mucho para ilustrar las funcionalidades de R

head(mtcars)
##                    mpg cyl disp  hp drat    wt  qsec vs am gear carb
## Mazda RX4         21.0   6  160 110 3.90 2.620 16.46  0  1    4    4
## Mazda RX4 Wag     21.0   6  160 110 3.90 2.875 17.02  0  1    4    4
## Datsun 710        22.8   4  108  93 3.85 2.320 18.61  1  1    4    1
## Hornet 4 Drive    21.4   6  258 110 3.08 3.215 19.44  1  0    3    1
## Hornet Sportabout 18.7   8  360 175 3.15 3.440 17.02  0  0    3    2
## Valiant           18.1   6  225 105 2.76 3.460 20.22  1  0    3    1

Estas bases de datos incorporadas en R no las utilizaremos en este curso.

3.2 Formatos de ficheros de datos

Para hacer análisis de datos, lo primero que hay que hacer es acceder a ellos, lo cual se hace generalmente leyendo los datos de un fichero donde están almacenados como una tabla. A continuación veremos los formatos de ficheros de datos más habituales y como leerlos usando las librerías correspondientes, las librerías de lectura que usamos permiten leer los datos directamente desde un servidor WEB, lo cual es un valor añadido. Como resumen de esta sección puede ser útil mirar la siguiente ficha resumen.

Formato CSV

El formato CSV consiste en un texto plano, es decir, contiene los valores de la tabla sin ninguna otra información sobre si se trata de fechas, números, caracteres, etc. Se puede editar con cualquier editor de texto (como NOTEPAD) y los campos están separados entre sí por una coma y los decimales se expresan con puntos. Para leer ficheros CSV utilizaremos la función read_csv de la librería readl incluida en la librería tidyverse. Si los campos en la tabla están separados por el símbolo ; y además los decimales de los números se expresan con comas, utilizaremos la función de lectura read_csv2. Si el delimitador entre campos no es ni una coma ni un punto, podemos usar la función read_delim que permite declarar cualquier delimitador entre campos. En la mencionada ficha resumen aparece una descripción más detallada de estas funciones.

A continuación leeremos un fichero CSV con la información de la población mundial de la base de datos de las Naciones Unidas (UN). Como sucede con frecuencia, las tablas de datos requieren de una manipulación para corregir errores o seleccionar los campos que nos interesan. En este caso, la primera línea de la tabla contiene comentarios y en la segunda línea, que contiene los nombres de los campos, hay un campo que viene sin nombre. En secciones posteriores de este tema veremos como manipular/transformar los datos. Esta base de datos se puede leer directamente desde el servidor de las Naciones Unidas usando el script:

UN_population <- read_csv('https://data.un.org/_Docs/SYB/CSV/SYB65_1_202209_Population,%20Surface%20Area%20and%20Density.csv',skip = 1)%>%
  as_tibble()

Por comodidad, hemos guardado una copia del fichero en nuestro repositorio local y la leemos desde esa fuente. Añadimos en la instrucción de lectura skip=1 para no tener en cuenta la primera línea de la tabla que contiene un comentario, una vez que leemos la tabla usamos la función str para analizar su estructura :

UN_population <- read_csv("https://ctim.es/AEDV/data/UN_population.csv",skip = 1)%>%
  as_tibble()
str(UN_population)
## tibble [7,873 × 7] (S3: tbl_df/tbl/data.frame)
##  $ Region/Country/Area: num [1:7873] 1 1 1 1 1 1 1 1 1 1 ...
##  $ ...2               : chr [1:7873] "Total, all countries or areas" "Total, all countries or areas" "Total, all countries or areas" "Total, all countries or areas" ...
##  $ Year               : num [1:7873] 2010 2010 2010 2010 2010 ...
##  $ Series             : chr [1:7873] "Population mid-year estimates (millions)" "Population mid-year estimates for males (millions)" "Population mid-year estimates for females (millions)" "Sex ratio (males per 100 females)" ...
##  $ Value              : num [1:7873] 6985.6 3514.4 3471.2 101.2 27.1 ...
##  $ Footnotes          : chr [1:7873] NA NA NA NA ...
##  $ Source             : chr [1:7873] "United Nations Population Division, New York, World Population Prospects: The 2022 Revision, last accessed July 2022." "United Nations Population Division, New York, World Population Prospects: The 2022 Revision, last accessed July 2022." "United Nations Population Division, New York, World Population Prospects: The 2022 Revision, last accessed July 2022." "United Nations Population Division, New York, World Population Prospects: The 2022 Revision; supplemented by da"| __truncated__ ...

Con frecuencia, no queda muy claro, a primera vista, el contenido real de algunas de las variables. Por ello, en el análisis exploratorio de datos, el primer paso es analizar con cierto detalle el contenido de las tablas. Para analizar el rango de valores posibles de las variables, especialmente en el caso de variables categóricas (tipo factor) podemos ver el contenido de algunas de las variables usando levels y tomando la variable como factor para que nos salga el rango de los valores posibles sin repetir. Para las variable numéricas podemos usar la función `summary’ para tener una primera idea de su rango de valores. Para esta primera tabla presentamos un análisis exhaustivo de las variables. En general, en este curso, para no hacer muy engorrosa la presentación de las tablas utilizadas, no analizaremos en tanto detalle las tablas usadas, pero es fundamental que los alumnos adquieran el hábito de analizar en detalle las tablas antes de empezar a trabajar con ellas.

levels(as.factor(UN_population$`Region/Country/Area`))
##   [1] "1"   "2"   "4"   "5"   "8"   "9"   "11"  "12"  "13"  "14"  "15"  "16" 
##  [13] "17"  "18"  "19"  "20"  "21"  "24"  "28"  "29"  "30"  "31"  "32"  "34" 
##  [25] "35"  "36"  "39"  "40"  "44"  "48"  "50"  "51"  "52"  "53"  "54"  "56" 
##  [37] "57"  "60"  "61"  "62"  "64"  "68"  "70"  "72"  "76"  "84"  "90"  "92" 
##  [49] "96"  "100" "104" "108" "112" "116" "120" "124" "132" "136" "140" "142"
##  [61] "143" "144" "145" "148" "150" "151" "152" "154" "155" "156" "158" "170"
##  [73] "174" "175" "178" "180" "184" "188" "191" "192" "196" "202" "203" "204"
##  [85] "208" "212" "214" "218" "222" "226" "231" "232" "233" "234" "238" "242"
##  [97] "246" "250" "254" "258" "262" "266" "268" "270" "275" "276" "288" "292"
## [109] "296" "300" "304" "308" "312" "316" "320" "324" "328" "332" "336" "340"
## [121] "344" "348" "352" "356" "360" "364" "368" "372" "376" "380" "384" "388"
## [133] "392" "398" "400" "404" "408" "410" "414" "417" "418" "419" "422" "426"
## [145] "428" "430" "434" "438" "440" "442" "446" "450" "454" "458" "462" "466"
## [157] "470" "474" "478" "480" "484" "492" "496" "498" "499" "500" "504" "508"
## [169] "512" "516" "520" "524" "528" "531" "533" "534" "535" "540" "548" "554"
## [181] "558" "562" "566" "570" "578" "580" "583" "584" "585" "586" "591" "598"
## [193] "600" "604" "608" "616" "620" "624" "626" "630" "634" "638" "642" "643"
## [205] "646" "652" "654" "659" "660" "662" "663" "666" "670" "674" "678" "682"
## [217] "686" "688" "690" "694" "702" "703" "704" "705" "706" "710" "716" "724"
## [229] "728" "729" "732" "740" "748" "752" "756" "760" "762" "764" "768" "772"
## [241] "776" "780" "784" "788" "792" "795" "796" "798" "800" "804" "807" "818"
## [253] "826" "830" "833" "834" "840" "850" "854" "858" "860" "862" "876" "882"
## [265] "887" "894"

La variable Region/Country/Area es un código numérico que identifica al país. Este código nos permite combinar los valores de esta tabla con otras tablas de datos de países que usen el mismo código. Esta variable la podemos gestionar como numeric o como factor, dado que se usa para clasificar a que país pertenece al dato de cada registro

levels(as.factor(UN_population$`Region/Country/Area`))
##   [1] "1"   "2"   "4"   "5"   "8"   "9"   "11"  "12"  "13"  "14"  "15"  "16" 
##  [13] "17"  "18"  "19"  "20"  "21"  "24"  "28"  "29"  "30"  "31"  "32"  "34" 
##  [25] "35"  "36"  "39"  "40"  "44"  "48"  "50"  "51"  "52"  "53"  "54"  "56" 
##  [37] "57"  "60"  "61"  "62"  "64"  "68"  "70"  "72"  "76"  "84"  "90"  "92" 
##  [49] "96"  "100" "104" "108" "112" "116" "120" "124" "132" "136" "140" "142"
##  [61] "143" "144" "145" "148" "150" "151" "152" "154" "155" "156" "158" "170"
##  [73] "174" "175" "178" "180" "184" "188" "191" "192" "196" "202" "203" "204"
##  [85] "208" "212" "214" "218" "222" "226" "231" "232" "233" "234" "238" "242"
##  [97] "246" "250" "254" "258" "262" "266" "268" "270" "275" "276" "288" "292"
## [109] "296" "300" "304" "308" "312" "316" "320" "324" "328" "332" "336" "340"
## [121] "344" "348" "352" "356" "360" "364" "368" "372" "376" "380" "384" "388"
## [133] "392" "398" "400" "404" "408" "410" "414" "417" "418" "419" "422" "426"
## [145] "428" "430" "434" "438" "440" "442" "446" "450" "454" "458" "462" "466"
## [157] "470" "474" "478" "480" "484" "492" "496" "498" "499" "500" "504" "508"
## [169] "512" "516" "520" "524" "528" "531" "533" "534" "535" "540" "548" "554"
## [181] "558" "562" "566" "570" "578" "580" "583" "584" "585" "586" "591" "598"
## [193] "600" "604" "608" "616" "620" "624" "626" "630" "634" "638" "642" "643"
## [205] "646" "652" "654" "659" "660" "662" "663" "666" "670" "674" "678" "682"
## [217] "686" "688" "690" "694" "702" "703" "704" "705" "706" "710" "716" "724"
## [229] "728" "729" "732" "740" "748" "752" "756" "760" "762" "764" "768" "772"
## [241] "776" "780" "784" "788" "792" "795" "796" "798" "800" "804" "807" "818"
## [253] "826" "830" "833" "834" "840" "850" "854" "858" "860" "862" "876" "882"
## [265] "887" "894"
levels(as.factor(UN_population$`...2`))
##   [1] "Afghanistan"                   "Africa"                       
##   [3] "Albania"                       "Algeria"                      
##   [5] "American Samoa"                "Americas"                     
##   [7] "Andorra"                       "Angola"                       
##   [9] "Anguilla"                      "Antigua and Barbuda"          
##  [11] "Argentina"                     "Armenia"                      
##  [13] "Aruba"                         "Asia"                         
##  [15] "Australia"                     "Australia and New Zealand"    
##  [17] "Austria"                       "Azerbaijan"                   
##  [19] "Bahamas"                       "Bahrain"                      
##  [21] "Bangladesh"                    "Barbados"                     
##  [23] "Belarus"                       "Belgium"                      
##  [25] "Belize"                        "Benin"                        
##  [27] "Bermuda"                       "Bhutan"                       
##  [29] "Bolivia (Plurin. State of)"    "Bonaire, St. Eustatius & Saba"
##  [31] "Bosnia and Herzegovina"        "Botswana"                     
##  [33] "Brazil"                        "British Virgin Islands"       
##  [35] "Brunei Darussalam"             "Bulgaria"                     
##  [37] "Burkina Faso"                  "Burundi"                      
##  [39] "Cabo Verde"                    "Cambodia"                     
##  [41] "Cameroon"                      "Canada"                       
##  [43] "Caribbean"                     "Cayman Islands"               
##  [45] "Central African Republic"      "Central America"              
##  [47] "Central Asia"                  "Chad"                         
##  [49] "Channel Islands"               "Chile"                        
##  [51] "China"                         "China, Hong Kong SAR"         
##  [53] "China, Macao SAR"              "Colombia"                     
##  [55] "Comoros"                       "Congo"                        
##  [57] "Cook Islands"                  "Costa Rica"                   
##  [59] "Côte d’Ivoire"                 "Croatia"                      
##  [61] "Cuba"                          "Curaçao"                      
##  [63] "Cyprus"                        "Czechia"                      
##  [65] "Dem. People's Rep. Korea"      "Dem. Rep. of the Congo"       
##  [67] "Denmark"                       "Djibouti"                     
##  [69] "Dominica"                      "Dominican Republic"           
##  [71] "Eastern Africa"                "Eastern Asia"                 
##  [73] "Eastern Europe"                "Ecuador"                      
##  [75] "Egypt"                         "El Salvador"                  
##  [77] "Equatorial Guinea"             "Eritrea"                      
##  [79] "Estonia"                       "Eswatini"                     
##  [81] "Ethiopia"                      "Europe"                       
##  [83] "Falkland Islands (Malvinas)"   "Faroe Islands"                
##  [85] "Fiji"                          "Finland"                      
##  [87] "France"                        "French Guiana"                
##  [89] "French Polynesia"              "Gabon"                        
##  [91] "Gambia"                        "Georgia"                      
##  [93] "Germany"                       "Ghana"                        
##  [95] "Gibraltar"                     "Greece"                       
##  [97] "Greenland"                     "Grenada"                      
##  [99] "Guadeloupe"                    "Guam"                         
## [101] "Guatemala"                     "Guinea"                       
## [103] "Guinea-Bissau"                 "Guyana"                       
## [105] "Haiti"                         "Holy See"                     
## [107] "Honduras"                      "Hungary"                      
## [109] "Iceland"                       "India"                        
## [111] "Indonesia"                     "Iran (Islamic Republic of)"   
## [113] "Iraq"                          "Ireland"                      
## [115] "Isle of Man"                   "Israel"                       
## [117] "Italy"                         "Jamaica"                      
## [119] "Japan"                         "Jordan"                       
## [121] "Kazakhstan"                    "Kenya"                        
## [123] "Kiribati"                      "Kuwait"                       
## [125] "Kyrgyzstan"                    "Lao People's Dem. Rep."       
## [127] "Latin America & the Caribbean" "Latvia"                       
## [129] "Lebanon"                       "Lesotho"                      
## [131] "Liberia"                       "Libya"                        
## [133] "Liechtenstein"                 "Lithuania"                    
## [135] "Luxembourg"                    "Madagascar"                   
## [137] "Malawi"                        "Malaysia"                     
## [139] "Maldives"                      "Mali"                         
## [141] "Malta"                         "Marshall Islands"             
## [143] "Martinique"                    "Mauritania"                   
## [145] "Mauritius"                     "Mayotte"                      
## [147] "Melanesia"                     "Mexico"                       
## [149] "Micronesia"                    "Micronesia (Fed. States of)"  
## [151] "Middle Africa"                 "Monaco"                       
## [153] "Mongolia"                      "Montenegro"                   
## [155] "Montserrat"                    "Morocco"                      
## [157] "Mozambique"                    "Myanmar"                      
## [159] "Namibia"                       "Nauru"                        
## [161] "Nepal"                         "Netherlands"                  
## [163] "New Caledonia"                 "New Zealand"                  
## [165] "Nicaragua"                     "Niger"                        
## [167] "Nigeria"                       "Niue"                         
## [169] "North Macedonia"               "Northern Africa"              
## [171] "Northern America"              "Northern Europe"              
## [173] "Northern Mariana Islands"      "Norway"                       
## [175] "Oceania"                       "Oman"                         
## [177] "Other non-specified areas"     "Pakistan"                     
## [179] "Palau"                         "Panama"                       
## [181] "Papua New Guinea"              "Paraguay"                     
## [183] "Peru"                          "Philippines"                  
## [185] "Poland"                        "Polynesia"                    
## [187] "Portugal"                      "Puerto Rico"                  
## [189] "Qatar"                         "Republic of Korea"            
## [191] "Republic of Moldova"           "Réunion"                      
## [193] "Romania"                       "Russian Federation"           
## [195] "Rwanda"                        "Saint Barthélemy"             
## [197] "Saint Helena"                  "Saint Kitts and Nevis"        
## [199] "Saint Lucia"                   "Saint Martin (French part)"   
## [201] "Saint Pierre and Miquelon"     "Saint Vincent & Grenadines"   
## [203] "Samoa"                         "San Marino"                   
## [205] "Sao Tome and Principe"         "Saudi Arabia"                 
## [207] "Senegal"                       "Serbia"                       
## [209] "Seychelles"                    "Sierra Leone"                 
## [211] "Singapore"                     "Sint Maarten (Dutch part)"    
## [213] "Slovakia"                      "Slovenia"                     
## [215] "Solomon Islands"               "Somalia"                      
## [217] "South-central Asia"            "South-eastern Asia"           
## [219] "South Africa"                  "South America"                
## [221] "South Sudan"                   "Southern Africa"              
## [223] "Southern Asia"                 "Southern Europe"              
## [225] "Spain"                         "Sri Lanka"                    
## [227] "State of Palestine"            "Sub-Saharan Africa"           
## [229] "Sudan"                         "Suriname"                     
## [231] "Sweden"                        "Switzerland"                  
## [233] "Syrian Arab Republic"          "Tajikistan"                   
## [235] "Thailand"                      "Timor-Leste"                  
## [237] "Togo"                          "Tokelau"                      
## [239] "Tonga"                         "Total, all countries or areas"
## [241] "Trinidad and Tobago"           "Tunisia"                      
## [243] "Türkiye"                       "Turkmenistan"                 
## [245] "Turks and Caicos Islands"      "Tuvalu"                       
## [247] "Uganda"                        "Ukraine"                      
## [249] "United Arab Emirates"          "United Kingdom"               
## [251] "United Rep. of Tanzania"       "United States of America"     
## [253] "United States Virgin Islands"  "Uruguay"                      
## [255] "Uzbekistan"                    "Vanuatu"                      
## [257] "Venezuela (Boliv. Rep. of)"    "Viet Nam"                     
## [259] "Wallis and Futuna Islands"     "Western Africa"               
## [261] "Western Asia"                  "Western Europe"               
## [263] "Western Sahara"                "Yemen"                        
## [265] "Zambia"                        "Zimbabwe"

La variable ...2 es el nombre del país y es de tipo character.

levels(as.factor(UN_population$Series))
## [1] "Population aged 0 to 14 years old (percentage)"      
## [2] "Population aged 60+ years old (percentage)"          
## [3] "Population density"                                  
## [4] "Population mid-year estimates (millions)"            
## [5] "Population mid-year estimates for females (millions)"
## [6] "Population mid-year estimates for males (millions)"  
## [7] "Sex ratio (males per 100 females)"                   
## [8] "Surface area (thousand km2)"

La variable Series, describe el nombre del indicador asociado al dato de cada registro, es decir, indica lo que se está midiendo en cada registro. Podemos gestionarla como character o como factor dado que también se usa para clasificar los registros. Con frecuencia, no queda claro, a partir del nombre del indicador, cual es su significado exacto. En ese caso hay que mirar información complementaria a la tabla donde se explica con más detalle el significado de los indicadores utilizados. Esto es muy importante para poder interpretar y comprender los datos que manejamos.

levels(as.factor(UN_population$Year))
## [1] "2010" "2015" "2017" "2020" "2022"

La variable Year determina el año asociado al dato de cada registro. Habitualmente convertiremos los datos temporales en tipo Date, en este caso, por ejemplo, podemos asociarle el último día del año en cuestión.

summary(UN_population$Value) 
##      Min.   1st Qu.    Median      Mean   3rd Qu.      Max. 
##      0.00      5.00     21.52    255.80     94.70 136162.00

La variable Value', de tiponumeric`, suministra el valor numérico del dato de cada registro.

levels(as.factor(UN_population$Footnotes))
##   [1] "A dispute exists between the Governments of Argentina and the United Kingdom of Great Britain and Northern Ireland concerning sovereignty over the Falkland Islands (Malvinas)."                                                                                                                                                                                             
##   [2] "A dispute exists between the Governments of Argentina and the United Kingdom of Great Britain and Northern Ireland concerning sovereignty over the Falkland Islands (Malvinas). For statistical purposes, the data for United Kingdom do not include this area."                                                                                                             
##   [3] "Calculated by the UN Statistics Division."                                                                                                                                                                                                                                                                                                                                   
##   [4] "Calculated by the UN Statistics Division.;Projected estimate (medium fertility variant)."                                                                                                                                                                                                                                                                                    
##   [5] "Changes in total area per year are the result of new measuring and correcting of the administrative borders between former Yugoslavian countries."                                                                                                                                                                                                                           
##   [6] "Comprising the Northern Region (former Saguia el Hamra) and Southern Region (former Rio de Oro)."                                                                                                                                                                                                                                                                            
##   [7] "Data refer to 1 October 2007."                                                                                                                                                                                                                                                                                                                                               
##   [8] "Data refer to the Vatican City State."                                                                                                                                                                                                                                                                                                                                       
##   [9] "Data updated according to \"Superintendencia Agraria\". Interior waters correspond to natural or artificial bodies of water or snow."                                                                                                                                                                                                                                        
##  [10] "Excluding Åland Islands."                                                                                                                                                                                                                                                                                                                                                    
##  [11] "Excluding Channel Islands (Guernsey and Jersey) and Isle of Man, shown separately, if available."                                                                                                                                                                                                                                                                            
##  [12] "Excluding Faeroe Islands and Greenland shown separately, if available."                                                                                                                                                                                                                                                                                                      
##  [13] "Excluding inland water."                                                                                                                                                                                                                                                                                                                                                     
##  [14] "Excluding Kosovo."                                                                                                                                                                                                                                                                                                                                                           
##  [15] "Excluding Niue, shown separately, which is part of Cook Islands, but because of remoteness is administered separately."                                                                                                                                                                                                                                                      
##  [16] "Excluding the islands of Saint Brandon and Agalega."                                                                                                                                                                                                                                                                                                                         
##  [17] "For statistical purposes, the data for China do not include this area."                                                                                                                                                                                                                                                                                                      
##  [18] "For statistical purposes, the data for China do not include this area.;Projected estimate (medium fertility variant)."                                                                                                                                                                                                                                                       
##  [19] "For statistical purposes, the data for China do not include those for the Hong Kong Special Administrative Region (Hong Kong SAR), Macao Special Administrative Region (Macao SAR) and Taiwan Province of China."                                                                                                                                                            
##  [20] "For statistical purposes, the data for Denmark do not include Faroe Islands, and Greenland."                                                                                                                                                                                                                                                                                 
##  [21] "For statistical purposes, the data for Denmark do not include this area."                                                                                                                                                                                                                                                                                                    
##  [22] "For statistical purposes, the data for France do not include French Guiana, French Polynesia, Guadeloupe, Martinique, Mayotte, New Caledonia, Réunion, Saint Pierre and Miquelon, Saint Barthélemy, Saint Martin (French part), Wallis and Futuna Islands."                                                                                                                  
##  [23] "For statistical purposes, the data for France do not include this area."                                                                                                                                                                                                                                                                                                     
##  [24] "For statistical purposes, the data for France do not include this area.;Projected estimate (medium fertility variant)."                                                                                                                                                                                                                                                      
##  [25] "For statistical purposes, the data for Netherlands do not include Aruba, Bonaire, Sint Eustatius and Saba, Curaçao, and Sint Maarten (Dutch part)."                                                                                                                                                                                                                          
##  [26] "For statistical purposes, the data for Netherlands do not include this area."                                                                                                                                                                                                                                                                                                
##  [27] "For statistical purposes, the data for Netherlands do not include this area.;Projected estimate (medium fertility variant)."                                                                                                                                                                                                                                                 
##  [28] "For statistical purposes, the data for New Zealand do not include Cook Islands, Niue, and Tokelau."                                                                                                                                                                                                                                                                          
##  [29] "For statistical purposes, the data for New Zealand do not include this area."                                                                                                                                                                                                                                                                                                
##  [30] "For statistical purposes, the data for United Kingdom do not include this area."                                                                                                                                                                                                                                                                                             
##  [31] "For statistical purposes, the data for United States of America do not include American Samoa, Guam, Northern Mariana Islands, Puerto Rico, and United States Virgin Islands."                                                                                                                                                                                               
##  [32] "For statistical purposes, the data for United States of America do not include this area."                                                                                                                                                                                                                                                                                   
##  [33] "Including Abkhazia and South Ossetia."                                                                                                                                                                                                                                                                                                                                       
##  [34] "Including Agalega, Rodrigues and Saint Brandon."                                                                                                                                                                                                                                                                                                                             
##  [35] "Including Åland Islands."                                                                                                                                                                                                                                                                                                                                                    
##  [36] "Including Andorra, Gibraltar, Holy See, and San Marino."                                                                                                                                                                                                                                                                                                                     
##  [37] "Including Anguilla, Bonaire, Sint Eustatius and Saba, British Virgin Islands, Cayman Islands, Dominica, Montserrat, Saint Kitts and Nevis, Sint Maarten (Dutch part) and Turks and Caicos Islands."                                                                                                                                                                          
##  [38] "Including Ascension and Tristan da Cunha."                                                                                                                                                                                                                                                                                                                                   
##  [39] "Including Ascension and Tristan da Cunha. For statistical purposes, the data for United Kingdom do not include this area."                                                                                                                                                                                                                                                   
##  [40] "Including Ascension and Tristan da Cunha.;St. Helena Island has no substantial natural inland waters however there are 15 reservoirs and similar open water storage features on island."                                                                                                                                                                                     
##  [41] "Including Bermuda, Greenland, and Saint Pierre and Miquelon."                                                                                                                                                                                                                                                                                                                
##  [42] "Including Canary Islands, Ceuta and Melilla."                                                                                                                                                                                                                                                                                                                                
##  [43] "Including Christmas Island, Cocos (Keeling) Islands and Norfolk Island."                                                                                                                                                                                                                                                                                                     
##  [44] "Including Crimea."                                                                                                                                                                                                                                                                                                                                                           
##  [45] "Including East Jerusalem."                                                                                                                                                                                                                                                                                                                                                   
##  [46] "Including Falkland Islands (Malvinas)."                                                                                                                                                                                                                                                                                                                                      
##  [47] "Including Liechtenstein and Monaco."                                                                                                                                                                                                                                                                                                                                         
##  [48] "Including low water level for all islands (area to shoreline)."                                                                                                                                                                                                                                                                                                              
##  [49] "Including Marshall Islands, Nauru, Northern Mariana Islands and Palau."                                                                                                                                                                                                                                                                                                      
##  [50] "Including Nagorno-Karabakh."                                                                                                                                                                                                                                                                                                                                                 
##  [51] "Including Norfolk Island."                                                                                                                                                                                                                                                                                                                                                   
##  [52] "Including Pitcairn."                                                                                                                                                                                                                                                                                                                                                         
##  [53] "Including Sabah and Sarawak."                                                                                                                                                                                                                                                                                                                                                
##  [54] "Including Saint Helena."                                                                                                                                                                                                                                                                                                                                                     
##  [55] "Including Svalbard and Jan Mayen Islands."                                                                                                                                                                                                                                                                                                                                   
##  [56] "Including the Faroe Islands and the Isle of Man."                                                                                                                                                                                                                                                                                                                            
##  [57] "Including the Transnistria region."                                                                                                                                                                                                                                                                                                                                          
##  [58] "Including water bodies of lake Vaihiria, lake Temae and the Maiao lagoons, but not lake Maeva and the lagoons of Raiatea and Tahaa from the upper islands. No lagoons from lower islands are included."                                                                                                                                                                      
##  [59] "Including Zanzibar."                                                                                                                                                                                                                                                                                                                                                         
##  [60] "Inland waters include the reservoirs."                                                                                                                                                                                                                                                                                                                                       
##  [61] "Land area only."                                                                                                                                                                                                                                                                                                                                                             
##  [62] "Land area only. Excluding 84 square km of uninhabited islands."                                                                                                                                                                                                                                                                                                              
##  [63] "Projected estimate (medium fertility variant)."                                                                                                                                                                                                                                                                                                                              
##  [64] "Projected estimate (medium fertility variant).;A dispute exists between the Governments of Argentina and the United Kingdom of Great Britain and Northern Ireland concerning sovereignty over the Falkland Islands (Malvinas). For statistical purposes, the data for United Kingdom do not include this area."                                                              
##  [65] "Projected estimate (medium fertility variant).;Data refer to the Vatican City State."                                                                                                                                                                                                                                                                                        
##  [66] "Projected estimate (medium fertility variant).;Excluding Kosovo."                                                                                                                                                                                                                                                                                                            
##  [67] "Projected estimate (medium fertility variant).;For statistical purposes, the data for China do not include those for the Hong Kong Special Administrative Region (Hong Kong SAR), Macao Special Administrative Region (Macao SAR) and Taiwan Province of China."                                                                                                             
##  [68] "Projected estimate (medium fertility variant).;For statistical purposes, the data for Denmark do not include Faroe Islands, and Greenland."                                                                                                                                                                                                                                  
##  [69] "Projected estimate (medium fertility variant).;For statistical purposes, the data for Denmark do not include this area."                                                                                                                                                                                                                                                     
##  [70] "Projected estimate (medium fertility variant).;For statistical purposes, the data for France do not include French Guiana, French Polynesia, Guadeloupe, Martinique, Mayotte, New Caledonia, Réunion, Saint Pierre and Miquelon, Saint Barthélemy, Saint Martin (French part), Wallis and Futuna Islands."                                                                   
##  [71] "Projected estimate (medium fertility variant).;For statistical purposes, the data for France do not include this area."                                                                                                                                                                                                                                                      
##  [72] "Projected estimate (medium fertility variant).;For statistical purposes, the data for Netherlands do not include Aruba, Bonaire, Sint Eustatius and Saba, Curaçao, and Sint Maarten (Dutch part)."                                                                                                                                                                           
##  [73] "Projected estimate (medium fertility variant).;For statistical purposes, the data for Netherlands do not include this area."                                                                                                                                                                                                                                                 
##  [74] "Projected estimate (medium fertility variant).;For statistical purposes, the data for New Zealand do not include Cook Islands, Niue, and Tokelau."                                                                                                                                                                                                                           
##  [75] "Projected estimate (medium fertility variant).;For statistical purposes, the data for New Zealand do not include this area."                                                                                                                                                                                                                                                 
##  [76] "Projected estimate (medium fertility variant).;For statistical purposes, the data for United Kingdom do not include this area."                                                                                                                                                                                                                                              
##  [77] "Projected estimate (medium fertility variant).;For statistical purposes, the data for United States of America do not include American Samoa, Guam, Northern Mariana Islands, Puerto Rico, and United States Virgin Islands."                                                                                                                                                
##  [78] "Projected estimate (medium fertility variant).;For statistical purposes, the data for United States of America do not include this area."                                                                                                                                                                                                                                    
##  [79] "Projected estimate (medium fertility variant).;Including Abkhazia and South Ossetia."                                                                                                                                                                                                                                                                                        
##  [80] "Projected estimate (medium fertility variant).;Including Agalega, Rodrigues and Saint Brandon."                                                                                                                                                                                                                                                                              
##  [81] "Projected estimate (medium fertility variant).;Including Åland Islands."                                                                                                                                                                                                                                                                                                     
##  [82] "Projected estimate (medium fertility variant).;Including Andorra, Gibraltar, Holy See, and San Marino."                                                                                                                                                                                                                                                                      
##  [83] "Projected estimate (medium fertility variant).;Including Anguilla, Bonaire, Sint Eustatius and Saba, British Virgin Islands, Cayman Islands, Dominica, Montserrat, Saint Kitts and Nevis, Sint Maarten (Dutch part) and Turks and Caicos Islands."                                                                                                                           
##  [84] "Projected estimate (medium fertility variant).;Including Ascension and Tristan da Cunha. For statistical purposes, the data for United Kingdom do not include this area."                                                                                                                                                                                                    
##  [85] "Projected estimate (medium fertility variant).;Including Bermuda, Greenland, and Saint Pierre and Miquelon."                                                                                                                                                                                                                                                                 
##  [86] "Projected estimate (medium fertility variant).;Including Canary Islands, Ceuta and Melilla."                                                                                                                                                                                                                                                                                 
##  [87] "Projected estimate (medium fertility variant).;Including Christmas Island, Cocos (Keeling) Islands and Norfolk Island."                                                                                                                                                                                                                                                      
##  [88] "Projected estimate (medium fertility variant).;Including Crimea."                                                                                                                                                                                                                                                                                                            
##  [89] "Projected estimate (medium fertility variant).;Including East Jerusalem."                                                                                                                                                                                                                                                                                                    
##  [90] "Projected estimate (medium fertility variant).;Including Falkland Islands (Malvinas)."                                                                                                                                                                                                                                                                                       
##  [91] "Projected estimate (medium fertility variant).;Including Liechtenstein and Monaco."                                                                                                                                                                                                                                                                                          
##  [92] "Projected estimate (medium fertility variant).;Including Marshall Islands, Nauru, Northern Mariana Islands and Palau."                                                                                                                                                                                                                                                       
##  [93] "Projected estimate (medium fertility variant).;Including Nagorno-Karabakh."                                                                                                                                                                                                                                                                                                  
##  [94] "Projected estimate (medium fertility variant).;Including Pitcairn."                                                                                                                                                                                                                                                                                                          
##  [95] "Projected estimate (medium fertility variant).;Including Sabah and Sarawak."                                                                                                                                                                                                                                                                                                 
##  [96] "Projected estimate (medium fertility variant).;Including Saint Helena."                                                                                                                                                                                                                                                                                                      
##  [97] "Projected estimate (medium fertility variant).;Including Svalbard and Jan Mayen Islands."                                                                                                                                                                                                                                                                                    
##  [98] "Projected estimate (medium fertility variant).;Including the Faroe Islands and the Isle of Man."                                                                                                                                                                                                                                                                             
##  [99] "Projected estimate (medium fertility variant).;Including the Transnistria region."                                                                                                                                                                                                                                                                                           
## [100] "Projected estimate (medium fertility variant).;Including Zanzibar."                                                                                                                                                                                                                                                                                                          
## [101] "Projected estimate (medium fertility variant).;Refers to the United Kingdom of Great Britain and Northern Ireland. For statistical purposes, the data for United Kingdom do not include Anguilla, Bermuda, British Virgin Islands, Cayman Islands, Channel Islands, Falkland Islands (Malvinas), Gibraltar, Isle of Man, Montserrat, Saint Helena, Turks and Caicos Islands."
## [102] "Projected estimate (medium fertility variant).;Refers to the whole country."                                                                                                                                                                                                                                                                                                 
## [103] "Refers to Guernsey and Jersey."                                                                                                                                                                                                                                                                                                                                              
## [104] "Refers to habitable area. Excludes Saint Lucia's Forest Reserve."                                                                                                                                                                                                                                                                                                            
## [105] "Refers to the United Kingdom of Great Britain and Northern Ireland. For statistical purposes, the data for United Kingdom do not include Anguilla, Bermuda, British Virgin Islands, Cayman Islands, Channel Islands, Falkland Islands (Malvinas), Gibraltar, Isle of Man, Montserrat, Saint Helena, Turks and Caicos Islands."                                               
## [106] "Refers to the whole country."                                                                                                                                                                                                                                                                                                                                                
## [107] "Surface area is 0.44 Km2."                                                                                                                                                                                                                                                                                                                                                   
## [108] "Surface area is based on the 2002 population and housing census."                                                                                                                                                                                                                                                                                                            
## [109] "The land area of Singapore comprises the mainland and other islands."                                                                                                                                                                                                                                                                                                        
## [110] "The total area includes continental areas and islands, and excludes Antarctic area."                                                                                                                                                                                                                                                                                         
## [111] "The total surface is 21 040.79 square kilometres, without taking into account the last ruling of The Hague."

La variable Footnotes, es de tipo character e incluye posibles observaciones asociadas a algunos datos.

levels(as.factor(UN_population$Source))
## [1] "United Nations Population Division, New York, World Population Prospects: The 2022 Revision, last accessed July 2022."                                                                                                                                                                                    
## [2] "United Nations Population Division, New York, World Population Prospects: The 2022 Revision; supplemented by data from the United Nations Statistics Division, New York, Demographic Yearbook 2020 and Secretariat for the Pacific Community (SPC) for small countries or areas, last accessed July 2022."
## [3] "United Nations Statistics Division, New York, \"Demographic Yearbook 2020\" and the demographic statistics database, last accessed June 2022."

La variable source determina el nombre de la fuente de la cual se ha obtenido el dato de cada registro

Concluimos que la tabla nos da un dato, de tipo numérico, por países y periodos temporales, sobre algunos aspectos demográficos y su superficie. Se da información sobre 5 periodos temporales en concreto. En función de que lo queramos hacer, es posible que tengamos que hacer una coerción para cambiar el tipo de algunas variables como el año a tipo Date, o las variables que se usan para clasificar a tipo factor.

Formato EXCEL

Para leer hojas de cálculo excel utilizaremos la librería openxlsx que permite leer archivos alojados localmente o en un servidor web. Como ejemplo vamos a leer datos publicados por la OWID. Podemos leer los datos de la OWID directamente en su servidor web usando un script como el siguiente:

df <- read.xlsx("https://nyc3.digitaloceanspaces.com/owid-public/data/co2/owid-co2-data.xlsx",sheet=1) 

sin embargo, como la base de datos es muy grande y toma bastante tiempo leerla por Internet, hemos guardado algunos datos simplificados sobre la población por países en nuestro repositorio local data.

owid_country <- read.xlsx("https://ctim.es/AEDV/data/owid_country.xlsx",sheet=1) %>%
  as_tibble()

Esta tabla está organizada de forma más sencilla que la tabla UN_population y simplemente con la función str() podemos identificar como está organizada y su contenido:

str(owid_country) # str() imprime la estructura de la tabla
## tibble [237 × 17] (S3: tbl_df/tbl/data.frame)
##  $ iso_code                  : chr [1:237] "ABW" "AFG" "AGO" "AIA" ...
##  $ location                  : chr [1:237] "Aruba" "Afghanistan" "Angola" "Anguilla" ...
##  $ continent                 : chr [1:237] "North America" "Asia" "Africa" "North America" ...
##  $ population                : num [1:237] 106459 41128772 35588996 15877 2842318 ...
##  $ median_age                : num [1:237] 41.2 18.6 16.8 NA 38 NA 34 31.9 35.7 NA ...
##  $ life_expectancy           : num [1:237] 76.3 64.8 61.1 81.9 78.6 ...
##  $ aged_65_older             : num [1:237] 13.09 2.58 2.4 NA 13.19 ...
##  $ aged_70_older             : num [1:237] 7.45 1.34 1.36 NA 8.64 ...
##  $ gdp_per_capit             : num [1:237] 35974 1804 5819 NA 11803 ...
##  $ extreme_poverty           : num [1:237] NA NA NA NA 1.1 NA NA 0.6 1.8 NA ...
##  $ cardiovasc_death_rat      : num [1:237] NA 597 276 NA 304 ...
##  $ diabetes_prevalence       : num [1:237] 11.62 9.59 3.94 NA 10.08 ...
##  $ female_smokers            : num [1:237] NA NA NA NA 7.1 29 1.2 16.2 1.5 NA ...
##  $ male_smokers              : num [1:237] NA NA NA NA 51.2 37.8 37.4 27.7 52.1 NA ...
##  $ handwashing_facilities    : num [1:237] NA 37.7 26.7 NA NA ...
##  $ hospital_beds_per_thousand: num [1:237] NA 0.5 NA NA 2.89 NA 1.2 5 4.2 NA ...
##  $ human_development_index   : num [1:237] NA 0.511 0.581 NA 0.795 0.868 0.89 0.845 0.776 NA ...

Concluimos que esta tabla nos da información por países de algunos indicadores. El código identificativo de los países (variable iso_code), es de 3 letras, en lugar de 3 números como usaba la tabla anterior de UN. Esto supone un problema que habrá que resolver si queremos combinar las dos tablas. Nótese que la organización de esta tabla y la anterior es muy distinta. En esta, cada fila de la tabla contiene la información de todos los indicadores del país, cada uno de ellos corresponde a un campo distinto, y en la tabla anterior, cada fila contiene el dato de un solo indicador, y los nombres de los indicadores están en otro campo. Esta última organización (la de la tabla UN) se denomina tidy data y hablaremos de ella con más detalle al final de este tema.

Formato PC-Axis

El formato PC-Axis, especializado en almacenar datos estadísticos, es el utilizado por el INE y el ISTAD para exportar datos. Se puede editar con cualquier editor de texto plano (como NOTEPAD). Para leer este formato de ficheros usamos la función read.px de la librería pxR. Vamos a continuación a leer datos de la población por municipios de las islas Canarias previamente almacenados en el repositorio local de datos data a partir de una consulta realizada en el ISTAD.

istac_poblacion <- read.px("https://ctim.es/AEDV/data/PoblacionMunicipiosCanarios.px")%>% 
  as_tibble() 
istac_poblacion  %>%
  print(n=5)
## # A tibble: 2,112 × 5
##   Sexos       Años  Edades.año.a.año Municipios.por.islas   value
##   <fct>       <fct> <fct>            <fct>                  <dbl>
## 1 AMBOS SEXOS 2021  TOTAL            CANARIAS             2172944
## 2 AMBOS SEXOS 2020  TOTAL            CANARIAS             2175952
## 3 AMBOS SEXOS 2019  TOTAL            CANARIAS             2153389
## 4 AMBOS SEXOS 2018  TOTAL            CANARIAS             2127685
## 5 AMBOS SEXOS 2017  TOTAL            CANARIAS             2108121
## # ℹ 2,107 more rows
levels(as.factor(istac_poblacion$Sexos))
## [1] "AMBOS SEXOS"
levels(as.factor(istac_poblacion$Años))
##  [1] "2021" "2020" "2019" "2018" "2017" "2016" "2015" "2014" "2013" "2012"
## [11] "2011" "2010" "2009" "2008" "2007" "2006" "2005" "2004" "2003" "2002"
## [21] "2001" "2000"
levels(as.factor(istac_poblacion$`Edades.año.a.año`))
## [1] "TOTAL"
levels(as.factor(istac_poblacion$`Municipios.por.islas`))
##  [1] "CANARIAS"                     "LANZAROTE"                   
##  [3] "Arrecife"                     "Haría"                       
##  [5] "San Bartolomé"                "Teguise"                     
##  [7] "Tías"                         "Tinajo"                      
##  [9] "Yaiza"                        "FUERTEVENTURA"               
## [11] "Antigua"                      "Betancuria"                  
## [13] "Oliva (La)"                   "Pájara"                      
## [15] "Puerto del Rosario"           "Tuineje"                     
## [17] "GRAN CANARIA"                 "Agaete"                      
## [19] "Agüimes"                      "Artenara"                    
## [21] "Arucas"                       "Firgas"                      
## [23] "Gáldar"                       "Ingenio"                     
## [25] "Mogán"                        "Moya"                        
## [27] "Palmas de Gran Canaria (Las)" "San Bartolomé de Tirajana"   
## [29] "Aldea de San Nicolás (La)"    "Santa Brígida"               
## [31] "Santa Lucía"                  "Santa María de Guía"         
## [33] "Tejeda"                       "Telde"                       
## [35] "Teror"                        "Valsequillo"                 
## [37] "Valleseco"                    "Vega de San Mateo"           
## [39] "TENERIFE"                     "Adeje"                       
## [41] "Arafo"                        "Arico"                       
## [43] "Arona"                        "Buenavista del Norte"        
## [45] "Candelaria"                   "Fasnia"                      
## [47] "Garachico"                    "Granadilla de Abona"         
## [49] "Guancha (La)"                 "Guía de Isora"               
## [51] "Güimar"                       "Icod de Los Vinos"           
## [53] "Laguna (La)"                  "Matanza de Acentejo (La)"    
## [55] "Orotava (La)"                 "Puerto de La Cruz"           
## [57] "Realejos (Los)"               "Rosario (El)"                
## [59] "San Juan de La Rambla"        "San Miguel"                  
## [61] "Santa Cruz de Tenerife"       "Santa Úrsula"                
## [63] "Santiago del Teide"           "Sauzal (El)"                 
## [65] "Silos (Los)"                  "Tacoronte"                   
## [67] "Tanque (El)"                  "Tegueste"                    
## [69] "Victoria de Acentejo (La)"    "Vilaflor"                    
## [71] "LA GOMERA"                    "Agulo"                       
## [73] "Alajeró"                      "Hermigua"                    
## [75] "San Sebastián de La Gomera"   "Valle Gran Rey"              
## [77] "Vallehermoso"                 "LA PALMA"                    
## [79] "Barlovento"                   "Breña Alta"                  
## [81] "Breña Baja"                   "Fuencaliente"                
## [83] "Garafía"                      "Llanos de Aridane (Los)"     
## [85] "Paso (El)"                    "Puntagorda"                  
## [87] "Puntallana"                   "San Andrés y Sauces"         
## [89] "Santa Cruz de La Palma"       "Tazacorte"                   
## [91] "Tijarafe"                     "Villa de Mazo"               
## [93] "EL HIERRO"                    "Frontera"                    
## [95] "Valverde"                     "Pinar de El Hierro (El)"

Concluimos que esta tabla nos da información sobre la población de los municipios de las Islas Canarias entre los años 2000 y 2021 incluyendo ambos sexos y sumando todas las edades. No aparece ningún código identificativo del municipio.

Las bases de datos del INE y el ISTAD se obtienen a partir de una consulta que se hace en su servidor web, y es la consulta la que genera el fichero con los datos. Podemos editar el fichero en modo texto para ver algunos metadatos sobre la tabla que se pierden al cargarlos en un tibble. Si la lectura de los ficheros PC-Axis falla, o genera problemas, siempre podemos descargar la consulta, en otro formato de fichero, por ejemplo una hoja excel, e intentar cargar los datos desde la hoja excel.

Formato de texto

En ocasiones, cuando los datos vienen dados por un fichero de texto, no están organizados como una tabla y la lectura del fichero usando las funciones anteriormente vistas puede dar lugar a errores. En ese caso tenemos que corregir y actualizar el fichero antes de cargarlo como tabla. Esto se puede hacer abriendo el fichero con un editor de texto y manipularlo manualmente. Una forma alternativa, y automática, de hacerlo desde R es usar la función read_lines que carga el fichero de texto como un vector que contiene las líneas del fichero y que no asume que tenga un formato de tabla con campos y registros identificables. Podemos editar este vector y volver a escribirlo actualizado usando la función write_lines.

UN_population2 <- read_lines("https://ctim.es/AEDV/data/UN_population.csv")
# eliminamos la primera línea
UN_population2 <- UN_population2[-1]
# sustituimos el string "Region/Country/Area" por "location"
UN_population2 <- gsub('Region/Country/Area','location',UN_population2)  
# eliminamos todas las líneas que contienen el string "Total"
UN_population2 <- UN_population2[str_detect(UN_population2,"Total")==FALSE]
# escribimos el archivo actualizado
write_lines(UN_population2,"UN_population2.csv")

Formato ZIP

la librería readl permite gestionar ficheros comprimidos con ZIP almacenados localmente (no alojados en un servidor). Veamos un ejemplo con datos del fichero “data/UNCTAD.zip” obtenidos del UNCTAD un organismo vinculado a las Naciones Unidas dedicado al Comercio y Desarrollo. Primero vamos a ver que documentos incluye este fichero zip:

unzip("../data/UNCTAD.zip", list = TRUE)
##                                                                                        Name
## 1                                                  US_GovExpenditures_ST202306281615_v1.csv
## 2 Glossary_Classification of the functions of government (COFOG) - Statistics Explained.pdf
## 3                                              UNCTADstat - Productive Capacities Index.pdf
## 4                                                                      WordlOfDebt_data.csv
## 5                                                           Un mundo endeudado _ UNCTAD.pdf
## 6                                                                 US_PCI_20230704063200.csv
##    Length                Date
## 1 1890332 2023-09-18 11:25:00
## 2  670903 2023-09-01 10:56:00
## 3 2446315 2023-09-01 10:50:00
## 4 4248979 2023-09-01 11:19:00
## 5  659704 2023-09-01 11:25:00
## 6 3717173 2023-07-18 17:38:00

Observamos que este fichero zip incluye 3 ficheros CSV con datos y 3 documentos PDF explicativos. Vamos a abrir uno de los ficheros de datos:

WordlOfDebt_data <- read_csv(unzip("../data/UNCTAD.zip", "WordlOfDebt_data.csv")) %>% 
  as_tibble()
str(WordlOfDebt_data)
## tibble [28,455 × 10] (S3: tbl_df/tbl/data.frame)
##  $ ID                     : chr [1:28455] "AF" "AL" "DZ" "AO" ...
##  $ Name                   : chr [1:28455] "Afghanistan" "Albania" "Algeria" "Angola" ...
##  $ Region                 : chr [1:28455] "Developing Asia and Oceania" "Europe and Central Asia*" "Africa" "Africa" ...
##  $ World Bank income group: chr [1:28455] "Low income countries" "Upper middle income countries" "Lower middle income countries" "Lower middle income countries" ...
##  $ Development status     : chr [1:28455] "Developing countries" "Developed countries" "Developing countries" "Developing countries" ...
##  $ LDC                    : num [1:28455] 1 0 0 1 0 0 0 0 0 0 ...
##  $ SIDS                   : num [1:28455] 0 0 0 0 1 0 0 0 0 0 ...
##  $ Indicator              : chr [1:28455] "Public debt as a share of GDP" "Public debt as a share of GDP" "Public debt as a share of GDP" "Public debt as a share of GDP" ...
##  $ Year                   : chr [1:28455] "2010" "2010" "2010" "2010" ...
##  $ Value                  : num [1:28455] 0.077 0.577 0.105 0.372 0.897 ...
levels(as.factor(WordlOfDebt_data$Region))
## [1] "Africa"                          "Developing Asia and Oceania"    
## [3] "Europe and Central Asia*"        "Latin America and the Caribbean"
levels(as.factor(WordlOfDebt_data$`World Bank income group`))
## [1] "High income countries"         "Low income countries"         
## [3] "Lower middle income countries" "Upper middle income countries"
levels(as.factor(WordlOfDebt_data$`Development status`))
## [1] "Developed countries"  "Developing countries"
levels(as.factor(WordlOfDebt_data$`Indicator`))
##  [1] "Bilateral creditors as a share of external public debt"     
##  [2] "External public debt as a share of GDP"                     
##  [3] "External public debt in US$ billions"                       
##  [4] "External public debt in US$ per capita"                     
##  [5] "Multilateral creditors as a share of external public debt"  
##  [6] "Private creditors as a share of external public debt"       
##  [7] "Public debt as a share of GDP"                              
##  [8] "Public debt in US$ billions"                                
##  [9] "Public debt in US$ per capita"                              
## [10] "Public debt interest payments as a share of GDP"            
## [11] "Public debt interest payments as a share of revenues"       
## [12] "Public debt interest payments in US$ per capita"            
## [13] "Public education expenditure as a share of GDP"             
## [14] "Public health expenditure as share of GDP"                  
## [15] "Public investment expenditure as a share of GDP"            
## [16] "Ratio of public interest payments to education expenditure" 
## [17] "Ratio of public interest payments to health expenditure"    
## [18] "Ratio of public interest payments to investment expenditure"
levels(as.factor(WordlOfDebt_data$`Year`))
##  [1] "2010"      "2010-2012" "2011"      "2012"      "2013"      "2014"     
##  [7] "2014-2016" "2015"      "2016"      "2017"      "2018"      "2019"     
## [13] "2019-2021" "2020"      "2021"      "2022"

Concluimos que esta tabla suministra información por países y años (en ocasiones agrupados) de algunos indicadores sobre su deuda. Además los países se clasifican por sus ingresos y nivel de desarrollo.

3.3 Transformación de datos

El paquete dplyr

El paquete dplyr, que se encuentra dentro de la librería `tidyverse, se usa habitualmente para gestionar/transformar los datos. Como resumen de esta sección puede ser útil mirar la siguiente ficha resumen. Veremos, a continuación, las funcionalidades más importantes de este paquete.

filter()

Filtra las filas de la tabla a partir de condiciones. Por ejemplo, con la siguiente instrucción filtramos los países de Europa con una población superior a los 40 millones de habitantes

owid_country %>% 
  filter(continent=="Europe" & population>4e7)
## # A tibble: 6 × 17
##   iso_code location       continent population median_age life_expectancy
##   <chr>    <chr>          <chr>          <dbl>      <dbl>           <dbl>
## 1 DEU      Germany        Europe      83369840       46.6            81.3
## 2 ESP      Spain          Europe      47558632       45.5            83.6
## 3 FRA      France         Europe      67813000       42              82.7
## 4 GBR      United Kingdom Europe      67508936       40.8            81.3
## 5 ITA      Italy          Europe      59037472       47.9            83.5
## 6 RUS      Russia         Europe     144713312       39.6            72.6
## # ℹ 11 more variables: aged_65_older <dbl>, aged_70_older <dbl>,
## #   gdp_per_capit <dbl>, extreme_poverty <dbl>, cardiovasc_death_rat <dbl>,
## #   diabetes_prevalence <dbl>, female_smokers <dbl>, male_smokers <dbl>,
## #   handwashing_facilities <dbl>, hospital_beds_per_thousand <dbl>,
## #   human_development_index <dbl>

Con la función str_detect podemos filtrar la tabla a partir del contenido de un campo de strings. Por ejemplo, a continuación filtramos los países del mundo cuyo nombre contiene el string “ma” (sin tener en cuenta mayúsculas o minúsculas)

owid_country %>% 
  filter(str_detect(location, regex("ma", ignore_case = TRUE)))
## # A tibble: 29 × 17
##    iso_code location             continent population median_age life_expectancy
##    <chr>    <chr>                <chr>          <dbl>      <dbl>           <dbl>
##  1 BHS      Bahamas              North Am…     409989       34.3            73.9
##  2 CYM      Cayman Islands       North Am…      68722       NA              83.9
##  3 DEU      Germany              Europe      83369840       46.6            81.3
##  4 DNK      Denmark              Europe       5882259       42.3            80.9
##  5 GTM      Guatemala            North Am…   17843914       22.9            74.3
##  6 IMN      Isle of Man          Europe         84534       NA              81.4
##  7 JAM      Jamaica              North Am…    2827382       31.4            74.5
##  8 MAC      Macao                Asia          695180       39.2            84.2
##  9 MAF      Saint Martin (Frenc… North Am…      31816       NA              82.1
## 10 MDG      Madagascar           Africa      29611718       19.6            67.0
## # ℹ 19 more rows
## # ℹ 11 more variables: aged_65_older <dbl>, aged_70_older <dbl>,
## #   gdp_per_capit <dbl>, extreme_poverty <dbl>, cardiovasc_death_rat <dbl>,
## #   diabetes_prevalence <dbl>, female_smokers <dbl>, male_smokers <dbl>,
## #   handwashing_facilities <dbl>, hospital_beds_per_thousand <dbl>,
## #   human_development_index <dbl>

select()

Selecciona algunos campos de la tabla. Los campos se pueden seleccionar individualmente o por grupos usando el símbolo :.

owid_country %>% 
  filter(continent=="Europe" & population>4e7) %>% 
  arrange(desc(population)) %>% 
  select(location,life_expectancy:gdp_per_capit)  
## # A tibble: 6 × 5
##   location       life_expectancy aged_65_older aged_70_older gdp_per_capit
##   <chr>                    <dbl>         <dbl>         <dbl>         <dbl>
## 1 Russia                    72.6          14.2          9.39        24766.
## 2 Germany                   81.3          21.5         16.0         45229.
## 3 France                    82.7          19.7         13.1         38606.
## 4 United Kingdom            81.3          18.5         12.5         39753.
## 5 Italy                     83.5          23.0         16.2         35220.
## 6 Spain                     83.6          19.4         13.8         34272.

select también sirve para quitar campos de la tabla poniendo delante del campo el signo -

owid_country %>% 
  filter(continent=="Europe" & population>4e7) %>% 
  arrange(desc(population)) %>% 
  select(-iso_code,-continent)  
## # A tibble: 6 × 15
##   location     population median_age life_expectancy aged_65_older aged_70_older
##   <chr>             <dbl>      <dbl>           <dbl>         <dbl>         <dbl>
## 1 Russia        144713312       39.6            72.6          14.2          9.39
## 2 Germany        83369840       46.6            81.3          21.5         16.0 
## 3 France         67813000       42              82.7          19.7         13.1 
## 4 United King…   67508936       40.8            81.3          18.5         12.5 
## 5 Italy          59037472       47.9            83.5          23.0         16.2 
## 6 Spain          47558632       45.5            83.6          19.4         13.8 
## # ℹ 9 more variables: gdp_per_capit <dbl>, extreme_poverty <dbl>,
## #   cardiovasc_death_rat <dbl>, diabetes_prevalence <dbl>,
## #   female_smokers <dbl>, male_smokers <dbl>, handwashing_facilities <dbl>,
## #   hospital_beds_per_thousand <dbl>, human_development_index <dbl>

arrange()

Ordena la tabla a partir de uno o varios campos

owid_country %>% 
  filter(continent=="Europe" & population>4e7) %>% 
  arrange(desc(population)) # desc() se usa para ordenar en forma descendente. 
## # A tibble: 6 × 17
##   iso_code location       continent population median_age life_expectancy
##   <chr>    <chr>          <chr>          <dbl>      <dbl>           <dbl>
## 1 RUS      Russia         Europe     144713312       39.6            72.6
## 2 DEU      Germany        Europe      83369840       46.6            81.3
## 3 FRA      France         Europe      67813000       42              82.7
## 4 GBR      United Kingdom Europe      67508936       40.8            81.3
## 5 ITA      Italy          Europe      59037472       47.9            83.5
## 6 ESP      Spain          Europe      47558632       45.5            83.6
## # ℹ 11 more variables: aged_65_older <dbl>, aged_70_older <dbl>,
## #   gdp_per_capit <dbl>, extreme_poverty <dbl>, cardiovasc_death_rat <dbl>,
## #   diabetes_prevalence <dbl>, female_smokers <dbl>, male_smokers <dbl>,
## #   handwashing_facilities <dbl>, hospital_beds_per_thousand <dbl>,
## #   human_development_index <dbl>

mutate()

Calcula campos nuevos o modifica campos existentes pudiendo usar los campos de la tabla.

owid_country %>% 
  mutate( gdp = gdp_per_capit * population) %>%
  select(location,population,gdp)  %>%
  arrange(desc(gdp)) %>%
  head(10) %>% 
  knitr::kable( caption = "Países ordenados por su PIB",format = "html",table.attr = "style='width:60%;'")
Table 3.1: Países ordenados por su PIB
location population gdp
China 1425887360 2.182850e+13
United States 338289856 1.834392e+13
India 1417173120 9.107710e+12
Japan 123951696 4.834392e+12
Germany 83369840 3.770755e+12
Russia 144713312 3.583963e+12
Indonesia 275501344 3.082514e+12
Brazil 215313504 3.036664e+12
United Kingdom 67508936 2.683699e+12
France 67813000 2.617966e+12

relocate()

Cambia el orden de las columnas

owid_country %>% 
  relocate(location) %>% # pone location en primer lugar 
  relocate(continent,.after=location) %>%
  relocate(life_expectancy,.after=continent) %>%
  print(n=5)
## # A tibble: 237 × 17
##   location    continent     life_expectancy iso_code population median_age
##   <chr>       <chr>                   <dbl> <chr>         <dbl>      <dbl>
## 1 Aruba       North America            76.3 ABW          106459       41.2
## 2 Afghanistan Asia                     64.8 AFG        41128772       18.6
## 3 Angola      Africa                   61.2 AGO        35588996       16.8
## 4 Anguilla    North America            81.9 AIA           15877       NA  
## 5 Albania     Europe                   78.6 ALB         2842318       38  
## # ℹ 232 more rows
## # ℹ 11 more variables: aged_65_older <dbl>, aged_70_older <dbl>,
## #   gdp_per_capit <dbl>, extreme_poverty <dbl>, cardiovasc_death_rat <dbl>,
## #   diabetes_prevalence <dbl>, female_smokers <dbl>, male_smokers <dbl>,
## #   handwashing_facilities <dbl>, hospital_beds_per_thousand <dbl>,
## #   human_development_index <dbl>

rename()

Cambia el nombre de los campos

owid_country %>% 
  filter(continent=="Europe" & population>4e7) %>% 
  arrange(desc(population)) %>% 
  select(location,population,median_age) %>% 
  rename(country = location)%>%
  knitr::kable( caption = "Países europeos ordenados por su población",format = "html",table.attr = "style='width:60%;'")
Table 3.2: Países europeos ordenados por su población
country population median_age
Russia 144713312 39.6
Germany 83369840 46.6
France 67813000 42.0
United Kingdom 67508936 40.8
Italy 59037472 47.9
Spain 47558632 45.5

str_replace

Esta función reemplaza un string por otro dentro de un vector de strings

owid_country%>%
  mutate(location = str_replace(location,"United States","USA")) %>%
  tail(20)
## # A tibble: 20 × 17
##    iso_code location             continent population median_age life_expectancy
##    <chr>    <chr>                <chr>          <dbl>      <dbl>           <dbl>
##  1 TWN      Taiwan               Asia        23893396       42.2            80.5
##  2 TZA      Tanzania             Africa      65497752       17.7            65.5
##  3 UGA      Uganda               Africa      47249588       16.4            63.4
##  4 UKR      Ukraine              Europe      39701744       41.4            72.1
##  5 URY      Uruguay              South Am…    3422796       35.6            77.9
##  6 USA      USA                  North Am…  338289856       38.3            78.9
##  7 UZB      Uzbekistan           Asia        34627648       28.2            71.7
##  8 VAT      Vatican              Europe           808       NA              75.1
##  9 VCT      Saint Vincent and t… North Am…     103959       31.8            72.5
## 10 VEN      Venezuela            South Am…   28301700       29              72.1
## 11 VGB      British Virgin Isla… North Am…      31332       NA              79.1
## 12 VIR      USA Virgin Islands   North Am…      99479       42.2            80.6
## 13 VNM      Vietnam              Asia        98186856       32.6            75.4
## 14 VUT      Vanuatu              Oceania       326744       23.1            70.5
## 15 WLF      Wallis and Futuna    Oceania        11596       NA              79.9
## 16 WSM      Samoa                Oceania       222390       22              73.3
## 17 YEM      Yemen                Asia        33696612       20.3            66.1
## 18 ZAF      South Africa         Africa      59893884       27.3            64.1
## 19 ZMB      Zambia               Africa      20017670       17.7            63.9
## 20 ZWE      Zimbabwe             Africa      16320539       19.6            61.5
## # ℹ 11 more variables: aged_65_older <dbl>, aged_70_older <dbl>,
## #   gdp_per_capit <dbl>, extreme_poverty <dbl>, cardiovasc_death_rat <dbl>,
## #   diabetes_prevalence <dbl>, female_smokers <dbl>, male_smokers <dbl>,
## #   handwashing_facilities <dbl>, hospital_beds_per_thousand <dbl>,
## #   human_development_index <dbl>

Para cambiar un valor en todo el tibble podemos hacer:

owid_country[owid_country=="United States"] <- "USA"
owid_country%>%
  select(iso_code,location)%>%
  filter(location=="USA")
## # A tibble: 1 × 2
##   iso_code location
##   <chr>    <chr>   
## 1 USA      USA

group_by() y summarise()

group_by agrupa los registros por uno o varios campos y posteriormente summarise nos permite hacer operaciones sobre los agrupamientos obtenidos. La variable sobre la que se realiza el agrupamiento siempre aparece en el resultado de summarise. En el siguiente ejemplo se calcula el PIB por habitante agrupándolo por continentes. Es decir, el dato de cada país se asocia al grupo que comparte el mismo continente.

owid_country %>%  
  group_by(continent)  %>% 
  summarise(
    populationContinent=sum(population),
    gdp_per_capita=sum(na.omit(gdp_per_capit*population))/populationContinent
  ) %>%
  arrange(desc(gdp_per_capita)) %>%
  knitr::kable( caption = "PIB per capita",format = "html",table.attr = "style='width:40%;'")
Table 3.3: PIB per capita
continent populationContinent gdp_per_capita
North America 600323657 38468.345
Europe 745629155 32792.373
Oceania 45038907 31272.576
South America 436816679 14519.141
Asia 4721455390 12148.167
Africa 1426736614 4544.862

En este caso se ha utilizado la función sum para que el resultado sea la suma de los valores de los países de cada continente, se pueden utilizar otras funciones como min, max, mean, median, sd, first, last, prod o n (número de valores del vector).

Combinando datos de varias tablas

Con frecuencia hay que combinar la información de varias tablas. El tipo de combinación que usaremos aquí es el “left_join” que mantiene todos los registros de la primera tabla combinándolos con los de la segunda tabla. Como primer ejemplo vamos a combinar dos tablas de la OWID utilizando como campo común iso_code, que es un código de 3 letras que identifica a cada país. Para ello utilizaremos la función left_join de la librería dplyr.

owid_co2 <- read_csv(unzip("../data/owid-co2.zip", "owid-co2-data.csv")) %>% 
  as_tibble()
left_join(owid_country,owid_co2,by = "iso_code") 
## # A tibble: 41,294 × 95
##    iso_code location continent     population.x median_age life_expectancy
##    <chr>    <chr>    <chr>                <dbl>      <dbl>           <dbl>
##  1 ABW      Aruba    North America       106459       41.2            76.3
##  2 ABW      Aruba    North America       106459       41.2            76.3
##  3 ABW      Aruba    North America       106459       41.2            76.3
##  4 ABW      Aruba    North America       106459       41.2            76.3
##  5 ABW      Aruba    North America       106459       41.2            76.3
##  6 ABW      Aruba    North America       106459       41.2            76.3
##  7 ABW      Aruba    North America       106459       41.2            76.3
##  8 ABW      Aruba    North America       106459       41.2            76.3
##  9 ABW      Aruba    North America       106459       41.2            76.3
## 10 ABW      Aruba    North America       106459       41.2            76.3
## # ℹ 41,284 more rows
## # ℹ 89 more variables: aged_65_older <dbl>, aged_70_older <dbl>,
## #   gdp_per_capit <dbl>, extreme_poverty <dbl>, cardiovasc_death_rat <dbl>,
## #   diabetes_prevalence <dbl>, female_smokers <dbl>, male_smokers <dbl>,
## #   handwashing_facilities <dbl>, hospital_beds_per_thousand <dbl>,
## #   human_development_index <dbl>, country <chr>, year <dbl>,
## #   population.y <dbl>, gdp <dbl>, cement_co2 <dbl>, …

La instrucción by = "iso_code" es equivalente a join_by(iso_code == iso_code). La segunda tiene la ventaja de que podríamos usar un campo común con diferentes nombres en ambas tablas.

La función left_join solo funciona cuando el campo común en ambas tablas es idéntico, si el campo común es un string (por ejemplo el nombre de un municipio) puede haber pequeñas diferencias al escribir el municipio en ambas tablas lo que hace que la comparación falle. Lo ideal es que en todas las tablas, cada registro se acompañe de un código identificativo único y universal. Por ejemplo, el INE utiliza un código identificativo para cada municipio, pero desafortunadamente, este código no acompaña sistemáticamente a las tablas que resultan de hacer una consulta en el INE o en el ISTAC relacionada con municipios. Y lo que es peor, los nombres de los municipios pueden cambiar ligeramente de una consulta a otra, y por tanto, usar el nombre del municipio como identificador puede causar problemas. Para resolver estos problemas, lo primero que hay que hacer al leer una tabla del INE o ISTAC, es intentar asociarle el código identificativo universal del INE a partir del nombre del municipio (si estamos gestionando municipios). Los códigos INE de los municipios los tomaremos de la siguiente tabla que filtramos para quedarnos solo con los municipios canarios.

uclm_mun <- read.xlsx("https://ctim.es/AEDV/data/uclm-list-mun-2012.xlsx",sheet=1) %>%
  as_tibble() %>% filter(CA=="05")
uclm_mun  %>% 
  str()
## tibble [88 × 11] (S3: tbl_df/tbl/data.frame)
##  $ codine          : chr [1:88] "35001" "35002" "35003" "35004" ...
##  $ Municipio       : chr [1:88] "Agaete" "Agüimes" "Antigua" "Arrecife" ...
##  $ Superficie      : num [1:88] 45.5 79.3 250.6 22.7 66.7 ...
##  $ Capitalidad     : chr [1:88] "Agaete" "Agüimes" "Antigua" "Arrecife" ...
##  $ Año             : num [1:88] NA NA NA NA NA NA NA NA NA NA ...
##  $ CA              : chr [1:88] "05" "05" "05" "05" ...
##  $ Autonomía       : chr [1:88] "Canarias" "Canarias" "Canarias" "Canarias" ...
##  $ CP              : chr [1:88] "35" "35" "35" "35" ...
##  $ Provincia       : chr [1:88] "Palmas (Las)" "Palmas (Las)" "Palmas (Las)" "Palmas (Las)" ...
##  $ CPJ             : chr [1:88] "3504" "3508" "3503" "3501" ...
##  $ Partido_Judicial: chr [1:88] "Santa María de Guía de Gran Canaria" "Santa Lucía de Tirajana" "Puerto del Rosario" "Arrecife" ...

A continuación vamos a leer una tabla del ISTAC sobre municipios. Hemos modificado la tabla original añadiendo campos con los nombres de algunos municipios ligeramente cambiados para tener varias opciones a la hora de comparar los nombres: :

istac_municipios <- read.xlsx("https://ctim.es/AEDV/data/istac_municipios.xlsx") %>%
  as_tibble()
istac_municipios %>% 
  filter(is.na(nombre3)==FALSE) %>% 
  print(n=10)
## # A tibble: 19 × 5
##    nombre                       nombre2                 nombre3 isla  superficie
##    <chr>                        <chr>                   <chr>   <chr>      <dbl>
##  1 Aldea de San Nicolás (La)    La Aldea de San Nicolás La Ald… Gran…     124.  
##  2 Palmas de Gran Canaria (Las) Las Palmas de Gran Can… Las Pa… Gran…     101.  
##  3 Llanos de Aridane (Los)      Los Llanos de Aridane   Los Ll… La P…      35.8 
##  4 Puerto de la Cruz            <NA>                    P. de … Tene…       8.73
##  5 Puerto del Rosario           <NA>                    P. del… Fuer…     290.  
##  6 San Andrés y Sauces          <NA>                    S. And… La P…      42.8 
##  7 San Bartolomé                <NA>                    S. Bar… Lanz…      40.9 
##  8 San Bartolomé de Tirajana    San Bartolomé de Tiraj… S. B. … Gran…     333.  
##  9 San Cristóbal de La Laguna   <NA>                    La Lag… Tene…     102.  
## 10 San Juan de la Rambla        <NA>                    S.J. d… Tene…      20.7 
## # ℹ 9 more rows

Como la tabla istac_municipios no tiene el código INE, vamos a añadírselo. Para ello, en primer lugar, vamos a comprobar si a través de los nombres de los municipios en ambas tablas es posible encontrar un “matching” sin fallos entre las dos tablas. Para ello vamos a usar la función LeftJoinNearestString implementada por nosotros en el fichero utilidades.R que hace un “left join” entre dos tibbles de strings u y v que se corresponden con los posibles nombres que vamos a comparar en las 2 tablas usando la función adist, Esta función devuelve un tibble con los siguientes campos:

  • pos : vector con el índice del registro en la tabla v que menor distancia tiene con el de la tabla u

  • value1 : el string dentro de la tabla u que más se parece al de la tabla v

  • value2 : el string dentro de la tabla v que más se parece al de la tabla u

  • dis : la distancia entre los stringsvalue1yvalue2`

Esta función tiene como parámetros adicionales, los parámetros ignore.case y partial que por defecto están asignados como ignore.case=FALSE y partial=FALSE, pero que pueden modificarse añadiéndolos en la llamada a la función.

Nótese que esta función no genera las tablas combinadas, pero con el campo pos podemos poner en correspondencia los registros de una tabla y otra. Por tanto, a partir de esta información podemos combinar las tablas como nos interese. La función `LeftJoinNearestString tiene un elevado coste computacional y solo sirve para bases de datos relativamente pequeñas. Si se aplica en tablas con muchos registros puede tardar mucho.

Hay que tener en cuenta que la comparación puede fallar y por tanto es conveniente verificar y corregir los resultados. A continuación hacemos el “matching” entre los nombres de los municipios en ambas tablas e imprimimos los resultados de los que tienen una distancia mayor que cero.

source("utilidades.R")
res <- LeftJoinNearestString(istac_municipios%>%select(nombre:nombre3),uclm_mun%>%select(Municipio))

res%>%
  arrange(desc(dis)) %>% 
  filter(dis>0) %>% 
  print(n=100)
## # A tibble: 15 × 4
##      pos value1                       value2                        dis
##    <int> <chr>                        <chr>                       <dbl>
##  1    88 Pinar del Hierro (El)        Pinar de El Hierro, El          5
##  2    61 Paso (El)                    Paso, El                        3
##  3    66 Rosario (El)                 Rosario, El                     3
##  4    75 Sauzal (El)                  Sauzal, El                      3
##  5    78 Tanque (El)                  Tanque, El                      3
##  6    20 Aldea de San Nicolás (La)    Aldea de San Nicolás, La        3
##  7    52 Guancha (La)                 Guancha, La                     3
##  8    59 Matanza de Acentejo (La)     Matanza de Acentejo, La         3
##  9    14 Oliva (La)                   Oliva, La                       3
## 10    60 Orotava (La)                 Orotava, La                     3
## 11    85 Victoria de Acentejo (La)    Victoria de Acentejo, La        3
## 12    16 Palmas de Gran Canaria (Las) Palmas de Gran Canaria, Las     3
## 13    58 Llanos de Aridane (Los)      Llanos de Aridane, Los          3
## 14    65 Realejos (Los)               Realejos, Los                   3
## 15    76 Silos (Los)                  Silos, Los                      3

Observamos, inspeccionando el resultado, que el matching no tiene fallos y procedemos a añadir un campo a istac_municipios con el código de cada municipio y guardamos la nueva tabla en disco. De esta manera, en el futuro podríamos usar directamente esta nueva tabla con los código INE.

ine_code <- integer(length(istac_municipios$nombre))
for(i in 1:length(ine_code) ){
  ine_code[i] <- uclm_mun$codine[res$pos[i]]
}
istac_municipios$ine_code <- ine_code
istac_municipios %>%
  relocate(ine_code) %>%
  write.xlsx(file="istac_municipios_ine_codes.xlsx")

Vamos ahora a intentar hacer lo mismo para la tabla istac_poblacion que previamente filtramos para quedarnos con los datos del año 2021

istac_poblacion2021 <- istac_poblacion %>% 
  filter(Años==2021) %>%
  mutate(Municipios.por.islas=as.character(Municipios.por.islas))
istac_poblacion2021
## # A tibble: 96 × 5
##    Sexos       Años  Edades.año.a.año Municipios.por.islas   value
##    <fct>       <fct> <fct>            <chr>                  <dbl>
##  1 AMBOS SEXOS 2021  TOTAL            CANARIAS             2172944
##  2 AMBOS SEXOS 2021  TOTAL            LANZAROTE             156189
##  3 AMBOS SEXOS 2021  TOTAL            Arrecife               64497
##  4 AMBOS SEXOS 2021  TOTAL            Haría                   5365
##  5 AMBOS SEXOS 2021  TOTAL            San Bartolomé          19058
##  6 AMBOS SEXOS 2021  TOTAL            Teguise                23044
##  7 AMBOS SEXOS 2021  TOTAL            Tías                   20801
##  8 AMBOS SEXOS 2021  TOTAL            Tinajo                  6447
##  9 AMBOS SEXOS 2021  TOTAL            Yaiza                  16977
## 10 AMBOS SEXOS 2021  TOTAL            FUERTEVENTURA         119662
## # ℹ 86 more rows
res <- LeftJoinNearestString(istac_municipios%>%select(nombre:nombre3),istac_poblacion2021%>%select(Municipios.por.islas))

res%>%
  arrange(desc(dis)) %>% 
  filter(dis>0) %>% 
  print(n=100)
## # A tibble: 8 × 4
##     pos value1                     value2                       dis
##   <int> <chr>                      <chr>                      <dbl>
## 1    11 La Laguna                  Antigua                        6
## 2    96 Pinar del Hierro (El)      Pinar de El Hierro (El)        2
## 3    51 Güímar                     Güimar                         1
## 4    52 Icod de los Vinos          Icod de Los Vinos              1
## 5    56 Puerto de la Cruz          Puerto de La Cruz              1
## 6    59 San Juan de la Rambla      San Juan de La Rambla          1
## 7    75 San Sebastián de la Gomera San Sebastián de La Gomera     1
## 8    89 Santa Cruz de la Palma     Santa Cruz de La Palma         1

En este caso, observamos que en el municipio de “La Laguna” falla el matching. Una forma sencilla de resolver esto es editar a mano el fichero donde está almacenada la tabla istac_municipios y añadir como posible nombre del municipio el nombre con el que aparece en la otra tabla y volver a lanzar el script de R para comprobar si se ha resuelto el problema.

Tidy data (datos ordenados)

La misma información se puede organizar de muy diversas formas. Sin embargo, una buena organización requiere cumplir con ciertos criterios de la organización ordenada de datos “tidy data”. Estos criterios son esencialmente:

  • Cada variable (o campo) que mides debe corresponder a una única columna. Es decir las instancias de la misma variable no pueden estar asignadas a columnas distintas.

  • Cada fila solo puede contener el dato de una única observación. En otras palabras, en cada fila puede haber varias variables categóricas (incluidas fechas) pero un único valor observado.

  • Debe haber una tabla distinta para cada “clase” de variable. Es decir no se pueden combinar datos heterogéneos en la misma tabla.

  • Si tienes múltiples tablas, debe existir una columna en cada tabla que permita enlazarlas.

Vamos a ilustrar este concepto con un ejemplo de un tibble de algunos datos de población (en millones) de España, Francia y Alemania

data <- tibble(
  año=c(1985,2000,2015),
  España=c(38.734,40.75,46.122),
  Francia=c(55.38,59.387,64.395),
  Alemania=c(77.57,81.896,80.689))
data%>%
  knitr::kable( caption = "Tabla de datos no ordenados",format = "html",table.attr = "style='width:50%;'")
Table 3.4: Tabla de datos no ordenados
año España Francia Alemania
1985 38.734 55.380 77.570
2000 40.750 59.387 81.896
2015 46.122 64.395 80.689

esta forma de organizar una tabla se usa con frecuencia porque es una manera natural en la escribiríamos los datos si lo hiciéramos a mano. Sin embargo no cumple con los criterios de “tidy data” porque los campos con los nombres de las países son instancias de la variable país, y por tanto las columnas de la tabla deberían ser año,país y población. La función pivot_longer convierte automáticamente el tibble anterior en un tibble “ordenado” eliminando columnas y añadiendo filas:

data %>%
  pivot_longer(c(`España`, `Francia`, `Alemania`), names_to = "country", values_to = "population")%>%
  knitr::kable( caption = "Tabla de datos ordenados",format = "html",table.attr = "style='width:30%;'")
Table 3.5: Tabla de datos ordenados
año country population
1985 España 38.734
1985 Francia 55.380
1985 Alemania 77.570
2000 España 40.750
2000 Francia 59.387
2000 Alemania 81.896
2015 España 46.122
2015 Francia 64.395
2015 Alemania 80.689

Una ventaja importante de los “tidy data” es que hay muchos procesos y funciones diseñados para trabajar con esta organización de la información. En particular, los procesos de visualización de datos requieren “tidy data”. En ocasiones es interesante hacer la operación contraria a pivot_longer que es pivot_wider que organiza la tabla añadiendo columnas y quitando filas. Esto permite separar los campos y manejarlos individualmente :

data %>%
  pivot_longer(c(`España`, `Francia`, `Alemania`), names_to = "country", values_to = "population") %>%
  pivot_wider(names_from = country, values_from = population)
## # A tibble: 3 × 4
##     año España Francia Alemania
##   <dbl>  <dbl>   <dbl>    <dbl>
## 1  1985   38.7    55.4     77.6
## 2  2000   40.8    59.4     81.9
## 3  2015   46.1    64.4     80.7

Observamos que hacer un pivot_longer y a continuación un pivot_wider nos lleva a la tabla original. Estas operaciones nos permiten manejar la misma tabla en el formato que nos interese en cada momento.

Como resumen de esta sección puede ser útil mirar la siguiente ficha resumen.

La organización de las bases de datos públicas que usamos en este curso difiere bastante entre ellas. Por ejemplo las tablas de la OWID contienen muchas columnas con variables distintas y cada línea de la tabla es una observación de todas las variables para un país en una fecha concreta. Sin embargo, las tablas de la UN ponen una columna que contiene el nombre de la variable y una sola columna con el valor numérico para dicha variable, de tal manera que cada línea incluye únicamente la observación de una variable. Las bases del INE y el ISTAC tienen una organización similar a la de UN.

Combinando datos de UN y OWID

Las bases de datos de la OWID utilizan un código ISO (International Organization for Standardization) de 3 letras para identificar los países. Sin embargo las bases de datos de la UN utiliza su propia codificación. Para combinar tablas de las dos bases de datos utilizaremos una tabla que suministra las UN con las equivalencias entre diferentes códigos de países que nosotros hemos almacenado en el fichero “data/UN_code.xlsx”

UN_code <- read.xlsx("https://ctim.es/AEDV/data/UN_code.xlsx",sheet=1) %>%
  as_tibble()
UN_code %>%
  str()
## tibble [246 × 9] (S3: tbl_df/tbl/data.frame)
##  $ ctyCode             : num [1:246] 533 4 24 660 8 20 784 32 51 16 ...
##  $ ISO_A2              : chr [1:246] "AW" "AF" "AO" "AI" ...
##  $ ISO_A3              : chr [1:246] "ABW" "AFG" "AGO" "AIA" ...
##  $ cty.Name.English    : chr [1:246] "Aruba" "Afghanistan" "Angola" "Anguilla" ...
##  $ cty.Fullname.English: chr [1:246] "Aruba" "Afghanistan" "Angola" "Anguilla" ...
##  $ Cty.Abbreviation    : chr [1:246] "Aruba" "Afghanistan" "Angola" "Anguilla" ...
##  $ Cty.Comments        : chr [1:246] "NULL" "NULL" "NULL" "NULL" ...
##  $ Start.Valid.Year    : num [1:246] 1988 1962 1962 1981 1962 ...
##  $ End.Valid.Year      : num [1:246] 2061 2061 2061 2061 2061 ...

En esta tabla aparecen 3 códigos para cada país: en el campo ctyCode aparece un código numérico, en el campo ISO_A2 aparece un código de 2 caracteres y en el campo ISO_A3 aparece un código de 3 caracteres.

A continuación leemos una tabla de la UN, le cambiamos el nombre a algunos campos de interés, seleccionamos los campos y hacemos un pivot_wider

UN_population <- as_tibble(read_csv("https://ctim.es/AEDV/data/UN_population.csv",skip=1))%>%
  rename(un_code=`Region/Country/Area`,country=...2) %>%
  select(un_code,country,Year,Series,Value) %>%
  pivot_wider(names_from = Series, values_from = Value)
UN_population %>%
  str()
## tibble [1,056 × 11] (S3: tbl_df/tbl/data.frame)
##  $ un_code                                             : num [1:1056] 1 1 1 1 2 2 2 2 15 15 ...
##  $ country                                             : chr [1:1056] "Total, all countries or areas" "Total, all countries or areas" "Total, all countries or areas" "Total, all countries or areas" ...
##  $ Year                                                : num [1:1056] 2010 2015 2020 2022 2010 ...
##  $ Population mid-year estimates (millions)            : num [1:1056] 6986 7427 7841 7975 1055 ...
##  $ Population mid-year estimates for males (millions)  : num [1:1056] 3514 3737 3944 4009 526 ...
##  $ Population mid-year estimates for females (millions): num [1:1056] 3471 3689 3897 3967 529 ...
##  $ Sex ratio (males per 100 females)                   : num [1:1056] 101.2 101.3 101.2 101.1 99.3 ...
##  $ Population aged 0 to 14 years old (percentage)      : num [1:1056] 27.1 26.4 25.7 25.3 41.5 41.3 40.5 40.1 32.4 32.8 ...
##  $ Population aged 60+ years old (percentage)          : num [1:1056] 11.1 12.3 13.5 13.9 5 5.2 5.4 5.5 6.6 7.3 ...
##  $ Population density                                  : num [1:1056] 53.6 57 60.1 61.2 35.7 40.6 46 48.3 26.9 29.7 ...
##  $ Surface area (thousand km2)                         : num [1:1056] NA 136162 130094 NA NA ...

Ahora, usando left_join combinaremos las tablas y ordenamos un poco sus campos

owid_country %>%
  select(iso_code:population) %>%
  left_join(UN_code,join_by(iso_code==ISO_A3))  %>%
  left_join(UN_population,join_by (ctyCode==un_code))  %>%
  relocate(Year, .after=iso_code) %>%
  str()
## tibble [882 × 22] (S3: tbl_df/tbl/data.frame)
##  $ iso_code                                            : chr [1:882] "ABW" "ABW" "ABW" "ABW" ...
##  $ Year                                                : num [1:882] 2010 2015 2020 2022 2010 ...
##  $ location                                            : chr [1:882] "Aruba" "Aruba" "Aruba" "Aruba" ...
##  $ continent                                           : chr [1:882] "North America" "North America" "North America" "North America" ...
##  $ population                                          : num [1:882] 106459 106459 106459 106459 41128772 ...
##  $ ctyCode                                             : num [1:882] 533 533 533 533 4 4 4 4 24 24 ...
##  $ ISO_A2                                              : chr [1:882] "AW" "AW" "AW" "AW" ...
##  $ cty.Name.English                                    : chr [1:882] "Aruba" "Aruba" "Aruba" "Aruba" ...
##  $ cty.Fullname.English                                : chr [1:882] "Aruba" "Aruba" "Aruba" "Aruba" ...
##  $ Cty.Abbreviation                                    : chr [1:882] "Aruba" "Aruba" "Aruba" "Aruba" ...
##  $ Cty.Comments                                        : chr [1:882] "NULL" "NULL" "NULL" "NULL" ...
##  $ Start.Valid.Year                                    : num [1:882] 1988 1988 1988 1988 1962 ...
##  $ End.Valid.Year                                      : num [1:882] 2061 2061 2061 2061 2061 ...
##  $ country                                             : chr [1:882] "Aruba" "Aruba" "Aruba" "Aruba" ...
##  $ Population mid-year estimates (millions)            : num [1:882] 0.1 0.1 0.11 0.11 28.19 ...
##  $ Population mid-year estimates for males (millions)  : num [1:882] 0.05 0.05 0.05 0.05 14.24 ...
##  $ Population mid-year estimates for females (millions): num [1:882] 0.05 0.05 0.06 0.06 13.95 ...
##  $ Sex ratio (males per 100 females)                   : num [1:882] 91.2 90.2 89.1 89.2 102.1 ...
##  $ Population aged 0 to 14 years old (percentage)      : num [1:882] 20.7 18.8 17.4 16.2 49 45.8 43.8 43.1 45.7 45.8 ...
##  $ Population aged 60+ years old (percentage)          : num [1:882] 14.7 18.2 22.4 23.9 3.8 3.8 3.8 3.8 4.1 4.1 ...
##  $ Population density                                  : num [1:882] 557.5 579.2 592.1 591.4 43.4 ...
##  $ Surface area (thousand km2)                         : num [1:882] NA 0 0 NA NA ...

3.4 Análisis exploratorio inicial

Cualquier análisis de datos debe empezar por entender el contenido y organización de los datos que se van a utilizar. Para ello, sistemáticamente, abordaremos los siguientes pasos preliminares:

  1. Abrir los ficheros con los datos en formato texto o con excel (si se trata de una hoja excel) y analizar su contenido.
  2. Localizar y entender la posibles metadatos asociados. Los metadatos que, en general, acompañan a los datos, nos suministran información muy valiosa para entender el contenido de los datos. Estos metadatos pueden estar en otros ficheros o incluidos en alguna parte del fichero de datos. Hay que tener en cuenta que en este caso, los metadatos se pierden al cargar los datos como un tibble y hay que mirarlos en los ficheros de datos originales. Esto pasa, por ejemplo, en los ficheros en formato px.
  3. Identificar los tipos de las variables. Si hay una variable con información de fechas, identificar el formato. Estudiar si hay que hacer coerción de variables y transformar la variable con información de fechas.
  4. Identificar si los datos tienen una organización tidy, es decir, si cada fila incluye una sola observación acompañada de posibles variables categóricas (que se usan para clasificar) o, por el contrario, cada fila contiene múltiples observaciones.
  5. Identificar el rango de las variables categóricas para entender los posibles items de clasificación de los datos. Por ejemplo, si la variable categórica es el sexo, identificar que posibles valores puede tomar esta variable. Para ello podemos usar la funcionalidad de R levels(as.factor(NombreVariable))
  6. Identificar si existe una variable índice que nos va a permitir combinar la información de nuestra tabla de datos con otras tablas.
  7. Analizar la ausencia de datos NA e identificar como se codifica la ausencia de datos en los datos analizados. En el caso de series temporales, que son datos que van cambiando con el tiempo, la ausencia de datos puede deberse a que falten fechas intermedias. Esto en R se puede detectar usando la función lag para comparar una variable fecha con la misma variable desplazada un valor. Veamos un ejemplo:
date <-as.Date(c("2023-01-1","2023-01-2","2023-01-4","2023-01-5"))
date-lag(date)
## Time differences in days
## [1] NA  1  2  1

de esta manera, podemos detectar que faltan fechas cuando el valor de date-lag(date) es mayor que 1. Todo este análisis exploratorio inicial es fundamental y es necesario hacerlo como paso preliminar a cualquier procesado posterior de los datos.

Referencias

[Pe15] Roger D. Peng. R Programming for Data Science, Lulu, 2015.

[WiÇeGa23] Wickham, Hadley, Mine Çetinkaya-Rundel and Garrett Grolemund. R for Data Science (2e), O’Reilly Media, 2023.