The Clean Shot

The Clean Shot

Tutoriales R

Cómo se hace tabla SuperManager

Con función para optimizar equipos con los datos de El Rincón del SuperManager.

Avatar de Ivo Villanueva
Ivo Villanueva
sep 26, 2025
∙ De pago

La ACB está a punto de empezar y con ella el juego del SuperManager. Todos los años las mismas dudas y todos los años buscando consejos e información porque toda ayuda es poca. Esta función que tengo aquí es una versión en R de un tutorial en YouTube que explica cómo hacerlo en Excel y que me dio la idea para hacerlo en R. Lo pego aquí porque de seguro es súper útil y quizás más fácil para los que no sean muy expertos con R.

Cómo podéis ver, el vídeo tiene más años que la tos.

Empezamos con nuestro código aprovechando el post extra del viernes donde explico cómo extraer las tablas de mercado del SuperManager y de pretemporada del Rincón del SuperManager. Así que lo pego directamente, sin más explicación.

Cargamos las librerías los logos y el caption

library(tidyverse)
library(lpSolve)
library(gt)
library(gtExtras)
library(glue)
library(gtUtils)
library(rvest)
library(xml2)
library(janitor)


clubs <- read.csv("https://raw.githubusercontent.com/IvoVillanueva/logos_cuadrados_acb/refs/heads/main/acb_df.csv") %>%
  select(abb, equipo)

twitter <- "<span style='color:#000000;font-family: \"Font Awesome 6 Brands\"'>&#xE61A;</span>"
tweetelcheff <- "<span style='font-weight:bold;'>*@elcheff*</span>"
insta <- "<span style='color:#E1306C;font-family: \"Font Awesome 6 Brands\"'>&#xE055;</span>"
instaelcheff <- "<span style='font-weight:bold;'>*@sport_iv0*</span>"
github <- "<span style='color:#000000;font-family: \"Font Awesome 6 Brands\"'>&#xF092;</span>"
githubelcheff <- "<span style='font-weight:bold;'>*IvoVillanueva*</span>"
caption <- glue("**Gráfico**: *Ivo Villanueva* • {twitter} {tweetelcheff} • {insta} {instaelcheff} • {github} {githubelcheff}")

Y ahora cargamos las funciones para unir la tabla de mercado y la tabla de pretemporada.


url <- "https://www.rincondelmanager.com/smgr/pretemporada.php" %>%
  read_html()

tabla_bandera <- tibble(
  jugador = url %>% html_elements(".jugador") %>% html_text() %>% str_squish(),
  bandera = url %>% html_elements(".jugador") %>%
    xml_find_first(".//div") %>%
    xml_attr("class")
)

#Cambio algunos nombres para el joint

tabla <- url %>%
  html_element("table") %>%
  html_table(dec = ",") %>%
  clean_names() %>%
  mutate(broker = as.numeric(str_remove(broker, "\\."))) %>%
  left_join(tabla_bandera, join_by(jugador)) %>%
  relocate(bandera, .before = eq) %>%
  mutate(jugador = case_when(
    jugador == "Otis Livingston Ii"~ "Otis Livingston",
    jugador == "Pepe Vildoza" ~"José Vildoza",
    jugador =="Jermaine Samuels Jr."~ "Jermaine Samuels",
    TRUE ~ jugador
  ))


number <- 1:3
tablas <- "https://www.acb.com/articulo/ver/523322-supermanager-acb-2526-precios-y-tablas-de-broker.html" %>%
  read_html() %>%
  html_table(fill = TRUE)


tabladf <- function(number) {
  tablas %>% .[[number]] %>%
    janitor::clean_names() %>%
    mutate(pos = number,
           nombre = paste(nombre, apellido)) %>%
    select(equipo, nombre, precio, pos)
}
tabla_df <-map_df(number, tabladf)

#En la tabla final le doy nombre a la posicion y quito los jugadores sin #puntos y quito lesionados

tabla_df <-map_df(number, tabla)
data <- tabla_df %>%
  mutate(
    precio = parse_number(str_remove(precio, "\\.")),
    pos = case_when(
      pos == 1 ~ "Base",
      pos == 2 ~ "Alero",
      TRUE ~ "Pívot"
    ),
    val = precio / 50000
  ) %>%
  fuzzyjoin::stringdist_left_join(tabla %>% select(jugador, bandera, jug = jug_2, pts, val_est),
    by = c("nombre" = "jugador")
  ) %>%
  filter(!is.na(pts) & !nombre %in% c("Jean Montero", "Theo Maledon"))

Y ahora viene la función que busca el mejor equipo con los requisitos que necesitamos. Esto lo hace la librería lpSolve. Entonces:

  • Creamos una variable con el número de jugadores.

  • Marcamos el objetivo en la valoración media.

num_players <- nrow(data)

objetivo <- data %>% select(val_est) %>%
  replace(is.na(.), 0) %>% pull()

¿Te gusta este contenido? Dame, por favor, un empujonsito con una suscripción de pago.

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.

¿Ya eres suscriptor de pago? Iniciar sesión
© 2025 The Clean Shot
Privacidad ∙ Términos ∙ Aviso de recolección
Crea tu SubstackDescargar la app
Substack es el hogar de la gran cultura