Municipios natales de todos los futbolistas españoles del Valencia Club de Fútbol

Fútbol
Valencia CF
España
Municipios
GPKG
Autor/a
Afiliación

Jose Miguel Hernández Sánchez

Universitat de València

Fecha de publicación

23 de marzo de 2025

Input

Este proyecto busca representar gráficamente en un mapa interactivo, todos los municipios de España de los que provienen todos los jugadores nacionales que han debutado en partido oficial de cualquier competición con el Valencia CF, desde el día de su fundación, 18 de marzo de 1919, hasta el momento de realización de este trabajo, 10 de marzo de 2025.

No podemos empezar sin mencionar el inmenso trabajo de “Ciberche”, la mayor base de datos dedicada al Valencia CF y la página de donde hemos extraído toda la información, y agradecer su colaboración en este trabajo, facilitándonos dichos datos. El enlace a dicha página se adjunta aquí.

El trabajo ha sido realizado íntegramente a través del programa R.

Otra información de interés (metadatos):

  • Temática: Valencia CF

  • Autor: Ciberche

  • Fecha de extracción: 10 de marzo de 2025

  • Sitio web: https://www.ciberche.net/

  • Condiciones: “La presente base de datos está inscrita en el Registro de la Propiedad Intelectual con el número de asiento registral 09/2022/1276. Todos los datos recogidos son propiedad de Ciberche y su uso debe ser autorizado previamente por el propietario de los mismos.”

Descripción

Podemos empezar con la descripción de la base de datos obtenida, no sin antes cargar las librerías necesarias:

libs <- c("readxl", "writexl", "rvest", "xml2", "tidyverse", "openxlsx", "sf", "dplyr", "mapSpain", "ggplot2", "tidygeocoder", "leaflet", "knitr")
installed_libs <- libs %in% rownames(installed.packages())
if (any(installed_libs == F)) {install.packages(libs[!installed_libs])}
invisible(lapply(libs, library, character.only = T))
rm(libs, installed_libs)

Una vez llevado a cabo este paso inicial, podemos cargar nuestra base de datos y echarle un primer vistazo.

players_VCF <- read.xlsx("data/000119/JUGADORES VCF (Ciberche).xlsx")
players_VCF <- players_VCF %>% filter("Min." > 0)
kable(head(players_VCF))
X1 Nombre Min PJ Tit Sup Cam NJ PG %PG PE %PE PP %PP
1 Aarón Ñíguez 52 3 1 2 1 101 2 0.67 0 0.00 1 0.33
2 Abdón García 7380 82 82 0 0 60 34 0.41 14 0.17 34 0.41
3 Abel Hernández 0 0 0 0 0 36 0 0.00 0 0.00 0 0.00
4 Abelardo González 15176 171 167 4 3 242 86 0.50 38 0.22 47 0.27
5 Adjutorio Serrat 6886 80 79 1 6 56 27 0.34 25 0.31 28 0.35
6 Adri Gómez 0 0 0 0 0 46 0 0.00 0 0.00 0 0.00

Con estas dos líneas de código, hemos cargado los nombres y estadísticas (partidos jugados, minutos, porcentaje de victorias, etc.) de los casi mil jugadores españoles del Valencia CF que han sido convocados en partido oficial, y luego filtrado a aquellos cuya cantidad de minutos sea superior a cero, indicando así su debut con el equipo.

Como podemos ver, no existen datos geoespaciales de ningún tipo en nuestra base de datos, por lo que tuvimos que extraer esta base de datos a un excel (mostraremos el código en tipo comentario evitando así su ejecución, ya que no nos interesa guardar este archivo) y tras un tedioso proceso manual en el que copiamos de la base de datos de Ciberche todos los diferentes municipios natales de los 604 jugadores que aparecen ahora en el dataset, conseguimos añadir una variable más a nuestros datos y lo guardamos en un objeto diferente, eliminando aquellos sujetos que no nos interesaban, es decir, los que habíamos filtrados previamente:

