15 Mapas con R. Un poco de geografía lingüística (II)

15.1 shapefiles

Los mapas que has dibujado en el capítulo anterior son suficientemente buenos cuando no necesitas mayor precisión. Sin embargo, a veces puedes necesitar mayor detalle en lo que se refiere a los límites territoriales, que pueden ir desde los límites de la comunidad autómona a los de cada municipio. Todo depende de tu objetivo. Pero eso hace que sea algo más complicado que lo que has visto en la sección anterior.

Con los datos sobre el hinojo he redibujado el mapa limitándolo al territorio que comprende el Atlas Lingüístico y Etnográfico de Aragón, Navarra y La Rioja. Y lo he hecho con los límites provinciales, como puedes ver en el mapa que hay la figura 15.1.

Los resultados de F- incial en en ALEARN sobre un mapa con los límites provinciales

Figura 15.1: Los resultados de F- incial en en ALEARN sobre un mapa con los límites provinciales

Para dibujarlo la cosa se ha complicado un poco. Necesitarás una nueva librería, {sf}, y algo un poco más complejo: un fichero con la información geográfica, con los límites geográficos. Estos ficheros se llamadan shapefile y tienen las extensión .shp.

15.1.1 Obtención de los materiales

Ya sabes cómo instalar una librería. Puedes hacerlo desde el panel Packages o con la instrucción install.packages("sf"). Así que adelante. Instálala. El segundo elemento, la shapefile no es muy complicado, pero dar con la correcta puede serlo puesto que hay multitud de sitios en donde puedes conseguirlos. Todo depende del grado de granularidad que desees y del ámbito geográfico que quieras cubrir. Desde DIVA-GIS te puedes descargar un zip con todas las divisiones administrativas de España con cinco niveles:

  • 0 España (perímetro)
  • 1 España por comunidades autónomas
  • 2 España por provincias
  • 3 España por comarcas
  • 4 España por municipios.

Para lo que pretendes, estos ficheros son suficientes. Pero solo son el perfil de España (islas Canarias incluidas, así como Ceuta, Melilla y otros territorios del norte de África). No incluye el perfil de Portugal ni de Andorra ni el sur de Francia que, para cuestiones de lingüística iberorrománica son esenciales. Para obtener los perfiles necesarios de España, Portugal y el sur de Francia tienes que recurrir a la Base Cartográfica Nacional que ofrece toda la península Ibérica, el sur de Francia, Marruecos, y partes del Sahara Occidental, Argelia y Mauritania. Lo bueno es que en España la granularidad es provincial y, consiguiente, por comunidades. Para descargarlo basta con ir al Centro de Descargas del Intituto Geográfico Nacional, hacer clic sobre «Mapas vectoriales y Bases Cartográficas y Topográficas» y pulsar en Descargar el BCN500 (es el último de la página).

Tanto uno como el otro son ficheros comprimidos y ocuparán algo de espacio en el disco duro. Una vez que los descargues, descomprímelos. Mi recomendación es que crees un directorio en el que guardes estas nuevas carpetas con información geográfica. Yo la tengo en una directorio que he llamado mapas que tiene varios subdirectorios, uno para cada uno de los dos tipos juegos de ficheros que he bajado: BCN500 y ESP_adm.

BCN500 tiene muchas capas para dibujar carreteras, aeropuertos, ferrocarriles, ríos y otros recursos hídricos, etc. La básica para tu objetivo es BCN500_0101S_LIMITE_ADM.shp, que es la responsable de dibujar el mapa que tienes en la figura 15.2.

Los territorios recogidos en el BCN500 del Instituto Geográfico Nacional

Figura 15.2: Los territorios recogidos en el BCN500 del Instituto Geográfico Nacional

En ESP_adm, como ya te he dicho, tienes cinco niveles, que van desde todo el contorno de toda España a los municipios de todas la provincias de todas las comunidades. En la figura 15.3 tienes el mapa de los municipios de Valladolid.

Mapa con los municipios de Valladolid según `ESP_adm4`

Figura 15.3: Mapa con los municipios de Valladolid según ESP_adm4

También puedes imprimir las comarcas, tanto de una provincia, como en el mapa de la figura 15.4, como de toda una comunidad (figura 15.5).

Las comarcas de la provincia de Valladolid según `ESP_adm3`

Figura 15.4: Las comarcas de la provincia de Valladolid según ESP_adm3

Las comarcas de Castilla y León según `ESP_adm3`

Figura 15.5: Las comarcas de Castilla y León según ESP_adm3

También puedes representar las provincias. Tanto individualmente (figura 15.6) como todas las de una comunidad autónoma (figura 15.7) o de toda España.

La provincia de Valladolid según `ESP_adm2`

Figura 15.6: La provincia de Valladolid según ESP_adm2

La provincias de Castilla y León según `ESP_adm2`

Figura 15.7: La provincias de Castilla y León según ESP_adm2

Qué granularidad debes utilizar depende del objetivo de tu análisis. Si trabajas, por ejemplo, con un atlas regional (de pequeño dominio) solo te interesarán las provincias de ese territorio o tan solo la región considerada en el atlas. En cambio, si quieres usar una atlas de tipo supranacional (de gran dominio), entonces necesitas todos los territorios que lo constituyen, aunque a veces tan solo te puedan interesar unas regiones determinadas.

15.2 Un atlas de pequeño dominio y otro de gran dominio

Vas a trabajar con ambos tipos, por lo que vas a utilizar los dos tipos de shapefile que has descargado. El primer caso, un atlas de pequeño dominio: el Atlas Lingüístico y Etnográfico de Aragón, Navarra y La Rioja, por lo que solo te intereresarán esas tres comunidades autónomas y sus provincias. En el segundo, un atlas de gran dominio: el Atlas Lingüístico de la Península Ibérica (ALPI) y te interesa no solo el territorio de España, sino también Portugal y parte del sur de Francia, aunque en estos dos últimos hay que renunciar a las divisiones administrativas que pudieran equivaler a nuestras provincias.

En el primer caso obtendrás un mapa como el de la figura 15.8.

Los resultado de F- inicial en el ALEARN sobre un perfil comarcal de `ESP_adm3`

Figura 15.8: Los resultado de F- inicial en el ALEARN sobre un perfil comarcal de ESP_adm3

En el segundo el de la figura 15.9, que es un pelín más complicado de hacer, aunque la mayoría de los elementos son los mismos.

Las designaciones del _Sus scrofa_ en la Iberorromania sobre un perfil del `BCN500`

Figura 15.9: Las designaciones del Sus scrofa en la Iberorromania sobre un perfil del BCN500

15.3 Un atlas de pequeño dominio

Para el atlas de pequeño dominio de la figura 15.8 he utilizado el código que hay a continuación. Córtalo y pégalo en el editor de RStudio, pero no lo ejecutes. Lee las explicaciones y ve ejecutándolo según te indique.

library(sf)
library(tidyverse)
mapa <- st_read("../mapas/ESP_adm/ESP_adm3.shp")
ALEARN <- c("Aragón", "Comunidad Foral de Navarra", "La Rioja")
ALEARN_mapa <- mapa %>%
  filter(NAME_1 %in% ALEARN)
ALEARN_datos <- read_tsv("https://raw.githubusercontent.com/7PartidasDigital/AnaText/master/datos/geolinguistic/hinojo_alearn.txt")
ggplot() +
  geom_sf(data = ALEARN_mapa) +
  geom_text(data = ALEARN_datos,
            aes(x=longitud,
                y=latitud,
                label = F_inicial,
                colour = F_inicial),
            size = 4) +
  theme(legend.position = "none",
        panel.grid.major = element_line(color = "white"),
        panel.grid = element_blank(),
        axis.title = element_blank(),
        axis.text = element_blank(),
        axis.ticks = element_blank(),
        panel.background = element_blank(),
        rect = element_blank()) +
  labs(title = "Tratamiento de F- en el ALEARN",
       subtitle = "FOENICULUM")

15.3.1 Explicación del código

Lo primero es cargar las dos librerías que va a necesitar. Empieza con {tidyverse} que es la que se encargará de hacerte la vida más fácil en el manejo de las tablas de datos que utilizarás.

library(tidyverse)

Tan pronto como la cargues, el sistema te responderá con el clásico aviso de los paquetes que la constituyen

La siguiente librería que has de cargar es {sf}, que te ayudará a manejar los datos geográficos de los ficheros shapefile.

library(sf)

Tan pronto como la cargues, el sistema te responderá con

El siguiente paso es cargar el fichero shapefile que dibujará los límites geográficos. Puesto que lo que quieres es representarlo sobre las comarcas tienes que cargar el mapa del nivel 3. Debes sustituir todo lo que haya antes de /ESP_adm/ESP_adm3.shp por la ruta donde hayas guardado los ficheros después de descomprimirlos.

mapa <- st_read("../mapas/ESP_adm/ESP_adm3.shp")

Tan pronto ejecutes la orden, se habrá cargado la información en el objeto mapa y en la consola habrá aparecido un montón de información.

## Reading layer `ESP_adm3' from data source 
##   `/Users/JMFR/Library/CloudStorage/OneDrive-UVa/mapas/ESP_adm/ESP_adm3.shp' using driver `ESRI Shapefile'
## Simple feature collection with 369 features and 13 fields
## Geometry type: MULTIPOLYGON
## Dimension:     XY
## Bounding box:  xmin: -18.16153 ymin: 27.63736 xmax: 4.328195 ymax: 43.79153
## Geodetic CRS:  WGS 84

Vamos a desentrañarla. La primera línea te informa que ha leído una capa designada ESP_adm3 que se encuentra en el fichero ../mapas/ESP_adm/ESP_adm3.shp (todo lo que hay antes es la ruta en mi ordenador, en el tuyo será otra). Y lo ha leído utilizando el sistema desarrollado por Environmental Systems Research Institute –ESRI–. Se trata de una colección sencilla de rasgos (Simple Features) de trece columnas (fields) y 369 líneas (features). En realidad es una tabla, una dataframe. Lo veremos en un instante. Una de las columnas tiene información geométrica de tipo multipolígono, que es donde están los datos que permitirán dibujar los cortornos geográficos. Lo hace por medio de ejes cartesianos XY. La línea bbox es muy interesante, pues lo que hace es delimitar el ámbito geográfico que dibujará, y que se encuentra entre los paralelos (latitud) 27.63736 y 43.791153 y los meridianos (longitud) -18.16153 y 4.328195. Piensa que es como si le aplicaras a la faz de tierra una ventana rectangular cuyos límites coinciden con esas latitudes y longitudes. Por ahora es algo de lo que puedes pasar, pero un poco más abajo volveré sobre ello y te será de gran ayuda. Ya lo verás. La última línea informa de cuál es el sistema de referencia de coordenadas (CRS Coordinate Reference Systems). Hay varios sistemas, en este caso usa las coordenadas WGS84. No voy a entrar en estos detalles técnicos. No merece la pena, pues nos puede distraer del objetivo principal: dibujar mapas de interés lingüístico con R.

Acabo de decirte que lo que tienes en mapa es una tabla. Puedes comproblarlo con class(mapa). Si ejecutas esta función en la consola te responderá con un escueto

## [1] "sf"         "data.frame"

Se trata de una data.frame del tipo sf, es decir, creada por la librería {sf} que contiene simple features. También podrías ver la estructura con str(mapa), pero también puedes examinarla si ejecutas en la consola

mapa

Tan pronto como lo hagas presentará la información que se imprimió al cargar el fichero, pero con el añadido de las diez primeras líneas de la tabla y los nombres de cada columna (estos también los puedes obtener con colnames(mapa); pruébalo en la consola).

