<p>Since getting started with <a target="_blank" rel="nofollow" href="https://blog.ouseful.info/2017/02/23/reporting-in-a-repeatable-parameterised-transparent-way/">generating templated R reports</a> a few weeks ago, I’ve started spending the odd few minutes every race weekend around looking at ways of automating the generation of F1 <a target="_blank" rel="nofollow" href="http://psychemedia.github.io/wranglingf1datawithr/2017/f1_2017_rus_quali.html">qualifying</a> and race reports.</p>
<p>Im yesterday’s race, some of the commentary focussed on whether MAS had given BOT an “assist” in blocking VET, which got me thinking about better ways of visualising whether drivers are stuck in traffic or not.</p>
<p>The track position chart makes a start at this, but it can be hard to focus on a particular driver (identified using a particular character to infill the circle marker for that driver). The race leader’s track position ahead is identified from the lap offset race leader marker at the right hand side of the chart.</p>
<p><img sizes="(max-width: 477px) 100vw, 477px" data-image-description="" data-orig-file="https://ouseful.files.wordpress.com/2017/05/trackpostest.png?w=456" data-orig-size="477,376" data-image-title="trackpostest" class="wp-image-16180" data-comments-opened="1" data-recalc-dims="1" data-attachment-id="16180" data-permalink="https://blog.ouseful.info/2017/05/01/track-concordance-charts/trackpostest/" alt="" data-medium-file="https://ouseful.files.wordpress.com/2017/05/trackpostest.png?w=456?w=300" data-large-file="https://ouseful.files.wordpress.com/2017/05/trackpostest.png?w=456?w=477" data-image-meta="{&quot;aperture&quot;:&quot;0&quot;,&quot;credit&quot;:&quot;&quot;,&quot;camera&quot;:&quot;&quot;,&quot;caption&quot;:&quot;&quot;,&quot;created_timestamp&quot;:&quot;0&quot;,&quot;copyright&quot;:&quot;&quot;,&quot;focal_length&quot;:&quot;0&quot;,&quot;iso&quot;:&quot;0&quot;,&quot;shutter_speed&quot;:&quot;0&quot;,&quot;title&quot;:&quot;&quot;,&quot;orientation&quot;:&quot;0&quot;}" src="https://ouseful.files.wordpress.com/2017/05/trackpostest.png?w=456"></p>
<p>One way to help keep track of things from the perspective of a particular driver, rather than the race leader, is to rebase the origin of the x-axis relative to the that driver.</p>
<p>In my track chart code, I use a dataframe that has a <code>trackdiff</code> column that gives a time offset on track to race leader for each lead lap.</p>
<pre>track_encoder=function(lapTimes){
  #Find the accumulated race time at the start of each leader's lap
  lapTimes = ddply(lapTimes, .(leadlap), transform, lstart = min(acctime))

  #Find the on-track gap to leader
  lapTimes['trackdiff'] = lapTimes['acctime'] - lapTimes['lstart']
  lapTimes
}</pre>
<p>Rebasing for a particular driver simply means resetting the origin with respect to that time, using the <code>trackdiff</code> time for one driver as an offset for the others, to create a new <code>trackdiff2</code> for use on the x-axis.</p>
<pre>#I'm sure there must be a more idiomatic way of doing this?
rebase=lapTimes[lapTimes['code']==code,c('leadlap','trackdiff')]
rebase=rename(rebase,c('trackdiff'='trackrebase'))
lapTimes=merge(lapTimes,rebase,by='leadlap')
lapTimes['trackdiff2']=lapTimes['trackdiff']-lapTimes['trackrebase']</pre>
<p>Here’s how it looks for MAS:</p>
<p><img sizes="(max-width: 477px) 100vw, 477px" data-image-description="" data-orig-file="https://ouseful.files.wordpress.com/2017/05/mastracktrebase.png?w=456" data-orig-size="477,376" data-image-title="mastracktrebase" data-comments-opened="1" class="wp-image-16182" data-recalc-dims="1" data-attachment-id="16182" data-permalink="https://blog.ouseful.info/2017/05/01/track-concordance-charts/mastracktrebase/" alt="" data-medium-file="https://ouseful.files.wordpress.com/2017/05/mastracktrebase.png?w=456?w=300" data-large-file="https://ouseful.files.wordpress.com/2017/05/mastracktrebase.png?w=456?w=477" data-image-meta="{&quot;aperture&quot;:&quot;0&quot;,&quot;credit&quot;:&quot;&quot;,&quot;camera&quot;:&quot;&quot;,&quot;caption&quot;:&quot;&quot;,&quot;created_timestamp&quot;:&quot;0&quot;,&quot;copyright&quot;:&quot;&quot;,&quot;focal_length&quot;:&quot;0&quot;,&quot;iso&quot;:&quot;0&quot;,&quot;shutter_speed&quot;:&quot;0&quot;,&quot;title&quot;:&quot;&quot;,&quot;orientation&quot;:&quot;0&quot;}" src="https://ouseful.files.wordpress.com/2017/05/mastracktrebase.png?w=456"></p>
<p>But not so useful for BOT, who led much of the race:</p>
<p><img sizes="(max-width: 477px) 100vw, 477px" data-image-description="" data-orig-file="https://ouseful.files.wordpress.com/2017/05/bottrackrebase.png?w=456" data-orig-size="477,376" data-image-title="bottrackrebase" data-comments-opened="1" class="wp-image-16181" data-recalc-dims="1" data-attachment-id="16181" data-permalink="https://blog.ouseful.info/2017/05/01/track-concordance-charts/bottrackrebase/" alt="" data-medium-file="https://ouseful.files.wordpress.com/2017/05/bottrackrebase.png?w=456?w=300" data-large-file="https://ouseful.files.wordpress.com/2017/05/bottrackrebase.png?w=456?w=477" data-image-meta="{&quot;aperture&quot;:&quot;0&quot;,&quot;credit&quot;:&quot;&quot;,&quot;camera&quot;:&quot;&quot;,&quot;caption&quot;:&quot;&quot;,&quot;created_timestamp&quot;:&quot;0&quot;,&quot;copyright&quot;:&quot;&quot;,&quot;focal_length&quot;:&quot;0&quot;,&quot;iso&quot;:&quot;0&quot;,&quot;shutter_speed&quot;:&quot;0&quot;,&quot;title&quot;:&quot;&quot;,&quot;orientation&quot;:&quot;0&quot;}" src="https://ouseful.files.wordpress.com/2017/05/bottrackrebase.png?w=456"></p>
<p>This got me thinking about text concordances. In the NLTK text analysis package, the <a target="_blank" rel="nofollow" href="https://blog.ouseful.info/2015/12/13/n-gram-phrase-based-concordances-in-nltk/">text concordance function</a> allows you to display a search term centred in the context in which it is found:</p>
<p><img alt="concordance" src="https://ouseful.files.wordpress.com/2015/12/similarities.png?w=450#038;h=388" data-recalc-dims="1"></p>
<p>The concordance view finds the location of each token and then displays the search term surrounded by tokens in neighbouring locations, within a particular window size.</p>
<p>I spent a chunk of time wondering how to do this sensibly in R, struggling to identify what it was I actually wanted to do: for a particular driver, find the neighbouring cars in terms of accumulated laptime on each lap. After failing to see the light for more an hour or so, I thought of it in terms of an SQL query, and the answer fell straight out – for the specified driver on a particular lead leadlap, get their accumulated laptime and the rows with accumulated laptimes in a window around it.</p>
<pre>inscope=sqldf(paste0('SELECT l1.code as code,l1.acctime-l2.acctime as acctimedelta,
l2.lap-l1.lap as lapdelta, l2.lap as focuslap
FROM lapTimes as l1 join lapTimes as l2
WHERE l1.acctime &lt; (l2.acctime + ', abs(limits[2]), ') AND l1.acctime > (l2.acctime - ', abs(limits[1]),')
AND l2.code=&quot;',code,'&quot;;'))</pre>
<p>Plotting against the accumalated laptime delta on the x-axis gives a chart like this:</p>
<p><img sizes="(max-width: 477px) 100vw, 477px" data-image-description="" data-orig-file="https://ouseful.files.wordpress.com/2017/05/masconctest0.png?w=456" data-orig-size="477,376" data-image-title="masconctest0" data-comments-opened="1" class="wp-image-16184" data-recalc-dims="1" data-attachment-id="16184" data-permalink="https://blog.ouseful.info/2017/05/01/track-concordance-charts/masconctest0/" alt="" data-medium-file="https://ouseful.files.wordpress.com/2017/05/masconctest0.png?w=456?w=300" data-large-file="https://ouseful.files.wordpress.com/2017/05/masconctest0.png?w=456?w=477" data-image-meta="{&quot;aperture&quot;:&quot;0&quot;,&quot;credit&quot;:&quot;&quot;,&quot;camera&quot;:&quot;&quot;,&quot;caption&quot;:&quot;&quot;,&quot;created_timestamp&quot;:&quot;0&quot;,&quot;copyright&quot;:&quot;&quot;,&quot;focal_length&quot;:&quot;0&quot;,&quot;iso&quot;:&quot;0&quot;,&quot;shutter_speed&quot;:&quot;0&quot;,&quot;title&quot;:&quot;&quot;,&quot;orientation&quot;:&quot;0&quot;}" src="https://ouseful.files.wordpress.com/2017/05/masconctest0.png?w=456"></p>
<p>If we add in horizontal rules to show laps where the specified driver pitted and vertical bars to show pit windows, we get a much richer particular of the race from the point of view of the driver.</p>
<p><img sizes="(max-width: 477px) 100vw, 477px" data-image-description="" data-orig-file="https://ouseful.files.wordpress.com/2017/05/masconctest.png?w=456" data-orig-size="477,376" data-image-title="MASconctest" data-comments-opened="1" class="wp-image-16185" data-recalc-dims="1" data-attachment-id="16185" data-permalink="https://blog.ouseful.info/2017/05/01/track-concordance-charts/masconctest/" alt="" data-medium-file="https://ouseful.files.wordpress.com/2017/05/masconctest.png?w=456?w=300" data-large-file="https://ouseful.files.wordpress.com/2017/05/masconctest.png?w=456?w=477" data-image-meta="{&quot;aperture&quot;:&quot;0&quot;,&quot;credit&quot;:&quot;&quot;,&quot;camera&quot;:&quot;&quot;,&quot;caption&quot;:&quot;&quot;,&quot;created_timestamp&quot;:&quot;0&quot;,&quot;copyright&quot;:&quot;&quot;,&quot;focal_length&quot;:&quot;0&quot;,&quot;iso&quot;:&quot;0&quot;,&quot;shutter_speed&quot;:&quot;0&quot;,&quot;title&quot;:&quot;&quot;,&quot;orientation&quot;:&quot;0&quot;}" src="https://ouseful.files.wordpress.com/2017/05/masconctest.png?w=456"></p>
<p>Here’s how it looks from the perspective of BOT, who led most of the race:</p>
<p><img sizes="(max-width: 477px) 100vw, 477px" data-image-description="" data-orig-file="https://ouseful.files.wordpress.com/2017/05/botconctest.png?w=456" data-orig-size="477,376" data-image-title="botconctest" data-comments-opened="1" class="wp-image-16183" data-recalc-dims="1" data-attachment-id="16183" data-permalink="https://blog.ouseful.info/2017/05/01/track-concordance-charts/botconctest/" alt="" data-medium-file="https://ouseful.files.wordpress.com/2017/05/botconctest.png?w=456?w=300" data-large-file="https://ouseful.files.wordpress.com/2017/05/botconctest.png?w=456?w=477" data-image-meta="{&quot;aperture&quot;:&quot;0&quot;,&quot;credit&quot;:&quot;&quot;,&quot;camera&quot;:&quot;&quot;,&quot;caption&quot;:&quot;&quot;,&quot;created_timestamp&quot;:&quot;0&quot;,&quot;copyright&quot;:&quot;&quot;,&quot;focal_length&quot;:&quot;0&quot;,&quot;iso&quot;:&quot;0&quot;,&quot;shutter_speed&quot;:&quot;0&quot;,&quot;title&quot;:&quot;&quot;,&quot;orientation&quot;:&quot;0&quot;}" src="https://ouseful.files.wordpress.com/2017/05/botconctest.png?w=456"></p>
<p>Different symbols inside the markers can be used to track different drivers (in the above charts, BOT and VET are highlighted). The colours are used to identify whether or not cars on the same lap as the specified driver, are cars on laps ahead for shades of blue then green (as per <em>“blue flag”</em>) and orange to red for cars on increasing laps behind (i.e. backmarkers from the perspective of the specified driver). If a marker is light blue, that car is on the same lap and you’re racing…</p>
<p>All in all, I’m pretty chuffed (for now!) with how that chart came together.</p>
<p>And a new recipe to add to the <a target="_blank" rel="nofollow" href="https://leanpub.com/wranglingf1datawithr">Wrangling F1 Data With R</a> book, I guess..</p>
<p>PS in response to [misunderstanding…] a comment from @sidepodcast, we also have control over the concordance window size, and the plotsize:</p>
<p><img sizes="(max-width: 519px) 100vw, 519px" data-image-description="" data-orig-file="https://ouseful.files.wordpress.com/2017/05/concordresize.png?w=450#038;h=280" data-orig-size="1422,768" data-image-title="concordresize" data-comments-opened="1" class="wp-image-16193" data-recalc-dims="1" data-attachment-id="16193" data-permalink="https://blog.ouseful.info/2017/05/01/track-concordance-charts/concordresize/" alt="concordresize" data-medium-file="https://ouseful.files.wordpress.com/2017/05/concordresize.png?w=450#038;h=280?w=300" data-large-file="https://ouseful.files.wordpress.com/2017/05/concordresize.png?w=450#038;h=280?w=830" data-image-meta="{&quot;aperture&quot;:&quot;0&quot;,&quot;credit&quot;:&quot;&quot;,&quot;camera&quot;:&quot;&quot;,&quot;caption&quot;:&quot;&quot;,&quot;created_timestamp&quot;:&quot;0&quot;,&quot;copyright&quot;:&quot;&quot;,&quot;focal_length&quot;:&quot;0&quot;,&quot;iso&quot;:&quot;0&quot;,&quot;shutter_speed&quot;:&quot;0&quot;,&quot;title&quot;:&quot;&quot;,&quot;orientation&quot;:&quot;0&quot;}" src="https://ouseful.files.wordpress.com/2017/05/concordresize.png?w=450#038;h=280"></p>
<p>Generating <a target="_blank" rel="nofollow" href="http://ggplot2.tidyverse.org/reference/ggsave.html">hi-res versions in other file formats</a> is also possible.</p>
<p>Just got to wrap it all up in a templated report now…</p>
<p>PPS On the track position charts, I just noticed that where cars are lapped, they fall off the radar… so I’ve added them in behind the leader to keep the car count correct for each leadlap…</p>
<p><img sizes="(max-width: 404px) 100vw, 404px" data-image-description="" data-orig-file="https://ouseful.files.wordpress.com/2017/05/trackposrebaselapped.png?w=404&amp;resize=404%2C314#038;h=314" data-orig-size="952,740" data-image-title="trackposrebaselapped" data-comments-opened="1" class="wp-image-16198" data-recalc-dims="1" data-attachment-id="16198" data-permalink="https://blog.ouseful.info/2017/05/01/track-concordance-charts/trackposrebaselapped/" alt="trackposrebaselapped" data-medium-file="https://ouseful.files.wordpress.com/2017/05/trackposrebaselapped.png?w=404&amp;resize=404%2C314#038;h=314?w=300" data-large-file="https://ouseful.files.wordpress.com/2017/05/trackposrebaselapped.png?w=404&amp;resize=404%2C314#038;h=314?w=830" data-image-meta="{&quot;aperture&quot;:&quot;0&quot;,&quot;credit&quot;:&quot;&quot;,&quot;camera&quot;:&quot;&quot;,&quot;caption&quot;:&quot;&quot;,&quot;created_timestamp&quot;:&quot;0&quot;,&quot;copyright&quot;:&quot;&quot;,&quot;focal_length&quot;:&quot;0&quot;,&quot;iso&quot;:&quot;0&quot;,&quot;shutter_speed&quot;:&quot;0&quot;,&quot;title&quot;:&quot;&quot;,&quot;orientation&quot;:&quot;0&quot;}" src="https://ouseful.files.wordpress.com/2017/05/trackposrebaselapped.png?w=404&resize=404%2C314#038;h=314"></p>
<p> <a target="_blank" rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/ouseful.wordpress.com/16178/"><img alt="" src="http://feeds.wordpress.com/1.0/comments/ouseful.wordpress.com/16178/" border="0"></a> <img alt="" src="https://i1.wp.com/pixel.wp.com/b.gif?resize=1%2C1&ssl=1" border="0" data-recalc-dims="1"></p>
<img height="1" alt="" width="1" src="http://feeds.feedburner.com/~r/RBloggers/~4/ZI7JUHPgTVA">