= htmltab::htmltab(doc = "http://www.harrierleague.com/results/2017-18/druridge/SenF.htm") womens_results_raw
The Harrier League is a cross country running league with seven fixtures across the North East of England in the 2017/18 season across the winter months from September ’17 until March ’18.
The Harrier League is unique to other cross country fixtures because the senior runners are divided up into slow, medium and fast packs. In the senior men’s race, the slow runners start first followed 2 minutes 30 seconds later by the medium pack runners, then a further 2 minutes 30 seconds by the fast pack runners.
In order to progress to the fast pack, runners must first run in the slow pack and finish in the top 10% of finishers, this entitles them to run from the medium pack. If they then finish in the top 10% from the medium pack, then they can run from the fast pack.
Teams are split into three divisions and final team positions are calculated within each division by ordering the first six runners (four in the senior women) by race time. This is the total time elapsed from when the slow pack starts to when the runner crosses the finish line. Let’s answer one interesting question, what would the results be from the past weekends fixture without the handicaps, i.e. if everyone started from scratch.
The code for this analysis was written using R and the tidyverse. The full code can be found on Github. Let me know if you’d like me to answer other questions about the harrier league.
Senior Womens
We will look at the results from the previous race at Druridge Bay. In the senior women’s race there are four counters, any team with less than four runners will be removed from the final results. Now, we can calculate the position of each runner within each division by the actual running time of each runner.
First we need to download the relevant information, since the results are available as an HTML table, the package htmltab can be used to select the table containing the individual results
These results are then cleaned up, removing any guest runners and extracting the division of each runner from the club field.
= function(raw_results) {
clean_results %>%
raw_results as_data_frame() %>%
rename(race_time = `Race Time`, actual_time = `Actual Time`) %>%
filter(Cat != "guest") %>%
mutate(division = as.numeric(stringr::str_sub(Club, start = 2, end = 2)),
club = stringr::str_sub(Club, start = 5)) %>%
select(Name, actual_time, division, club) %>%
mutate(actual_seconds = as.numeric(lubridate::ms(actual_time)))
}
= clean_results(womens_results_raw) womens_results
Warning: `as_data_frame()` was deprecated in tibble 2.0.0.
Please use `as_tibble()` instead.
The signature and semantics have changed, see `?as_tibble`.
This warning is displayed once every 8 hours.
Call `lifecycle::last_lifecycle_warnings()` to see where this warning was generated.
Now we write a function which calculates the results for one division. This can be re-used for the men’s results by accepting the number of counters for each team as an argument to the function (4 women to count, 6 men to count). We remove any clubs who fielded incomplete teams and select the top counters ordered by the position supplied in the raw_results
dataframe. We then calculate the total points for each time, by summing the positions (lower is better) and concatenate the names of the counters into a single string.
= function(strings) {
concat Reduce(f = function(string_1, string_2) paste(string_1, string_2, sep = ", "), x = strings)
}
= function(raw_results, counters = 4) {
get_results_one_division = raw_results %>%
incomplete_teams count(club) %>%
filter(n < counters)
%>%
raw_results anti_join(incomplete_teams, by = "club") %>%
group_by(club) %>%
top_n(n = counters, wt = desc(pos)) %>%
group_by(club) %>%
summarise(total_points = sum(pos), total_counters = n(),
counters = concat(paste0(Name, " (", pos, ")"))) %>%
mutate(position = min_rank(total_points))
}
Now, we are ready to calculate the results given positions. But instead of using the race time (actual time + handicap time), we use the actual time to determine individual positions within each of the three divisions. We then use the previously defined function get_results_one_division()
to calculate the final score for each team in each division:
= function(results, counters) {
actual_time_results %>%
results group_by(division) %>%
mutate(pos = min_rank(actual_seconds)) %>%
do(get_results_one_division(., counters = counters)) %>%
arrange(division, position)
}
Here are the results for the women’s division one, two and three:
position | club | total_points | counters |
---|---|---|---|
1 | Tyne Bridge Harriers | 43 | Alison Dargie (3), Louise Rodgers (5), Heather Dorman (18), Mairi Clancy (17) |
2 | North Shields Poly | 63 | Rachel Mcintyre (15), Joanna Fletcher (26), Alison Smith (10), Katherine Davis (12) |
3 | Tynedale Harriers | 65 | Elizabeth Earle (24), Steph Scott (28), Kirstie Anderson (6), Jo Sutton (7) |
4 | Gateshead Harriers | 66 | Jemma Louise Bell (13), Sarah Holmes (36), Sarah Hill (8), Elizabeth Raven (9) |
5 | Morpeth Harriers & AC | 71 | Emma Holt (1), Jane Hodgson (2), Alison Brown (11), Sue Smith (57) |
6 | South Shields Harriers | 89 | Linda Bone (28), Rachel Breheny (16), Fran Dembele (26), Claire O’Callaghan (19) |
7 | Alnwick Harriers | 93 | Johanna Gascoigne-Owens (4), Lisa Baston (33), Alice Tetley-Paul (34), Karen Kelly (22) |
8 | Gosforth Harriers | 111 | Louise Watson (20), Angela Richardson (31), Sylvie Moffat (21), Susan Driscoll (39) |
9 | Durham City Harriers | 117 | Kelly Bentley (25), Gemma Soulsby (14), Rachel Terry (40), Rachel Bentley (38) |
10 | Elvet Striders | 186 | Susan Davis (41), Rachelle Mason (44), Sarah Davies (50), Rachael Bullock (51) |
position | club | total_points | counters |
---|---|---|---|
1 | Heaton Harriers | 31 | Nina Cameron (8), Louise Johnson (10), Ellen Roberts (2), Janine Routledge (11) |
2 | Jesmond Joggers | 49 | Emma Glover (4), Laura Cheetham (5), Jo King (18), Kate Black (22) |
3 | Crook AC | 53 | Kirstin Farquhar (6), Helene Pratt (32), Elizabeth Wood (12), Joanne Raine (3) |
4 | Sunderland Harriers | 88 | Linda Mudford (24), Lauren Flaxen (26), Vikki Cotton (9), Peter Richardson (29) |
5 | Elswick Harriers | 89 | Elspeth Aspinall (7), Catherine Lee (13), Graham Leslie (33), Jill Bennett (36) |
6 | Claremont RR | 94 | Mandy Herworth (20), Sarah Kerr (25), Nicki O’Brien (14), Jane Evans (35) |
6 | Low Fell RC | 94 | Emma Sproat (16), Claire Diamond-Howe (17), Cheryl Parkin (19), William Doidge (42) |
8 | Birtley AC | 121 | Chloe Price (1), Clare Atkinson (31), Shannel Curtis (37), Stephanie Young (52) |
9 | Blackhill | 152 | Louise Priestley (30), Caroline Slane (34), Kerry Anderson (40), Juliet Robinson (48) |
10 | Wallsend Harriers | 154 | Donna Thompson (15), Emily James (28), Julie Williams (47), Julie Collinson (64) |
position | club | total_points | counters |
---|---|---|---|
1 | Saltwell Harriers | 46 | Christie Waddington (4), Gemma Bradley (3), Sarah Garrett (12), Nicola Whitman (27) |
2 | Sunderland Strollers | 70 | Wendy Chapman (2), Clare Baharie (14), Hasina Khanom (16), Michelle Houghton (38) |
3 | Ponteland Runners | 72 | Elaine Stroud (15), Fiona Nicholson (18), Alison Guadagno (19), Laura Choake (20) |
4 | Blyth RC | 76 | Claire Calverley (8), Holly Johnson (21), Lisa Scorer (23), Sandra Watson (24) |
5 | Blaydon Harriers | 88 | Claire Collinson (10), Liane Brown (25), Joanne Ramshaw (26), Izzi Jackson (27) |
6 | Derwent Valley Running Club | 93 | Lindsay Smith (5), Dawn Cooper (13), Eleanor Shotton (22), Bernadette Salmon (53) |
7 | Jarrow & Hebburn AC | 94 | Rachel Jameson (9), Elaine Leslie (1), Heather Robinson (7), Julia Barnshaw (77) |
8 | Derwentside AC | 171 | Emma Armstrong (31), Fiona Gilchrist (40), Claire Wilkie (44), Janet Brooks (56) |
9 | Washington Running Club | 174 | Katherine Conway (30), Sarah Turnbull (42), Radina Tahtadzhieva (47), Nicole Clarke (55) |
10 | Ashington Hirst | 192 | Lee Elder (34), Kate Mclean (41), Laura Jobson (58), Lindsay Freeman (59) |
11 | Derwent Valley Trail Runners | 226 | Dawn Metcalfe (17), Susie Thompson (37), Vicky Hopper (72), Kathleen Boyle (100) |
12 | Newcastle Frontrunners | 309 | Heather Witham (52), Gillian Dodds (70), Grace Lewis (89), Jo Morrissey (98) |
13 | Stocksfield Striders | 353 | Rachael Maitland (49), Holly Kelleher (71), Louise Newton (116), Jane Buckingham (117) |
Senior Men
In the senior men’s race there are six counters, any team with less than six runners will be removed from the final results. Now, we can calculate the position of each runner within each division by the actual running time of each runner.
= htmltab(doc = "http://www.harrierleague.com/results/2017-18/druridge/SenM.htm")
mens_results_raw = clean_results(mens_results_raw) mens_results
position | club | total_points | counters |
---|---|---|---|
1 | Tyne Bridge Harriers | 89 | Paul O’Mara (9), James Dunce (2), Tom Charlton (4), Alasdair Blain (26), Tony Carter (21), Paul Turnbull (27) |
2 | Durham City Harriers | 111 | Alexander Cook (22), Jonathan Wilkinson (8), Francisco Martinez-Sevilla (16), Michael Wade (17), David Cross (36), Robin Linten (12) |
3 | Morpeth Harriers & AC | 129 | Robert Balmbra (1), Thomas Innes (23), Tony Lewis (37), Richard Castledine (39), Alistair Douglass (14), Mark Snowball (15) |
4 | Sunderland Harriers | 149 | Sean Mackie (31), Paul Blakey (10), Andrew Powell (3), Robert Walker (20), Steven Duffy (33), Paul Merrison (52) |
5 | Gateshead Harriers | 159 | Matthew Linsley (43), Ross Christie (13), Conrad Franks (7), Steven Asquith (31), Kevin Connolly (18), Peter Grimoldby (47) |
6 | Heaton Harriers | 188 | Matt Hetherington (19), Sam Thorpe (30), James Meader (24), James Mckenzie (11), Mark Oliver (50), Ian Norman (54) |
7 | Elvet Striders | 255 | Stephen Jackson (5), Jack Lee (57), Jason Harding (34), Michael Mason (25), Phil Ray (66), Scott Watson (68) |
8 | Birtley AC | 348 | Adrian Bailes (6), Peter Farnie (40), Karl Oakes (79), Peter Gill (44), Mark Hornsby (87), Trevor Crewe (92) |
9 | North Shields Poly | 374 | Paul West (29), Michael Parkinson (27), Michael Gibson (78), Paul Davies (49), William Powis (95), Richard Hanley (96) |
10 | Wallsend Harriers | 445 | Simon Lyon (35), David Diston (76), Jack Armstrong (57), Brian Hetherington (59), Keith Odonnell (108), Paul James (110) |
position | club | total_points | counters |
---|---|---|---|
1 | Jarrow & Hebburn AC | 90 | Andy Burn (1), Jonny Evans (3), Kevin Emmett (20), Jack Brown (25), Jonathan Gilroy (14), Conal Tuffnell (27) |
2 | Alnwick Harriers | 122 | Dan Turnbull (5), Adam Fletcher (22), Steve Carragher (10), Ian Simon (34), Dominic Harris (21), Philip Hemsley (30) |
3 | Gosforth Harriers | 132 | Tom Coates (18), Maurice Bourke (31), Andrew Heppell (15), Jonny Stephenson (24), James McCreesh (13), Neil Ramsay (31) |
4 | Elswick Harriers | 176 | Iain Hardy (40), Lee Bennett (7), John Bell (43), Mark Turnbull (19), Kevin Richardson (11), David Armstrong (56) |
5 | Saltwell Harriers | 181 | Graham Stephenson (28), Iain Armstrong (12), Fred Smith (44), Jim Thompson (16), Matt O’Brien (16), Peter Mullarkey (65) |
6 | South Shields Harriers | 214 | Luke Adams (2), Jeff Mcgurty (40), Paul Owen (45), Neil Turner (46), Stephen Mackin (53), Mark Wilson (28) |
7 | Blyth RC | 219 | Graeme Stewart (36), Tony Horsley (38), Gary Jones (8), Graham Wood (51), Calum Storey (22), Paul Whalley (64) |
8 | Sunderland Strollers | 253 | Callum Thom (9), Luke Mccormack (49), Ritchie Gerry (26), Paul Dunlop (66), Michael Dixon (68), Ken Maynard (35) |
9 | Sedgefield Harriers | 311 | James Oldfield (4), David Bentley (42), Mark Raine (48), David Walker (56), Mil Walton (77), Chris Lines (84) |
10 | Blackhill | 319 | Jordan Bell (6), Ian Young (55), Gary Dixon (60), Jonathan Richards (68), Daryl Priestley (79), Michael Mcdonald (51) |
11 | Crook AC | 847 | Paul Brennan (90), Geoff Hewitson (98), Mark Nichol (148), Gerry Hehir (168), Lloyd Ashby (169), Paul Wragg (174) |
position | club | total_points | counters |
---|---|---|---|
1 | Low Fell RC | 77 | Gavin Thompson (13), David France (3), Ian Marriott (23), Fai Ng (25), Paul Harrison (9), Stephen Magrath (4) |
2 | Houghton AC | 80 | Juma Tatah (14), Stephen Johnson (21), Lee Dover (2), Adam Middleton (16), Tom Whelan (17), Thomas Grey (10) |
3 | Blaydon Harriers | 140 | David Garner (11), Isaac Dunn (5), James Ramshaw (30), James Dias (7), Jamie Boswell (41), Liam Friel (46) |
4 | Derwentside AC | 201 | Graham Marshall (18), Mark Davinson (29), David Reay (34), John S Donneky (8), Steven Dickson (27), Chris Lowes (85) |
5 | Jesmond Joggers | 267 | Josh Freed (19), Angus Miller (33), Stuart Harper (43), Gregory Stamp (55), Tim Mcgahey (58), John Farr (59) |
6 | Ponteland Runners | 268 | John Mcgargill (47), James Leiper (15), Chris Kenyon (56), Tim Allsop (20), Matthew Levison (62), Matty Bell (68) |
7 | Ashington Hirst | 271 | Kurt Heron (1), Paul White (6), Iain Singer (52), Martin Thompson (59), Philip Battista (74), Nic Crofts (79) |
8 | Washington Running Club | 302 | Peter Setterfield (24), Tim Jones (28), Craig Smith (50), Nick Butchart (51), Carl Smith (66), David Bannan (83) |
9 | Claremont RR | 391 | Roberto Marzo (22), Anthony Liddle (39), Danny Edwards (70), Duncan Scott (72), David Devennie (93), Dean O’Brien (95) |
10 | Derwent Valley Trail Runners | 445 | Stephen Heseltine (38), Ian Hutchinson (49), Andrew Nesbit (76), Jordan Babak (91), Tony Curry (93), Dan English (98) |
11 | Derwent Valley Running Club | 553 | Mark Marchant (35), Simon Woolley (79), Peter Storey (100), Nick Belcher (105), John Kirby (113), Steve Wade (121) |
12 | Newcastle Frontrunners | 587 | Russell Dickinson Deane (32), Phillip Hall (67), Mark Sutherland (75), Curtis Allen (123), Ken Hodson (144), Allen Dickinson Deane (146) |
Citation
@online{law2017,
author = {Jonny Law},
title = {Harrier {League} {Cross} {Country}},
date = {2017-10-26},
langid = {en}
}