## Simple feature collection with 369 features and 13 fields
## Geometry type: MULTIPOLYGON
## Dimension:     XY
## Bounding box:  xmin: -18.16153 ymin: 27.63736 xmax: 4.328195 ymax: 43.79153
## Geodetic CRS:  WGS 84
## First 10 features:
##    ID_0 ISO NAME_0 ID_1    NAME_1 ID_2  NAME_2 ID_3           NAME_3  TYPE_3 ENGTYPE_3 NL_NAME_3
## 1   215 ESP  Spain    1 Andalucía    1 Almería    1        n.a. (15) Comarca   Comarca      <NA>
## 2   215 ESP  Spain    1 Andalucía    1 Almería    2        n.a. (16) Comarca   Comarca      <NA>
## 3   215 ESP  Spain    1 Andalucía    1 Almería    3        n.a. (17) Comarca   Comarca      <NA>
## 4   215 ESP  Spain    1 Andalucía    1 Almería    4        n.a. (18) Comarca   Comarca      <NA>
## 5   215 ESP  Spain    1 Andalucía    1 Almería    5        n.a. (19) Comarca   Comarca      <NA>
## 6   215 ESP  Spain    1 Andalucía    1 Almería    6        n.a. (20) Comarca   Comarca      <NA>
## 7   215 ESP  Spain    1 Andalucía    1 Almería    7        n.a. (21) Comarca   Comarca      <NA>
## 8   215 ESP  Spain    1 Andalucía    1 Almería    8        n.a. (22) Comarca   Comarca      <NA>
## 9   215 ESP  Spain    1 Andalucía    2   Cádiz    9   Bahía de Cádiz Comarca   Comarca      <NA>
## 10  215 ESP  Spain    1 Andalucía    2   Cádiz   10 Campiña de Jerez Comarca   Comarca      <NA>
##    VARNAME_3                       geometry
## 1       <NA> MULTIPOLYGON (((-2.306884 3...
## 2       <NA> MULTIPOLYGON (((-2.070494 3...
## 3       <NA> MULTIPOLYGON (((-2.830269 3...
## 4       <NA> MULTIPOLYGON (((-3.00383 37...
## 5       <NA> MULTIPOLYGON (((-3.030139 3...
## 6       <NA> MULTIPOLYGON (((-2.738094 3...
## 7       <NA> MULTIPOLYGON (((-1.911064 3...
## 8       <NA> MULTIPOLYGON (((-2.184581 3...
## 9       <NA> MULTIPOLYGON (((-6.219583 3...
## 10      <NA> MULTIPOLYGON (((-6.050446 3...

Las cuatro primeras columnas son de poco interés para lo que quieres hacer, pues son números (salvo ISO y NAME_0 que identifican en embos casos que los mapas son de España). Las importantes para ti son NAME_1, NAME_2 y NAME_3. También es fundamental la llamada geometry, pero esta no la manejarás tú sino R. NAME_1 contiene el nombre de todas las comunidades autónomas. Puedes verlo con esta secuencia:

mapa %>%
  count(NAME_1) %>%
  print(n = Inf)

que imprimirá la información técnica de la tabla y en la columna NAME_1 podrás ver los nombres de cada comunidad autónoma. No son los oficiales, son lo que hay dentro de fichero shp y serán las que tú tengas que usar para manejar la información.

## Simple feature collection with 18 features and 2 fields
## Geometry type: GEOMETRY
## Dimension:     XY
## Bounding box:  xmin: -18.16153 ymin: 27.63736 xmax: 4.328195 ymax: 43.79153
## Geodetic CRS:  WGS 84
##                        NAME_1  n                       geometry
## 1                   Andalucía 58 MULTIPOLYGON (((-6.836527 3...
## 2                      Aragón 22 POLYGON ((-0.753443 42.9245...
## 3                   Cantabria 11 MULTIPOLYGON (((-4.026528 4...
## 4             Castilla y León 65 MULTIPOLYGON (((-4.160161 4...
## 5          Castilla-La Mancha 34 MULTIPOLYGON (((-3.367154 4...
## 6                    Cataluña 40 MULTIPOLYGON (((3.186806 41...
## 7             Ceuta y Melilla  2 MULTIPOLYGON (((-4.300972 3...
## 8  Comunidad Foral de Navarra  9 POLYGON ((-1.308545 43.0692...
## 9        Comunidad Valenciana 35 MULTIPOLYGON (((-0.458195 3...
## 10        Comunidad de Madrid  6 MULTIPOLYGON (((-4.263162 4...
## 11                Extremadura 22 POLYGON ((-4.672777 39.4266...
## 12                    Galicia 16 MULTIPOLYGON (((-8.726648 4...
## 13             Islas Baleares  9 MULTIPOLYGON (((3.010139 39...
## 14             Islas Canarias  2 MULTIPOLYGON (((-15.3643 27...
## 15                   La Rioja  8 POLYGON ((-2.517114 42.4916...
## 16                 País Vasco 10 MULTIPOLYGON (((-2.495694 4...
## 17     Principado de Asturias  8 MULTIPOLYGON (((-6.98875 43...
## 18           Región de Murcia 12 MULTIPOLYGON (((-1.266251 3...
La instrucción print(n = Inf), que ya has usado en alguna ocasión anterior, se emplea para imprimir en la consola todo el resultado, las 18 regiones en las que ESP_adm3 ha dividido España. El valor de n puede ser cualquier número; he puesto Infpara no preocuparme de saber cuántas líneas tiene la tabla del resultado. Por lo tanto, se juicioso al usar el valor Inf, puedes encontrarte imprimiendo cientos o miles de líneas.

En NAME_2 tienes los nombres de las provincias. Ejecuta en la consola

mapa %>%
  count(NAME_2) %>%
  print(n = Inf)

y se imprimirá la tabla con los nombre de las 52 provincias en que está divida España.

## Simple feature collection with 52 features and 2 fields
## Geometry type: GEOMETRY
## Dimension:     XY
## Bounding box:  xmin: -18.16153 ymin: 27.63736 xmax: 4.328195 ymax: 43.79153
## Geodetic CRS:  WGS 84
##                    NAME_2  n                       geometry
## 1                A Coruña  3 MULTIPOLYGON (((-9.015695 4...
## 2                Albacete  7 POLYGON ((-2.05449 39.3565,...
## 3                Alicante  9 MULTIPOLYGON (((0.231251 38...
## 4                 Almería  8 MULTIPOLYGON (((-2.355637 3...
## 5                Asturias  8 MULTIPOLYGON (((-6.98875 43...
## 6                 Badajoz 12 POLYGON ((-5.464918 38.4888...
## 7                Baleares  9 MULTIPOLYGON (((3.010139 39...
## 8               Barcelona 12 MULTIPOLYGON (((1.68791 42....
## 9                  Burgos 10 MULTIPOLYGON (((-4.056132 4...
## 10              Cantabria 11 MULTIPOLYGON (((-4.026528 4...
## 11              Castellón  8 MULTIPOLYGON (((0.669583 39...
## 12                  Ceuta  1 MULTIPOLYGON (((-4.300972 3...
## 13            Ciudad Real  7 MULTIPOLYGON (((-3.374903 3...
## 14                 Cuenca  7 POLYGON ((-1.520783 39.5488...
## 15                Cáceres 10 POLYGON ((-5.201958 39.5920...
## 16                  Cádiz  6 MULTIPOLYGON (((-6.322557 3...
## 17                Córdoba  8 MULTIPOLYGON (((-4.93158 37...
## 18                 Girona  8 MULTIPOLYGON (((2.010181 42...
## 19                Granada 10 POLYGON ((-4.257491 37.2504...
## 20            Guadalajara  6 MULTIPOLYGON (((-3.367154 4...
## 21              Guipúzcoa  1 POLYGON ((-1.794833 43.3934...
## 22                 Huelva  6 MULTIPOLYGON (((-6.836527 3...
## 23                 Huesca  8 POLYGON ((0.334388 41.68814...
## 24                   Jaén  9 POLYGON ((-2.774214 37.9256...
## 25               La Rioja  8 POLYGON ((-2.517114 42.4916...
## 26             Las Palmas  1 MULTIPOLYGON (((-15.3643 27...
## 27                   León 11 POLYGON ((-5.258957 42.2753...
## 28                 Lleida 12 MULTIPOLYGON (((1.715604 41...
## 29                   Lugo  6 MULTIPOLYGON (((-7.437918 4...
## 30                 Madrid  6 MULTIPOLYGON (((-4.263162 4...
## 31                Melilla  1 MULTIPOLYGON (((-2.441528 3...
## 32                 Murcia 12 MULTIPOLYGON (((-1.266251 3...
## 33                 Málaga  4 MULTIPOLYGON (((-4.416805 3...
## 34                Navarra  9 POLYGON ((-1.308545 43.0692...
## 35                Ourense  3 POLYGON ((-7.184755 41.9725...
## 36               Palencia  7 MULTIPOLYGON (((-4.040786 4...
## 37             Pontevedra  4 MULTIPOLYGON (((-8.864028 4...
## 38              Salamanca  9 POLYGON ((-5.637583 41.2321...
## 39 Santa Cruz de Tenerife  1 MULTIPOLYGON (((-17.92875 2...
## 40                Segovia  3 POLYGON ((-4.169325 41.4757...
## 41                Sevilla  7 POLYGON ((-4.843152 37.4140...
## 42                  Soria  8 POLYGON ((-2.079829 41.171,...
## 43              Tarragona  8 MULTIPOLYGON (((1.607361 41...
## 44                 Teruel  6 POLYGON ((-1.104665 41.1676...
## 45                 Toledo  7 POLYGON ((-4.023634 40.2491...
## 46               Valencia 18 MULTIPOLYGON (((-1.276446 4...
## 47             Valladolid  5 MULTIPOLYGON (((-5.464102 4...
## 48                Vizcaya  2 MULTIPOLYGON (((-2.495694 4...
## 49                 Zamora  6 POLYGON ((-6.784177 42.2536...
## 50               Zaragoza  8 POLYGON ((-1.834528 41.6606...
## 51                  Álava  7 POLYGON ((-2.499302 42.6115...
## 52                  Ávila  6 POLYGON ((-4.533494 40.8641...

Si cambiaras a NAME_3 se imprimirían los nombres de todas las comarcas. Pruébalo ejecutando en la consola

## Simple feature collection with 358 features and 2 fields
## Geometry type: GEOMETRY
## Dimension:     XY
## Bounding box:  xmin: -18.16153 ymin: 27.63736 xmax: 4.328195 ymax: 43.79153
## Geodetic CRS:  WGS 84
## First 10 features:
##               NAME_3 n                       geometry
## 1           Alacanti 1 POLYGON ((-0.468581 38.6508...
## 2          Alcalaten 1 POLYGON ((-0.249668 40.3735...
## 3             Alcoia 1 POLYGON ((-0.737097 38.7567...
## 4        Alt Millars 1 POLYGON ((-0.37167 40.24397...
## 5       Alt Palancia 1 POLYGON ((-0.620456 40.0458...
## 6       Alt Vinalopo 1 POLYGON ((-0.917491 38.7762...
## 7      Alta Maestrat 1 POLYGON ((0.098796 40.53728...
## 8          Altiplano 1 POLYGON ((-1.205211 38.7477...
## 9   Alto Guadalentin 1 MULTIPOLYGON (((-1.546874 3...
## 10 Alto Guadalquivir 1 POLYGON ((-3.057392 38.0356...