# Extraemos la base de datos a un nuevo excel y añadimos manualmente las localidades
write_xlsx(players_VCF, "JUGADORES VCF.xlsx") 
# Una vez añadida la nueva columna, cargamos el nuevo archivo
playersVCF <- read.xlsx("data/000119/JUGADORES VCF.xlsx")
kable(head(playersVCF))
X1 Nombre Min PJ Tit Sup Cam NJ PG %PG PE %PE PP %PP Localidad
1 Aarón Ñíguez 52 3 1 2 1 101 2 0.67 0 0.00 1 0.33 Elche (Alicante)
2 Abdón García 7380 82 82 0 0 60 34 0.41 14 0.17 34 0.41 Avilés (Asturias)
4 Abelardo González 15176 171 167 4 3 242 86 0.50 38 0.22 47 0.27 Sotrondio (Asturias)
5 Adjutorio Serrat 6886 80 79 1 6 56 27 0.34 25 0.31 28 0.35 Olot (Girona)
7 Adrián Guerrero 127 2 1 1 1 48 1 0.50 1 0.50 0 0.00 Blanes (Girona)
9 Alba 90 1 1 0 0 70 0 0.00 0 0.00 1 1.00 NA

Por tanto, para aclarar un poco toda esta parte que puede parecer un poco liosa, el proceso fue el siguiente: Obtuvimos el primer conjunto de datos con 964 jugadores (players_VCF) y filtramos aquellos que nos interesaban reduciendo en más de 300 observaciones el dataset. Luego guardamos este nuevo dataset (playersVCF) y le añadimos una variable nueva que eran las respectivas localidades. Hemos preferido guardarlo en estos dos objetos para diferenciarlos y por tanto, en este desarrollo, sólo necesitaremos el segundo, ya limpio y preparado para su manipulación.

Ahora sí, con nuestro conjunto de datos listo, podíamos empezar con su tratamiento.

Tratamiento

Primero de todo, podemos ver como la localidad aparecía conjunta, por lo que era importante separar el municipio de su provincia (y eliminar sus paréntesis), permitiéndonos así poder asignar una ubicación a cada municipio concreto, además de poder disponer de las respectivas provincias en caso de querer usarlas más tarde. Para ello, usamos estas líneas de código:

playersVCF <- playersVCF %>%
  separate("Localidad", into = c("Ciudad", "Provincia"), sep = " \\(", fill = "right", extra = "merge")   %>%
  mutate(Provincia = ifelse(!is.na(Provincia), gsub("\\)$", "", Provincia), Provincia))

Ahora ya sí, podemos geolocalizar dichos municipios usando como referencia sus respectivos nombres con el paquete tidygeocoder a través de los datos de Open Street Maps (OSM). Esto nos llevará un rato, no más de 5 minutos.

playersVCF <- playersVCF %>%
  geocode(address = "Ciudad", method = "osm")
Passing 247 addresses to the Nominatim single address geocoder
Query completed in: 251.2 seconds
kable(head(playersVCF))
X1 Nombre Min PJ Tit Sup Cam NJ PG %PG PE %PE PP %PP Ciudad Provincia lat long
1 Aarón Ñíguez 52 3 1 2 1 101 2 0.67 0 0.00 1 0.33 Elche Alicante 38.26533 -0.6988391
2 Abdón García 7380 82 82 0 0 60 34 0.41 14 0.17 34 0.41 Avilés Asturias 43.55544 -5.9222466
4 Abelardo González 15176 171 167 4 3 242 86 0.50 38 0.22 47 0.27 Sotrondio Asturias 43.27602 -5.6048833
5 Adjutorio Serrat 6886 80 79 1 6 56 27 0.34 25 0.31 28 0.35 Olot Girona 42.18222 2.4890211
7 Adrián Guerrero 127 2 1 1 1 48 1 0.50 1 0.50 0 0.00 Blanes Girona 41.67562 2.7932391
9 Alba 90 1 1 0 0 70 0 0.00 0 0.00 1 1.00 NA NA NA NA

Uno de los principales problemas que hemos encontrado durante el proceso de representación de los datos fueron los errores que cometía la función anterior a la hora de geolocalizar las diferentes ciudades que pasábamos. Los errores básicamente consistían en que las ubicaciones no eran correctas, por lo que aparecían jugadores en municipios que no les correspondían. Por eso, tras revisar detallada y cuidadosamente el proceso para todos las observaciones, hemos encontrado ciertos errores en determinadas ciudades que hemos solucionado de esta manera, después de adquirir sus coordenadas desde Google Maps, que también usa el sistema de coordenadas EPSG: 4326:

