Hawkin Dynamics Blog

Dive Deeper into hawkinR

Written by Lauren Green | Nov 3, 2023 5:24:00 PM

Downloading R and RStudio

If you are new to R and want to start on your journey of learning to program with R, you can visit the Posit (the creators of RStudio) website to download R and RStudio. It is a pretty straightforward download process with plenty of documentation for Windows, Mac, and Linux users on the site.

Installing Packages

If you are new to programming you might be wondering what a package is and why we created a special one for Hawkin Dynamics. A package can be looked at as a mini software inside of the program. Packages are a downloadable group of functions (scripted actions and calculations) that are meant to save the user time and make certain repeated processes much easier and more efficient. And that is exactly why we created the hawkinR package. Accessing and organizing your data would take the use of multiple other packages and 10s to hundreds of lines of code, which we were able to reduce to single lines of code with our package.

R is maintained by an international team of developers who make the language available through the web page of The Comprehensive R Archive Network, or CRAN. Most of the packages you will utilize in R can be accessed through CRAN and installed on your machine directly from there. However, this requires a lengthy review process to get packages into the repository. Luckily, the use of packages like devtools and sites like GitHub allows us to provide our development version of the package to users directly.

To access and download the hawkinR package, you can simply copy the script into your console.

# install.packages("devtools")
devtools::install_github("HawkinDynamics/hawkinR")

 

Getting Your Data

hawkinR provides simple functionality with the Hawkin Dynamics API. These functions are for use with 'Hawkin Dynamics Beta API' version 1.8-beta. You must be a Hawkin Dynamics user with an active integration account to utilize functions within the package.

This package was meant to help execute requests to the Hawkin Dynamics API with a single line of code. There are 11 functions to help execute 4 primary objectives:

  • Get Access: get_access() Handles authentication by entering your secret integration key
  • Get Test Types: get_testTypes() Returns all the tests in the HD system and their unique IDs
  • Get Organization data:
    • get_teams() Returns all the teams in your organization
    • get_groups() Returns all the groups in your organization
    • get_athletes() Returns all the athletes in your organization
  • Get Test Data
    • get_tests() Returns all the tests in your database and can be filtered by a date range. Can also be set to sync = TRUE, to only call new tests or updated tests in a given time period.
    • get_tests_type() Returns only tests of the specified test type, and can also be filtered to a given time range.
    • get_tests_ath() Returns only tests from the specified athlete, and can also be filtered to a given time range.
    • get_tests_team() Returns only tests from the specified team/s, and can also be filtered to a given time range.
    • get_tests_group() Returns only tests from the specified group/s, and can also be filtered to a given time range.
    • get_forcetime() Returns a data frame of the time, force, and calculated metrics of the provided test. Used to plot the tests' force-time data as is shown in the app/cloud.

Using these functions in just a few lines of code, you can manipulate and visualize your data in any way imaginable.

 

Loading Libraries

Whenever you start a new R session, we need to load the necessary packages into the session. All though you have already installed the packages, you still have to let the system know which of our installed packages you are going to use for this session. It’s like getting your starting lineup for the game ready. You have all the players on your team, but you need to decide who you need today to execute the game plan.

1. Get Access

To get into your organization through the API, the first thing you need to do is get an access token. Our API uses an authorization style called “Bearer token”. This essentially means that you have to provide the secret integration key that was created by your site and enter that so the system can give you a temporary access token. This helps keep things secure by changing the access token every hour. Meaning that there is no static password to gain access to your data.

As you can see, if the call is successful, you will receive a confirmation message with an expiration time. We have set up the package so that you don’t have to manually save the access token and enter it again with each subsequent call. The access token is actually saved to the R session and can be retrieved by the other functions when used. If the access token is expired, you will simply get a message that it is no longer valid, and to run the get_access() function again.

# Get Access - - - - -

# This function only needs to be executed 1 time and provides access for 1 hour

# The `region` parameter is default to "Americas", and does not need to be included if your site is in this region. Other regions ("Europe", "Asia/Pacific") would need to specify

# Input your secret integration key where I have 'secretKey'
get_access(secretKey, region = "Americas")

## [1] "Success! Your access token was received and stored for use by other hawkinR functions. Your token will expire at 2023-11-03 13:57:24"

 

Known Identities

Next, you want to make sure you have all of your identifiers in order to create your data model so that you can sort and filter your data as you like. Our identifiers are things like our roster, teams, and groups. If you have specific test variations you use and manage without ‘tags’ functionality, this might be a good time to organize those as well.

 

Test Types

To start, you can pull in the different test types and their unique IDs. This will give you the 9 different test types available in the HD system, and their unique Ids. Which will come in handy when you want to call tests by type or filter by test type.

# Get Test IDs - - - - -

# Returns a data frame of HD test types and their unique IDs
testIds <- get_testTypes()

 

NAME

ID

Countermovement Jump

7nNduHeM5zETPjHxvm7s

Squat Jump

QEG7m7DhYsD6BrcQ8pic

Isometric Test

2uS5XD5kXmWgIZ5HhQ3A

Drop Jump

gyBETpRXpdr63Ab2E0V8

Free Run

5pRSUQVSJVnxijpPMck3

CMJ Rebound

pqgf2TPUOQOQs6r0HQWb

Multi Rebound

r4fhrkPdYlLxYQxEeM78

Weigh In

