[This article was first published on Rcrastinate, and kindly contributed to R-bloggers]. (You can report issue about the content on this page here)
Want to share your content on R-bloggers? click here if you have a blog, or here if you don't.
Here is some updated R code from my previous post. It doesn’t throw any warnings when importing tracks with and without heart rate information. Also, it is easier to distinguish types of tracks now (e.g., when you want to plot runs and rides separately). Another thing I changed: You get very basic information on the track when you click on it (currently the name of the track and the total length).Want to share your content on R-bloggers? click here if you have a blog, or here if you don't.
Have fun and leave a comment if you have any questions.
options(stringsAsFactors = F)
rm(list=ls())
library(httr)
library(rjson)
library(leaflet)
library(dplyr)
token <- “<your Strava API token>”
# Functions —————————————————————
get.coord.df.from.stream <- function (stream.obj) {
data.frame(lat = sapply(stream.obj[[1]]$data, USE.NAMES = F, FUN = function (x) x[[1]]),
lon = sapply(stream.obj[[1]]$data, USE.NAMES = F, FUN = function (x) x[[2]]))
}
get.stream.from.activity <- function (act.id, token) {
stream <- GET(“https://www.strava.com/”,
path = paste0(“api/v3/activities/”, act.id, “/streams/latlng”),
query = list(access_token = token))
content(stream)
}
get.activities2 <- function (token) {
activities <- GET(“https://www.strava.com/”, path = “api/v3/activities”,
query = list(access_token = token, per_page = 200))
activities <- content(activities, “text”)
activities <- fromJSON(activities)
res.df <- data.frame()
for (a in activities) {
values <- sapply(c(“name”, “distance”, “moving_time”, “elapsed_time”, “total_elevation_gain”,
“type”, “id”, “start_date_local”,
“location_country”, “average_speed”, “max_speed”, “has_heartrate”, “elev_high”,
“elev_low”, “average_heartrate”, “max_heartrate”), FUN = function (x) {
if (is.null(a[[x]])) {
NA } else { a[[x]] }
})
res.df <- rbind(res.df, values)
}
names(res.df) <- c(“name”, “distance”, “moving_time”, “elapsed_time”, “total_elevation_gain”,
“type”, “id”, “start_date_local”,
“location_country”, “average_speed”, “max_speed”, “has_heartrate”, “elev_high”,
“elev_low”, “average_heartrate”, “max_heartrate”)
res.df
}
get.multiple.streams <- function (act.ids, token) {
res.list <- list()
for (act.id.i in 1:length(act.ids)) {
if (act.id.i %% 5 == 0) cat(“Actitivy no.”, act.id.i, “of”, length(act.ids), “\n”)
stream <- get.stream.from.activity(act.ids[act.id.i], token)
coord.df <- get.coord.df.from.stream(stream)
res.list[[length(res.list) + 1]] <- list(act.id = act.ids[act.id.i],
coords = coord.df)
}
res.list
}
activities <- get.activities2(token)
stream.list <- get.multiple.streams(activities$id, token)
# Leaflet —————————————————————–
lons.range <- c(9.156572, 9.237580)
lats.range <- c(48.74085, 48.82079)
map <- leaflet() %>%
addProviderTiles(“OpenMapSurfer.Grayscale”, # nice: CartoDB.Positron, OpenMapSurfer.Grayscale, CartoDB.DarkMatterNoLabels
options = providerTileOptions(noWrap = T)) %>%
fitBounds(lng1 = min(lons.range), lat1 = max(lats.range), lng2 <- max(lons.range), lat2 = min(lats.range))
add.run <- function (act.id, color, act.name, act.dist, strlist = stream.list) {
act.ind <- sapply(stream.list, USE.NAMES = F, FUN = function (x) {
x$act.id == act.id
})
act.from.list <- strlist[act.ind][[1]]
map <<- addPolylines(map, lng = act.from.list$coords$lon,
lat = act.from.list$coords$lat,
color = color, opacity = 1/3, weight = 2,
popup = paste0(act.name, “, “, round(as.numeric(act.dist) / 1000, 2), ” km”))
}
# plot all
for (i in 1:nrow(activities)) {
add.run(activities[i, “id”], ifelse(activities[i, “type”] == “Run”, “red”,
ifelse(activities[i, “type”] == “Ride”, “blue”, “black”)),
activities[i, “name”], activities[i, “distance”])
}
map
To leave a comment for the author, please follow the link and comment on their blog: Rcrastinate.
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.