Solo se imprimirán las diez primeras de las 358 comarcas en las que está dividida España, aunque es una información que raras veces usamos. A pesar de ello, lo he escogido para representar las subdivisiones de tercer nivel del territorio que estás considerando.

Como solo nos interesa dibujar las comunidades de Aragón, Navarra y La Rioja, tienes que extraer la información de estos tres territorios. Puedes hacerlo de dos maneras. En la primera, lo primero que tienes que hacer es declarar los territorios que deseas dibujar. La manera más sencilla es creando un nuevo vector con los nombre de las tres comunidades, y para conseguirlo has de concaternarlos con la función c().

ALEARN <- c("Aragón", "Comunidad Foral de Navarra", "La Rioja")

Para comprobar que lo has hecho bien, ejectura en la consola

ALEARN

deberá imprimirse este resultado:

## [1] "Aragón"                     "Comunidad Foral de Navarra" "La Rioja"

Ahora debes extraer la información de mapa y guardarla en ALEARN_mapa puesto que contendrá la información para dibujar el mapa de esas tres comunidades y las comarcas en las que están divididas (los límites provinciales se pierden). Para ello tienes que usar la función filter() que permite extraer solo una parte de las líneas que contenga una tabla.

ALEARN_mapa <- mapa %>%
  filter(NAME_1 %in% ALEARN)

Lo que le has dicho es que extraiga de mapa todas las líneas cuya variable NAME_1 tengan cualquiera de los valores que haya en el vector ALEARN. Todo habría ido bien si en la ventana Environment ha aparecido una tabla llamada ALEARN_mapa que tiene 39 observaciones y 14 variables. Si no es así es sencillamente porque en el vector ALEARN habrá algún error. Comprueba que los nombres de las tres comunidades son tal y como aparecen en la columna NAME_1. Antes te he mostrado como verlo.

El segundo método no crea un vector intermedio, lo que hace es insertar la función c() y los valores en lugar de ALEARN, como puedes ver en estas líneas de código:

ALEARN_mapa <- mapa %>%
  filter(NAME_1 %in% c("Aragón",
                       "Comunidad Foral de Navarra",
                       "La Rioja"))

Ya te he dicho muchas veces las cosas se pueden hacer de varias maneras en R. Tú eliges la más cómoda para tus necesidades.

Ahora tienes que leer los datos lingüísticos que se encuentran en el fichero hinojo.txt que hay en el respositorio del proyecto y guardarlos en la tabla ALEARN_datos.

ALEARN_datos <- read_tsv("https://raw.githubusercontent.com/7PartidasDigital/AnaText/master/datos/geolinguistic/hinojo_alearn.txt")

Cuando ejecutes la instrucción anterior, se imprimirá en la consola la información que te indica cómo se llama cada una de las columnas de la tabla y qué tipo de valores tiene cada una de ellas.

## Rows: 179 Columns: 8
## ── Column specification ────────────────────────────────────────────────────────────────────────────────
## Delimiter: "\t"
## chr (6): atlas, provincia, poblacion, id, F_inicial, cl_inter
## dbl (2): latitud, longitud
## 
## ℹ Use `spec()` to retrieve the full column specification for this data.
## ℹ Specify the column types or set `show_col_types = FALSE` to quiet this message.

Échale una ojeada a la tabla ejecutando en la consola

ALEARN_datos

aunque solo imprimirá las primeras diez líneas:

## # A tibble: 179 × 8
##    atlas  provincia   poblacion          latitud longitud id    F_inicial cl_inter
##    <chr>  <chr>       <chr>                <dbl>    <dbl> <chr> <chr>     <chr>   
##  1 ALEARN Burgos      Bugedo                42.6   -3.02  BU400 li        x       
##  2 ALEARN Burgos      Bugedo                42.7   -2.75  BU400 li        x       
##  3 ALEARN Castellón   Arañuel               40.1   -0.482 CS300 li        x       
##  4 ALEARN Castellón   Segorbe               39.9   -0.485 CS301 ø         x       
##  5 ALEARN Castellón   Bejís                 39.9   -0.704 CS302 ø         x       
##  6 ALEARN Cuenca      Valdemeca             40.2   -1.74  CU200 <NA>      <NA>    
##  7 ALEARN Cuenca      Santa Cruz de Moya    40.0   -1.26  CU400 ø         x       
##  8 ALEARN Guadalajara Tortuera              41.0   -1.80  GU200 <NA>      <NA>    
##  9 ALEARN Guadalajara Orea                  41     -1.73  GU400 ø         x       
## 10 ALEARN Huesca      Sallent de Gállego    42.8   -0.335 HU100 θ         x       
## # ℹ 169 more rows

No me entretengo en explicarte el contenido de cada una de ellas. Ya lo hice al comienzo de este capítulo. Pero no te sorprendas porque las nueve primeras líneas sean valores de lugares de la provincia de Burgos, Castellón, Cuenca y Guadalajara (también los hay de Valencia y Álava). No hay error. Los diseñadores del atlas creyeron necesario incluir una serie de puntos de las zonas circundantes para tener una mejor visión de la complejidad dialectal de Aragón, Navarra y La Rioja.

LLegó la hora de imprimir el mapa. Ya tienes todos los datos. En ALEARN_mapa la información geográfica y en ALEARN_datos la información lingüística. Para imprimirlo sería suficiente estas líneas:

ggplot() +
  geom_sf(data = ALEARN_mapa) +
  geom_text(data = ALEARN_datos,
            aes(x=longitud,
                y=latitud,
                label = F_inicial,
                colour = F_inicial),
            size = 4)

pero imprimirían el mapa con la cuadrícula de fondo y la leyenda lateral que no es nada informativa ni atrayente. Habría que añadir las líneas de código cosmético. Pero antes te explico que hace cada una de las líneas de código anteriores. Como estas con ggplot() las diversas líneas se encadenan con un signo de adición + al final de cada línea. No lo olvides, o estarás un buen rato buscando el error. La función geom_sf(data = ALEARN_mapa) es la responsable de dibujar la capa que representa el territorio. Prúebalo. Ejecuta en la consola

ggplot() +
  geom_sf(data = ALEARN_mapa)

Se habrá impreso en la ventana Plots el mapa que hay en la figura 15.10.

Las comarcas de las comunidades de Aragón, Navarra y La Rioja

Figura 15.10: Las comarcas de las comunidades de Aragón, Navarra y La Rioja

Tan solo ha dibujado los límites de las comarcas de las tres comunidades autónomas reflejadas en el ALEARN. La siguiente línea de código, que es la más larga, por el momento, se ocupa de situar en el mapa el resultado de cada punto de encuenta y que tienes recogidos en ALEARN_datos.

. . . +
  . . . +
  geom_text(data = ALEARN_datos,
            aes(x=longitud,
                y=latitud,
                label = F_inicial,
                colour = F_inicial),
            size = 4)

Usas las función geom_text() porque lo que pretendes es que imprima los símbolos fonéticos de los resultados f, θ y ø que tienes en la variable F_inicial y le indicas que los datos se encuentran en la tabla ALEARN_datos (no olvides de anteponer data =, te puede ahorrar más de un quebradero de cabeza).

Con aes() le indicas que en el eje x = debe situar los puntos que le indique la columna longitud y en el eje y = lo que diga la columna latitud. Es decir, dentro del mapa localiza el punto donde se crucen los valores de longitud y latitud y, una vez que lo hayas localizado, escribe, con label =, el contenido que haya en la columna (variable) F_inicial. Lo que hace colour = es mirar cuantos valores diferentes hay en F_inicial y otorgarle a cada uno de ellos un color diferente. Como hay tres valores posibles, usará tres colores. Los elige R, aunque podrías establecerlos tú, pero, evidentemente, complicaría la programación.

Con la última línea size = determinas el tamaño de la letras que se van a imprimir en cada punto del mapa. Aquí es cuestión de prueba y error. Todo depende del destino final del gráfico. Lo que ves en la figura 15.11 es lo que se imprimiría al juntar las dos primeras líneas con las del grupo que te acabo de presentar.

El mapa de los resultados con leyenda y fondos

Figura 15.11: El mapa de los resultados con leyenda y fondos

En la consola se habrá impreso el mensaje de aviso:

Warning message:
Removed 39 rows containing missing values (geom_text).

Te avisa, sencillamente, de que en ALEARN_datos hay 39 puntos de encuesta en los que no hubo respuesta y que contienen el valor NA y que, por tanto, no los puede representar.

El resto del código, es la serie de instrucciones que hacen que no se imprima el fondo gris, la cuadrícula, la leyenda lateral, las indicaciones de latitud y longitud y añade el título en la parte superior.

. . .
  theme(legend.position = "none",
        panel.grid.major = element_line(color = "white"),
        panel.grid = element_blank(),
        axis.title = element_blank(),
        axis.text = element_blank(),
        axis.ticks = element_blank(),
        panel.background = element_blank(),
        rect = element_blank()) +
  labs(title = "Tratamiento de F- en el ALEARN",
       subtitle = "FOENICULUM")

El resultado tiene que ser el del mapa de la figura 15.12.

Mapa _embellecido_ con los resultados

Figura 15.12: Mapa embellecido con los resultados

15.4 Atlas de gran dominio

15.4.1 Los datos lingüísticos

En la península Ibérica solo hay un atlas de gran dominio, el Atlas Lingüístico de la península Ibérica que no solo incluye la España peninsular e islas Baleares, sino también dos países más: Portugal y Andorra y una pequeña porción de Francia, el Rosellón. Es un atlas concebido por Ramón Menéndez Pidal a principios del siglo XX y que dirigió Tomás Navarro Tomás desde el Centro de Estudios Históricos en los años veinte y treinta del siglo pasado. Aunque la mayoría de las encuestas se realizaron entre 1931 y 1936, el proyecto se paró a causa de la guerra civil. Tras la contienda se retomó la labor parcialmente y en 1962 se publicó el primer tomo, con 75 mapas.

Los materiales anduvieron perdidos y cuando afloraron se empezaron a poner a disposición de los investigadores en los servidores del CSIC. De ahí se han extraido los datos referentes a diez preguntas procedentes del segundo cuaderno de encuesta.

puntos pregunta
458 Guisantes
493 Mariquita
496 Lagartija
502 Aguzanieves
520a Jabalí
600a Cadera
704 Cuna
751 LLevar a cuestas
753a Dar volteretas
825 Levadura

Las respuestas a estas diez cuestiones se pueden consultar en la web del ALPI –Consulta mapas–. Se trata de una página de resultados que ofrece compleja tabla que no permite extraer de manera automática los resultados (figura 15.13).

Captura de la primera página de resultados del ALPI

Figura 15.13: Captura de la primera página de resultados del ALPI

Aún así, se han podido recoger y formar una tabla que contiene las respuestas a esas diez preguntas en todos los puntos de encuesta del ALPI. Es una tabla con las columnas correspondientes al código de identificación (id), la pregunta (pregunta), la respuesta ortográfica (ortografia) (que es una recreación hecha por los investigadores del CSIC a partir de las transcipciones fonéticas de los cuadernos de encuesta) y la transcripción AFI (afi), que es una conversión desde el alfabeto RFE, que es el que usa el ALPI, a un sistema de transcripción fonética que puede viajar por la red y está estandarizado. No se han recogido el nombre del lugar, el de la provincia ni la referencia al cuestionario en el que figuran las cuestiones puesto que es información ociosa para el objetivo de este capítulo.

La tabla creada tiene este aspecto