playersVCF <- playersVCF %>%
  mutate(
    lat = case_when(
      Ciudad == "Arroyo de la Miel" ~ 36.5956,
      Ciudad == "Almenara" ~ 39.7535, 
      Ciudad == "Puerto de Santa María" ~ 36.59597,
      Ciudad == "Cartagena" ~ 37.6256,
      Ciudad == "Teruel" ~ 40.34605,
      Ciudad == "Durango" ~ 43.1719,
      Ciudad == "Anglès" ~ 41.9566,
      Ciudad == "Palencia" ~ 42.0098, 
      Ciudad == "Ibiza" ~ 38.9067, 
      TRUE ~ lat
    ),
    long = case_when(
      Ciudad == "Arroyo de la Miel" ~ -4.5522,
      Ciudad == "Almenara" ~ -0.22298,
      Ciudad == "Puerto de Santa María" ~ -6.2335,
      Ciudad == "Cartagena" ~ -0.9964,
      Ciudad == "Teruel" ~ -1.10577,
      Ciudad == "Durango" ~ -2.63298,
      Ciudad == "Anglès" ~ 2.6334,
      Ciudad == "Palencia" ~ -4.5288,
      Ciudad == "Ibiza" ~ 1.42003,
      TRUE ~ long
    )
  )

Una vez superado uno de los principales obstáculos de este trabajo, convertimos nuestros datos a un objeto sf (datos espaciales) uniendo las dos columnas que teníamos reservadas para la latitud y la longitud, respectivamente. Usamos el crs = 4326 (sistema de coordenadas) porque, a pesar de estar trabajando para datos de España, tanto OSM como la librería leaflet que usaremos más tarde para representar los datos en el mapa trabajan con el sistema de referencia global, EPSG:4326 (WGS 84):

playersVCF_sf <- st_as_sf(playersVCF, coords = c("long", "lat"), na.fail = FALSE, crs = 4326)
kable(head(playersVCF_sf))
X1 Nombre Min PJ Tit Sup Cam NJ PG %PG PE %PE PP %PP Ciudad Provincia geometry
1 Aarón Ñíguez 52 3 1 2 1 101 2 0.67 0 0.00 1 0.33 Elche Alicante POINT (-0.6988391 38.26533)
2 Abdón García 7380 82 82 0 0 60 34 0.41 14 0.17 34 0.41 Avilés Asturias POINT (-5.922247 43.55544)
4 Abelardo González 15176 171 167 4 3 242 86 0.50 38 0.22 47 0.27 Sotrondio Asturias POINT (-5.604883 43.27602)
5 Adjutorio Serrat 6886 80 79 1 6 56 27 0.34 25 0.31 28 0.35 Olot Girona POINT (2.489021 42.18222)
7 Adrián Guerrero 127 2 1 1 1 48 1 0.50 1 0.50 0 0.00 Blanes Girona POINT (2.793239 41.67562)
9 Alba 90 1 1 0 0 70 0 0.00 0 0.00 1 1.00 NA NA POINT EMPTY

Ahora, para contextualizar los datos obtenidos y representarlos correctamente en el mapa de España, obtuvimos los 8131 municipios que componen nuestro país, sus nombres, geometrías, provincia y comunidad autónoma, entre otras variables, con el paquete mapSpain, y lo guardamos en otro objeto nuevo: spain_mun:

