Running the Numbers – How Can Hamilton Still Take the 2016 F1 Drivers’ Championship?
Want to share your content on R-bloggers? click here if you have a blog, or here if you don't.
Way back in 2012, I posted a simple R script for trying to work out the finishing combinations in the last two races of that year’s F1 season for Fernando Alonso and Sebastien Vettel to explore the circumstances under which Alonso could take the championship (Paths to the F1 2012 Championship Based on How They Might Finish in the US Grand Prix); I also put together a simple shiny version of the script to make it bit more app like (Interactive Scenarios With Shiny – The Race to the F1 2012 Drivers’ Championship), which I also updated for the 2014 season (F1 Championship Race, 2014 – Winning Combinations…).
And now we come to 2016, and once again, with two races to go, there are two drivers in with a chance of winning overall… But what race finishing combinations could see Hamilton make a last stand and reclaim his title? The F1 Drivers’ Championship Scenarios, 2016 shiny app will show you…
You can find the code in a gist here:
library(shiny) | |
library(ggplot2) | |
library(reshape) | |
# Define server logic required to generate and plot a random distribution | |
shinyServer(function(input, output) { | |
points=data.frame(pos=1:11,val=c(25,18,15,12,10,8,6,4,2,1,0)) | |
points[[1,2]] | |
a=330 | |
v=349 | |
pospoints=function(a,v,pdiff,points){ | |
pp=matrix(ncol = nrow(points), nrow = nrow(points)) | |
for (i in 1:nrow(points)){ | |
for (j in 1:nrow(points)) | |
pp[[i,j]]=v-a+pdiff[[i,j]] | |
} | |
pp | |
} | |
pdiff=matrix(ncol = nrow(points), nrow = nrow(points)) | |
for (i in 1:nrow(points)){ | |
for (j in 1:nrow(points)) | |
pdiff[[i,j]]=points[[i,2]]-points[[j,2]] | |
} | |
ppx=pospoints(a,v,pdiff,points) | |
winmdiff=function(vadiff,pdiff,points){ | |
win=matrix(ncol = nrow(points), nrow = nrow(points)) | |
for (i in 1:nrow(points)){ | |
for (j in 1:nrow(points)) | |
if (i==j) win[[i,j]]='' | |
else if ((vadiff+pdiff[[i,j]])>=0) win[[i,j]]='ROS' | |
else win[[i,j]]='HAM' | |
} | |
win | |
} | |
# Function that generates a plot of the distribution. The function | |
# is wrapped in a call to reactivePlot to indicate that: | |
# | |
# 1) It is "reactive" and therefore should be automatically | |
# re-executed when inputs change | |
# 2) Its output type is a plot | |
# | |
output$distPlot <- renderPlot( { | |
wmd=winmdiff(ppx[[input$ros,input$ham]],pdiff,points) | |
wmdm=melt(wmd) | |
g=ggplot(wmdm)+geom_text(aes(X1,X2,label=value,col=value)) | |
g=g+xlab('ROS position in Abu Dhabi')+ ylab('HAM position in Abu Dhabi') | |
g=g+labs(title="Championship outcomes in Abu Dhabi") | |
g=g+ theme(legend.position="none") | |
g=g+scale_x_continuous(breaks=seq(1, 11, 1))+scale_y_continuous(breaks=seq(1, 11, 1)) | |
g=g+coord_flip() | |
print(g) | |
}) | |
}) |
library(shiny) | |
shinyUI(pageWithSidebar( | |
# Application title | |
headerPanel("F1 Driver Championship Scenarios, 2016"), | |
# Sidebar with a slider input for number of observations | |
sidebarPanel( | |
sliderInput("ham", | |
"HAM race pos in Brazilian Grand Prix:", | |
min = 1, | |
max = 11, | |
value = 1), | |
sliderInput("ros", | |
"ROS race pos in Brazilian Grand Prix:", | |
min = 1, | |
max = 11, | |
value = 2), | |
hr(), | |
em("See also:"),br(), | |
a(href="http://f1datajunkie.com","f1datajunkie.com"), | |
br(), | |
a(href="https://leanpub.com/wranglingf1datawithr","Wrangling F1 Data With R") | |
), | |
# Show a plot of the generated distribution | |
mainPanel( | |
plotOutput("distPlot"), | |
h3("How to use the Championship predictor"), | |
p("With two more races to go in the 2016 F1 season, what do Hamilton and Rosberg each need to do to win the Drivers' Championship?" ), | |
p("Using the sliders, select various finishing positions for the drivers in the next race, the Brazilian Grand Prix." ), | |
p("The output will then update to show the who will be champion if for a all possible points scoring finishing positions at the last race in Abu Dhabi. For a particular finishing combination, the champion will be the named driver." ), | |
h4("How to Read the Chart"), | |
p("If you expect Hamilton to win in Brazil, and Rosberg to come second, set the sliders accordingly. The display changes to show that if HAM finished first in Abu Dhabi, if ROS finishes second or third, ROS will take the championship. If HAM finishes second in Abu Dhabi, HAM will win overall if ROS places 8th or lower. If ROS places 9th in Abu DHan=bi, HAM wins overall if he makes it onto the race podium. If ROS finishes on the race podium in the final race, he takes the Drivers' Championship wherever HAM finishes." ), | |
p("If neither of the drivers take points in Brazil, HAM can still win overall if he wins in Abu Dhabi and ROC somes 8th or lower." ), | |
hr(), | |
em("For more F1 stats'n'data wrangling, see "), a(href="http://f1datajunkie.com","f1datajunkie.com"), em("or the Leanpub book"), | |
a(href="https://leanpub.com/wranglingf1datawithr","Wrangling F1 Data With R"),em(".") | |
) | |
)) |

R-bloggers.com offers daily e-mail updates about R news and tutorials about learning R and many other topics. Click here if you're looking to post or find an R/data-science job.
Want to share your content on R-bloggers? click here if you have a blog, or here if you don't.