ubeWMPN1lJFbuQbAM97s

Drop Landing

rKgI4y3ItTAzUekTUpvR

 

Athletes

An obvious step would be to pull in your athletes. You can bring in all the active athletes in your system by default, or you can include inactive athletes as well by setting inactive = TRUE.

## Get Roster Data - - - - -

# Parameter 'inactive=FALSE' not shown. Can set to TRUE to include inactive
Roster <- get_athletes()    

ID

NAME

ACTIVE

TEAMS

GROUPS

0kEjAzSLpBwUZc4Yp2Ov

Athlete 1

TRUE

Team1

Group1,Group2

1E1zYBv0CKbrKnsKz1vj

Athlete 2

TRUE

Team1

Group1

1lXEZKkNuNwvMLXiqFRr

Athlete 3

TRUE

Team1,Team2

Group2

2JmTLzF3b2y0XyfFHNwJ

Athlete 4

TRUE

Team2

Group1,Group2

34qIsu5IACUtk5nomQqd

Athlete 5

TRUE

Team1,Team2

Group2

 

Teams & Groups

For more detailed sorting and filtering ability, you can also bring in your Teams and Groups. Each team and group you create in your organization is assigned a unique ID as well. This helps eliminate errors with misspellings or redundancy issues.

## Get Teams data - - - - - 

# Returns data frame of team names and IDs
Teams <- get_teams()    

ID

NAME

DPMb6ek2mgUNVcg8siSqpnIvE2i2

Team1

KBHev5JXD9YY1Xz5zmSp

Team2

## Get Groups -----

# Returns data frame of group names and IDs
Groups <- get_groups()    

ID

NAME

6zQBrZ4PJ14JeKDJ68aA

Group1

FMlGcJZ4xbH2YTEbZWkk

Group2

 

Sorting Teams and Groups

One of the advantages of the HD Cloud and the HD software as a whole is the flexibility to manage your athletes in infinite ways. Being able to have an athlete or athletes, in multiple teams and groups allows for the practitioner to sort, analyze, and compare these different groupings of athletes in any way they would need to for any circumstance they face.

However, this can be an issue when pulling the data into other systems. To overcome this challenge, it might be helpful to create separate rosters for each of your teams. This isn’t always needed but could be helpful when pulling your data into other data management systems like Power BI.

Teams

teamList <- data.frame(
      Name = c()
)
## Team Rosters - - - - -
for (i in seq_along(Teams$id)) {

     # Extract the current group ID
      team_id <- Teams$id[i]

    # Filter Roster for athletes belonging to the current group
    teamRost <- Roster %>%
         filter(str_detect(teams, team_id)) %>%
         mutate("teamID" = team_id) %>%
         select(name,id, teamID)

     # Create a name to be assigned to the group roster from group[i]
     teamName <- paste0("t_",tidy_names(Teams$name[i], syntactic = TRUE))

     # Assign the filtered roster to a new group name
     assign(teamName, teamRost, envir = .GlobalEnv)

     teamList <- rbind(teamList, data.frame(Name = teamName))
}

NAME

t_Greenhouse.Performance

t_St..John.Bosco.Baseball

t_Test.Team

Groups

groupList <- data.frame(Name = c())

## Group Rosters - - - - -
for (i in seq_along(Groups$id)) {

      # Extract the current group ID
      group_id <- Groups$id[i]

      # Filter Roster for athletes belonging to the current group
      grpRost <- Roster %>%
            filter(str_detect(groups, group_id)) %>%
            mutate("grpID" = group_id) %>%
            select(name,id, grpID)

      # Create a name to be assigned to the group roster from group[i]
      grpName <- paste0("g_",tidy_names(Groups$name[i], syntactic = TRUE))

      # Assign the filtered roster to a new group name
      assign(grpName, grpRost, envir = .GlobalEnv)

      groupList <- rbind(groupList, data.frame(Name = grpName))
}

Name

g_Class24

g_INF

g_Baseball

g_Class28

g_Class26

g_Another.Group

g_Class25

g_Pitchers

g_Catchers

g_OF

g_Class27

g_Testing

 

Test Data

This is the most obvious and important step. How do I get all my tests and results so I can organize and analyze them? As you saw above, there are a few functions that allow you to call your test data in with different filtering emphases. However it is good to note that queries that are specific to a test type will only include the metrics accounted for with that test. While queries that do not include a specific test type will include all metrics for all tests, including NULL values in cases where those metrics don’t apply.

For that reason, I think it is best to utilize the get_tests_type() function so that you can make a data frame for each test type. This allows for a much more clear view of the data for each test type, and a more manageable list of variables for each.

# Test Data -----
for (i in seq_along(testIds$id)) {

    # Extract current test type Id
    test_id <- testIds$id[i]

    # call for tests of type test_id
    df <- get_tests_type( typeId = test_id ) %>%
       mutate("date" = with_tz(as_datetime(timestamp),tzone = Sys.timezone())) %>%
       select(-c(athlete.teams,athlete.groups)) %>%
       select(id, timestamp,date, everything())

    # Create a name to be assigned to the test data frame
    dfName <- paste0(tidy_names(testIds$name[i], syntactic = TRUE))

    # Assign the test data to a data frame with the given test name
    assign(dfName, df, envir = .GlobalEnv)


}

 

We hope you enjoy hawkinR and please reach out if you need any help or have questions! We’ve always got you covered.