spain_mun <- esp_get_munic(epsg = "4326", moveCAN = FALSE)
kable(head(spain_mun))
codauto ine.ccaa.name cpro ine.prov.name cmun name LAU_CODE geometry
382 01 Andalucía 04 Almería 001 Abla 04001 POLYGON ((-2.77744 37.23836…
379 01 Andalucía 04 Almería 002 Abrucena 04002 POLYGON ((-2.88984 37.09213…
374 01 Andalucía 04 Almería 003 Adra 04003 POLYGON ((-2.93161 36.75079…
375 01 Andalucía 04 Almería 004 Albánchez 04004 POLYGON ((-2.13138 37.29959…
358 01 Andalucía 04 Almería 005 Alboloduy 04005 POLYGON ((-2.70077 37.09674…
373 01 Andalucía 04 Almería 006 Albox 04006 POLYGON ((-2.15335 37.54576…

Sin embargo, nos dimos cuenta de otro problema que nos iba a dificultar bastante las cosas, sobre todo a la hora de etiquetar los datos en el mapa: los nombres de los diferentes pueblos. La existencia de los diferentes idiomas oficiales en nuestro territorio fue uno de los principales detonantes del inconveniente, siendo los nombres de los municipios vascos los que causaban mayores complicaciones, pese a que en su gran mayoría eran reconocidos tanto en Español como en Euskera, y los que no únicamente tuvimos que tener cuidado de darnos cuenta para que no se perdiera ningún dato y traducirlo. Por otra parte, también encontramos otros pueblos, generalmente valencianos, catalanes o gallegos con denominaciones muy variadas, habiendo muchos que empezaban por Les, por L’ o por O, y mientras nosotros lo poníamos al principio de cada pueblo, (por ejemplo: L’ Alcúdia), mapSpain lo ponía al final (Alcúdia, L’). Este problema se atajó creando una función que luego aplicaríamos a nuestro objeto creado previamente spain_mun:

# Función para corregir nombres invertidos
corregir_nombre <- function(nombre) {
  sub("^(.*), (El|La|Los|Las|L'|l'|Els|Les|O|A|la|el|els|les )$", "\\2 \\1", nombre)
}

# Aplicamos la corrección en spain_mun
spain_mun$name <- sapply(spain_mun$name, corregir_nombre)

Con los municipios y sus datos geoespaciales ya guardados, los jugadores con la ubicación de sus ciudades natales y los problemas tanto de ubicación como de denominación resueltos, el siguiente paso era combinar los dos objetos:

playersVCF_mun <- st_join(playersVCF_sf, spain_mun, join = st_within)
kable(head(playersVCF_mun))
X1 Nombre Min PJ Tit Sup Cam NJ PG %PG PE %PE PP %PP Ciudad Provincia geometry codauto ine.ccaa.name cpro ine.prov.name cmun name LAU_CODE
1 Aarón Ñíguez 52 3 1 2 1 101 2 0.67 0 0.00 1 0.33 Elche Alicante POINT (-0.6988391 38.26533) 10 Comunitat Valenciana 03 Alicante/Alacant 065 Elche / Elx 03065
2 Abdón García 7380 82 82 0 0 60 34 0.41 14 0.17 34 0.41 Avilés Asturias POINT (-5.922247 43.55544) 03 Asturias, Principado de 33 Asturias 004 Avilés 33004
4 Abelardo González 15176 171 167 4 3 242 86 0.50 38 0.22 47 0.27 Sotrondio Asturias POINT (-5.604883 43.27602) 03 Asturias, Principado de 33 Asturias 060 San Martín del Rey Aurelio 33060
5 Adjutorio Serrat 6886 80 79 1 6 56 27 0.34 25 0.31 28 0.35 Olot Girona POINT (2.489021 42.18222) 09 Cataluña 17 Girona 114 Olot 17114
7 Adrián Guerrero 127 2 1 1 1 48 1 0.50 1 0.50 0 0.00 Blanes Girona POINT (2.793239 41.67562) 09 Cataluña 17 Girona 023 Blanes 17023
9 Alba 90 1 1 0 0 70 0 0.00 0 0.00 1 1.00 NA NA POINT EMPTY NA NA NA NA NA NA NA

De esta manera, lo que hemos hecho es unir ambos objetos pero de forma que, si un punto de un jugador de playersVCF_sf está dentro del polígono de un municipio en spain_mun, herede sus características tales como el nombre (aquí podemos ver la importancia de la corrección anterior para hacer más consistentes los nombres), provincia o comunidad, ya mencionadas antes. Sin embargo, no se guardan dichos polígonos de los pueblos, ya que eso es algo que utilizaremos más adelante.

Ahora agruparemos los datos de playersVCF_sf, concretamente los nombres de los jugadores, en función de los nombres de los municipios a los que pertenecen, además de sus respectivos puntos geográficos (que no polígonos de los mismos, reiteramos):

municipios_seleccionados <- playersVCF_mun %>%
  group_by(name) %>%
  summarise(Nombres = paste(Nombre, collapse = ", "))
kable(head(municipios_seleccionados))
name Nombres geometry
A Coruña Carlos Pellicer, Jason Remeseiro, José María Martín, José Reverter, Manolete Ríos, Nico González, Waldo Botana POINT (-8.395943 43.37097)
Aielo de Malferit Rafael Barber POINT (-0.5911695 38.88036)
Alaquàs Francisco Cotino, Manuel Ruz, Matías Rubio, Miguel Pallardó POINT (-0.46098 39.45729)
Albaida Daniel Olcina POINT (-0.5181895 38.83867)
Albal José Paredes, Salva Ruiz POINT (-0.4150821 39.39564)
Alboraia / Alboraya Fernando Giner POINT (-0.34948 39.501)

Como último paso antes de llevar a cabo la representación del mapa interactivo, unimos municipios_seleccionados con spain_mun, aplicando esta vez sí, los polígonos. Por tanto lo que conseguimos con el siguiente código es agregar a cada polígono la lista de jugadores que pertenecen a él. Dicho de otra forma, estamos obteniendo todos los pueblos de España y a cada uno le asociamos el nombre de los futbolistas que hayan nacido en él o se queda en blanco en caso de no tener representantes. Dada esta explicación, va a ser lógico esperar que una gran cantidad de pueblos no tengan jugadores asociados y por tanto es completamente normal que hayan columnas con muchos NA’s.

municipios_final <- st_join(spain_mun, municipios_seleccionados, join = st_intersects)
kable(head(municipios_final))
codauto ine.ccaa.name cpro ine.prov.name cmun name.x LAU_CODE name.y Nombres geometry
382 01 Andalucía 04 Almería 001 Abla 04001 NA NA POLYGON ((-2.77744 37.23836…
379 01 Andalucía 04 Almería 002 Abrucena 04002 NA NA POLYGON ((-2.88984 37.09213…
374 01 Andalucía 04 Almería 003 Adra 04003 NA NA POLYGON ((-2.93161 36.75079…
375 01 Andalucía 04 Almería 004 Albánchez 04004 NA NA POLYGON ((-2.13138 37.29959…
358 01 Andalucía 04 Almería 005 Alboloduy 04005 NA NA POLYGON ((-2.70077 37.09674…
373 01 Andalucía 04 Almería 006 Albox 04006 NA NA POLYGON ((-2.15335 37.54576…

Output

Se han obtenido como resultado dos conjuntos de datos para que, en función de la utilidad deseada, podamos elegir entre uno u otro. Pese a que el que nosotros utilizaremos a continuación para la representación del mapa es el que hemos almacenado en municipios_final, creemos que el obtenido previo a este (municipios_seleccionados), es más visual y representativo a la hora de verlos en formato tabla. Esto se debe a que, mientras que el primero contiene las geometrías necesarias de absolutamente todos los pueblos nacionales (tengan representación o no) para poder destacarlos en caso favorable, apareciendo así con miles de observaciones prácticamente inservibles, el segundo contiene única y exclusivamente los nombres de aquellos municipios de los que sí ha salido al menos un jugador (además de una categoría NA que contiene a los futbolistas de los cuales no se han podido encontrar datos de nacimiento).

Este último lo podemos guardar ya en formato GeoPackage con la función st_write:

st_write(municipios_seleccionados, "Municipios Jugadores VCF.gpkg")

El otro todavía vamos a emplearlo para generar un mapa que nos permita visualizar de forma interactiva las localidades de residencia de cada jugador, de modo que si pinchamos en uno de estos pueblos sombreados, aparecen los nombres de los jugadores procedentes del mismo.

# Aplicamos la paleta de colores
colores_vcf <- c("#F5A503", "#000000", "#FFFAF0", "#D4AF37")
paleta_colores <- colorFactor(palette = colores_vcf, domain = municipios_final$name.y)

# Graficamos
leaflet() %>%
  addTiles() %>%
  addPolygons(data = municipios_final, 
              fillColor = ~ifelse(!is.na(name.y), paleta_colores(name.y), "transparent"), 
              fillOpacity = ~ifelse(!is.na(name.y), 0.7, 0),
              color = "black", 
              weight = 1, 
              popup = ~paste("Jugadores de", name.x, ":", Nombres),
              highlightOptions = highlightOptions(
                weight = 3,
                color = "red",
                bringToFront = TRUE
              ))


Como ya hemos presentado antes, este mapa representa todos los pueblos de España y sombrea con color aquellos que cuentan con al menos un representante futbolístico en la historia del Valencia CF. Al clicar en cada uno de sus términos municipales, aparece el nombre de dicho municipio y también el de todos los jugadores que, tras nacer allí, llegaron a debutar en competición oficial en el primer equipo del Valencia CF. Es interesante ver la variedad y distribución de estos jugadores, y se pueden extraer muchas conclusiones como, el que a pesar de que las ciudades más grandes cuenten con la mayor representación, en cualquier pueblito de cualquier rincón de España puede aparecer un gran futbolista.

Una vez visto y curioseado nuestro mapa, estamos listos para descargar el conjunto de datos definitivo, que cuenta con todas las poblaciones españolas:

st_write(municipios_final, "Todos los municipios - Jugadores VCF.gpkg")

Ambos ficheros generados con este procedimiento se pueden descargar en formato GeoPackage directamente de aquí.



Proyectos de Innovación Educativa Emergente PIEE-2737007 y PIEE-3325394