id pregunta ortografia afi
100 Cuna berce ˈbɛɾθe
101 Cuna berce ˈbɛɾθe
102 Cuna berce ˈbɛɾθe
103 Cuna berce ˈbɛɾθə
104 Cuna berce ˈbɛɾθə
105 Cuna berce ˈbɛɾθi
106 Cuna berce ˈbɛɾs̺i̥
107 Cuna berce ˈbɛɾθi̥
108 Cuna berce ˈbɛɹs̺i̥
109 Cuna berce ˈbɛɾse

Lo primero que tienes que hacer es leer la tabla. Pero antes de hacerlo has de cargar la librería {tidyverse}, que es esencial para hacer la vida más fácil en el manejo de tablas.

library(tidyverse)

Lee ahora la tabla con

alpi <- read_tsv("https://raw.githubusercontent.com/7PartidasDigital/AnaText/master/datos/geolinguistic/alpi.txt")

Esta tabla tiene más de 5600 líneas, pero solo vas a usar las correspondientes a las respuestas que se obtuvieron a la pregunta del jabalí, por lo que vas a borrar todas las demás. Para ello tan solo tienes que usar la función filter(), como puedes ver en esta instrucción que hay a continuación. Con ella lo que le pides za R es que conserve aquellas líneas en las que el contenido de la variable pregunta sea idéntico a (==) Jabalí. Recuerda que si lo escribes con minúscula, o te olvidas de la tilde de la i no obtendrás resultado alguno. Los ordenadores son exasperadamente literales.

alpi <- alpi %>%
  filter(pregunta == "Jabalí")

Tan pronto como la ejecutes, la tabla se habrá reducido a 503 líneas. Échale una ojeada ejecutando en la consola

alpi

Se habrán impreso las diez primeras líneas de la tabla, muy parecida a la que viste antes, pero en la que las columnas 2, 3 y 4 han cambiado totalmente sus valores.

## # A tibble: 503 × 4
##    id    pregunta ortografia  afi          
##    <chr> <chr>    <chr>       <chr>        
##  1 100   Jabalí   porco bravo ˈpɔɾko ˈβɾaβo
##  2 101   Jabalí   porco bravo ˈpɔɾko ˈβɾaβo
##  3 102   Jabalí   porco bravo ˈpɔɾko ˈβɾaβo
##  4 103   Jabalí   cocho bravo ˈkɔt͡ʃo ˈβɾaβo
##  5 104   Jabalí   jabalín     xɑβɘˈlĩŋ     
##  6 105   Jabalí   porco bravo ˈpɔɾko ˈβɾaβo
##  7 106   Jabalí   porco bravo ˈpɔɹko ˈβɾaβo
##  8 107   Jabalí   cocho bravo ˈkɔt͡ʃo ˈβɾaβo
##  9 108   Jabalí   porco fero  ˈpɔɹko ˈfeɹo 
## 10 109   Jabalí   porco bravo ˈpɔɹko ˈβɾaβo
## # ℹ 493 more rows

Ya tienes toda la información lingüística que vas a necesitar. Ahora has de conseguir el mapa sobre el que cartografiarás los resultados.

15.4.2 Dibujar el mapa

Como ya he dicho, el ALPI es un atlas de gran dominio y, además, supranacional puesto que abarca España (península e islas Baleares), Portugal (continental), Andorra y el sur de Francia, por lo que para ubicar los resultados de las encuestas has de utilizar un mapa que represente esos territorios. Podrías hacerlo con la función borders() de ggplot().

ggplot() +
  borders("world",
          c("spain", "portugal", "france"))
Siluetas de España, Portugal, Andorra y Francia con `borders`

Figura 15.14: Siluetas de España, Portugal, Andorra y Francia con borders

Esta función dibuja toda Francia, incluída la isla de Córcega, como puedes ver en el mapa de la figura 15.14. Pero de Francia solo nos interesa un pequeño territorio del sur, el Rosellón. Como mucho nos interesaría que dibujara el territorio al sur del paralelo 44 y al oeste del meridiano 5, como puedes ver en el mapa de la figura 15.15. Con este sistema, excelente en otros momentos, no puedes conseguir el resultado pertinente, por lo que hay que recurrir a una shapefile que pueda dibujar el ámbito geográfico pertinente.

