Introduction
The 2021 Formula One season will be remembered for the close world championship title fight between Max Verstappen and Lewis Hamilton. The two drivers traded blows throughout the year, before Verstappen ultimately took the crown during the last race. In doing so, Verstappen became the first ever dutch driver and the first non-Mercedes driver in the turbo-hybrid era to win the World Championship.
To gain a deeper understanding and visualisation of how the championship battle between the two played out, we performed a bit of data exploration on the results, race by race. Data was scraped from the archives of the official Formula One website, and scripts to do so can be found on the github repository.
Data Preparation
We begin by loading in the necessary packages, data sets, plot themes, etc. This preparation work is important because it simplifies much of the code later on.
# load packages
library(readr)
library(tidyverse)
library(zoo)
library(lubridate)
library(reshape2)
library(knitr)
library(kableExtra)
library(CGPfunctions)
# load data sets from csv files
race_results <- read_csv('/Users/marcohui/Desktop/2021titlefight/f1-2021-titlefight/data/results2021.csv')
starting_grid <- read_csv('/Users/marcohui/Desktop/2021titlefight/f1-2021-titlefight/data/starts2021.csv')
fastest_laps <- read_csv('/Users/marcohui/Desktop/2021titlefight/f1-2021-titlefight/data/flaps2021.csv')
sprint_results <- read_csv('/Users/marcohui/Desktop/2021titlefight/f1-2021-titlefight/data/sprints2021.csv')
qualis <- read_csv('/Users/marcohui/Desktop/2021titlefight/f1-2021-titlefight/data/qualis2021.csv')
gp_names <- read_csv('/Users/marcohui/Desktop/2021titlefight/f1-2021-titlefight/data/names2021.csv')
# factorise gp_names based on race calendar order
gp_names <- gp_names %>%
mutate(gp_name=factor(gp_name,levels=c('Bahrain','Emilia Romagna','Portugal','Spain',
'Monaco','Azerbaijan','France','Styria',
'Austria','Great Britain','Hungary',
'Belgium','Netherlands','Italy',
'Russia','Turkey','United States',
'Mexico','Brazil','Qatar','Saudi Arabia','Abu Dhabi')))
# add unique gp_name column to all data sets
race_results <- race_results %>% left_join(gp_names,by='race_num')
starting_grid <- starting_grid %>% left_join(gp_names,by='race_num')
fastest_laps <- fastest_laps %>% left_join(gp_names,by='race_num')
sprint_results <- sprint_results %>% left_join(gp_names,by='race_num')
qualis <- qualis %>% left_join(gp_names,by='race_num')
# create tibble for teammate pairings
teammates <- tribble(
~No,~TeammateNo,
33,11, 11,33, # Red Bull
44,77, 77,44, # Mercedes
55,16, 16,55, # Ferrari
4,3, 3,4, # Mclaren
14,31, 31,14, # Alpine
10,22, 22,10, # AlphaTauri
18,5, 5,18, # Aston Martin
63,6, 6,63, # Williams
7,99, 99,7, # Alfa Romeo
47,9, 9,47 # Haas
)
# store constructor colour hex codes in variables
alfa_clr='#900000'
alpha_clr='#2B4562'
alpine_clr='#0090FF'
aston_clr='#006F62'
ferrari_clr='#DC0000'
haas_clr='#FFFFFF'
mclaren_clr='#FF8700'
mercedes_clr='#00D2BE'
redbull_clr='#0600EF'
williams_clr='#005AFF'
# create plot theme
hui_ggplot <- theme(plot.title = element_text(face='bold',size=22,vjust=1),
axis.title.x = element_blank(),
axis.title.y = element_blank(),
text = element_text(color='white'),
axis.text = element_text(color='white'),
legend.position='right',
legend.background = element_rect(fill='#1e2226',colour='#1e2226'),
legend.key = element_rect(fill='#1e2226',colour='#1e2226'),
plot.background = element_rect(fill='#1e2226',colour='#1e2226'),
panel.background = element_rect(fill='#1e2226',colour='#1e2226'),
panel.grid.major = element_line(colour="grey27"),
panel.grid.major.x = element_blank(),
panel.grid.minor = element_blank(),
panel.border = element_blank())
Verstappen and Hamilton Topping the Charts
Overall, the two-way dogfight between Verstappen and Hamilton is immediately evident in several summary statistics. The drivers eclipse the rest in number of wins, number of podiums, and average finishing positions. As expected from the eventual world champion, Verstappen edges out slightly in all categories.
Number of Wins
A Grand Prix victory in Formula One grants the driver 25 championship points, making it an important contributor to title bids. In the 2021 season, six different drivers across four constructors achieved a victory. Predictably from the championship contenders, Verstappen and Hamilton top the charts with 10 and 8 wins respectively, significantly more than the others.
race_results %>%
filter(Pos==1) %>%
group_by(Driver,Car) %>%
summarise(numWins = n()) %>%
arrange(-numWins) %>%
mutate(Driver=str_sub(Driver,-3,-1)) %>%
ggplot() +
geom_bar(aes(x=reorder(Driver,-numWins),y=numWins,fill=Car),stat='identity') +
labs(title='Number of Grand Prix Wins by Driver',
fill='Constructor') +
scale_y_continuous(breaks=c(0,2,4,6,8,10),expand=c(0,0)) +
scale_fill_manual(values=c(alpine_clr,mclaren_clr,mercedes_clr,redbull_clr)) +
hui_ggplot
Number of Podiums
An impressive thirteen drivers from eight constructors achieved a podium finish in 2021. This reflects a much tighter grid where many can challenge for top positions compared to years past. Again, Verstappen and Hamilton recorded the significantly more podium finishes than the rest, at 18 and 17 each. Often benefiting from the high performing Mercedes car, Valterri Bottas rounds out the top three with 11 himself.
race_results %>%
filter(Pos==1|Pos==2|Pos==3) %>%
group_by(Driver,Car) %>%
summarise(numPodiums = n()) %>%
arrange(-numPodiums) %>%
mutate(Driver=str_sub(Driver,-3,-1)) %>%
ggplot() +
geom_bar(aes(x=reorder(Driver,-numPodiums),y=numPodiums,fill=Car),stat='identity') +
labs(title='Number of Grand Prix Podiums by Driver',
fill='Constructor') +
scale_y_continuous(breaks=c(0,2,4,6,8,10,12,14,16,18,20),expand=c(0,0)) +
scale_fill_manual(values=c(alpha_clr,alpine_clr,aston_clr,
ferrari_clr,mclaren_clr,mercedes_clr,
redbull_clr,williams_clr)) +
hui_ggplot
Average Finishing Position
This metric takes the average of every finishing race result for a driver (retirements and disqualifications excluded). Unsurprisingly, Verstappen and Hamilton tend to finish much higher up the order. However, the difference between the two are marginal at at 2.65 and 2.76. It is interesting to note that several poor results dragged Red Bull Racing’s Sergio Perez to below both Ferrari drivers Carlos Sainz and Charles Leclerc.
race_results %>%
# disregard non-finishing positions
filter(Pos!='NC' & Pos!='DQ') %>%
mutate(Pos=as.numeric(Pos)) %>%
group_by(Driver) %>%
summarise(avgFinPos=round(mean(Pos),3)) %>%
arrange(avgFinPos) %>%
kbl(col.names=c('Driver','Average Finishing Position'),
align='lc') %>%
kable_material_dark() %>%
row_spec(c(1,2),background='lightyellow',color='black')
Driver | Average Finishing Position |
---|---|
Max Verstappen VER | 2.650 |
Lewis Hamilton HAM | 2.762 |
Valtteri Bottas BOT | 5.000 |
Carlos Sainz SAI | 6.500 |
Charles Leclerc LEC | 6.600 |
Sergio Perez PER | 6.600 |
Lando Norris NOR | 6.619 |
Pierre Gasly GAS | 7.737 |
Daniel Ricciardo RIC | 8.095 |
Fernando Alonso ALO | 9.050 |
Esteban Ocon OCO | 9.158 |
Lance Stroll STR | 10.789 |
Sebastian Vettel VET | 11.053 |
Yuki Tsunoda TSU | 11.722 |
Kimi Räikkönen RAI | 12.500 |
George Russell RUS | 12.833 |
Antonio Giovinazzi GIO | 12.905 |
Robert Kubica KUB | 14.500 |
Nicholas Latifi LAT | 15.105 |
Mick Schumacher MSC | 16.474 |
Nikita Mazepin MAZ | 17.812 |
Note: calculations exclude sprint qualifying results
Change in Position
A look into how the drivers moved up and down the race order throughout races.
Average Position Gained or Lost
A slopegraph below marks the average start position and average end position for each driver across every race they competed in. Like before, Verstappen and Hamilton feature at the top for both statistics, starting and ending high up the grid overall. The visual suggests that both generally move down the grid over the course of a race. And while Verstappen tends to start races in better positions, he has a lower end position on average.
However, it is important to note the limitations of this metric as an indicator of performance. Because they are means that factor in non-finishing positions, the numbers can be significantly skewed by outliers. In other words, a few poor results by a driver through no fault of their own (such as retirements) can heavily drag down their statistic. Additionally, gaining positions on average does not signal better performances because drivers who often start at the front, like Verstappen and Hamilton, have much fewer opportunities to gain positions; whereas hypothetically, a driver starting from last has 19 cars to overtake.
# set slopegraph colours
cols <- c('VER'='#0600EF','HAM'='#00D2BE',
'PER'='gray','BOT'='gray','LEC'='gray','SAI'='gray','NOR'='gray','RIC'='gray',
'VET'='gray','STR'='gray','GAS'='gray','TSU'='gray','MSC'='gray','MAZ'='gray',
'RUS'='gray','LAT'='gray','ALO'='gray','OCO'='gray','RAI'='gray','GIO'='gray','KUB'='gray')
# simplify race_results table
race_results_s <- race_results %>%
select(Driver,gp_name,Pos) %>%
rename(endPos=Pos)
# simplify starting_grid table
starting_grid_s <- starting_grid %>%
select(Driver,gp_name,Pos) %>%
rename(startPos=Pos)
startend <- race_results_s %>%
left_join(starting_grid_s,by=c('Driver','gp_name')) %>%
# replace non-numeric values with 21
mutate(endPos=replace(endPos,endPos=='NC','21'), # DNF/DNS
endPos=replace(endPos,endPos=='DQ','21'), # disqualification
startPos=replace(startPos,is.na(startPos),'21'), # pit lane start
endPos=as.numeric(endPos),
startPos=as.numeric(startPos))
startend %>%
group_by(Driver) %>%
summarise(avgStartPos=round(mean(startPos),3),
avgEndPos=round(mean(endPos),3)) %>%
mutate(Driver=str_sub(Driver,-3,-1)) %>%
melt() %>%
newggslopegraph(Times=variable,
Measurement=value,
Grouping=Driver,
ReverseYAxis=TRUE,
Title='Average Start and End Position by Driver',
SubTitle=element_blank(),
Caption=element_blank(),
TitleTextSize=20,
XTextSize=15,
DataTextSize=5,
LineColor=cols)
Note: pit lane starts, retirements, and disqualifications are considered 21st position.
Position Gained or Lost by Race
We then plot the positions gained and lost race by race for Verstappen and Hamilton. Seeing how the two drivers gain or lose positions at each Grand Prix gives us a more detailed understanding that a summary statistic cannot.
Counting the vertical lines tells us that Hamilton maintained his position in a race 12 times this season, which is more often than Verstappen did at 10 times. At 6 and 7, both moved up in races similar number of times. It is also interesting to see how Verstappen and Hamilton lost out greatly in the Italy and Azerbaijan GP.
Again, gaining positions does not necessarily indicate better performances because you cannot move up if you are already in the lead.
startend %>%
mutate(difPos=startPos-endPos) %>%
filter(Driver=='Lewis Hamilton HAM'|Driver=='Max Verstappen VER') %>%
mutate(Driver=str_sub(Driver,-3,-1)) %>%
ggplot() +
geom_bar(aes(x=gp_name,y=difPos),stat='identity',colour='white',fill='white') +
facet_wrap(~Driver) +
labs(title='Number of Grand Prix Wins by Driver',
fill='Constructor') +
scale_y_continuous(breaks=c(-20,-15,-10,-5,0,5,10,15,20),expand=c(0,0)) +
coord_flip() +
hui_ggplot
Is Hamilton Worse at Converting Qualifying Performance to Race Results?
In Motorsports, performance during qualifying sessions plays a significant role in determining grid positions for the race. Therefore, a good qualifying showing that puts the car further up the pack can help a driver achieve better results on race day.
Average Qualifying Gap to Teammate
One common metric to evaluate qualifying performance for a driver is the average lap time gap to teammate. While both qualify quicker than their teammates over the course of the 2021 season, Verstappen seems to pull larger gaps. Verstappen out-qualifies teammate Perez by 0.67 seconds on average; Hamilton out-qualifies teammate Bottas by 0.35 seconds on average.
# replace DNFs and DNSs with NA values
qualis[qualis=='DNF'] <- NA
qualis[qualis=='DNS'] <- NA
qualis %>%
# filter out Robert Kubica, who only participated in two sessions
filter(Driver!='Robert Kubica KUB') %>%
left_join(teammates,by='No') %>%
# filter out rows where driver did not set a qualifying lap time
filter(!is.na(Q1)) %>%
# set best time to the latest qualifying lap time
mutate(bestTime=coalesce(Q3,Q2,Q1)) %>%
mutate(bestTime=as.duration(ms(bestTime))) %>%
group_by(gp_name) %>%
mutate(mateTime=bestTime[match(TeammateNo,No)]) %>%
ungroup() %>%
# filter out rows where teammate did not set a qualifying lap time
filter(mateTime>0) %>%
group_by(Driver,Car) %>%
summarise(avgGap=mean(bestTime-mateTime)) %>%
arrange(Car) %>%
kbl(col.names=c('Driver','Constructor','Average Qualifying Gap to Teammate'),
align='llc') %>%
kable_material_dark() %>%
row_spec(c(15,17),background='lightyellow',color='black')
Driver | Constructor | Average Qualifying Gap to Teammate |
---|---|---|
Antonio Giovinazzi GIO | Alfa Romeo Racing Ferrari | -0.2962632 |
Kimi Räikkönen RAI | Alfa Romeo Racing Ferrari | 0.2962632 |
Pierre Gasly GAS | AlphaTauri Honda | -0.7170500 |
Yuki Tsunoda TSU | AlphaTauri Honda | 0.7170500 |
Esteban Ocon OCO | Alpine Renault | -0.0081364 |
Fernando Alonso ALO | Alpine Renault | 0.0081364 |
Lance Stroll STR | Aston Martin Mercedes | 1.8265714 |
Sebastian Vettel VET | Aston Martin Mercedes | -1.8265714 |
Carlos Sainz SAI | Ferrari | 1.0493182 |
Charles Leclerc LEC | Ferrari | -1.0493182 |
Mick Schumacher MSC | Haas Ferrari | -0.9259500 |
Nikita Mazepin MAZ | Haas Ferrari | 0.9259500 |
Daniel Ricciardo RIC | McLaren Mercedes | -0.2445000 |
Lando Norris NOR | McLaren Mercedes | 0.2445000 |
Lewis Hamilton HAM | Mercedes | -0.3467273 |
Valtteri Bottas BOT | Mercedes | 0.3467273 |
Max Verstappen VER | Red Bull Racing Honda | -0.6726667 |
Sergio Perez PER | Red Bull Racing Honda | 0.6726667 |
George Russell RUS | Williams Mercedes | -0.5189545 |
Nicholas Latifi LAT | Williams Mercedes | 0.5189545 |
Average Qualifying Position
A more important metric to look at is the average qualifying position, which describes where a driver generally qualifies throughout the season in terms of position rather than time. This statistic is less indicative of pure driver capabilities because qualifying order is partially determined by car performance during the Grand Prix weekend; however, it is ultimately more decisive in final race results.
In this regard, Hamilton is shown to outdo Verstappen. With an average qualifying position of 2.19, Hamilton tend to qualify higher up the order compared to Verstappen. Knowing from before that Verstappen achieved higher race results throughout the season, does this imply that Hamilton is less capable of converting qualifying results into points during a Grand Prix?
qualis %>%
# ignore non-qualifying positions
filter(Pos!='NC' & Pos!='RT') %>%
mutate(Pos=as.numeric(Pos)) %>%
group_by(Driver) %>%
summarise(avgQualiPos=round(mean(Pos),3)) %>%
arrange(avgQualiPos) %>%
kbl(col.names=c('Driver','Average Qualifying Position'),
align='lc') %>%
kable_material_dark() %>%
row_spec(c(1,2),background='lightyellow',color='black')
Driver | Average Qualifying Position |
---|---|
Lewis Hamilton HAM | 2.190 |
Max Verstappen VER | 2.773 |
Valtteri Bottas BOT | 3.727 |
Sergio Perez PER | 6.364 |
Lando Norris NOR | 6.545 |
Charles Leclerc LEC | 6.591 |
Pierre Gasly GAS | 6.773 |
Carlos Sainz SAI | 8.091 |
Daniel Ricciardo RIC | 9.591 |
Esteban Ocon OCO | 10.955 |
Fernando Alonso ALO | 10.955 |
Sebastian Vettel VET | 11.727 |
Yuki Tsunoda TSU | 12.050 |
George Russell RUS | 12.591 |
Lance Stroll STR | 12.900 |
Antonio Giovinazzi GIO | 13.714 |
Kimi Räikkönen RAI | 15.700 |
Nicholas Latifi LAT | 16.364 |
Mick Schumacher MSC | 18.050 |
Robert Kubica KUB | 18.500 |
Nikita Mazepin MAZ | 19.545 |
Average Starting Position (After Penalties and Sprints)
No, because qualifying performance does not directly translate to starting grid position, which is a bigger influence final race positions. The starting grid takes qualifying order and adjust it based on penalties and sprint qualifying results. When examining the starting grids of races, we find that Verstappen actually starts further up front on average.
startend %>%
group_by(Driver) %>%
summarise(avgStartPos=round(mean(startPos),3)) %>%
arrange(avgStartPos) %>%
kbl(col.names=c('Driver','Average Starting Position'),
align='lc') %>%
kable_material_dark() %>%
row_spec(c(1,2),background='lightyellow',color='black')
Driver | Average Starting Position |
---|---|
Max Verstappen VER | 2.864 |
Lewis Hamilton HAM | 3.091 |
Valtteri Bottas BOT | 5.591 |
Charles Leclerc LEC | 6.455 |
Lando Norris NOR | 6.864 |
Sergio Perez PER | 7.091 |
Pierre Gasly GAS | 7.318 |
Carlos Sainz SAI | 7.909 |
Daniel Ricciardo RIC | 9.682 |
Fernando Alonso ALO | 10.500 |
Esteban Ocon OCO | 10.682 |
Sebastian Vettel VET | 11.773 |
George Russell RUS | 13.000 |
Lance Stroll STR | 13.091 |
Yuki Tsunoda TSU | 13.136 |
Antonio Giovinazzi GIO | 13.455 |
Kimi Räikkönen RAI | 15.400 |
Nicholas Latifi LAT | 16.182 |
Robert Kubica KUB | 16.500 |
Mick Schumacher MSC | 17.545 |
Nikita Mazepin MAZ | 18.545 |
Number of Qualifying P1s versus Pole Positions
The difference between qualifying position and starting grid position is particularly pronounced when looking at the top positions.
Although Verstappen and Hamilton almost match each other in topping the timing sheets during qualifying sessions, Verstappen ends up starting the race in pole position significantly more often. This can be explained by Hamilton losing positions at sprint qualifying and taking an engine penalty while ahead, both of which Verstappen never did.
This is an important observation because starting from the most favourable position on the grid ultimately is the biggest contributor to race victories. According to race archives, 40% of all race victories in Formula One has been on from pole position.
poles <- starting_grid %>%
filter(Pos==1) %>%
group_by(Driver) %>%
summarise(numPoles=n()) %>%
arrange(-numPoles)
qualip1s <- qualis %>%
filter(Pos==1) %>%
group_by(Driver) %>%
summarise(numQualiP1s=n()) %>%
arrange(-numQualiP1s)
# table
qualip1s %>%
left_join(poles,by='Driver') %>%
kbl(col.names=c('Driver','Number of Qualifying P1s','Number of Pole Positions'),
align='lcc') %>%
kable_material_dark() %>%
row_spec(c(1,2),background='lightyellow',color='black')
Driver | Number of Qualifying P1s | Number of Pole Positions |
---|---|---|
Max Verstappen VER | 9 | 10 |
Lewis Hamilton HAM | 7 | 5 |
Valtteri Bottas BOT | 3 | 4 |
Charles Leclerc LEC | 2 | 2 |
Lando Norris NOR | 1 | 1 |
# plot
qualip1s %>%
left_join(poles,by='Driver') %>%
melt() %>%
ggplot() +
geom_bar(aes(x=reorder(Driver,-value),y=value,fill=variable),
stat='identity',
width=0.5,
position='dodge') +
labs(title='Number of Qualifying P1s and Pole Positions by Driver',
fill='Statistic') +
scale_y_continuous(breaks=c(0,2,4,6,8,10),expand=c(0,0)) +
hui_ggplot
Wins from Pole
Now knowing that Hamilton has started races from pole position far less often than Verstappen did, it makes sense why why a lower number and percentage of Hamilton’s victories are won from pole position.
startend %>%
filter(endPos=='1') %>%
mutate(WFP=if_else(endPos==1&startPos==1,1,0)) %>%
group_by(Driver) %>%
summarise(numWins=n(),
numWFP=sum(WFP),
pcntWFP=numWFP/sum(endPos)) %>%
arrange(-numWins) %>%
kbl(col.names=c('Driver','Number of Wins','Number of Wins From Pole', 'Percent of Wins From Pole'),
align='lccc') %>%
kable_material_dark() %>%
row_spec(c(1,2),background='lightyellow',color='black')
Driver | Number of Wins | Number of Wins From Pole | Percent of Wins From Pole |
---|---|---|---|
Max Verstappen VER | 10 | 7 | 0.700 |
Lewis Hamilton HAM | 8 | 3 | 0.375 |
Daniel Ricciardo RIC | 1 | 0 | 0.000 |
Esteban Ocon OCO | 1 | 0 | 0.000 |
Sergio Perez PER | 1 | 0 | 0.000 |
Valtteri Bottas BOT | 1 | 1 | 1.000 |
Pole Conversion Rate
In fact, when Hamilton is on pole position because of a good qualifying performance, he is nearly just as likely to achieve a win compared to Verstappen. The difference between two in pole conversion rate is much lower than that in percentage of wins from poles.
startend %>%
filter(startPos=='1') %>%
mutate(converted=if_else(endPos==1&startPos==1,1,0)) %>%
group_by(Driver) %>%
summarise(numPoles=n(),
numConverted=sum(converted),
pcntConverted=numConverted/sum(startPos)) %>%
arrange(-numPoles) %>%
kbl(col.names=c('Driver','Number of Poles','Number of Poles Converted','Percent of Poles Converted'),
align='lccc') %>%
kable_material_dark() %>%
row_spec(c(1,2),background='lightyellow',color='black')
Driver | Number of Poles | Number of Poles Converted | Percent of Poles Converted |
---|---|---|---|
Max Verstappen VER | 10 | 7 | 0.70 |
Lewis Hamilton HAM | 5 | 3 | 0.60 |
Valtteri Bottas BOT | 4 | 1 | 0.25 |
Charles Leclerc LEC | 2 | 0 | 0.00 |
Lando Norris NOR | 1 | 0 | 0.00 |
Who Has the Most Fastest Laps?
Another facet of the season to explore is fastest laps. A fast lap is important to the championship because one championship point is awarded to the driver with the fastest lap each race (but only if they finish within the top 10 positions).
Number of Fastest Laps
Over the season, Hamilton and Verstappen achieved the fastest lap of a race the same number of times in total. When unable to fight for the lead, Mercedes strategists have many times targeted the point for fastest lap towards the end of a race as part of damage limitation. It is interesting to see this play reflected in the numbers, which show Hamilton in general achieving the fastest lap in later laps of a Grand Prix.
fastest_laps %>%
filter(Pos==1) %>%
group_by(Driver) %>%
summarise(numFastestLaps=n(),avgLap=round(mean(Lap),3)) %>%
arrange(-numFastestLaps) %>%
kbl(col.names=c('Driver','Number of Fastest Laps','Average Lap'),
align='lcc') %>%
kable_material_dark() %>%
row_spec(c(1,2),background='lightyellow',color='black')
Driver | Number of Fastest Laps | Average Lap |
---|---|---|
Lewis Hamilton HAM | 6 | 60.000 |
Max Verstappen VER | 6 | 49.833 |
Valtteri Bottas BOT | 4 | 62.000 |
Sergio Perez PER | 2 | 60.500 |
Daniel Ricciardo RIC | 1 | 53.000 |
Lando Norris NOR | 1 | 39.000 |
Pierre Gasly GAS | 1 | 70.000 |
Note: there is no fastest lap recorded in the Belgium GP
Championship Standings
Let’s see if a broader look at the season reveals any insights about the championship title fight between Verstappen and Hamilton.
Championship Points By Driver
Earning consistently top results throughout the season, both Verstappen and Hamilton have a firm lead in the championship standings, over 150 points clear of the third highest scoring driver Valterri Bottas. Moreover, the two seem to have brought the majority of points for their respective constructors, with Verstappen at 67.5 percent and Hamilton at 63.2 percent.
# add point finishes in sprint qualifying to race_results
sprint_results_points <- sprint_results %>% filter(PTS>0)
race_results <- rbind(race_results,sprint_results_points)
driverpoints <- race_results %>%
group_by(Driver,Car) %>%
summarise(driverPoints = sum(PTS))
teampoints <- race_results %>%
group_by(Car) %>%
summarise(teamPoints = sum(PTS))
driverpoints %>%
left_join(teampoints,by='Car') %>%
arrange(-driverPoints) %>%
mutate(pcntTeamPoints=round(driverPoints/teamPoints,3)) %>%
kbl(col.names=c('Driver','Constructor','Driver Points',
'Constructor Points','Percent of Constructor Points'),
align='llccc') %>%
kable_styling(full_width = F) %>%
kable_material_dark() %>%
row_spec(c(1,2),background='lightyellow',color='black')
Driver | Constructor | Driver Points | Constructor Points | Percent of Constructor Points |
---|---|---|---|---|
Max Verstappen VER | Red Bull Racing Honda | 395.5 | 585.5 | 0.675 |
Lewis Hamilton HAM | Mercedes | 387.5 | 613.5 | 0.632 |
Valtteri Bottas BOT | Mercedes | 226.0 | 613.5 | 0.368 |
Sergio Perez PER | Red Bull Racing Honda | 190.0 | 585.5 | 0.325 |
Carlos Sainz SAI | Ferrari | 164.5 | 323.5 | 0.509 |
Lando Norris NOR | McLaren Mercedes | 160.0 | 275.0 | 0.582 |
Charles Leclerc LEC | Ferrari | 159.0 | 323.5 | 0.491 |
Daniel Ricciardo RIC | McLaren Mercedes | 115.0 | 275.0 | 0.418 |
Pierre Gasly GAS | AlphaTauri Honda | 110.0 | 142.0 | 0.775 |
Fernando Alonso ALO | Alpine Renault | 81.0 | 155.0 | 0.523 |
Esteban Ocon OCO | Alpine Renault | 74.0 | 155.0 | 0.477 |
Sebastian Vettel VET | Aston Martin Mercedes | 43.0 | 77.0 | 0.558 |
Lance Stroll STR | Aston Martin Mercedes | 34.0 | 77.0 | 0.442 |
Yuki Tsunoda TSU | AlphaTauri Honda | 32.0 | 142.0 | 0.225 |
George Russell RUS | Williams Mercedes | 16.0 | 23.0 | 0.696 |
Kimi Räikkönen RAI | Alfa Romeo Racing Ferrari | 10.0 | 13.0 | 0.769 |
Nicholas Latifi LAT | Williams Mercedes | 7.0 | 23.0 | 0.304 |
Antonio Giovinazzi GIO | Alfa Romeo Racing Ferrari | 3.0 | 13.0 | 0.231 |
Mick Schumacher MSC | Haas Ferrari | 0.0 | 0.0 | NaN |
Nikita Mazepin MAZ | Haas Ferrari | 0.0 | 0.0 | NaN |
Robert Kubica KUB | Alfa Romeo Racing Ferrari | 0.0 | 13.0 | 0.000 |
Cumative Points Scored by Race by Driver
A visual on the cumulative points scored race by race illustrates how the lead changed hands a total of six times in 2021. Overall, it seems like Verstappen was ahead more often than Hamilton was.
race_points_cum <- race_results %>%
group_by(Driver,gp_name) %>%
summarise(totalPoints=sum(PTS)) %>%
mutate(cumPoints=cumsum(totalPoints)) %>%
select(Driver,gp_name,cumPoints)
levels(race_points_cum$gp_name) <- c('BHR','EMI','POR','ESP','MON','AZE','FRA','STY','AUT','GBR',
'HUN','BEL','NED','ITA','RUS','TUR','USA','MXC','SAP','QAT',
'SAU','ABU')
# table
race_points_cum %>%
pivot_wider(names_from=gp_name,values_from=cumPoints) %>%
arrange(-ABU) %>%
kbl() %>%
kable_styling(full_width=F) %>%
kable_material_dark() %>%
row_spec(c(1,2),background='lightyellow',color='black')
Driver | BHR | EMI | POR | ESP | MON | AZE | FRA | STY | AUT | GBR | HUN | BEL | NED | ITA | RUS | TUR | USA | MXC | SAP | QAT | SAU | ABU |
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
Max Verstappen VER | 18 | 43 | 61 | 80 | 105 | 105 | 131 | 156 | 182 | 185 | 187 | 199.5 | 224.5 | 226.5 | 244.5 | 262.5 | 287.5 | 312.5 | 332.5 | 351.5 | 369.5 | 395.5 |
Lewis Hamilton HAM | 25 | 44 | 69 | 94 | 101 | 101 | 119 | 138 | 150 | 177 | 195 | 202.5 | 221.5 | 221.5 | 246.5 | 256.5 | 275.5 | 293.5 | 318.5 | 343.5 | 369.5 | 387.5 |
Valtteri Bottas BOT | 16 | 16 | 32 | 47 | 47 | 47 | 59 | 74 | 92 | 108 | 108 | 108.0 | 123.0 | 141.0 | 151.0 | 177.0 | 185.0 | 185.0 | 203.0 | 203.0 | 218.0 | 226.0 |
Sergio Perez PER | 10 | 10 | 22 | 32 | 44 | 69 | 84 | 96 | 104 | 104 | 104 | 104.0 | 108.0 | 118.0 | 120.0 | 135.0 | 150.0 | 165.0 | 178.0 | 190.0 | 190.0 | 190.0 |
Carlos Sainz SAI | 4 | 14 | 14 | 20 | 38 | 42 | 42 | 50 | 60 | 68 | 83 | 83.5 | 89.5 | 97.5 | 112.5 | 116.5 | 122.5 | 130.5 | 139.5 | 145.5 | 149.5 | 164.5 |
Lando Norris NOR | 12 | 27 | 37 | 41 | 56 | 66 | 76 | 86 | 101 | 113 | 113 | 113.0 | 114.0 | 132.0 | 139.0 | 145.0 | 149.0 | 150.0 | 151.0 | 153.0 | 154.0 | 160.0 |
Charles Leclerc LEC | 8 | 20 | 28 | 40 | 40 | 52 | 52 | 58 | 62 | 80 | 80 | 82.0 | 92.0 | 104.0 | 104.0 | 116.0 | 128.0 | 138.0 | 148.0 | 152.0 | 158.0 | 159.0 |
Daniel Ricciardo RIC | 6 | 14 | 16 | 24 | 24 | 26 | 34 | 34 | 40 | 50 | 50 | 56.0 | 56.0 | 83.0 | 95.0 | 95.0 | 105.0 | 105.0 | 105.0 | 105.0 | 115.0 | 115.0 |
Pierre Gasly GAS | 0 | 6 | 7 | 8 | 16 | 31 | 37 | 37 | 39 | 39 | 50 | 54.0 | 66.0 | 66.0 | 66.0 | 74.0 | 74.0 | 86.0 | 92.0 | 92.0 | 100.0 | 110.0 |
Fernando Alonso ALO | 0 | 1 | 5 | 5 | 5 | 13 | 17 | 19 | 20 | 26 | 38 | 38.0 | 46.0 | 50.0 | 58.0 | 58.0 | 58.0 | 60.0 | 62.0 | 77.0 | 77.0 | 81.0 |
Esteban Ocon OCO | 0 | 2 | 8 | 10 | 12 | 12 | 12 | 12 | 12 | 14 | 39 | 42.0 | 44.0 | 45.0 | 45.0 | 46.0 | 46.0 | 46.0 | 50.0 | 60.0 | 72.0 | 74.0 |
Sebastian Vettel VET | 0 | 0 | 0 | 0 | 10 | 28 | 30 | 30 | 30 | 30 | 30 | 35.0 | 35.0 | 35.0 | 35.0 | 35.0 | 36.0 | 42.0 | 42.0 | 43.0 | 43.0 | 43.0 |
Lance Stroll STR | 1 | 5 | 5 | 5 | 9 | 9 | 10 | 14 | 14 | 18 | 18 | 18.0 | 18.0 | 24.0 | 24.0 | 26.0 | 26.0 | 26.0 | 26.0 | 34.0 | 34.0 | 34.0 |
Yuki Tsunoda TSU | 2 | 2 | 2 | 2 | 2 | 8 | 8 | 9 | 9 | 10 | 18 | 18.0 | 18.0 | 18.0 | 18.0 | 18.0 | 20.0 | 20.0 | 20.0 | 20.0 | 20.0 | 32.0 |
George Russell RUS | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 4 | 13.0 | 13.0 | 15.0 | 16.0 | 16.0 | 16.0 | 16.0 | 16.0 | 16.0 | 16.0 | 16.0 |
Kimi Räikkönen RAI | 0 | 0 | 0 | 0 | 0 | 1 | 1 | 1 | 1 | 1 | 2 | 2.0 | NA | NA | 6.0 | 6.0 | 6.0 | 10.0 | 10.0 | 10.0 | 10.0 | 10.0 |
Nicholas Latifi LAT | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 6 | 7.0 | 7.0 | 7.0 | 7.0 | 7.0 | 7.0 | 7.0 | 7.0 | 7.0 | 7.0 | 7.0 |
Antonio Giovinazzi GIO | 0 | 0 | 0 | 0 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1.0 | 1.0 | 1.0 | 1.0 | 1.0 | 1.0 | 1.0 | 1.0 | 1.0 | 3.0 | 3.0 |
Mick Schumacher MSC | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 |
Nikita Mazepin MAZ | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 |
Robert Kubica KUB | NA | NA | NA | NA | NA | NA | NA | NA | NA | NA | NA | NA | 0.0 | 0.0 | NA | NA | NA | NA | NA | NA | NA | NA |
# plot
race_points_cum %>%
filter(Driver=='Max Verstappen VER'|Driver=='Lewis Hamilton HAM') %>%
ggplot() +
geom_line(aes(x=gp_name,y=cumPoints,colour=Driver,group=Driver)) +
labs(title='Cumulative Points Scored by Race by Driver') +
scale_y_continuous(breaks=c(0,50,100,150,200,250,300,350,400),expand=c(0,0)) +
scale_colour_manual(values=c(mercedes_clr,redbull_clr)) +
hui_ggplot
Points Scored by Race by Driver
A breakdown of points scored per Grand Prix allows for a more detailed view of how the drivers performed throughout the season. For instance, the troughs on the dark blue line see Verstappen scoring minimal points in Azerbaijan, Great Britain, Hungary, and Italy mostly due to retirements or technical issues. The extended peak from France to Austria represents a particular run of good form.
On the light blue line, the highest point at the middle shows Lewis Hamilton achieving more points than any other weekend due to a second place finish at the sprint qualifying and a victory at the race. The three race peak covering Sao Paolo, Qatar, and Saudi Arabia portrays a slew of good results that helped him catch up to Verstappen in the championship. The datapoints in the middle section represents several mediocre results.
On balance, Verstappen achieves better results more often than Hamilton during the 2021 season. However, his consistently good showings are counteracted by a couple very poor finishes. So although Hamilton does not win as much as Verstappen, he is able to stay in the title fight because his lows are not as low. Also unsurprisingly, whenever one wins, the other usually picks up a second place finish.
race_points <- race_results %>%
group_by(Driver,gp_name) %>%
summarise(totalPoints=sum(PTS)) %>%
select(Driver,gp_name,totalPoints)
levels(race_points$gp_name) <- c('BHR','EMI','POR','ESP','MON','AZE','FRA','STY','AUT','GBR',
'HUN','BEL','NED','ITA','RUS','TUR','USA','MXC','SAP','QAT',
'SAU','ABU')
# table
race_points %>%
pivot_wider(names_from=gp_name,values_from=totalPoints) %>%
arrange(-ABU) %>%
kbl() %>%
kable_styling(full_width = F) %>%
kable_material_dark() %>%
row_spec(c(1,2),background='lightyellow',color='black')
Driver | BHR | EMI | POR | ESP | MON | AZE | FRA | STY | AUT | GBR | HUN | BEL | NED | ITA | RUS | TUR | USA | MXC | SAP | QAT | SAU | ABU |
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
Max Verstappen VER | 18 | 25 | 18 | 19 | 25 | 0 | 26 | 25 | 26 | 3 | 2 | 12.5 | 25 | 2 | 18 | 18 | 25 | 25 | 20 | 19 | 18 | 26 |
Lewis Hamilton HAM | 25 | 19 | 25 | 25 | 7 | 0 | 18 | 19 | 12 | 27 | 18 | 7.5 | 19 | 0 | 25 | 10 | 19 | 18 | 25 | 25 | 26 | 18 |
Carlos Sainz SAI | 4 | 10 | 0 | 6 | 18 | 4 | 0 | 8 | 10 | 8 | 15 | 0.5 | 6 | 8 | 15 | 4 | 6 | 8 | 9 | 6 | 4 | 15 |
Yuki Tsunoda TSU | 2 | 0 | 0 | 0 | 0 | 6 | 0 | 1 | 0 | 1 | 8 | 0.0 | 0 | 0 | 0 | 0 | 2 | 0 | 0 | 0 | 0 | 12 |
Pierre Gasly GAS | 0 | 6 | 1 | 1 | 8 | 15 | 6 | 0 | 2 | 0 | 11 | 4.0 | 12 | 0 | 0 | 8 | 0 | 12 | 6 | 0 | 8 | 10 |
Valtteri Bottas BOT | 16 | 0 | 16 | 15 | 0 | 0 | 12 | 15 | 18 | 16 | 0 | 0.0 | 15 | 18 | 10 | 26 | 8 | 0 | 18 | 0 | 15 | 8 |
Lando Norris NOR | 12 | 15 | 10 | 4 | 15 | 10 | 10 | 10 | 15 | 12 | 0 | 0.0 | 1 | 18 | 7 | 6 | 4 | 1 | 1 | 2 | 1 | 6 |
Fernando Alonso ALO | 0 | 1 | 4 | 0 | 0 | 8 | 4 | 2 | 1 | 6 | 12 | 0.0 | 8 | 4 | 8 | 0 | 0 | 2 | 2 | 15 | 0 | 4 |
Esteban Ocon OCO | 0 | 2 | 6 | 2 | 2 | 0 | 0 | 0 | 0 | 2 | 25 | 3.0 | 2 | 1 | 0 | 1 | 0 | 0 | 4 | 10 | 12 | 2 |
Charles Leclerc LEC | 8 | 12 | 8 | 12 | 0 | 12 | 0 | 6 | 4 | 18 | 0 | 2.0 | 10 | 12 | 0 | 12 | 12 | 10 | 10 | 4 | 6 | 1 |
Antonio Giovinazzi GIO | 0 | 0 | 0 | 0 | 1 | 0 | 0 | 0 | 0 | 0 | 0 | 0.0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 2 | 0 |
Daniel Ricciardo RIC | 6 | 8 | 2 | 8 | 0 | 2 | 8 | 0 | 6 | 10 | 0 | 6.0 | 0 | 27 | 12 | 0 | 10 | 0 | 0 | 0 | 10 | 0 |
George Russell RUS | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 4 | 9.0 | 0 | 2 | 1 | 0 | 0 | 0 | 0 | 0 | 0 | 0 |
Kimi Räikkönen RAI | 0 | 0 | 0 | 0 | 0 | 1 | 0 | 0 | 0 | 0 | 1 | 0.0 | NA | NA | 4 | 0 | 0 | 4 | 0 | 0 | 0 | 0 |
Lance Stroll STR | 1 | 4 | 0 | 0 | 4 | 0 | 1 | 4 | 0 | 4 | 0 | 0.0 | 0 | 6 | 0 | 2 | 0 | 0 | 0 | 8 | 0 | 0 |
Mick Schumacher MSC | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0.0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 |
Nicholas Latifi LAT | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 6 | 1.0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 |
Nikita Mazepin MAZ | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0.0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 |
Sebastian Vettel VET | 0 | 0 | 0 | 0 | 10 | 18 | 2 | 0 | 0 | 0 | 0 | 5.0 | 0 | 0 | 0 | 0 | 1 | 6 | 0 | 1 | 0 | 0 |
Sergio Perez PER | 10 | 0 | 12 | 10 | 12 | 25 | 15 | 12 | 8 | 0 | 0 | 0.0 | 4 | 10 | 2 | 15 | 15 | 15 | 13 | 12 | 0 | 0 |
Robert Kubica KUB | NA | NA | NA | NA | NA | NA | NA | NA | NA | NA | NA | NA | 0 | 0 | NA | NA | NA | NA | NA | NA | NA | NA |
# plot
race_points %>%
filter(Driver=='Max Verstappen VER'|Driver=='Lewis Hamilton HAM') %>%
ggplot() +
geom_line(aes(x=gp_name,y=totalPoints,colour=Driver,group=Driver)) +
labs(title='Points Scored by Race by Driver') +
scale_y_continuous(breaks=c(0,1,2,4,6,8,10,12,15,18,25,27),expand=c(0,0)) +
scale_colour_manual(values=c(mercedes_clr,redbull_clr)) +
hui_ggplot
3 Race Rolling Average Points by Driver
Form is temporary but it can nevertheless be analysed. To study how performance fluctuated across the season between Verstappen and Hamilton, we plot a 3 race rolling average for points scored. This graph more clearly identifies the peak of Verstappen’s form at the Styrian GP right before the midway point. It also shows a subsequent dip bottoming out at the Hungarian GP before rising back up by the Mexican GP. In comparison, Hamilton generally did not achieve a run of form as high. He delivered results during Verstappen’s drop-off midseason, but really peaked only over the last few races, especially Qatar.
race_points_roll3 <- race_points %>%
mutate(totalPoints_roll3=rollmean(totalPoints,k=3,fill=NA)) %>%
select(Driver,gp_name,totalPoints_roll3)
levels(race_points_roll3$gp_name) <- c('BHR','EMI','POR','ESP','MON','AZE','FRA','STY','AUT','GBR',
'HUN','BEL','NED','ITA','RUS','TUR','USA','MXC','SAP','QAT',
'SAU','ABU')
# table
race_points_roll3 %>%
pivot_wider(names_from=gp_name,values_from=totalPoints_roll3) %>%
arrange(-ABU) %>%
kbl() %>%
kable_styling(full_width = F) %>%
kable_material_dark() %>%
row_spec(c(1,2),background='lightyellow',color='black')
Driver | BHR | EMI | POR | ESP | MON | AZE | FRA | STY | AUT | GBR | HUN | BEL | NED | ITA | RUS | TUR | USA | MXC | SAP | QAT | SAU | ABU |
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
Antonio Giovinazzi GIO | NA | 0.0000000 | 0.000000 | 0.3333333 | 0.3333333 | 0.3333333 | 0.0000000 | 0.0000000 | 0.0000000 | 0.0000000 | 0.0000000 | 0.0000000 | 0.0000000 | 0.000000 | 0.0000000 | 0.0000000 | 0.0000000 | 0.0000000 | 0.000000 | 0.6666667 | 0.6666667 | NA |
Carlos Sainz SAI | NA | 4.6666667 | 5.333333 | 8.0000000 | 9.3333333 | 7.3333333 | 4.0000000 | 6.0000000 | 8.6666667 | 11.0000000 | 7.8333333 | 7.1666667 | 4.8333333 | 9.666667 | 9.0000000 | 8.3333333 | 6.0000000 | 7.6666667 | 7.666667 | 6.3333333 | 8.3333333 | NA |
Charles Leclerc LEC | NA | 9.3333333 | 10.666667 | 6.6666667 | 8.0000000 | 4.0000000 | 6.0000000 | 3.3333333 | 9.3333333 | 7.3333333 | 6.6666667 | 4.0000000 | 8.0000000 | 7.333333 | 8.0000000 | 8.0000000 | 11.3333333 | 10.6666667 | 8.000000 | 6.6666667 | 3.6666667 | NA |
Daniel Ricciardo RIC | NA | 5.3333333 | 6.000000 | 3.3333333 | 3.3333333 | 3.3333333 | 3.3333333 | 4.6666667 | 5.3333333 | 5.3333333 | 5.3333333 | 2.0000000 | 11.0000000 | 13.000000 | 13.0000000 | 7.3333333 | 3.3333333 | 3.3333333 | 0.000000 | 3.3333333 | 3.3333333 | NA |
Esteban Ocon OCO | NA | 2.6666667 | 3.333333 | 3.3333333 | 1.3333333 | 0.6666667 | 0.0000000 | 0.0000000 | 0.6666667 | 9.0000000 | 10.0000000 | 10.0000000 | 2.0000000 | 1.000000 | 0.6666667 | 0.3333333 | 0.3333333 | 1.3333333 | 4.666667 | 8.6666667 | 8.0000000 | NA |
Fernando Alonso ALO | NA | 1.6666667 | 1.666667 | 1.3333333 | 2.6666667 | 4.0000000 | 4.6666667 | 2.3333333 | 3.0000000 | 6.3333333 | 6.0000000 | 6.6666667 | 4.0000000 | 6.666667 | 4.0000000 | 2.6666667 | 0.6666667 | 1.3333333 | 6.333333 | 5.6666667 | 6.3333333 | NA |
George Russell RUS | NA | 0.0000000 | 0.000000 | 0.0000000 | 0.0000000 | 0.0000000 | 0.0000000 | 0.0000000 | 0.0000000 | 1.3333333 | 4.3333333 | 4.3333333 | 3.6666667 | 1.000000 | 1.0000000 | 0.3333333 | 0.0000000 | 0.0000000 | 0.000000 | 0.0000000 | 0.0000000 | NA |
Kimi Räikkönen RAI | NA | 0.0000000 | 0.000000 | 0.0000000 | 0.3333333 | 0.3333333 | 0.3333333 | 0.0000000 | 0.0000000 | 0.3333333 | 0.3333333 | 1.6666667 | NA | NA | 1.3333333 | 1.3333333 | 1.3333333 | 1.3333333 | 1.333333 | 0.0000000 | 0.0000000 | NA |
Lance Stroll STR | NA | 1.6666667 | 1.333333 | 1.3333333 | 1.3333333 | 1.6666667 | 1.6666667 | 1.6666667 | 2.6666667 | 1.3333333 | 1.3333333 | 0.0000000 | 2.0000000 | 2.000000 | 2.6666667 | 0.6666667 | 0.6666667 | 0.0000000 | 2.666667 | 2.6666667 | 2.6666667 | NA |
Lando Norris NOR | NA | 12.3333333 | 9.666667 | 9.6666667 | 9.6666667 | 11.6666667 | 10.0000000 | 11.6666667 | 12.3333333 | 9.0000000 | 4.0000000 | 0.3333333 | 6.3333333 | 8.666667 | 10.3333333 | 5.6666667 | 3.6666667 | 2.0000000 | 1.333333 | 1.3333333 | 3.0000000 | NA |
Lewis Hamilton HAM | NA | 23.0000000 | 23.000000 | 19.0000000 | 10.6666667 | 8.3333333 | 12.3333333 | 16.3333333 | 19.3333333 | 19.0000000 | 17.5000000 | 14.8333333 | 8.8333333 | 14.666667 | 11.6666667 | 18.0000000 | 15.6666667 | 20.6666667 | 22.666667 | 25.3333333 | 23.0000000 | NA |
Max Verstappen VER | NA | 20.3333333 | 20.666667 | 20.6666667 | 14.6666667 | 17.0000000 | 17.0000000 | 25.6666667 | 18.0000000 | 10.3333333 | 5.8333333 | 13.1666667 | 13.1666667 | 15.000000 | 12.6666667 | 20.3333333 | 22.6666667 | 23.3333333 | 21.333333 | 19.0000000 | 21.0000000 | NA |
Mick Schumacher MSC | NA | 0.0000000 | 0.000000 | 0.0000000 | 0.0000000 | 0.0000000 | 0.0000000 | 0.0000000 | 0.0000000 | 0.0000000 | 0.0000000 | 0.0000000 | 0.0000000 | 0.000000 | 0.0000000 | 0.0000000 | 0.0000000 | 0.0000000 | 0.000000 | 0.0000000 | 0.0000000 | NA |
Nicholas Latifi LAT | NA | 0.0000000 | 0.000000 | 0.0000000 | 0.0000000 | 0.0000000 | 0.0000000 | 0.0000000 | 0.0000000 | 2.0000000 | 2.3333333 | 2.3333333 | 0.3333333 | 0.000000 | 0.0000000 | 0.0000000 | 0.0000000 | 0.0000000 | 0.000000 | 0.0000000 | 0.0000000 | NA |
Nikita Mazepin MAZ | NA | 0.0000000 | 0.000000 | 0.0000000 | 0.0000000 | 0.0000000 | 0.0000000 | 0.0000000 | 0.0000000 | 0.0000000 | 0.0000000 | 0.0000000 | 0.0000000 | 0.000000 | 0.0000000 | 0.0000000 | 0.0000000 | 0.0000000 | 0.000000 | 0.0000000 | 0.0000000 | NA |
Pierre Gasly GAS | NA | 2.3333333 | 2.666667 | 3.3333333 | 8.0000000 | 9.6666667 | 7.0000000 | 2.6666667 | 0.6666667 | 4.3333333 | 5.0000000 | 9.0000000 | 5.3333333 | 4.000000 | 2.6666667 | 2.6666667 | 6.6666667 | 6.0000000 | 6.000000 | 4.6666667 | 6.0000000 | NA |
Robert Kubica KUB | NA | NA | NA | NA | NA | NA | NA | NA | NA | NA | NA | NA | NA | NA | NA | NA | NA | NA | NA | NA | NA | NA |
Sebastian Vettel VET | NA | 0.0000000 | 0.000000 | 3.3333333 | 9.3333333 | 10.0000000 | 6.6666667 | 0.6666667 | 0.0000000 | 0.0000000 | 1.6666667 | 1.6666667 | 1.6666667 | 0.000000 | 0.0000000 | 0.3333333 | 2.3333333 | 2.3333333 | 2.333333 | 0.3333333 | 0.3333333 | NA |
Sergio Perez PER | NA | 7.3333333 | 7.333333 | 11.3333333 | 15.6666667 | 17.3333333 | 17.3333333 | 11.6666667 | 6.6666667 | 2.6666667 | 0.0000000 | 1.3333333 | 4.6666667 | 5.333333 | 9.0000000 | 10.6666667 | 15.0000000 | 14.3333333 | 13.333333 | 8.3333333 | 4.0000000 | NA |
Valtteri Bottas BOT | NA | 10.6666667 | 10.333333 | 10.3333333 | 5.0000000 | 4.0000000 | 9.0000000 | 15.0000000 | 16.3333333 | 11.3333333 | 5.3333333 | 5.0000000 | 11.0000000 | 14.333333 | 18.0000000 | 14.6666667 | 11.3333333 | 8.6666667 | 6.000000 | 11.0000000 | 7.6666667 | NA |
Yuki Tsunoda TSU | NA | 0.6666667 | 0.000000 | 0.0000000 | 2.0000000 | 2.0000000 | 2.3333333 | 0.3333333 | 0.6666667 | 3.0000000 | 3.0000000 | 2.6666667 | 0.0000000 | 0.000000 | 0.0000000 | 0.6666667 | 0.6666667 | 0.6666667 | 0.000000 | 0.0000000 | 4.0000000 | NA |
# plot
race_points_roll3 %>%
filter(Driver=='Max Verstappen VER'|Driver=='Lewis Hamilton HAM') %>%
ggplot() +
geom_line(aes(x=gp_name,y=totalPoints_roll3,colour=Driver,group=Driver)) +
labs(title='3 Race Rolling Average Points by Driver') +
scale_y_continuous(breaks=c(0,1,2,4,6,8,10,12,15,18,25,27),expand=c(0,0)) +
scale_colour_manual(values=c(mercedes_clr,redbull_clr)) +
hui_ggplot
Some Key Takeaways
- Verstappen has the most wins, most podiums, and highest average race finish position
- Hamilton tends to take fastest laps towards the end of a race as part of damage limitation
- Verstappen achieved better results more often than Hamilton
- Hamilton kept the championship fight alive with consistency (his lows were not as low) and a much greater points haul in the Great Britain GP
- Verstappen was in peak form during the few races before (France, Styria, Austria) and after (Turkey, USA, Mexico) the mid season
- Hamilton was in peak form during the last few races of the season (Sao Paolo, Qatar, Saudi Arabia)