Marvel Rivals is a objective-based competitive hero shooter, where one team of 6 battles to win an objective over the opposing team. Rivals features three roles that each have different characters to choose from: Strategist, Duelist, and Vanguard. The game offers casual game play as well as competitive, with new season and half-season updates every couple of months.
My dataset includes over 500 of my own matches and tracks a wide variety of variables through each, including: competitive or casual match status, win/loss, points gained/lost (competitive), total points (competitive), current rank (competitive), rank up games (competitive), KDA (kills/deaths/assists) ratio, mvp or svp earned, hero/heroes played, main role played, type of match, map, duration in minutes, bots, and platform.
Using this data, I will explore the relationship between my KDA ratio and win rate to determine the importance of KDA ratio in winning competitive games. I will also analyze my overall win rate by season, with a visual distinction between competitive games and non-competitive games. Together, these analyses provide insight into how individual KDA performance relates to match outcome, and how overall success has varied across seasons. This seasonal comparison can help identify periods of stronger or weaker performance, which may aid further analysis oh how to optimize gameplay.
Data Wrangling
The dataset was compiled from personal gameplay records tracked over multiple game seasons through the site tracker.gg/marvel-rivals. Each row represents a single completed match, distinguished by their specific date and time stamp.
Variables
datetime - Date and time the match was played
season - Current game season during the match
competitive - Indicates whether the match was competitive (TRUE/FALSE)
won - Indicates whether the match was won (TRUE/FALSE)
points_change - Change in rank points after the match
total_points - Total rank points after the match
current_rank - Player’s rank at the end of the match
rank_up - Indicates whether the match resulted in a rank increase (TRUE/FALSE)
kda_ratio - Kill/Death/Assist ratio recorded for the match
mvp_or_svp - Indicates whether the player received MVP or SVP recognition (TRUE/FALSE)
heroes_played - Hero or heroes used during the match
main_role - Role played during the match (DPS = Duelist, Tank = Vanguard, Support = Strategist)
match_type - Type of match played
map - Map where the match took place
match_duration - Length of the match in minutes
bots - Indicates whether bots were present in the match (TRUE/FALSE)
xbox_or_pc - Platform used to play the match
# Setuplibrary(tidyverse)
── Attaching core tidyverse packages ──────────────────────── tidyverse 2.0.0 ──
✔ dplyr 1.2.0 ✔ readr 2.1.6
✔ forcats 1.0.1 ✔ stringr 1.6.0
✔ ggplot2 4.0.2 ✔ tibble 3.3.1
✔ lubridate 1.9.5 ✔ tidyr 1.3.2
✔ purrr 1.2.1
── Conflicts ────────────────────────────────────────── tidyverse_conflicts() ──
✖ dplyr::filter() masks stats::filter()
✖ dplyr::lag() masks stats::lag()
ℹ Use the conflicted package (<http://conflicted.r-lib.org/>) to force all conflicts to become errors
library(ggplot2)library(gt)rivals_data <-read_csv("rivals.csv", na =c("", "null"))
Rows: 516 Columns: 17
── Column specification ────────────────────────────────────────────────────────
Delimiter: ","
chr (8): datetime, current_rank, heroes_played, main_role, match_type, map, ...
dbl (4): season, points_change, total_points, kda_ratio
lgl (5): competitive, won, rank_up, mvp_or_svp, bots
ℹ Use `spec()` to retrieve the full column specification for this data.
ℹ Specify the column types or set `show_col_types = FALSE` to quiet this message.
Visualization
# Filter dataset to only Competitive gamesrivals_comp_data <-filter(rivals_data, competitive, TRUE)#Create KDA vs Match Outcome box plotkda_win_plot <- rivals_comp_data |>select(kda_ratio, won) |>ggplot(aes(x = kda_ratio, y = won, fill = won)) +geom_boxplot() +labs(title ="KDA Ratio vs. Competitive Match Outcome",x ="KDA Ratio",y ="Match Won" ) kda_win_plot
# Create Season vs Win Percentage bar chartseason_win_plot <- rivals_data |>group_by(season, competitive) |>select(won, season) |>summarise(win_percentage =mean(won)*100) |>ggplot(aes(x = season, y = win_percentage, fill = competitive)) +geom_col(position ="dodge") +labs(title ="Win Percentage by Season",x ="Season",y ="Win Percentage" ) +scale_x_continuous(limits =c(2, 7),breaks =seq(2.5, 6.5, .5) )
Adding missing grouping variables: `competitive`
`summarise()` has regrouped the output.
season_win_plot
Tables
# Create KDA Ratio vs. Match Outcome tablekda_win_table <- rivals_comp_data |>select(kda_ratio, won) |>group_by(won) |>summarise(avg_kda =mean(kda_ratio),median_kda =median(kda_ratio) ) |>gt() |>cols_label(won ="Match Won",avg_kda ="Average KDA Ratio",median_kda ="Median KDA Ratio" )kda_win_table
Adding missing grouping variables: `competitive`
`summarise()` has regrouped the output.
season_win_table
Competitive
Win Percentage
2.5
FALSE
54.9
TRUE
52.0
3
FALSE
59.8
TRUE
42.6
3.5
FALSE
70.0
TRUE
45.7
4
FALSE
66.7
TRUE
37.1
4.5
FALSE
56.0
TRUE
29.2
5
FALSE
50.0
TRUE
80.0
5.5
FALSE
70.0
TRUE
43.8
6
TRUE
50.0
6.5
TRUE
33.3
Conclusions
The analysis shows a clear relationship between KDA ratio and match outcome. Matches that were won generally had markedly higher KDA ratios than matches that were lost, suggesting that stronger individual performance plays an important role in winning competitive Marvel Rivals games. The seasonal analysis shows that win percentage varies across seasons and between competitive and non-competitive matches. These differences highlight how overall performance can vary over time and between competitive and casual game modes, and open the door for further analysis toward succeeding in the game. Overall, this dataset demonstrates how gameplay statistics can be used to gain a better understanding of patterns that may help optimize match success.