Zona que interesa (recuadro rojo

Figura 15.15: Zona que interesa (recuadro rojo

En la sección Obtención de materiales te indiqué que bajaras los ficheros con las divisiones administrativas de España (ESP_adm). También te dije que bajaras de la página del Instituto Geográfico Nacional el fichero que contenía la Base Cartográfica Nacional (BCN500). Este es el que vas a usar puesto que sierve para dibujar todos los territorios que te interesan, aunque tiene algunos de más, de los que tendrás que deshacerte.

Lo primero es cargar la información necesaria para dibujar el mapa, que, para mayor comodidad guardarás en un objeto llamado mapa, pero para hacerlo necesitas cargar previamente la librería {sf}.

library(sf)

al hacerlo imprimirá un pequeño mensaje.

El código para cargar la información en mapa es por medio de la función st_read() que has visto en la sección anterior. (Recuerda que todo lo que hay antes de BCN500 en la expresión que hay a continuación lo debes cambiar por la ruta donde guardaste el resultado de descomprimir el fichero que descargarte del Instituo Geográfico Nacional.)

mapa <- st_read("../mapas/BCN500/BCN500_0101S_LIMITE_ADM.shp")

Tras leer el fichero aparecerá la información relativa al mapa que has cargado.

## Reading layer `BCN500_0101S_LIMITE_ADM' from data source 
##   `/Users/JMFR/Library/CloudStorage/OneDrive-UVa/mapas/BCN500/BCN500_0101S_LIMITE_ADM.shp' 
##   using driver `ESRI Shapefile'
## Simple feature collection with 66 features and 7 fields
## Geometry type: MULTIPOLYGON
## Dimension:     XYZ
## Bounding box:  xmin: -18.1595 ymin: 25.99936 xmax: 4.963209 ymax: 43.97295
## z_range:       zmin: 0 zmax: 0
## Geodetic CRS:  Europe ETRS 89 (EUREF 89 System), Latitude-Longitude; Degrees

No me detengo en explicártela porque ya lo he hecho párrafos atrás, aunque tendremos que volver sobre una parte de ella. Lo que sí tienes que ver es cómo se llama cada una de las columnas que constituyen la tabla. La forma más sencilla es ejecutando en la consola

mapa

De los siete campos (columnas) que contiene, la crucial en estos momentos es CCAA, que recoge los nombres las todas las comunidades autónomas de España, pero podrás ver que también aparecen nombres de otros sitios en mayúsculas. Veamos cuáles son todos esos nombres. La manera más sencilla, y rápida, es diciéndole a R que entresaque los valores únicos, es decir, sin repetir, que pueda haber en la columna CCAA. La forma de indicarle a R que quieres esos valores únicos es con la función unique(). Puesto que lo que quieres es el contenido de la variable (columna) CCAA del objeto mapa le tienes que indicar tanto el objeto como la variable que te interesa separadas por el signo del dollar $. Si ejecutas en la consola la expresión

unique(mapa$CCAA)

te presantará este resultado:

##  [1] "SAHARA OCCIDENTAL"          "ALGERIA"                    "Comunidad Valenciana"      
##  [4] "Andalucía"                  "MARRUECOS"                  "Ciudad Autónoma de Melilla"
##  [7] "CEUTA"                      "Melilla"                    "País Vasco"                
## [10] "Canarias"                   "Castilla La Mancha"         "Extremadura"               
## [13] "Comunidad de Madrid"        "Aragón"                     "Castilla León"             
## [16] "Galicia"                    "Cataluña"                   "La Rioja"                  
## [19] "Comunidad Foral de Navarra" "Principado de Asturias"     "Cantabria"                 
## [22] "Illes Balears"              "ANDORRA"                    "FRANCIA"                   
## [25] "PORTUGAL"                   "Región de Murcia"           "MAURITANIA"

Examínalo con detenimiento. Como te he dicho, hay una serie de valores que están en mayúsculas: SAHARA OCCIDENTAL, CEUTA, PORTUGAL, ALGERIA, MARRUECOS, ANDORRA, FRANCIA y MAURITANIA. De todos estos nombres solo te interesan PORTUGAL, ANDORRA y FRANCIA. Si revisas los nombres en minúsculas, tampoco te interesan, porque no son territorios contemplados en el ALPI, CEUTA, Melilla, Ciudad Autónoma de Melilla ni Canarias. Hay que decirle a mapa que se olvide de todos esos territorios.

Es un proceso que requiere varios pasos. El primero es guardar en un vector todos los nombres que hay en la columna CCAA, lo que se logran con

comunidades <- unique(mapa$CCAA)

Si lo revisas ejecutando en la consola

comunidades

verás que están los mismos que se han impreso antes. La diferencia con lo de hiciste antes es que solo le pediste que te indicara cuáles eran los valores únicos que había en mapa$CCAA. No los guardaste. Ahora los has almacenado en el vector comunidades.

##  [1] "SAHARA OCCIDENTAL"          "ALGERIA"                    "Comunidad Valenciana"      
##  [4] "Andalucía"                  "MARRUECOS"                  "Ciudad Autónoma de Melilla"
##  [7] "CEUTA"                      "Melilla"                    "País Vasco"                
## [10] "Canarias"                   "Castilla La Mancha"         "Extremadura"               
## [13] "Comunidad de Madrid"        "Aragón"                     "Castilla León"             
## [16] "Galicia"                    "Cataluña"                   "La Rioja"                  
## [19] "Comunidad Foral de Navarra" "Principado de Asturias"     "Cantabria"                 
## [22] "Illes Balears"              "ANDORRA"                    "FRANCIA"                   
## [25] "PORTUGAL"                   "Región de Murcia"           "MAURITANIA"

Ahora tienes que borrar de comunidades todos los nombres de los territorios que no quieres que se dibujen en el mapa, o dicho de otra manera, solo quieres quedarte con los nombres de los territorios que has de representar en el mapa. Recordarás que los resultados de R siempre tienen un índice, son esos números que se habrán impreso en el margen izquierdo de la consola cuando se han impreso del contido de comunidades. Para quedarte con los nombres que quieres tan solo tiene que extraer de comunidades los elementos que quieres conservar. Puesto que quieres quedarte con los elementos que hay en las posiciones 3, 4, 9, y 11 a 26, la forma más sencilla es con la expresión:

comunidades <- comunidades[c(3,4,9,11:26)]
Recuerda que cuando en R escribes dos números separados por dos puntos : se interpretan como maneja/imprime todos los números que vayan desde el que hay a la izquierda de los dos puntos, hasta la derecha de los dos puntos, ambos incluidos. Hacerlo con la expresión 11:26 es más rápido, y seguro, que escribir cada uno de los números. Pero recuerda que al ser valores salteados –3, 4, 9, 11:26– no puedes indicárselo directamente, poniendo los números entre corchetes, sino que tienes que crear un vector volátil concatenando los valores con c(). Si no lo haces así te dará un bonito error.

Comprueba ahora que la lista con los nombres de las comunidades no contiene ninguno de los nombres que no quieres usar. Ejecuta, de nuevo, en la consola

comunidades

El resultado tiene que ser

##  [1] "Comunidad Valenciana"       "Andalucía"                  "País Vasco"                
##  [4] "Castilla La Mancha"         "Extremadura"                "Comunidad de Madrid"       
##  [7] "Aragón"                     "Castilla León"              "Galicia"                   
## [10] "Cataluña"                   "La Rioja"                   "Comunidad Foral de Navarra"
## [13] "Principado de Asturias"     "Cantabria"                  "Illes Balears"             
## [16] "ANDORRA"                    "FRANCIA"                    "PORTUGAL"                  
## [19] "Región de Murcia"

Ya tienes la lista de todos los territorios que quieres dibujar en el mapa. Ahora solo te falta borrarlos del objeto mapa. Para ello basta con decirle a R que tome solo aquellas líneas cuyo valor de la columna CCAA sea uno de los nombres que hay en el vector comunidades que acabas de crear y la manera de hacerlo es con el operador %in%. Esta es la orden:

mapa <- mapa %>%
  filter(CCAA %in% comunidades)

Antes de que ejecutes la orden anterior comprueba en la ventana Environment cuántas observaciones hay en mapa. Dirá 66. Ejecuta ahora la orden anterior y comprueba si ha variado el número de las observaciones de mapa. Debería ser ahora 53.

Vas a comprobar si has borrado todos los territorios del norte de África y las islas Canarias (fig. 15.16). Vas a imprimir en la ventana Plots el mapa. La instrucción ya la conoces puesto que la has usado varias veces. Tardará un poquito, ten paciencia.

ggplot() +
  geom_sf(data = mapa)
Eliminación de los territorios no deseados

Figura 15.16: Eliminación de los territorios no deseados

Uff… No ha salido todo lo bien que querías. La razón es sencilla. Fíjate en el cuadro marcado por la longitud 15ºW (-15) y la latitud 34ºN (34) –esquina inferior izquierda–. Hay algo dibujado ahí. Se trata de la isla de Madeira. No te interesa. El problema es que el objeto mapa no tiene una casilla especial para Madeira, toda la información de los límites de Portugal se encuentran reunidos en un único polígono. Esto obliga a buscar otra solución.

Recordarás que cuando te expliqué el contenido de la información que se imprimía al leer un fichero shp había una línea que comenzaba con bbox que decía xmin: -18.1595 ymin: 25.99936 xmax: 4.963209 ymax: 43.97295. Esos valores son los de la longitud más occidental -18.1595 y oriental 4.963209 y la latitud más meridional 25.99936 y la más septentrional 43.97295. Lo único que hay que hacer es cambiar los valores de xmin: -18.1595, el punto más occidental, y el de ymin: 25.99936, la posición más al sur por otros que permitan reducir el área considerada. Aquí vas a actuar a ojo de buen cubero. El paralelo más cercano al sur de España es 36ºN (36) y el meridiano occidental más próximo a la península es 10ºW (-10).

Puede parecer que es algo muy complicado, y de hecho deber serlo, pero la gran noticia es que entre las funciones de la librería {sf} hay una para recortar los mapas. Se trata de st_crop() que requiere saber cuál es el objeto que ha de recortar, en nuestro caso mapa, y los límites del recorte, es decir cuáles son las latitudes ymax (= norte), ymin (sur), y las longitudes xmas (este) y xmin (oeste) que debe considerar para delimitar el dibujo del mapa. Puesto que ymax y xmas, la latitud norte y la longitud este, no varían, solo tienes que variar los valores de xmin (límite oeste) e ymin (límite sur). La instrucción que tienes a continuación recortará el mapa convenientemente.

mapa <-  st_crop(mapa, c(xmin= -10, ymin = 36, xmax = 4.837648, ymax = 44))

Tan pronto como hayas ejecutado la orden anterior se habrá impreso este mensaje:

## st_as_s2(): dropping Z and/or M coordinate
## Warning: attribute variables are assumed to be spatially constant throughout all geometries

No tienes de qué preocuparte, es uno de los avisos que imprime R cuando sucede algo que no supone un error pero que los programadores pensaron que debe saberlo quien esté usando la función. Por otra parte, aparentemente mapa no ha sufrido cambio alguno. Para comprobar el resultado tan solo tienes que volver a ejecutar la instrucción para dibujarlo.

ggplot() +
  geom_sf(data = mapa)

El resultado es el del mapa de la figura 15.17.

El mapa de España, Portugal, Francia y Andorra delimitado al ámbito del ALPI

Figura 15.17: El mapa de España, Portugal, Francia y Andorra delimitado al ámbito del ALPI

Si quieres ahorrarte todo el trabajo de recortar el mapa cada vez que lo quieras usar porque vas a trabajar a menudo con él, lo que puedes hacer es guardarlo con el disco duro como un fichero .RData.

Los ficheros RData son específicos de R y pueden almacenar cuantos objetos quieres y tengas en el panel Environment. Tan solo tienes que usar la función save() que requiere saber qué objetos ha de guardar y el nombre del fichero en que los grabará en el disco duro. Así, por ejemplo, para guardar el objeto mapa que tienes ahora mismo, lo que tendrías que ejecutar en la consola es save(mapa, file = "mapa_peninsula.RData"). Cuando lo tengas que usar de nuevo, lo cargarás con load("mapa_peninsula.RData") (quizá tengas que darle la ruta completa hasta el fichero, todo depende dónde lo hayas guardado). Una vez ejecutes la instrucción load() aparecerá en el panel Environment el objeto mapa listo para dibujar el mapa de la península Ibérica, islas Baleares y el sur de Francia.

15.4.3 Las coordenadas de los puntos de encuesta

Ya tienes los datos para dibujar el mapa y los datos lingüísticos en los objetos mapa y alpi. Sin embargo, falta un detalle. La localización de cada uno de los puntos de encuesta. Al contario de lo que viste en la sección Un atlas pequeño dominio, el objeto con los datos lingüísticos que has leído del repositorio del proyecto no tiene las coordenadas de cada punto de encuesta. Tienes que conseguirlas.

No vas a buscarlos a mano, ni tampoco con la librería {georeference} porque tendrías muchos errores y te llevaría mucho tiempo. En el proyecto 7PartidasDigital hemos creado un fichero tsv en el que se han localizado todos los puntos de encuesta de varios atlas lingüísticos peninsulares: Atlas Lingüístico y Etnográfico de Andalucía –ALEA–, Atlas Lingüístico y Etnográfico de Aragón, Navarra y La Rioja –ALEARN–, Atlas Lingüístico (y Etnográfico) de Castilla-La Mancha –ALCLM–, Atlas Lingüístico de Castilla y León –ALCYL–, Atlas dialectal de Madrid –ADIM–, Petit Atles Linguistic del Domini Català –PALDC– y, por supuesto, el Atlas lingüístico de la península Ibérica –ALPI– (en el futuro, según tengamos acceso a los materiales, se añadirán los puntos de encuesta del Atlas lingüístico y etnográfico de Cantabria, el Atlas Lingüístico Galego, etc.).

La estructura del fichero con esta información es la que puedes observar en la tabla que hay a continuación.

## Rows: 1558 Columns: 7
## ── Column specification ────────────────────────────────────────────────────────────────────────────────
## Delimiter: "\t"
## chr (5): atlas, id, poblacion, provincia, CCAA
## dbl (2): latitud, longitud
## 
## ℹ Use `spec()` to retrieve the full column specification for this data.
## ℹ Specify the column types or set `show_col_types = FALSE` to quiet this message.
atlas id poblacion latitud longitud provincia CCAA
ADIM M1 Mangirón 40.96408 -3.587009 Madrid Madrid
ADIM M2 Buitrago de Lozoya 40.98729 -3.646177 Madrid Madrid
ADIM M3 Lozoya 40.95550 -3.799294 Madrid Madrid
ADIM M4 Patones 40.85464 -3.489306 Madrid Madrid
ADIM M5 Navacerrada 40.72645 -4.021921 Madrid Madrid
ADIM M6 El Boalo 40.71722 -3.919913 Madrid Madrid
ADIM M7 Alalpardo 40.62820 -3.480723 Madrid Madrid
ADIM M8 Meco 40.55122 -3.338020 Madrid Madrid
ADIM M9 Santa María de la Alameda 40.59782 -4.262920 Madrid Madrid
ADIM M10 Valdemorillo 40.48650 -4.091224 Madrid Madrid

La variable atlas contiene la sigla de los atlas lingüísticos recogidos. La variable id contiene la referencia al punto de encuesta. Es el único valor inequívoco en lo que respecta a la identificación del punto. Los nombres de las poblaciones, recogidos en la variable poblacion, son muy problemáticos, pues los nombre que dan los diversos atlas pueden tener variaciones ortográficas, haber cambiado totalmente, e incluso haber desaparecido. Las columnas latitud y longitud corresponden a la coordenadas del punto de encuesta lugar. No se puede decir a qué punto concreto corresponde del municipio (en el caso de que sea un municipio) ya que la tabla se ha construido con la librería {georeference} y, cuando ha habido errores de localización, se ha corregido manualmente localizando el lugar en Google Maps o con las coordenadas que ofrece Wikipedia para las diversas ciudades y poblaciones que tiene recogidas en cualquiera de sus versiones. La columna provincia contiene el nombre de la provincia en el que se encuentra el lugar encuestado. En el caso de Francia son departamentos y en el de Portugal distritos. La última variable, CCAA recoge el nombre de la comunidad autónoma en la que se ubica cada punto de encuesta. En el caso de los puntos de encuesta de Portugal, Francia y Andorra es el nombre del país.

Con esta tabla ya puedes obtener las coordenadas para cada punto de encuesta de cualquier atlas lingüístico cuyos datos quieras representar en un mapa de manera diferente a como parecen en las publicaciones originales.

Como estas trabajando con el ALPI, y en el fichero hay información de otros seis atlas, tan solo te interesa acceder a los datos del ALPI. Ya sabes que la forma de borrar de una tabla o extraer de ella datos es por medio de la función filter(). Reducir el objeto atlas de 1558 a los poco más de 500 puntos que conforman la red de puntos del ALPI se consigue con

atlas <- atlas %>%
  filter(atlas == "ALPI")

Cuando ejecutes la orden anterior, podrás ver que el objeto atlas tiene ahora 524. El siguiente paso es incorporar al objeto alpi la información de las variables latitud y longitud.

Recordarás que cuando querías borrar las palabras vacías, usaste la función anti_join(). Lo que esta hacía era mirar en el objeto que le indicabas en el argumento y comprobar si en el texto que estabas analizando existían esas palabras y si existían las borraba. Ahora se trata de unir, añadir, a alpi las columnas longitud y latitud del objeto atlas. Hay varias funciones para unir dos tablas: full_join(), left_join(), right_join() e inner_join(). Cada una de ellas tiene un comportamiento diferente.

Para estas uniones tiene que haber una variable en común. En este caso será id que es la única que es inequívoca para cada uno de los atlas, pues, como te he dicho, los nombres de las poblaciones han podido cambiar con respecto a los nombres que ofrecen los diversos atlas lingüísticos. Por ejemplo, en el ALEA el punto GR400 corresponde a Cúllar-Baza, pero el nombre oficial de esta población granadina es, desde 1986, Cúllar. Otro caso extremo es la desginación de algunos puntos de encuenta en el PALDC. El punto 149 de este atlas se identifica como Vilafranca del Maestrat que se corresponde con Villafranca del Cid (nombre oficial castellano) o Vilafranca (nombre oficial valenciano). Estos pequeños problemas llevan cierto tiempo al recolectar los datos.

Incorpora a alpi las informaciones geográficas de contenidas en atlas por medio de la variable común id. En este caso particular es indiferente que uses inner_join(), left_join() o right_join() puesto que todas ofrecerán el mismo resultado: añadirán a continuación de la columna afi todas las columnas de atlas.

Con right_join() el resultado sería (la cantidad de columnas que se imprima depende del ancho de la consola):

## # A tibble: 552 × 10
##    id    pregunta ortografia  afi           atlas poblacion             latitud longitud provincia CCAA 
##    <chr> <chr>    <chr>       <chr>         <chr> <chr>                   <dbl>    <dbl> <chr>     <chr>
##  1 100   Jabalí   porco bravo ˈpɔɾko ˈβɾaβo ALPI  Sismundi                 43.7    -7.87 La Coruña Gali…
##  2 101   Jabalí   porco bravo ˈpɔɾko ˈβɾaβo ALPI  Valdoviño                43.6    -8.16 La Coruña Gali…
##  3 102   Jabalí   porco bravo ˈpɔɾko ˈβɾaβo ALPI  Miño                     43.3    -8.21 La Coruña Gali…
##  4 103   Jabalí   cocho bravo ˈkɔt͡ʃo ˈβɾaβo ALPI  Santa María de Oleir…    43.3    -8.32 La Coruña Gali…
##  5 104   Jabalí   jabalín     xɑβɘˈlĩŋ      ALPI  Abegondo                 43.2    -8.28 La Coruña Gali…
##  6 105   Jabalí   porco bravo ˈpɔɾko ˈβɾaβo ALPI  Aranga                   43.2    -8.02 La Coruña Gali…
##  7 106   Jabalí   porco bravo ˈpɔɹko ˈβɾaβo ALPI  Baio                     43.2    -8.99 La Coruña Gali…
##  8 107   Jabalí   cocho bravo ˈkɔt͡ʃo ˈβɾaβo ALPI  Carballo                 43.2    -8.71 La Coruña Gali…
##  9 108   Jabalí   porco fero  ˈpɔɹko ˈfeɹo  ALPI  Corcubión                42.9    -9.19 La Coruña Gali…
## 10 109   Jabalí   porco bravo ˈpɔɹko ˈβɾaβo ALPI  Santa Comba              43.0    -8.81 La Coruña Gali…
## # ℹ 542 more rows

Si utilizas left_join() sería:

## # A tibble: 503 × 10
##    id    pregunta ortografia  afi           atlas poblacion             latitud longitud provincia CCAA 
##    <chr> <chr>    <chr>       <chr>         <chr> <chr>                   <dbl>    <dbl> <chr>     <chr>
##  1 100   Jabalí   porco bravo ˈpɔɾko ˈβɾaβo ALPI  Sismundi                 43.7    -7.87 La Coruña Gali…
##  2 101   Jabalí   porco bravo ˈpɔɾko ˈβɾaβo ALPI  Valdoviño                43.6    -8.16 La Coruña Gali…
##  3 102   Jabalí   porco bravo ˈpɔɾko ˈβɾaβo ALPI  Miño                     43.3    -8.21 La Coruña Gali…
##  4 103   Jabalí   cocho bravo ˈkɔt͡ʃo ˈβɾaβo ALPI  Santa María de Oleir…    43.3    -8.32 La Coruña Gali…
##  5 104   Jabalí   jabalín     xɑβɘˈlĩŋ      ALPI  Abegondo                 43.2    -8.28 La Coruña Gali…
##  6 105   Jabalí   porco bravo ˈpɔɾko ˈβɾaβo ALPI  Aranga                   43.2    -8.02 La Coruña Gali…
##  7 106   Jabalí   porco bravo ˈpɔɹko ˈβɾaβo ALPI  Baio                     43.2    -8.99 La Coruña Gali…
##  8 107   Jabalí   cocho bravo ˈkɔt͡ʃo ˈβɾaβo ALPI  Carballo                 43.2    -8.71 La Coruña Gali…
##  9 108   Jabalí   porco fero  ˈpɔɹko ˈfeɹo  ALPI  Corcubión                42.9    -9.19 La Coruña Gali…
## 10 109   Jabalí   porco bravo ˈpɔɹko ˈβɾaβo ALPI  Santa Comba              43.0    -8.81 La Coruña Gali…
## # ℹ 493 more rows

mientras que con inner_join():

## # A tibble: 503 × 10
##    id    pregunta ortografia  afi           atlas poblacion             latitud longitud provincia CCAA 
##    <chr> <chr>    <chr>       <chr>         <chr> <chr>                   <dbl>    <dbl> <chr>     <chr>
##  1 100   Jabalí   porco bravo ˈpɔɾko ˈβɾaβo ALPI  Sismundi                 43.7    -7.87 La Coruña Gali…
##  2 101   Jabalí   porco bravo ˈpɔɾko ˈβɾaβo ALPI  Valdoviño                43.6    -8.16 La Coruña Gali…
##  3 102   Jabalí   porco bravo ˈpɔɾko ˈβɾaβo ALPI  Miño                     43.3    -8.21 La Coruña Gali…
##  4 103   Jabalí   cocho bravo ˈkɔt͡ʃo ˈβɾaβo ALPI  Santa María de Oleir…    43.3    -8.32 La Coruña Gali…
##  5 104   Jabalí   jabalín     xɑβɘˈlĩŋ      ALPI  Abegondo                 43.2    -8.28 La Coruña Gali…
##  6 105   Jabalí   porco bravo ˈpɔɾko ˈβɾaβo ALPI  Aranga                   43.2    -8.02 La Coruña Gali…
##  7 106   Jabalí   porco bravo ˈpɔɹko ˈβɾaβo ALPI  Baio                     43.2    -8.99 La Coruña Gali…
##  8 107   Jabalí   cocho bravo ˈkɔt͡ʃo ˈβɾaβo ALPI  Carballo                 43.2    -8.71 La Coruña Gali…
##  9 108   Jabalí   porco fero  ˈpɔɹko ˈfeɹo  ALPI  Corcubión                42.9    -9.19 La Coruña Gali…
## 10 109   Jabalí   porco bravo ˈpɔɹko ˈβɾaβo ALPI  Santa Comba              43.0    -8.81 La Coruña Gali…
## # ℹ 493 more rows

En los tres casos obtienes un tabla de 503 observaciones (filas) y diez variables (columnas). Así que, elige uno de los tres _join() y ejecútalo.

alpi <- alpi %>%
  left_join(atlas, by = "id")

Comprueba cómo efectivamente ha crecido el número de columnas (variables) de alpi. Ejecuta en la consola

glimpse(alpi)

Podrás comprobar que hay 10 columnas: las cuatro originales de alpi y las seis que tiene atlas.

## Rows: 503
## Columns: 10
## $ id         <chr> "100", "101", "102", "103", "104", "105", "106", "107", "108", "109", "110", "111",…
## $ pregunta   <chr> "Jabalí", "Jabalí", "Jabalí", "Jabalí", "Jabalí", "Jabalí", "Jabalí", "Jabalí", "Ja…
## $ ortografia <chr> "porco bravo", "porco bravo", "porco bravo", "cocho bravo", "jabalín", "porco bravo…
## $ afi        <chr> "ˈpɔɾko ˈβɾaβo", "ˈpɔɾko ˈβɾaβo", "ˈpɔɾko ˈβɾaβo", "ˈkɔt͡ʃo ˈβɾaβo", "xɑβɘˈlĩŋ", "ˈp…
## $ atlas      <chr> "ALPI", "ALPI", "ALPI", "ALPI", "ALPI", "ALPI", "ALPI", "ALPI", "ALPI", "ALPI", "AL…
## $ poblacion  <chr> "Sismundi", "Valdoviño", "Miño", "Santa María de Oleiros", "Abegondo", "Aranga", "B…
## $ latitud    <dbl> 43.70717, 43.60976, 43.34911, 43.33589, 43.21667, 43.23469, 43.15569, 43.21394, 42.…
## $ longitud   <dbl> -7.869936, -8.161575, -8.211247, -8.324253, -8.283330, -8.017050, -8.987465, -8.706…
## $ provincia  <chr> "La Coruña", "La Coruña", "La Coruña", "La Coruña", "La Coruña", "La Coruña", "La C…
## $ CCAA       <chr> "Galicia", "Galicia", "Galicia", "Galicia", "Galicia", "Galicia", "Galicia", "Galic…

15.4.4 Cartografiar los datos

Ya tienes todos los elementos para cartografiar los datos referentes a las respuestas que los encuestados dieron para la pregunta Jabalí. Sin embargo, no son respuestas uniformes. Vas a comprobar cuántas respuestas diferentes ha habido. Para ello tan solo tienes que contar con count() para ver cuáles son los valores que hay en ortografia.

alpi %>%
  count(ortografia, sort = T)

Cuando ejecutes la orden anterior, se imprimirá en la consola el comienzo de la tabla de resultados.

## # A tibble: 66 × 2
##    ortografia       n
##    <chr>        <int>
##  1 jabalín        110
##  2 jabalí         100
##  3 porco-bravo     24
##  4 porco bravo     23
##  5 <NA>            22
##  6 porc singlar    21
##  7 javardo         19
##  8 porco-montês    13
##  9 javali          11
## 10 xabaril         11
## # ℹ 56 more rows
También puedes comprobarlo con unique(alpi$respuestas). El resultado es el mismo. Recuerda que en R las cosas se pueden hacer de más de una manera.

Hay 66 respuestas diferentes. Eso puede ser un auténtico desastre. Échale un ojo al mapa (fig. 15.18) que podría resultar.

Resultado con todos los valores de `ortografia`

Figura 15.18: Resultado con todos los valores de ortografia

Un auténtico batiburrillo de respuestas, aunque puedes ver una serie de agrupaciones. Aquí es donde tienes que tomar una serie de decisiones de cómo interpretar y presentar los datos y los resultados. Quizá la manera más elemental sea tener en cuenta el étimo puesto que hay varias formas que se remontan al latín PORCUS (porco, porc y puerco) y otras al arabismo ǧabalī ‘de monte’. Un tercer grupo lo pueden constituir las formas cochino, marrano, gorrino, todos sinónimos de puerco (< PORCUS). El cuarto son las formas sanglier, senglar y singlar, formas relacionadas con la forma francesa sanglier (< SINGULARIS) y, por último las formas bacó ‘cerdo’. Después tienes que todas las formas salvo jabalí suelen tener un calificativo: bravo, montés, jabalí, muntanyés, etc. Hay una extramada variabilidad.

Échale una nueva ojeada al mapa (fig. 15.19), aunque sin la leyenda, que será más claro.

Resultados ortográficos de la denominación del _Sus scrofa_ en la península Ibérica

Figura 15.19: Resultados ortográficos de la denominación del Sus scrofa en la península Ibérica

Se puede ver una cierta distribución. Vas a reducirla a cinco posibilidades: derivados de PORCUS, derivados de ǧabalī, relacionados con el francés sanglier, con el catalán bacó y, en último lugar, un grupo que recoja las demás formas. Esto complica un poco el manejo de la tabla. Pero no mucho.

Lo primero es deshacerse de los puntos en los que no hubo respuesta. Son los NA. Para logarlo tienes la función drop_na(). Así que, adelante.

alpi <- alpi %>%
  drop_na()

Ahora viene lo más complicado. Reducir la maraña de 65 variantes gráficas a cuatro formas básicas: PORCUS, ǧabalī, sanglier y el resto bajo la etiqueta otras. Para esto tienes que crear una nueva columna a la que llamarás respuesta y rellenarás las casillas con una de esas cuatro posibilidades dependiendo del valor la columna ortografia. La nueva columna se crea con una vieja conocida: mutate(). Lo complicado es reducir las 65 respuestas a tan solo cinco.

Aquí entran en juego las reglas de expresión regular con la función str_detect() y un condicional múltiple con la función case_when(). En esta instrucción ten muchísimo cuidado con los paréntesis; es muy fácil no cerrarlos bien. El código para reducirlo a esos cuatro valores es el que tienes a continuación. Córtalo y cópialo en el editor de RStudio, pero no lo ejecutes hasta haber leído la explicación.

alpi <- alpi %>%
  mutate(respuesta = case_when(
    str_detect(ortografia, "^p[ueo]+rc") ~ "porco",
    str_detect(ortografia, "^[cxjsha]?h?a[bv]") ~ "jabalí",
    str_detect(ortografia, "^s.*gl") ~ "sanglier",
    TRUE ~ 'otras'
 )
  )

15.4.4.1 Explicación del código

Como te he dicho vas a añadir una columna llamada respuesta a alpi y esto se consigue con mutate().

La función case_when() comprueba que se cumpla alguna de las condiciones que se establezcan dentro del paréntesis y que es la detección de una patrón de caracteres determinado. Lo que está haciendo es preguntando si el valor de cada una de las casillas de la columna ortografia comienza por alguno de los grupos de letras que hay en cada expresión de str_detect(). En el momento que alguna sea verdadera (TRUE) se rellena la casilla correspondiente de la variable respuesto con el valor que hay tras la tilde ~. Si no se cumple ninguna de las tres establecidas en las expresiones str_detect() entonces se rellenará con otras. El esquema gráfico de esta condicional es el de la figura 15.20).

Esquema de flujo de `case_when()`

Figura 15.20: Esquema de flujo de case_when()

La función str_detect() lo que hace es mirar si en la variable ortografia, primer argumento de la función, hay alguna de las secuencias que hay entre los corchetes. Por ejemplo, en el primer caso tienes ^p[ueo]+rc. Esta expresión regular lo que le dice a str_detect() es que mire si el valor de la casilla comienza por –el ^– una p y le sigue una o más veces –el +– una u, una e o una o, por eso están encerrado entre corchetes [], y a continuación debe haber una r seguida de una c. Esta expresión será verdadera (TRUE) en todas aquellas celdas de ortografia que comiencen por porc o puerc, por lo que la casilla correspondiente de la nueva columna respuesta se rellenará con el valor porco.

En la segunda expresión de str_detect() es, sin duda, la más complicada, puesto que la gama de formas gráficas es muy grande. Lo que le pides a R es que siempre la casilla ortografia comience –^– por una c, x, j, s, h o una a, por eso está la secuencia entre corchetes [cxjsha]. Puesto que cualquiera de estas letras puede aprecer o no se le pospone a la fórmula un signo de interrogación. En algunos casos a la c le puede seguir una hchabalín–, por eso hay una h seguida de ?. Para asegurar la expresión y que los resultados sean todos los posibles relacionados con jabalí le indicas que a continuación tiene que haber una a, pero esto te abre la posibilidad de capturas todos aquellos casos en que la respuesta ortográfica comience por sa y eso incluiría sanglier, por lo que tienes que poner una restricción: la consonante que sigue a esa sílaba inicial y, en este caso solo hay dos letras posibles b y v con lo que añades la disyuntiva [bv]. Con esta complicada expresión regular puedes reducir las 21 formas ortográficas para los derivados de ǧabalī a tan solo una, que es el valor que se guardará en las casillas correspondientes de la nueva columna respuesta. Estas son las 21 formas ortográficas que hay en esta cuestion:

##  [1] "jabalín"   "jabalí"    "xabaril"   "xabalí"    "xabarín"   "xabalín"   "javali"    "javaril"  
##  [9] "javardo"   "javato"    "habalín"   "sabarín"   "jabarín"   "jabaril"   "xabarí"    "jabalises"
## [17] "jabalís"   "jabato"    "abalí"     "jabali"    "chabalín"

No creo que sea necesario que me demore en explicar la dos última regla –^s.*gl– porque es meridianamente clara. Extraerá estas formas:

## [1] "singlar"  "sanglier" "senglar"

Ejecuta el código y échale una ojeada a la tabla resultante ejecutando en la consola

glimpse(alpi)

Podrás ver que la última línea corresponde a la nueva columna respuesta.

## Rows: 481
## Columns: 11
## $ id         <chr> "100", "101", "102", "103", "104", "105", "106", "107", "108", "109", "110", "111",…
## $ pregunta   <chr> "Jabalí", "Jabalí", "Jabalí", "Jabalí", "Jabalí", "Jabalí", "Jabalí", "Jabalí", "Ja…
## $ ortografia <chr> "porco bravo", "porco bravo", "porco bravo", "cocho bravo", "jabalín", "porco bravo…
## $ afi        <chr> "ˈpɔɾko ˈβɾaβo", "ˈpɔɾko ˈβɾaβo", "ˈpɔɾko ˈβɾaβo", "ˈkɔt͡ʃo ˈβɾaβo", "xɑβɘˈlĩŋ", "ˈp…
## $ atlas      <chr> "ALPI", "ALPI", "ALPI", "ALPI", "ALPI", "ALPI", "ALPI", "ALPI", "ALPI", "ALPI", "AL…
## $ poblacion  <chr> "Sismundi", "Valdoviño", "Miño", "Santa María de Oleiros", "Abegondo", "Aranga", "B…
## $ latitud    <dbl> 43.70717, 43.60976, 43.34911, 43.33589, 43.21667, 43.23469, 43.15569, 43.21394, 42.…
## $ longitud   <dbl> -7.869936, -8.161575, -8.211247, -8.324253, -8.283330, -8.017050, -8.987465, -8.706…
## $ provincia  <chr> "La Coruña", "La Coruña", "La Coruña", "La Coruña", "La Coruña", "La Coruña", "La C…
## $ CCAA       <chr> "Galicia", "Galicia", "Galicia", "Galicia", "Galicia", "Galicia", "Galicia", "Galic…
## $ respuesta  <chr> "porco", "porco", "porco", "otras", "jabalí", "porco", "porco", "otras", "porco", "…

Comprueba ahora cuantos valores diferentes hay en la variable respuesta. Puedes hacerlo con

alpi %>% count(respuesta)

o con

unique(alpi$respuesta)

En cualquier caso serán cuatro posibilidades, las que determinaste para cada búsqueda con case_when(). La única diferencia es la cantidad de información que da una y otra respuesta. Quizá la más interesante sea la primera, puesto que te informa de en cuantos puntos se dio cada una de esas respuestas.

## # A tibble: 4 × 2
##   respuesta     n
##   <chr>     <int>
## 1 jabalí      308
## 2 porco       120
## 3 otras        40
## 4 sanglier     13

Es evidente que en el ámbito iberorrománico los hablantes, en los años 1930, preferían los derivados de ǧabalī y en segundo lugar los de PORCUS. Ya es hora de verlo reflejado en el mapa (fig. 33) y extraer las conclusiones pertienentes.

El código es el mismo que usaste antes, solo que ahora tienes que cambiar de qué columna debe extraer los valores para asignar los colores (color =).

ggplot() +
  geom_sf(data = mapa) +
  geom_point(data = alpi,
             aes(x = longitud,
                 y = latitud,
                 color = ortografia))

En el primer intento fue ortografia, ahora es la nueva variable respuesta, así que el código será

ggplot() +
  geom_sf(data = mapa) +
  geom_point(data = alpi,
             aes(x = longitud,
                 y = latitud,
                 color = respuesta))

Lo que dibujará este hermoso mapa de la figura 15.21.

Resultados reducidos de las respuestas del ALPI a la pregunta «Jabalí»

Figura 15.21: Resultados reducidos de las respuestas del ALPI a la pregunta «Jabalí»

Es evidente que en la zona central de la iberorromania predominan los derivados de ǧabalī y que en las zonas laterales (gallego-portugués y catalán) los de PORCUS, aunque hay una fuerte penetración de ǧabalī en el gallego y del Tajo hacia el sur en el portugués y, además, ha divido el territorio catalán en dos puesto que la forma mayoritaria en Tarragona son derivados de ǧabalī, mientras que en Lérida, Barcelona y Gerona predominan los de PORCUS, aunque con varios puntos de la forma francesa sanglier, que es la que predomina en el Rosellón.

Lo puedes observar mejor en el mapa de la figura 34, en el que los huecos entre los puntos se han rellenado y forman unas áreas más claras y que efectivamente, los derivados de ǧabalī son los que predominan en el ámbito Ibeororrománico y le han ido comiendo el terreno a los de PORCUS en las área laterales y que hay islotes en los que hay formas cuyo primer elemento no contiene las formas dominantes (marrano, cochino, guarro, tocino, etc. que puede está seguido o no de un adjetivo tipo bravo, javalí, sauvatge, montanyès, etc.)

## The legacy packages maptools, rgdal, and rgeos, underpinning the sp package,
## which was just loaded, will retire in October 2023.
## Please refer to R-spatial evolution reports for details, especially
## https://r-spatial.org/r/2023/05/15/evolution4.html.
## It may be desirable to make the sf package available;
## package maintainers should consider adding sf to Suggests:.
## The sp package is now running under evolution status 2
##      (status 2 uses the sf package in place of rgdal)
## rgeos version: 0.6-4, (SVN revision 699)
##  GEOS runtime version: 3.10.2-CAPI-1.16.0 
##  Please note that rgeos will be retired during October 2023,
## plan transition to sf or terra functions using GEOS at your earliest convenience.
## See https://r-spatial.org/r/2023/05/15/evolution4.html for details.
##  GEOS using OverlayNG
##  Linking to sp version: 2.0-0 
##  Polygon checking: TRUE
Áreas de distribución de los derivados ortográficos para las designaciones del _Sus scrofa_

Figura 15.22: Áreas de distribución de los derivados ortográficos para las designaciones del Sus scrofa

15.5 Diagramas de Voronoi con un atlas de pequeño dominio

El mapa con el que se cierra la sección anterior (fig. 15.22) está trazado con los llamados polígonos de Voronoi o Thiessen que es una manera elegante y matemáticamente adecuada para determinar el difusión de un fenómeno dialectal y representarlo en un mapa. De nuevo, las matemáticas que permiten el trazado de los polígonos de Voronoi son de infarto. Sin embargo, los programadores han creado una librería que permite el dibujarlos con extremada sencillez en R. Se trata de la librería {ggvoronoi} que, en realidad, es un complemento para usarlo con {ggplot2}. Así que instálala en tu ordenador. Ya sabes cómo.

install.packages("ggvoronoi") # Solo se instala la primera vez.

No vas a trazar el mapa anterior (fig. 15.22) puesto que los datos encierran un pequeño problema que los diagramas de Voronoi no pueden resolver: las respuestas múltiples de los encuestados. Para esta explicación vas a establecer las áreas de seseo, ceceo y distinguidoras en Andalucía a partir de los datos del Atlas Lingüístico de Andalucía. Este atlas tiene un mapa, el 1705, que se titula «áreas de mantenimiento o neutralización de la oposición /s/ : /θ/». Este es en realidad un mapa resumen, pues no da datos brutos sino resumidos por medio de símbolos, uno para cada una de las cuatro posibilidades que los investigadores establecieron: distinción, seseo, ceceo y polimorfismo (hay otra mucha información que no interesa para el objetivo de esta sección).

A partir de ese mapa 1705 se ha creado una tabla con dos columnas: id, que corresponde al código identificativo de cada punto de encuesta, y resultado, en la que aparece una de las cuatro posibles respuestas que he mencionado. Este es el aspecto de la tabla.

id resultado
AL100 distinción
AL200 distinción
AL201 distinción
AL202 distinción
AL203 distinción
AL204 distinción
AL205 distinción
AL300 distinción
AL301 distinción
AL302 distinción

Vas a aprender a dibujar el mapa de Andalucía y representar en él con los polígonos de Voronoi las áreas que distinguen, sesean, cecean y en las que hay polimorfismo.

15.5.1 Al teclado

Carga las librerías que vas a necesitar. Son estas tres.

library(tidyverse)
library(sf)
library(ggvoronoi)

Ten en cuenta que {tidyverse} y {sf} imprimirán mensajes de carga. No los reproduzco para no alargarme.

Lo siguiente es cargar los datos. La tabla seseo-alea es una fichero separado por tabuladores que se encuentra en el repositorio del proyecto 7PartidasDigital que vas a guardar en el objeto alea. Esta es la url https://raw.githubusercontent.com/7PartidasDigital/AnaText/master/datos/geolinguistic/seseo-alea.txt y la orden para leerlo es

alea <- read_tsv("https://raw.githubusercontent.com/7PartidasDigital/AnaText/master/datos/geolinguistic/seseo-alea.txt")

Al cargarlo se impimirá el consabido mensaje en el que te informa del nombre de las variables y del tipo de datos que contiene cada una de ellas.

## Rows: 228 Columns: 2
## ── Column specification ────────────────────────────────────────────────────────────────────────────────
## Delimiter: "\t"
## chr (2): id, resultado
## 
## ℹ Use `spec()` to retrieve the full column specification for this data.
## ℹ Specify the column types or set `show_col_types = FALSE` to quiet this message.

Ahora tienes que añadirle la información geográfica de cada punto. Es decir, las coordenadas geográficas para cada uno de los puntos de encuesta. Ya lo has usado al tratar con el ALPI, con lo que la manera de carga la tienes más atrás, pero te la recuerdo. Primero lees la tabla con la onformación geográfica de los atlas lingüísticos.

atlas <- read_tsv("https://raw.githubusercontent.com/7PartidasDigital/AnaText/master/datos/geolinguistic/ATLAS_LINGUISTICOS.txt")

Al cargarse se imprimirá el aviso con los nombres de las variables y el el tipo de contenido.

## Rows: 1558 Columns: 7
## ── Column specification ────────────────────────────────────────────────────────────────────────────────
## Delimiter: "\t"
## chr (5): atlas, id, poblacion, provincia, CCAA
## dbl (2): latitud, longitud
## 
## ℹ Use `spec()` to retrieve the full column specification for this data.
## ℹ Specify the column types or set `show_col_types = FALSE` to quiet this message.

Ahora tienes que extraer de atlas las coordenadas y adjuntarlas a la tabla de los datos, a alea. La tabla atlas tiene las coordenadas de varios atlas lingüísticos, como puedes comprobar en esta tabla.

atlas n
ALPI 524
ALEA 228
ALCYL 208
PALDC 189
ALEARN 177
ALCLM 162
ALECan 47
ADIM 16
ALECAn 7

Como lo que te interesa es la información referente al ALEA, solo tienes que borrar la información que no se refiera al ALEA con filter().

atlas <- atlas %>%
  filter(atlas == "ALEA")

Lo que reducirá el tamaño de atlas de las más de 1500 líneas que tiene a tan solo 228, que es el número de puntos de encuesta del ALEA.

Ahora tienes que unir ambas tablas con rigth_join() (o con inner_join() o left_join()) de manera que la tabla alea importe las coordenadas (latitud y longitud) que hay en atlas.

alea <- alea %>%
  left_join(atlas, by = "id")

Puedes examinar el contenido de la tabla con

alea

lo que te mostrará las diez primeras línea de la tabla y podrás comprobar que se han incorporado las columnas atlas, poblacion, latitud, longitud, provincia y CCAA.

## # A tibble: 228 × 8
##    id    resultado  atlas poblacion   latitud longitud provincia CCAA     
##    <chr> <chr>      <chr> <chr>         <dbl>    <dbl> <chr>     <chr>    
##  1 AL100 distinción ALEA  Lúcar          37.4    -2.42 Almería   Andalucía
##  2 AL200 distinción ALEA  Topares        37.9    -2.23 Almería   Andalucía
##  3 AL201 distinción ALEA  Vélez-Rubio    37.6    -2.07 Almería   Andalucía
##  4 AL202 distinción ALEA  El Contador    37.6    -2.36 Almería   Andalucía
##  5 AL203 distinción ALEA  Oria           37.5    -2.30 Almería   Andalucía
##  6 AL204 distinción ALEA  La Perulera    37.4    -2.16 Almería   Andalucía
##  7 AL205 distinción ALEA  Pulpí          37.4    -1.75 Almería   Andalucía
##  8 AL300 distinción ALEA  Alcóntar       37.3    -2.60 Almería   Andalucía
##  9 AL301 distinción ALEA  Bacares        37.3    -2.45 Almería   Andalucía
## 10 AL302 distinción ALEA  Gérgal         37.1    -2.54 Almería   Andalucía
## # ℹ 218 more rows

Solo necesitas las columnas id, resultado, latitud y longitud. Si quieres puedes quedarte con esas cuatro solo, pero no merece la pena enredar más de lo necesario.

Ya tienes toda la información necesaria para representar los datos sobre un mapa. Tan solo te falta el mapa. Como estás operando únicamente con el territorio de la comunidad de Andalucía, entonces te interesan los ficheros shapefile con las divisiones administrativas ESP_adm. Recordarás que te dije que había cinco niveles:

  1. España (perímetro)
  2. España por comunidades autónomas
  3. España por provincias
  4. España por comarcas
  5. España por municipios.

Tan solo te interesa la comunidad autónoma de Andalucía y, además, no te hacen falta los límites de las provincias, por lo que necesitas cargar el fichero para el nivel 1, comunidades autónomas. Recuerda que estos ficheros se llaman ESP_admX.shp, donde la X la has de sustituir por el nivel de granularidad que deseas. Puesto que solo quieres la silueta de Andalucía, el fichero adecuado es ESP_adm1.shp. Cárgalo con (lo que hay antes de ESP_adm es la ruta de mi ordenador, cámbiala por la correspondiente a tu ordenador, la ruta que lleva al lugar donde hayas guardado las shapefile que descargarte al principio de este capítulo).

mapa <- st_read("../mapas/ESP_adm/ESP_adm1.shp")

Al cargarse se imprimirá la información acerca de este complicado objeto sf.

## Reading layer `ESP_adm1' from data source 
##   `/Users/JMFR/Library/CloudStorage/OneDrive-UVa/mapas/ESP_adm/ESP_adm1.shp' using driver `ESRI Shapefile'
## Simple feature collection with 18 features and 9 fields
## Geometry type: MULTIPOLYGON
## Dimension:     XY
## Bounding box:  xmin: -18.16153 ymin: 27.63736 xmax: 4.328195 ymax: 43.79153
## Geodetic CRS:  WGS 84

Ahora tienes que averiguar el nombre exacto que los creadores de ESP_adm1.shp le han dado a cada una de las comunidades autónomas. Lo puedes logar de manera rápida con

unique(mapa$NAME_1)

lo que hará que se imprima en la consola

##  [1] "Andalucía"                  "Aragón"                     "Cantabria"                 
##  [4] "Castilla-La Mancha"         "Castilla y León"            "Cataluña"                  
##  [7] "Ceuta y Melilla"            "Comunidad de Madrid"        "Comunidad Foral de Navarra"
## [10] "Comunidad Valenciana"       "Extremadura"                "Galicia"                   
## [13] "Islas Baleares"             "Islas Canarias"             "La Rioja"                  
## [16] "País Vasco"                 "Principado de Asturias"     "Región de Murcia"

El nombre de la comunidad que te interesa es Andalucía. Ahora solo te queda borrar de mapa el resto de las comunidades con filter().

mapa <- mapa %>%
  filter(NAME_1 == "Andalucía")

La expresión anterior reducirá el objeto de 18 observaciones a tan solo 1.

Ya tienes todo lo necesario para representar sobre el mapa los datos como el que hay en la figura 15.23.

Puntos distinguidores, seseantes, ceceantes y polimórficos en el ALEA

Figura 15.23: Puntos distinguidores, seseantes, ceceantes y polimórficos en el ALEA

Puedes ver algunos los patrones areales, pero no son claros porque es una ensalada de puntos. Aquí es donde entran los polígonos Voronoi. La instrucción para dibujar el mapa de la figura 15.23 era

ggplot() +
    geom_sf(data = mapa) +
    geom_point(data = alea,
               aes(x = longitud,
                   y = latitud,
                   color = resultado))

Para dibujarlo con los polígonos Voronoi es

ggplot() +
  geom_voronoi(data = alea,
               aes(x = longitud,
                   y = latitud,
                   fill=resultado),
               outline = mapa)

No la ejecutes. Si lo has hecho te habrá impreso este mensaje:

Warning messages:
1: In if (class(outline) != "data.frame" & class(outline) != "SpatialPolygonsDataFrame" &  : la condición tiene longitud > 1 y sólo el primer elemento será usado
2: In voronoi_polygon(data, deparse(substitute(x)), deparse(substitute(y)),  : Outline must be of class data.frame or SpatialPolygonsDataFrame. No outline will be used.

En la ventana Plots puede que se haya impreso algo abstracto (figura ??), que quizá tenga su interés artístico.

Si ha sucedido eso, es porque la función geom_voronoi() ya tiene que hacer suficientes cálculos como para enredarse con los que le obligaría el objeto sf de mapa. El aviso que se imprimió ya te da las posibles soluciones. O convertir mapa a una data.frame o a una SpatialPolygonsDataFrame. Parece que es algo que los programadores de la librería {sf} ya preveieron e incluyeron una función para convertir un objeto sf en un objeto SpatialPolygonsDataFrame. La función para hacerlo es as_Spatial() y tan solo necesita saber qué objeto y que columna debe convertir. En este caso el objeto sf lo tienes en mapa y la columna que necesitas transformar es geometry, que es donde está la información para trazar el perfil del territorio. La manera más sencilla de indicar una sola columna de una tabla es separando el nombre de la tabla y el de la columna con el signo del dólar $. Por lo tanto la manera de convertir mapa al tipo de objeto adecuado es

mapa <- as_Spatial(mapa$geometry)

Si echas una ojeada al panel Enviroment, verás que mapa ahora es un Large SpatialPolygons de poco más de 690 Kb. No merece la pena detenerse en explorar el contenido de este nuevo objeto. Es bastante críptico para los nos iniciados, aunque si tienes curiosidad Google te puede ayudar a entender el contenido.

Si ejecutas de nuevo la instrucción de ggplot() se tiene que imprimir el mapa de la figura 15.24 (tardará un poquito).

Áreas de distribución de los hablantes distinguidores, seseantes, ceceantes y polimórficos

Figura 15.24: Áreas de distribución de los hablantes distinguidores, seseantes, ceceantes y polimórficos

Parece que la forma mayoritaria en la Andalucía de los años sesenta, cuando Alvar hizo las encuestas, es la neutralización de la oposición /s/:/θ/ frente a la distinción. Puedes simplificar aún más el mapa y ver tan solo dos zonas (y posibles islotes): nuetralización y distinción. El mapa resultante sería el de la figura 15.25.

Zonas distinguidoras y neutralizadoras de la oposición /s/:/θ/

Figura 15.25: Zonas distinguidoras y neutralizadoras de la oposición /s/:/θ/

Es muchísimo más claro que el anterior. Para conseguirlo solo he tenido que crear una nueva variable en alea para reducir las cuatro posibilidades a dos: neutralización, que recoge poliformismo, seseo y ceceo y distinción.

En el caso de las denominaciones para el Sus scrofa usaste la función case_when() que es para cuando las posibilidades son más de dos. Tómate como el reto final de este capítulo el averiguar cuál es la función que haría el trabajo. Ya la has visto en un capítulo anterior.