library(tidyverse)
library(lubridate)
library(data.table)Visualización del mercado de videojuegos en Steam
steam <- fread("games_march2025_cleaned.csv")games_per_year <- steam %>% mutate(year = lubridate::year(release_date)) %>% count(year) %>% filter(year >= 2005, year < 2025)Evolución de los lanzamientos en Steam
Se observa un crecimiento muy acusado a partir de 2015, lo que coincide con la expansión del desarrollo independiente y la consolidación de Steam como plataforma dominante.
ggplot(games_per_year, aes(x = year, y = n)) +
geom_line(color = "steelblue", linewidth = 1) +
geom_point(color = "steelblue") +
labs(
title = "Evolución de los lanzamientos de videojuegos en Steam",
subtitle = "Número de juegos publicados por año",
x = "Año",
y = "Número de lanzamientos"
) +
theme_minimal()El predominio del género indie indica una baja barrera de entrada y una fuerte presencia de desarrolladores pequeños.
genres_clean <- steam %>%
select(genres) %>%
filter(!is.na(genres)) %>%
mutate(
genres = str_remove_all(genres, "\\[|\\]|'")
)genres_count <- genres_clean %>%
separate_rows(genres, sep = ", ") %>%
count(genres, sort = TRUE)top_genres <- genres_count %>%
slice_max(n, n = 10)
ggplot(top_genres, aes(x = reorder(genres, n), y = n)) +
geom_col(fill = "steelblue") +
coord_flip() +
labs(
title = "Géneros más frecuentes en Steam",
subtitle = "Top 10 por número de videojuegos",
x = "Género",
y = "Número de juegos"
) +
theme_minimal()Los géneros indie y casual presentan precios más bajos, mientras que RPG y estrategia muestran mayor dispersión.
price_genres <- steam %>%
select(genres, price) %>%
filter(!is.na(genres), !is.na(price), price <= 60) %>%
mutate(
genres = str_remove_all(genres, "\\[|\\]|'")
) %>%
separate_rows(genres, sep = ", ") %>%
filter(genres %in% top_genres$genres)
ggplot(price_genres, aes(x = genres, y = price)) +
geom_boxplot(fill = "steelblue", alpha = 0.7, outlier.alpha = 0.2) +
coord_flip() +
labs(
title = "Distribución de precios por género",
subtitle = "Comparación entre los géneros más frecuentes en Steam",
x = "Género",
y = "Precio (€)"
) +
theme_minimal()steam_genres <- steam %>%
select(genres, pct_pos_total) %>%
filter(!is.na(genres), !is.na(pct_pos_total)) %>%
mutate(
genres = str_remove_all(genres, "\\[|\\]|'")
) %>%
separate_rows(genres, sep = ", ")top_genres_names <- top_genres$genres
steam_genres_top <- steam_genres %>%
filter(genres %in% top_genres_names)ggplot(steam_genres_top, aes(x = genres, y = pct_pos_total)) +
geom_boxplot(fill = "steelblue", alpha = 0.7, outlier.alpha = 0.2) +
coord_flip() +
labs(
title = "Valoraciones de los videojuegos por género",
subtitle = "Porcentaje de reseñas positivas",
x = "Género",
y = "% de reseñas positivas"
) +
theme_minimal()scatter_data <- steam %>%
select(price, pct_pos_total) %>%
filter(
!is.na(price),
!is.na(pct_pos_total),
price >= 0,
price <= 60 # cap visual razonable
)ggplot(scatter_data, aes(x = price, y = pct_pos_total)) +
geom_point(alpha = 0.25) +
geom_smooth(method = "lm", se = FALSE) +
labs(
title = "Relación entre precio y valoración de los videojuegos en Steam",
subtitle = "Línea de tendencia para facilitar la interpretación",
x = "Precio (€)",
y = "% de reseñas positivas"
) +
theme_minimal()popularity_data <- steam %>%
select(num_reviews_total, pct_pos_total) %>%
filter(
!is.na(num_reviews_total),
!is.na(pct_pos_total),
num_reviews_total > 10
)
ggplot(popularity_data,
aes(x = num_reviews_total, y = pct_pos_total)) +
geom_point(alpha = 0.2) +
scale_x_log10() +
geom_hline(yintercept = 90, linetype = "dashed") +
labs(
title = "Popularidad vs valoración de los videojuegos",
subtitle = "Línea discontinua: juegos con >90% de reseñas positivas",
x = "Número de reseñas (log)",
y = "% de reseñas positivas"
) +
theme_minimal()