A plataforma Steam é uma das maiores lojas de distribuição digital de jogos, com milhões de usuários ativos diariamente. Com uma vasta gama de jogos disponíveis, entender o que torna um jogo popular, bem como os fatores que influenciam as avaliações dos jogadores, é crucial para desenvolvedores, publicadores e até mesmo para os próprios jogadores. Este relatório busca explorar os dados de jogos da Steam para identificar padrões e tendências que possam ajudar a entender o sucesso de um jogo em termos de vendas, receita e avaliações.
Para abordar essa questão, utilizaremos o dataset “Steam Games, Reviews, and Rankings”, que contém informações detalhadas sobre jogos, avaliações de usuários e rankings por gênero. A metodologia incluirá a limpeza e preparação dos dados, análise exploratória e a criação de visualizações que ajudem a contar a história por trás dos dados.
A técnica adotada inclui a análise de correlações entre horas jogadas e avaliações, a identificação de gêneros mais populares e a exploração de como as recomendações dos usuários impactam a popularidade dos jogos. Também serão criadas novas variáveis, como a proporção de avaliações positivas, para enriquecer a análise.
Esta análise será útil para desenvolvedores que desejam entender o que os jogadores valorizam em um jogo, para publicadores que buscam maximizar o retorno sobre o investimento, e para jogadores que desejam escolher jogos com base em avaliações e popularidade.
| Pacote | Uso |
|---|---|
| library(kableExtra) | Para estilizar e formatar tabelas em HTML, LaTeX ou Word |
| library(dplyr) | Conjunto de pacotes para manipulação de dados. |
| library(lubridate) | Facilita a manipulação de datas. |
| library(knitr) | Auxilia na formatação de tabelas no relatório. |
| library(ggplot2) | Para criação de gráficos sofisticados. |
| library(scales) | Para ajustar escalas em gráficos. |
| library(stringr) | Manipular strings |
| library(tidyr) | Ajudar a criar dados organizados |
Os dados foram obtidos do dataset “Steam Games, Reviews, and Rankings”, disponível publicamente. O dataset foi coletado a partir das páginas públicas da Steam. Link para o dataset
O dataset original contém três arquivos principais:
O dataset original possui mais de 990.000 linhas de dados, com algumas peculiaridades como valores ausentes e exclusão de jogos com conteúdo restrito.
games_desc <- read.csv("games_description.csv")
reviews <- read.csv("steam_game_reviews.csv")
rankings <- read.csv("games_ranking.csv")## 'data.frame': 290 obs. of 13 variables:
## $ name : chr ...
## $ short_description : chr ...
## $ long_description : chr ...
## $ genres : chr ...
## $ minimum_system_requirement : chr ...
## $ recommend_system_requirement : chr ...
## $ release_date : chr ...
## $ developer : chr ...
## $ publisher : chr ...
## $ overall_player_rating : chr ...
## $ number_of_reviews_from_purchased_people: chr ...
## $ number_of_english_reviews : chr ...
## $ link : chr ...
## 'data.frame': 992153 obs. of 8 variables:
## $ review : chr ...
## $ hours_played : chr ...
## $ helpful : chr ...
## $ funny : chr ...
## $ recommendation: chr ...
## $ date : chr ...
## $ game_name : chr ...
## $ username : chr ...
## 'data.frame': 672 obs. of 4 variables:
## $ game_name: chr ...
## $ genre : chr ...
## $ rank_type: chr ...
## $ rank : int NULL ...
Removemos as colunas que não iremos utilizar.
# Remover colunas desnecessárias
games_desc <- games_desc %>%
select(-minimum_system_requirement, -recommend_system_requirement, -link,
-release_date, -number_of_english_reviews, -number_of_reviews_from_purchased_people)Rremovemos jogos sem reviews suficientes para gerar um
overall_player_rating consistente.
# Remover jogos com pouquissimos reviews, onde o valor da coluna for 'user reviews ${x number}'
games_desc <- games_desc[!grepl("user reviews", games_desc$overall_player_rating), ]Por fim ajustamos o restante das coluna:
name para game_name com a
finalidade de manter o padrão com os outros datasets.
overall_player_rating para fator.
[ ]) e aspas (').
genres em linhas separadas, utilizando
vírgula como separador.
genres para genre com a
finalidade de manter a semântica.
games_desc <- games_desc %>%
rename(game_name = name)
games_desc$overall_player_rating <- as.factor(games_desc$overall_player_rating)
games_desc <- games_desc %>%
mutate(
genres = str_replace_all(genres, "\\[|\\]|'", ""),
developer = str_replace_all(developer, "\\[|\\]|'", ""),
publisher = str_replace_all(publisher, "\\[|\\]|'", "")
)
games_desc <- games_desc %>%
separate_rows(genres, sep = ",")
games_desc <- games_desc %>%
rename(genre = genres)
games_desc$genre <- trimws(games_desc$genre)
games_desc$genre <- tolower(games_desc$genre)
games_desc$developer <- trimws(games_desc$developer)
games_desc$developer <- tolower(games_desc$developer)
games_desc$publisher <- trimws(games_desc$publisher)
games_desc$publisher <- tolower(games_desc$publisher)rank_type para fator.
genre.
rank para numérica.
Removemos a coluna date do dataset.
Removemos linhas onde review for nulo
Tratamos o restante das colunas:
recommendation para fator.
hours_played, removendo espaços extras e
vírgulas, e convertemos para numérica.
funny, removendo espaços extras e
vírgulas, e convertemos para numérica.
helpful, removendo espaços extras e
vírgulas, e convertemos para numérica.
reviews$recommendation <- as.factor(reviews$recommendation)
reviews$hours_played <- trimws(reviews$hours_played)
reviews$hours_played <- gsub(",", "", reviews$hours_played)
reviews$hours_played <- as.numeric(reviews$hours_played)
reviews$funny <- trimws(reviews$funny)
reviews$funny <- gsub(",", "", reviews$hours_played)
reviews$funny <- as.numeric(reviews$funny)
reviews$helpful <- trimws(reviews$helpful)
reviews$helpful <- gsub(",", "", reviews$helpful)
reviews$helpful <- as.numeric(reviews$helpful)## tibble [5,427 × 7] (S3: tbl_df/tbl/data.frame)
## $ game_name : chr [1:5427] ...
## $ short_description : chr [1:5427] ...
## $ long_description : chr [1:5427] ...
## $ genre : chr [1:5427] ...
## $ developer : chr [1:5427] ...
## $ publisher : chr [1:5427] ...
## $ overall_player_rating: Factor w/ 7 levels "Mixed","Mostly Negative",..: NULL ...
## 'data.frame': 992150 obs. of 7 variables:
## $ review : chr ...
## $ hours_played : num NULL ...
## $ helpful : num NULL ...
## $ funny : num NULL ...
## $ recommendation: Factor w/ 2 levels "Not Recommended",..: NULL ...
## $ game_name : chr ...
## $ username : chr ...
## 'data.frame': 672 obs. of 4 variables:
## $ game_name: chr ...
## $ genre : chr ...
## $ rank_type: Factor w/ 3 levels "Revenue","Review",..: NULL ...
## $ rank : num NULL ...
| game_name | short_description | long_description | genre | developer | publisher | overall_player_rating |
|---|---|---|---|---|---|---|
| review | hours_played | helpful | funny | recommendation | game_name | username |
|---|---|---|---|---|---|---|
| game_name | genre | rank_type | rank |
|---|---|---|---|
avg_hours_played: Média de horas jogadas.
total_reviews: Número total de avaliações.
positive_reviews: Número de avaliações positivas.
review_score: Proporção de avaliações positivas.
avg_helpful: Média de votos “úteis”.
avg_funny: Média de votos “engraçados”.
data <- data %>%
group_by(game_name) %>%
mutate(
avg_hours_played = mean(hours_played, na.rm = TRUE),
total_reviews = n(),
positive_reviews = sum(recommendation == "Recommended", na.rm = TRUE),
review_score = positive_reviews / total_reviews,
avg_helpful = mean(helpful, na.rm = TRUE),
avg_funny = mean(funny, na.rm = TRUE)
) %>%
ungroup() # Remove o agrupamento para evitar problemas em operações futurasResultado Final:
## tibble [2,127,557 × 21] (S3: tbl_df/tbl/data.frame)
## $ game_name : chr [1:2127557] ...
## $ short_description : chr [1:2127557] ...
## $ long_description : chr [1:2127557] ...
## $ genre : chr [1:2127557] ...
## $ developer : chr [1:2127557] ...
## $ publisher : chr [1:2127557] ...
## $ overall_player_rating: Factor w/ 7 levels "Mixed","Mostly Negative",..: NULL ...
## $ rank_type : Factor w/ 3 levels "Revenue","Review",..: NULL ...
## $ rank : num [1:2127557] NULL ...
## $ review : chr [1:2127557] ...
## $ hours_played : num [1:2127557] NULL ...
## $ helpful : num [1:2127557] NULL ...
## $ funny : num [1:2127557] NULL ...
## $ recommendation : Factor w/ 2 levels "Not Recommended",..: NULL ...
## $ username : chr [1:2127557] ...
## $ avg_hours_played : num [1:2127557] NULL ...
## $ total_reviews : int [1:2127557] NULL ...
## $ positive_reviews : int [1:2127557] NULL ...
## $ review_score : num [1:2127557] NULL ...
## $ avg_helpful : num [1:2127557] NULL ...
## $ avg_funny : num [1:2127557] NULL ...
| game_name | short_description | long_description | genre | developer | publisher | overall_player_rating | rank_type | rank | review | hours_played | helpful | funny | recommendation | username | avg_hours_played | total_reviews | positive_reviews | review_score | avg_helpful | avg_funny |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
Agora que temos os dados combinado com novas variáveis, podemos realizar uma análise exploratória para identificar padrões e tendências.
ggplot(data, aes(x = hours_played, y = review_score)) +
geom_point(alpha = 0.3, color = "blue") +
geom_smooth(method = "lm", color = "red") +
labs(title = "Relação entre Horas Jogadas e Proporção de avaliações positivas.",
x = "Horas Jogadas",
y = "Proporção de avaliações positivas.") +
theme_minimal()Apesar da dispersão, não há uma correlação muito clara entre o tempo jogado e a proporção de avaliações positivas. Jogos com poucas horas podem ter tanto avaliações muito positivas quanto mais negativas.
# Média de horas jogadas por gênero
genre_avg_hours <- data %>%
group_by(genre) %>%
summarise(avg_hours = mean(avg_hours_played, na.rm = TRUE))
# Gráfico de barras
ggplot(genre_avg_hours, aes(x = reorder(genre, -avg_hours), y = avg_hours)) +
geom_bar(stat = "identity") +
labs(title = "Média de Horas Jogadas por Gênero",
x = "Gênero",
y = "Média de Horas Jogadas") +
theme_minimal() +
theme(axis.text.x = element_text(angle = 45, hjust = 1))Observa-se que o gênero action tem a maior média de horas jogadas, sugerindo que jogos desse tipo costumam manter os jogadores engajados por mais tempo. Role-playing e simulation também apresentam médias elevadas, o que pode indicar que esses gêneros possuem mecânicas envolventes e experiências prolongadas. Por outro lado, sports & racing tem a menor média de horas jogadas, possivelmente porque esses jogos são jogados em sessões curtas e menos contínuas.
# Gráfico de dispersão entre rank e média de horas jogadas
ggplot(data, aes(x = rank, y = avg_hours_played)) +
geom_point(alpha = 0.5) +
facet_wrap(~rank_type) +
labs(title = "Relação entre Rank e Média de Horas Jogadas",
x = "Rank",
y = "Média de Horas Jogadas") +
theme_minimal()O gráfico mostra a relação entre Rank e Média de Horas Jogadas, separando os dados em três categorias: Revenue, Review e Sales. Observa-se que, em todas as categorias, a maioria dos jogos tem uma média de horas jogadas relativamente baixa, com alguns outliers apresentando valores significativamente mais altos.
Isso pode indicar que jogos de nicho, apesar de não estarem no topo do ranking de vendas ou avaliações, conseguem manter os jogadores engajados por longos períodos.
review_score por genre# Gráfico de dispersão entre rank e média de horas jogadas
data %>%
group_by(genre) %>%
summarise(avg_review_score = mean(review_score, na.rm = TRUE)) %>%
arrange(desc(avg_review_score)) %>%
head(10) %>%
ggplot(aes(x = reorder(genre, avg_review_score), y = avg_review_score)) +
geom_bar(stat = "identity", fill = "gold") +
coord_flip() +
labs(title = "Top 10 Gêneros com Melhores Avaliações Médias",
x = "Gênero",
y = "Avaliação Média") +
theme_minimal()O gráfico revela que jogadores valorizam muito a qualidade dos jogos, com todos os 10 gêneros apresentando avaliações elevadas. O gênero “role-playing” se destaca como o mais bem avaliado, sugerindo uma preferência por jogos com narrativas envolventes e personagens complexos. A diversidade de gêneros populares também indica que há espaço para desenvolvedores explorarem nichos e atender diferentes gostos, desde que a qualidade seja alta.
# Gráfico de dispersão entre rank e média de horas jogadas
correlation_matrix <- data %>%
select(hours_played, helpful, funny, review_score, total_reviews, positive_reviews) %>%
cor(use = "complete.obs")
# Exibindo a tabela formatada
kable(correlation_matrix, digits = 3, caption = "Matriz de Correlação", format = "html") %>%
kable_styling(full_width = FALSE, bootstrap_options = c("striped", "hover", "condensed", "responsive")) %>%
scroll_box(width = "100%")| hours_played | helpful | funny | review_score | total_reviews | positive_reviews | |
|---|---|---|---|---|---|---|
| hours_played | 1.000 | 0.030 | 1.000 | -0.017 | 0.094 | 0.096 |
| helpful | 0.030 | 1.000 | 0.030 | -0.021 | 0.031 | 0.021 |
| funny | 1.000 | 0.030 | 1.000 | -0.017 | 0.094 | 0.096 |
| review_score | -0.017 | -0.021 | -0.017 | 1.000 | -0.107 | 0.298 |
| total_reviews | 0.094 | 0.031 | 0.094 | -0.107 | 1.000 | 0.894 |
| positive_reviews | 0.096 | 0.021 | 0.096 | 0.298 | 0.894 | 1.000 |
A matriz de correlação apresenta algumas relações interessantes entre as variáveis analisadas:
Este relatório buscou explorar os dados de jogos da plataforma Steam para identificar padrões e tendências que possam ajudar a entender o sucesso de um jogo em termos de vendas, receita e avaliações. Através da análise exploratória, foi possível identificar fatores que influenciam a popularidade e a satisfação dos jogadores, como gênero, tempo de jogo e avaliações dos usuários.
Para abordar o problema, utilizamos o dataset “Steam Games, Reviews, and Rankings”, que contém informações detalhadas sobre jogos, avaliações de usuários e rankings por gênero. A metodologia incluiu a limpeza e preparação dos dados, análise exploratória e a criação de visualizações que ajudaram a contar a história por trás dos dados. Também foram criadas novas variáveis, como a proporção de avaliações positivas, para enriquecer a análise.
A análise exploratória revelou vários insights interessantes:
Este relatório forneceu uma análise detalhada dos dados de jogos da Steam, identificando padrões e tendências que podem ser úteis para desenvolvedores, publicadores e jogadores. Através da análise exploratória, foi possível entender melhor os fatores que influenciam o sucesso de um jogo em termos de vendas, receita e avaliações. A análise de dados é uma ferramenta poderosa para entender o comportamento dos consumidores e tomar decisões informadas, e este relatório é um passo importante nessa direção.