class: left, top background-image: url("ACU MHPS 2021/Images/Metricon 2.jpg") background-size: cover opacity: 0.5 # Using R and Power BI in Sport #### Heidi Thornton, PhD | ACU High-Performance Sport Seminar --- class: left background-image: url("ACU MHPS 2021/Images/Home.jpg") background-position: 100% 50% background-size: 40% 65% # About me πI'm an applied sports scientist -- I currently work with two πteams -- - Gold Coast Suns Football Club (AFL) - Newcastle Knights Rugby League Club (NRL) -- I use R and Power BI daily -- Outside of work, I love running and the gym ποΈββοΈ -- πI live in an pretty amazing place (Newcastle) --- class: center, middle <font size="20"> 'Start with the end in mind' </font> ### Credit to [Dr Jacquie Tran](https://jacquietran.github.io/2019_essa_forum/R/#1) --- class: left # Why not just use excel? Both [Alice Sweeting](http://sportstatisticsrsweet.rbind.io/) and [Jacquie Tran](https://www.jacquietran.com/) have presented on this previously -- BUT the general story is.... .pull-left[ <img src="https://media.giphy.com/media/Sb9KqeeymLlESGWZyE/giphy.gif" width="45%" /> ] -- .pull-right[ <img src="https://media.giphy.com/media/Rhhr8D5mKSX7O/giphy.gif" width="65%" /> ] --- class: left # Lets get started β I'm skipping the setup of R and Power BI as there are **tonnes** of resources available (see end of presentation) -- βοΈ We will create a GPS match report in R **without** touching Excel -- π Firstly, we need to install a few R **packages** ```r Packages <- c('readxl','tidyverse','dplyr','ggplot2', 'sparkline', 'kableExtra', 'data.table', 'formattable', 'DT') # Install listed packages install.packages(Packages) ``` <br> <img src="ACU MHPS 2021/Images/readxl.png" width="9%" /><img src="ACU MHPS 2021/Images/tidyverse.jpg" width="9%" /><img src="ACU MHPS 2021/Images/dplyr.png" width="9%" /><img src="ACU MHPS 2021/Images/catapultR.png" width="9%" /><img src="ACU MHPS 2021/Images/KableExtra.jpg" width="9%" /><img src="ACU MHPS 2021/Images/ggplot2.jpg" width="9%" /><img src="ACU MHPS 2021/Images/datatable.png" width="9%" /><img src="ACU MHPS 2021/Images/R.jpg" width="9%" /> --- # CatapultR package βοΈ **`catapultR`** is a new R package developed by Catapult -- .pull-left[It allows users to pull data directly from their cloud] <img src="https://media.giphy.com/media/l4HodBpDmoMA5p9bG/giphy.gif" width="23%" style="display: block; margin: auto;" /> -- π¨ **`catapultR`** is still a demo version π You can download it, but Catapult aren't accepting new users just yet ```r # Install catapultR devtools::install_bitbucket("catapultsports/catapultr") library(catapultR) ``` --- # Pull sessions from the cloud
These credentials are for presentation purposes only (need your own) π This token allows us to query your cloud and access data using the catapult API ```r # token <- ofCloudGetToken(sRegion = "America", sName = "brian_wsoccer_demo", sPwd = "d3cCM4yvh6", # sClientID = "h9vrcJ3FXxY71HDzdU0a6C4QLt5VjoOunABsRlK8", # sClientSecret = "STe67MbNGfkO5XH8jaZDyoQvnz4VBYiL0Clg2RcW") ``` There is a link to request access to catapultR - https://docs.google.com/forms/d/e/1FAIpQLScv8w7OHvzdR05_M-Piu1rNJU9OPzIwsBfLNvY56RZx_nnU_g/viewform --- # View activities βοΈ Now we have saved our account token details, we can select what session/game we want to select ```r # View activities activities <- ofCloudGetActivities(token) glimpse(activities) ``` ``` ## Rows: 1,210 ## Columns: 19 ## $ id <chr> "6e035081-1e4b-4b13-b0ba-e27aa5a454e2", "77895525-cf54-~ ## $ name <chr> "210821SatAFLRd23vsSydney", "Activity 20210821075312", ~ ## $ start_time <int> 1629517523, 1629496354, 1629423083, 1629323771, 1629244~ ## $ end_time <int> 1629526735, 1629511575, 1629425226, 1629327783, 1629249~ ## $ modified_at <chr> "2021-08-27 01:56:35", "2021-08-21 02:36:28", "2021-08-~ ## $ game_id <chr> "6e035081-1e4b-4b13-b0ba-e27aa5a454e2", "77895525-cf54-~ ## $ owner_id <chr> "0d2d37ee-9879-4987-9189-bc0cd388bb98", "4b6264d6-cf87-~ ## $ owner <df[,10]> <data.frame[26 x 10]> ## $ periods <list> [<data.frame[4 x 4]>], [<data.frame[1 x 4]>], [<dat~ ## $ tags <list> <"LPS", "Saturday", "Full", "T6Full">, "GPS", <"Friday~ ## $ tag_list <list> [<data.frame[4 x 5]>], [<data.frame[1 x 5]>], [<data.f~ ## $ athlete_count <int> 23, 8, 26, 8, 31, 3, 6, 23, 14, 28, 3, 39, 7, 32, 23, ~ ## $ period_count <int> 4, 1, 1, 9, 16, 1, 7, 4, 4, 1, 7, 16, 10, 5, 4, 7, 14, ~ ## $ venue_name <chr> "AFL Q", "AFL Q", "AFL Q", "AFL Q", "AFL Q", "AFL Q", "~ ## $ venue_width <int> 0, 0, 0, 0, 0, 0, 0, 0, 159, 0, 0, 0, 0, 0, 0, 0, 159, ~ ## $ venue_length <int> 0, 0, 0, 0, 0, 0, 0, 0, 159, 0, 0, 0, 0, 0, 0, 0, 159, ~ ## $ venue_rotation <int> 0, 0, 0, 0, 0, 0, 0, 0, -179, 0, 0, 0, 0, 0, 0, 0, -179~ ## $ venue_lat <dbl> 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0~ ## $ venue_lng <dbl> 0.0000, 0.0000, 0.0000, 0.0000, 0.0000, 0.0000, 0.0000,~ ``` ```r # Select what activities we want to report on target <- c("210529SatAFLRd11vsHawthorn","210522SatAFLRd10vsGeelong","210515SatAFLRd9vsBrisbane", "210508Rd8vsStKilda","210501SatAFLRd7vsCollingwood","210424SatAFLRd6vsSydney", "210417SatAFLRd5vsWesternBulldogs","210410SatAFLRd4vsCarlton", "210402FriAFLRd3vsAdelaide","210327Rd2vsNorthMelbourne","210321SunAFLRd1vsWestCoast") activities <- filter(activities, name %in% target) ``` --- # View parameters
Now lets see what parameters are available to view Currently, there are **1046** metrics available ```r # view parameters parameters <- ofCloudGetParameters(token) glimpse(parameters) ``` ``` ## Rows: 1,046 ## Columns: 6 ## $ id <chr> "00025054-617c-45f1-ae03-a768ebfcd893", "003eb200-19~ ## $ parameter_type_id <chr> "417654ed-209f-4c6f-a028-62c10f873d18", "65344b9a-85~ ## $ name <chr> "IMA Accel Medium", "Velocity Band 2 Average Effort ~ ## $ original_name <chr> "IMA Accel Medium", "Velocity Band 2 Average Effort ~ ## $ slug <chr> "ima_band2_accel_count", "velocity_band2_average_eff~ ## $ calculation <chr> "", "", "", "", "", "", "", "", "", "", "", "", "", ~ ``` --- # Create dataset
Using our credentials, we can now select what metrics we want ```r data <- ofCloudGetStatistics( token, params = c("date","athlete_name","total_duration","total_distance", "meterage_per_minute","velocity_band6_total_distance","max_vel"), groupby = c("athlete", "activity"), filters = list(name = "activity_id", comparison = "=", values = activities$id)) ``` -- ```r head(data, n=3) ``` ``` ## date Name total_distance total_duration max_vel ## 1 21/03/2021 Athlete 41 13000.07 5753.67 30.75762 ## 2 27/03/2021 Athlete 41 12280.45 5510.38 33.12540 ## 3 02/04/2021 Athlete 41 11235.87 4722.58 30.84264 ## velocity_band6_total_distance meterage_per_minute ## 1 341.81 135.5664 ## 2 353.66 133.7162 ## 3 377.41 142.7508 ``` --- # Summarise data
Using the **`dplyr`** package, we will replicate what we might normally do with a **pivot table** to summarise our data -- ```r data <- data %>% mutate(date=as.Date(as.character(date), format = "%d/%m/%Y")) %>% group_by(date, Name) %>% summarize( Duration=sum(total_duration)/60, Speed_mmin=mean(meterage_per_minute), Distance=sum(total_distance), HSR=sum(velocity_band6_total_distance), Max_velocity=max(max_vel)) ``` -- ``` ## # A tibble: 5 x 7 ## # Groups: date [1] ## date Name Duration Speed_mmin Distance HSR Max_velocity ## <date> <chr> <dbl> <dbl> <dbl> <dbl> <dbl> ## 1 2021-03-21 Athlete 13 100. 116. 11582. 99.9 27.9 ## 2 2021-03-21 Athlete 14 101. 138. 13994. 337. 29.4 ## 3 2021-03-21 Athlete 2 86.8 149. 12902. 60.6 26.7 ## 4 2021-03-21 Athlete 20 89.7 127. 11403. 19.8 26.2 ## 5 2021-03-21 Athlete 23 72.9 139. 10120. 272. 31.3 ``` --- # Sparklines -- .pull-left[
Sparklines are HTML widgets that can summarise data nicely in reports I think of them as 'mini graphs' π€· <img src="ACU MHPS 2021/Images/sparklinetable.png" width="55%" /> ] -- .pull-right[ ```r sparklines <- data %>% group_by(Name) %>% arrange(date) %>% summarize( Distance_SPK = spk_chr( round(Distance, 0), type='line', fillColor = "transparent", RangeMin = mean(Distance)-(sd(Distance)*0.5), RangeMax = mean(Distance)+(sd(Distance)*0.5), chartRangeClip = T, width = 100, height = 15), Duration_SPK = spk_chr( round(Duration, 0), type='line', fillColor = "transparent", RangeMin = mean(Duration)-(sd(Duration)*0.5), RangeMax = mean(Duration)+(sd(Duration)*0.5), chartRangeClip = T, width = 100,height = 15)) ``` ] --- # Sparklines dataset --- # Merge data frames
First we need to merge the summary data and sparklines together using the **`dplyr`** package
Then filter by the date we want to report on -- ```r combined <- full_join(data, sparklines, by = c("Name")) %>% filter(date == "2021-05-29") head(combined, n=5) ``` ``` ## # A tibble: 5 x 10 ## # Groups: date [1] ## date Name Duration Speed_mmin Distance HSR Max_velocity Distance_SPK ## <date> <chr> <dbl> <dbl> <dbl> <dbl> <dbl> <html> ## 1 2021-05-29 Athle~ 14.4 143. 2062. 173. 30.7 "<span id=\~ ## 2 2021-05-29 Athle~ 114. 134. 15259. 359. 32.1 "<span id=\~ ## 3 2021-05-29 Athle~ 96.9 123. 11920. 155. 32.3 "<span id=\~ ## 4 2021-05-29 Athle~ 92.2 132. 12187. 85.7 28.1 "<span id=\~ ## 5 2021-05-29 Athle~ 86.2 141. 12142. 50.6 28.6 "<span id=\~ ## # ... with 2 more variables: Duration_SPK <html>, Speed_mmin_SPK <html> ``` --- # GPS report - Version 1 First we will create a basic table with limited formatting using the **`formattable`** package -- ```r library(formattable) formattable(combined, align = c('c'), list(options =list(dom ='tp'))) ``` -- <table class="table table-condensed"> <thead> <tr> <th style="text-align:center;"> date </th> <th style="text-align:center;"> Name </th> <th style="text-align:center;"> Duration </th> <th style="text-align:center;"> Speed_mmin </th> <th style="text-align:center;"> Distance </th> <th style="text-align:center;"> HSR </th> <th style="text-align:center;"> Max_velocity </th> <th style="text-align:center;"> Distance_SPK </th> <th style="text-align:center;"> Duration_SPK </th> <th style="text-align:center;"> Speed_mmin_SPK </th> </tr> </thead> <tbody> <tr> <td style="text-align:center;"> 2021-05-29 </td> <td style="text-align:center;"> Athlete 9 </td> <td style="text-align:center;"> 117.4733 </td> <td style="text-align:center;"> 116.0014 </td> <td style="text-align:center;"> 13627.07 </td> <td style="text-align:center;"> 53.62 </td> <td style="text-align:center;"> 29.68420 </td> <td style="text-align:center;"> <span id="htmlwidget-672495a6168ad6bd217d" class="sparkline html-widget"></span> <script type="application/json" data-for="htmlwidget-672495a6168ad6bd217d">{"x":{"values":[11876,14013,13358,14210,14204,13443,12816,12681,11514,14292,13627],"options":{"type":"line","fillColor":"transparent","spotColor":false,"normalRangeMin":12798.9545612611,"normalRangeMax":13752.6425587389,"chartRangeClip":true,"chartRangeMinX":1,"chartRangeMinX.1":60,"height":15,"width":100},"width":100,"height":15},"evals":[],"jsHooks":[]}</script> </td> <td style="text-align:center;"> <span id="htmlwidget-b4d748fc9ebdb1432eba" class="sparkline html-widget"></span> <script type="application/json" data-for="htmlwidget-b4d748fc9ebdb1432eba">{"x":{"values":[106,117,122,125,128,112,112,114,103,128,117],"options":{"type":"line","fillColor":"transparent","spotColor":false,"normalRangeMin":112.629401311607,"normalRangeMax":121.045901718696,"chartRangeClip":true,"height":15,"width":100},"width":100,"height":15},"evals":[],"jsHooks":[]}</script> </td> <td style="text-align:center;"> <span id="htmlwidget-e6f3cf4189aa10f83b57" class="sparkline html-widget"></span> <script type="application/json" data-for="htmlwidget-e6f3cf4189aa10f83b57">{"x":{"values":[112,120,109,113,111,120,114,112,112,111,116],"options":{"type":"line","fillColor":"transparent","spotColor":false,"normalRangeMin":111.94199681885,"normalRangeMax":115.408412272059,"chartRangeClip":true,"height":15,"width":100},"width":100,"height":15},"evals":[],"jsHooks":[]}</script> </td> </tr> <tr> <td style="text-align:center;"> 2021-05-29 </td> <td style="text-align:center;"> Athlete 14 </td> <td style="text-align:center;"> 114.2290 </td> <td style="text-align:center;"> 133.5855 </td> <td style="text-align:center;"> 15259.34 </td> <td style="text-align:center;"> 359.05 </td> <td style="text-align:center;"> 32.12881 </td> <td style="text-align:center;"> <span id="htmlwidget-608102498d20e0b43937" class="sparkline html-widget"></span> <script type="application/json" data-for="htmlwidget-608102498d20e0b43937">{"x":{"values":[13994,14273,14253,15225,16513,15746,14731,14435,14855,15339,15259],"options":{"type":"line","fillColor":"transparent","spotColor":false,"normalRangeMin":14592.3836661635,"normalRangeMax":15339.1089756547,"chartRangeClip":true,"chartRangeMinX":1,"chartRangeMinX.1":60,"height":15,"width":100},"width":100,"height":15},"evals":[],"jsHooks":[]}</script> </td> <td style="text-align:center;"> <span id="htmlwidget-33bd0fc6f1999a39d849" class="sparkline html-widget"></span> <script type="application/json" data-for="htmlwidget-33bd0fc6f1999a39d849">{"x":{"values":[101,106,105,114,127,119,107,103,114,113,114],"options":{"type":"line","fillColor":"transparent","spotColor":false,"normalRangeMin":107.328021860506,"normalRangeMax":115.035493291009,"chartRangeClip":true,"height":15,"width":100},"width":100,"height":15},"evals":[],"jsHooks":[]}</script> </td> <td style="text-align:center;"> <span id="htmlwidget-065a7324419a4b66103a" class="sparkline html-widget"></span> <script type="application/json" data-for="htmlwidget-065a7324419a4b66103a">{"x":{"values":[138,135,135,134,130,132,138,140,130,136,134],"options":{"type":"line","fillColor":"transparent","spotColor":false,"normalRangeMin":133.197880505247,"normalRangeMax":136.375994040208,"chartRangeClip":true,"height":15,"width":100},"width":100,"height":15},"evals":[],"jsHooks":[]}</script> </td> </tr> <tr> <td style="text-align:center;"> 2021-05-29 </td> <td style="text-align:center;"> Athlete 32 </td> <td style="text-align:center;"> 112.0963 </td> <td style="text-align:center;"> 138.6244 </td> <td style="text-align:center;"> 15539.29 </td> <td style="text-align:center;"> 399.11 </td> <td style="text-align:center;"> 30.27415 </td> <td style="text-align:center;"> <span id="htmlwidget-0190b4b402ecae64bf95" class="sparkline html-widget"></span> <script type="application/json" data-for="htmlwidget-0190b4b402ecae64bf95">{"x":{"values":[13203,14522,11999,15693,15305,14211,14477,12834,14669,15539],"options":{"type":"line","fillColor":"transparent","spotColor":false,"normalRangeMin":13636.7765758708,"normalRangeMax":14853.6352041292,"chartRangeClip":true,"chartRangeMinX":1,"chartRangeMinX.1":60,"height":15,"width":100},"width":100,"height":15},"evals":[],"jsHooks":[]}</script> </td> <td style="text-align:center;"> <span id="htmlwidget-cd9192812bac33d16f43" class="sparkline html-widget"></span> <script type="application/json" data-for="htmlwidget-cd9192812bac33d16f43">{"x":{"values":[96,105,90,119,117,103,104,93,111,112],"options":{"type":"line","fillColor":"transparent","spotColor":false,"normalRangeMin":100.045973727323,"normalRangeMax":109.895626272677,"chartRangeClip":true,"height":15,"width":100},"width":100,"height":15},"evals":[],"jsHooks":[]}</script> </td> <td style="text-align:center;"> <span id="htmlwidget-b1f991bd895ab9ae2d23" class="sparkline html-widget"></span> <script type="application/json" data-for="htmlwidget-b1f991bd895ab9ae2d23">{"x":{"values":[138,139,133,132,132,137,140,138,132,139],"options":{"type":"line","fillColor":"transparent","spotColor":false,"normalRangeMin":134.21596480739,"normalRangeMax":137.52307319261,"chartRangeClip":true,"height":15,"width":100},"width":100,"height":15},"evals":[],"jsHooks":[]}</script> </td> </tr> <tr> <td style="text-align:center;"> 2021-05-29 </td> <td style="text-align:center;"> Athlete 28 </td> <td style="text-align:center;"> 111.5465 </td> <td style="text-align:center;"> 121.7306 </td> <td style="text-align:center;"> 13578.62 </td> <td style="text-align:center;"> 235.78 </td> <td style="text-align:center;"> 28.60774 </td> <td style="text-align:center;"> <span id="htmlwidget-2aa13d0288cf7252a16a" class="sparkline html-widget"></span> <script type="application/json" data-for="htmlwidget-2aa13d0288cf7252a16a">{"x":{"values":[12498,13583,13864,14485,15037,14073,12365,13150,13368,14441,13579],"options":{"type":"line","fillColor":"transparent","spotColor":false,"normalRangeMin":13264.7073252413,"normalRangeMax":14088.1855820314,"chartRangeClip":true,"chartRangeMinX":1,"chartRangeMinX.1":60,"height":15,"width":100},"width":100,"height":15},"evals":[],"jsHooks":[]}</script> </td> <td style="text-align:center;"> <span id="htmlwidget-69cfc1015d9ca9cb36ee" class="sparkline html-widget"></span> <script type="application/json" data-for="htmlwidget-69cfc1015d9ca9cb36ee">{"x":{"values":[91,102,104,110,116,108,93,99,104,116,112],"options":{"type":"line","fillColor":"transparent","spotColor":false,"normalRangeMin":100.67910878847,"normalRangeMax":109.125982120621,"chartRangeClip":true,"height":15,"width":100},"width":100,"height":15},"evals":[],"jsHooks":[]}</script> </td> <td style="text-align:center;"> <span id="htmlwidget-b68a9ee0ba32d3ea09c9" class="sparkline html-widget"></span> <script type="application/json" data-for="htmlwidget-b68a9ee0ba32d3ea09c9">{"x":{"values":[138,133,134,132,130,131,133,133,128,125,122],"options":{"type":"line","fillColor":"transparent","spotColor":false,"normalRangeMin":128.398855615205,"normalRangeMax":132.892960748432,"chartRangeClip":true,"height":15,"width":100},"width":100,"height":15},"evals":[],"jsHooks":[]}</script> </td> </tr> <tr> <td style="text-align:center;"> 2021-05-29 </td> <td style="text-align:center;"> Athlete 4 </td> <td style="text-align:center;"> 108.8887 </td> <td style="text-align:center;"> 109.8003 </td> <td style="text-align:center;"> 11956.00 </td> <td style="text-align:center;"> 28.44 </td> <td style="text-align:center;"> 26.01875 </td> <td style="text-align:center;"> <span id="htmlwidget-ae666eca5a3212acddb9" class="sparkline html-widget"></span> <script type="application/json" data-for="htmlwidget-ae666eca5a3212acddb9">{"x":{"values":[12133,13762,13052,11999,11912,11632,12141,12805,12673,11956],"options":{"type":"line","fillColor":"transparent","spotColor":false,"normalRangeMin":12079.7243109113,"normalRangeMax":12733.2584570887,"chartRangeClip":true,"chartRangeMinX":1,"chartRangeMinX.1":60,"height":15,"width":100},"width":100,"height":15},"evals":[],"jsHooks":[]}</script> </td> <td style="text-align:center;"> <span id="htmlwidget-9c033560708a323e607a" class="sparkline html-widget"></span> <script type="application/json" data-for="htmlwidget-9c033560708a323e607a">{"x":{"values":[109,120,118,107,106,107,104,118,126,109],"options":{"type":"line","fillColor":"transparent","spotColor":false,"normalRangeMin":108.380223752687,"normalRangeMax":115.862142913979,"chartRangeClip":true,"height":15,"width":100},"width":100,"height":15},"evals":[],"jsHooks":[]}</script> </td> <td style="text-align:center;"> <span id="htmlwidget-4c1c3e7e9dd068f738a8" class="sparkline html-widget"></span> <script type="application/json" data-for="htmlwidget-4c1c3e7e9dd068f738a8">{"x":{"values":[112,115,110,112,113,109,117,109,101,110],"options":{"type":"line","fillColor":"transparent","spotColor":false,"normalRangeMin":108.635743407367,"normalRangeMax":112.992846592633,"chartRangeClip":true,"height":15,"width":100},"width":100,"height":15},"evals":[],"jsHooks":[]}</script> </td> </tr> <tr> <td style="text-align:center;"> 2021-05-29 </td> <td style="text-align:center;"> Athlete 30 </td> <td style="text-align:center;"> 108.0282 </td> <td style="text-align:center;"> 134.8545 </td> <td style="text-align:center;"> 14568.09 </td> <td style="text-align:center;"> 548.45 </td> <td style="text-align:center;"> 35.88166 </td> <td style="text-align:center;"> <span id="htmlwidget-b3a77fd85c207384df5a" class="sparkline html-widget"></span> <script type="application/json" data-for="htmlwidget-b3a77fd85c207384df5a">{"x":{"values":[13119,12377,13275,15047,14672,13715,12060,13362,14181,14952,14568],"options":{"type":"line","fillColor":"transparent","spotColor":false,"normalRangeMin":13248.5636421865,"normalRangeMax":14265.8789396317,"chartRangeClip":true,"chartRangeMinX":1,"chartRangeMinX.1":60,"height":15,"width":100},"width":100,"height":15},"evals":[],"jsHooks":[]}</script> </td> <td style="text-align:center;"> <span id="htmlwidget-0f2e5b0f9a65e6072251" class="sparkline html-widget"></span> <script type="application/json" data-for="htmlwidget-0f2e5b0f9a65e6072251">{"x":{"values":[94,88,98,110,112,101,85,94,107,112,108],"options":{"type":"line","fillColor":"transparent","spotColor":false,"normalRangeMin":95.9916759859909,"normalRangeMax":105.544778559464,"chartRangeClip":true,"height":15,"width":100},"width":100,"height":15},"evals":[],"jsHooks":[]}</script> </td> <td style="text-align:center;"> <span id="htmlwidget-0bf004b8a36b4ff5ce68" class="sparkline html-widget"></span> <script type="application/json" data-for="htmlwidget-0bf004b8a36b4ff5ce68">{"x":{"values":[140,140,136,137,132,136,141,142,133,133,135],"options":{"type":"line","fillColor":"transparent","spotColor":false,"normalRangeMin":135.006259655701,"normalRangeMax":138.594565798844,"chartRangeClip":true,"height":15,"width":100},"width":100,"height":15},"evals":[],"jsHooks":[]}</script> </td> </tr> <tr> <td style="text-align:center;"> 2021-05-29 </td> <td style="text-align:center;"> Athlete 41 </td> <td style="text-align:center;"> 106.3490 </td> <td style="text-align:center;"> 137.5965 </td> <td style="text-align:center;"> 14633.25 </td> <td style="text-align:center;"> 468.82 </td> <td style="text-align:center;"> 31.78578 </td> <td style="text-align:center;"> <span id="htmlwidget-b3a83c5f4cafb59a6a28" class="sparkline html-widget"></span> <script type="application/json" data-for="htmlwidget-b3a83c5f4cafb59a6a28">{"x":{"values":[13000,12280,11236,13889,11920,5017,13810,14633],"options":{"type":"line","fillColor":"transparent","spotColor":false,"normalRangeMin":10458.9621259303,"normalRangeMax":13487.4840440697,"chartRangeClip":true,"chartRangeMinX":1,"chartRangeMinX.1":60,"height":15,"width":100},"width":100,"height":15},"evals":[],"jsHooks":[]}</script> </td> <td style="text-align:center;"> <span id="htmlwidget-8eab2712c89ccef6a250" class="sparkline html-widget"></span> <script type="application/json" data-for="htmlwidget-8eab2712c89ccef6a250">{"x":{"values":[96,92,79,105,88,31,105,106],"options":{"type":"line","fillColor":"transparent","spotColor":false,"normalRangeMin":75.2942319238201,"normalRangeMax":100.394476409513,"chartRangeClip":true,"height":15,"width":100},"width":100,"height":15},"evals":[],"jsHooks":[]}</script> </td> <td style="text-align:center;"> <span id="htmlwidget-8482f2dc34ac0d7c99a2" class="sparkline html-widget"></span> <script type="application/json" data-for="htmlwidget-8482f2dc34ac0d7c99a2">{"x":{"values":[136,134,143,132,135,164,131,138],"options":{"type":"line","fillColor":"transparent","spotColor":false,"normalRangeMin":133.48800222144,"normalRangeMax":144.33161027856,"chartRangeClip":true,"height":15,"width":100},"width":100,"height":15},"evals":[],"jsHooks":[]}</script> </td> </tr> <tr> <td style="text-align:center;"> 2021-05-29 </td> <td style="text-align:center;"> Athlete 37 </td> <td style="text-align:center;"> 105.3603 </td> <td style="text-align:center;"> 132.4269 </td> <td style="text-align:center;"> 13952.54 </td> <td style="text-align:center;"> 300.39 </td> <td style="text-align:center;"> 32.25472 </td> <td style="text-align:center;"> <span id="htmlwidget-2b2758da4aa006e2e9da" class="sparkline html-widget"></span> <script type="application/json" data-for="htmlwidget-2b2758da4aa006e2e9da">{"x":{"values":[11451,13563,13783,14861,15244,13930,13749,12628,13533,14477,13953],"options":{"type":"line","fillColor":"transparent","spotColor":false,"normalRangeMin":13225.9629221477,"normalRangeMax":14260.0916505796,"chartRangeClip":true,"chartRangeMinX":1,"chartRangeMinX.1":60,"height":15,"width":100},"width":100,"height":15},"evals":[],"jsHooks":[]}</script> </td> <td style="text-align:center;"> <span id="htmlwidget-9eb11f4bbf1576e36e95" class="sparkline html-widget"></span> <script type="application/json" data-for="htmlwidget-9eb11f4bbf1576e36e95">{"x":{"values":[83,103,103,117,117,106,103,97,107,110,105],"options":{"type":"line","fillColor":"transparent","spotColor":false,"normalRangeMin":99.9734519562204,"normalRangeMax":109.291426831658,"chartRangeClip":true,"height":15,"width":100},"width":100,"height":15},"evals":[],"jsHooks":[]}</script> </td> <td style="text-align:center;"> <span id="htmlwidget-f85cb51e8e516809487c" class="sparkline html-widget"></span> <script type="application/json" data-for="htmlwidget-f85cb51e8e516809487c">{"x":{"values":[138,132,133,127,131,132,134,130,126,132,132],"options":{"type":"line","fillColor":"transparent","spotColor":false,"normalRangeMin":129.964895052553,"normalRangeMax":133.146946765629,"chartRangeClip":true,"height":15,"width":100},"width":100,"height":15},"evals":[],"jsHooks":[]}</script> </td> </tr> </tbody> </table> --- # GPS report - Version 2 βοΈ A few more steps with this one, but worth it for the final product ```r combined <- combined[c(1,3,10,4,11,5,9,7)] %>% filter(Duration > 98) %>% ungroup() %>% formattable::formattable list(Duration = color_tile("white","indianred"), Speed_mmin = color_tile("white","indianred"), Distance = color_tile("white","indianred"), Max_velocity = color_tile("white","lightgreen"))) %>% formattable::as.datatable(rownames = FALSE, class = 'white-space: nowrap', colnames = c("Name","Duration (mins)","Duration trend","Speed (m.min) ","Speed trend", " Distance (m)","Distance trend","Max speed (m.s)"), options = list(dom = 'tp', bPaginate=FALSE, columnDefs = list(className = 'dt-center', targets = "_all")), fnDrawCallback = htmlwidgets:: JS('function(){HTMLWidgets.staticRender();}')) %>% spk_add_deps() %>% formatStyle(c(1,3,5,7), `border-right` = "solid 1px", `border-color` = "darkgrey") ``` --- # GPS Report - Version 2 outut
--- # Power BI
If you know how to use **Microsoft Excel**, you'll already know parts of **Microsoft Power BI** -- π Create simple, powerful visualisations, in a time efficient manner --
It's **free** (desktop version) -- π All calculations/formulas can be done directly in **Power BI** -- βοΈ Download direct from the internet <br> <img src="ACU MHPS 2021/Images/pb.png" width="15%" style="display: block; margin: auto;" /> --- # Power BI report
Create a drill intensity report also using R showing intensity of drills compared to the peak of a game for 3 metrics -- <img src="2021-ACU-HT_files/figure-html/power bi report 2-1.png" width="55%" style="display: block; margin: auto;" /> --- # Power BI data π Repeat similiar steps using **`catapultR`** and added in **period name** (drill name) -- ```r # token <- ofCloudGetToken(sRegion = "APAC, sName = " Acc name", sPwd = "acc password", # sClientID = "ID", ClientSecret = "secret") activities <- ofCloudGetActivities(token) activities <-filter(activities, activities$name=="210609Wed") # Pull through most recent data data <- ofCloudGetStatistics(token, params = c("date", "activity_name","athlete_name","period_name","start_time_h","end_time_h", "total_duration","meterage_per_minute","hirmin","acceleration_density"), groupby = c("athlete", "period", "activity"), filters = list(name = "activity_id", comparison = "=", values = activities$id[1])) data$total_duration <- as.numeric(data$total_duration)/60 write.csv(data, row.names=FALSE, "assets/data.csv") # Export data ``` --- # Create Power BI report - Open power BI and connect data using **Get Data** button - Calculate **% game intensity** columns using pre-determined **intercept** (peak intensity) and **slope** (decrement) values - Add a table and select columns you want (averages) -- <br> .pull-left[ <img src="ACU MHPS 2021/Images/Int Slope.png" width="95%" /> ] .pull-right[ <img src="ACU MHPS 2021/Images/Formula.png" width="110%" /> ] -- .footnote[ **References** <br> Delaney et al. (2017). Modelling the decrement in running intensity within professional soccer players. Science and Medicine in Football. <br> Duthie et al. (2018). Running intensities in elite youth soccer by age. Journla of Strength and Conditioning Research. ] --- # Formatting π¦ Colour code the table to reflect the intensity of each drill using **conditional formatting** rules - Below: 0-89% - At: 90-109% - Above: 110-129% - Above: 130%+ <br> <img src="ACU MHPS 2021/Images/Power BI formatting rules.png" width="50%" /> --- # Power BI report version 2 πΉ Alternatively, we can select other options such as data bars, icons, font colour etc <img src="ACU MHPS 2021/Images/Ticks.png" width="110%" /> --- # Useful Resources catapultR - http://catapultr.catapultsports.com/download_catapultR.html Mitch Henderson - https://www.mitchhenderson.org/ Alice Sweeting - http://sportstatisticsrsweet.rbind.io/ Josh Trewin - http://futbolanalysr.rbind.io/ Neil Collins - https://www.sportscidata.com/ Jose Fernandez - https://twitter.com/jfernandez__ --- class: center, middle # Thank you and good luck! ####
[heidi.thornton@goldcoastfc.com.au](mailto:heidi.thornton@goldcoastfc.com.au)<br> ####
[heidithornton09](https://twitter.com/heidithornton09)<br>