Cómo se hace: gráfica Euroleague Box Creation
Desde el scraping hasta la visualización con gt()
🎯 En este post te enseño paso a paso cómo extraer los datos de la EuroLeague, calcular el indicador Box Creation ajustado por posesiones y construir una tabla visual con fotos, colores y exportación en PNG.
🚨 Antes de nada: aviso de vacaciones
Hola a todos,
⛱️ Estaré de vacaciones durante tres semanas, así que haré una pausa en las publicaciones hasta el 26/08. Me tomo este parón para recargar ideas y meditar un poco sobre este año y en que puedo mejorar
Mientras tanto, podéis repasar los posts más leídos últimamente:
Nos leemos a la vuelta. ¡Gracias por estar ahí!
¿Premiamos al mejor defensor o al mejor sistema defensivo?
Qué Odín me libre de decir que Tavares no se merece el premio a defensor del año.
Nos leemos a la vuelta. ¡Gracias por estar ahí!
🧰 Y ahora si: Librerías necesarias
En este post vamos a desglosar el código en R que permite extraer, analizar, crear y visualizar la estadística avanzada de Box Creation en la EuroLeague para la temporada 2024–2025.
Empezamos cargando las librerías necesarias para manipular datos, hacer scraping y formatear resultados:
library(tidyverse) # manipulación y visualización de datos
library(rvest) # Para hacer scraping de datos desde páginas web (HTML)
library(janitor) # Limpieza rápida de nombres de columnas y tablas
library(httr) # Para hacer peticiones HTTP (GET, POST) a APIs
library(jsonlite) # Para trabajar con datos en formato JSON ✍️ Créditos personalizados (caption)
Preparo el caption de los enlaces a mis redes y firma personalizada:
twitter <- "<span style='color:#000000;font-family: \"Font Awesome 6 Brands\"'></span>"
tweetelcheff <- "<span style='font-weight:bold;'>*@elcheff*</span>"
insta <- "<span style='color:#E1306C;font-family: \"Font Awesome 6 Brands\"'></span>"
instaelcheff <- "<span style='font-weight:bold;'>*@sport_iv0*</span>"
github <- "<span style='color:#000000;font-family: \"Font Awesome 6 Brands\"'></span>"
githubelcheff <- "<span style='font-weight:bold;'>*IvoVillanueva*</span>"
caption <- glue::glue("**Datos**: *@EuroLeague* • **Gráfico**: *Ivo Villanueva* • {twitter} {tweetelcheff} • {insta} {instaelcheff} • {github} {githubelcheff}")
📥 Descarga de estadísticas de equipo (RealGM)
Extraemos las estadísticas avanzadas de equipo desde RealGM usando rvest. Esto nos da el número de posesiones por equipo (pace), esencial para convertir los datos a valores por 100 posesiones.
También renombramos los equipos para que coincidan con los nombres oficiales:
pos <- "https://basketball.realgm.com/international/league/1/Euroleague/team-stats/2025/Advanced_Stats/Team_Totals" %>%
read_html() %>%
html_node("table") %>%
html_table() %>%
clean_names() %>%
select(team, pace) %>%
mutate(team = case_when(
team == "Olympiacos" ~ "Olympiacos Piraeus",
team == "Panathinaikos" ~ "Panathinaikos AKTOR Athens",
team == "Anadolu Efes" ~ "Anadolu Efes Istanbul",
team == "AS Monaco Basket" ~ "AS Monaco",
team == "Fenerbahce Beko" ~ "Fenerbahce Beko Istanbul",
team == "Barca" ~ "FC Barcelona",
team == "Real Madrid" ~ "Real Madrid",
team == "KK Partizan" ~ "Partizan Mozzart Bet Belgrade",
team == "KK Crvena Zvezda" ~ "Crvena Zvezda Meridianbet Belgrade",
team == "Paris Basketball" ~ "Paris Basketball",
team == "Bayern Munich" ~ "FC Bayern Munich",
team == "Baskonia" ~ "Baskonia Vitoria-Gasteiz",
team == "AX Armani Exchange Milan" ~ "EA7 Emporio Armani Milan",
team == "Zalgiris" ~ "Zalgiris Kaunas",
team == "Maccabi FOX Tel Aviv" ~ "Maccabi Playtika Tel Aviv",
team == "ASVEL Basket" ~ "LDLC ASVEL Villeurbanne",
team == "Virtus Bologna" ~ "Virtus Segafredo Bologna",
team == "ALBA Berlin" ~ "ALBA Berlin",
TRUE ~ team
))
🎨 Descarga de colores y logos de equipos (API EuroLeague)
Consultamos la API oficial de EuroLeague para obtener información visual: colores, nombres y logos. Este dataframe enriquecerá la tabla final.
Aquí te enseño como 👇
Entonces una vez que tenemos el enlace de la api corremos el siguiente código
teams <- "https://feeds.incrowdsports.com/provider/euroleague-feeds/v2/competitions/E/seasons/E2025/clubs" %>%
httr::GET(query = list()) %>% # Hace una petición GET a la URL del feed de equipos EuroLeague 2025
httr::content() %>% # Extrae el contenido de la respuesta en formato R
purrr::pluck("data") %>% # Extrae solo el objeto 'data' dentro del JSON
dplyr::tibble(value = .) %>% # Lo convierte en un tibble con una columna llamada 'value'
tidyr::unnest_wider(value) %>% # Desanida la lista principal de información de cada equipo
tidyr::unnest_wider(images, names_sep = "_") %>% # Desanida el campo 'images', separando columnas con prefijo 'images_'
select(team = sponsor, # Selecciona y renombra el nombre visible del equipo...
color = primaryColor, # ...el color principal...
alternate_color = secondaryColor) # ...y el color alternativ🕒 Recuerda: puedes activar los 10 días de prueba gratis para ver este post completo sin compromiso.
Continúa leyendo con una prueba gratuita de 7 días
Suscríbete a The Clean Shot para seguir leyendo este post y obtener 7 días de acceso gratis al archivo completo de posts.







