Skip to content

Instantly share code, notes, and snippets.

@holgerbrandl
Last active December 15, 2017 22:03
Show Gist options
  • Save holgerbrandl/5595165 to your computer and use it in GitHub Desktop.
Save holgerbrandl/5595165 to your computer and use it in GitHub Desktop.
Analyze RunKeeper tracks with R
## Inspired by
#http://runkeeper.com/download/activity?activityId=181462294&downloadType=googleEarth
#http://cnr.lwlss.net/GarminR/
#install.packages("lubridate")
library(XML)
library(plyr)
library(lubridate)
library(stringr)
library(ggplot2)
# setwd("/Users/holger/Dropbox/projects/runkeeper_analysis")
filename="http://dl.dropboxusercontent.com/u/422074/RK_gpx%20_2013-05-16_1709.gpx"
### Parse the xml's into a dataframe
doc=xmlParse(filename,useInternalNodes=TRUE)
trkDataRaw <- ldply(xpathSApply(doc, "//*[local-name()='trkpt']"), function(x) unlist(xmlToList(x)))
colnames(trkDataRaw)=c("Elevation","DateTime","Latitude", "Longitude")
trkData <- data.frame(DateTime=trkDataRaw$DateTime, colwise(as.numeric, .(Elevation, Latitude, Longitude))(trkDataRaw))
trkData$Activity <- "tt"
## convert times to seconds since the start of the run
trkData <- ddply(trkData, .(Activity), mutate, Time=str_match(DateTime, "T(.*)Z")[,2], TimeSec=period_to_seconds(hms(Time)), TimeSinceStart=TimeSec-TimeSec[1])
trkData$Time <- NULL; trkData$TimeSec <- NULL;
## add the next frame for difference calculation
trkData <- ddply(trkData, .(Activity), transform, NextLatiude=c(Latitude[-1], NA), NextLongitude=c(Longitude[-1], NA), NextTimeSinceStart=c(TimeSinceStart[-1], NA))
## The following program computes the distance on the surface of the earth between two points point1 and point2. Both the points are of the form (Longitude, Latitude)
## http://www.biostat.umn.edu/~sudiptob/Software/distonearth.R
geodetic.distance <- function(point1, point2) {
R <- 6371000
p1rad <- point1 * pi/180
p2rad <- point2 * pi/180
d <- sin(p1rad[2])*sin(p2rad[2])+cos(p1rad[2])*cos(p2rad[2])*cos(abs(p1rad[1]-p2rad[1]))
d <- acos(d)
R*d
}
## calculate the distances
trkData <- adply(trkData, 1, with, c(distance=geodetic.distance(c(Longitude, Latitude), c(NextLongitude, NextLatiude))))
## calculate speed
trkData <- trkData[complete.cases(trkData),]
trkData <- mutate(trkData, speed=distance/(NextTimeSinceStart-TimeSinceStart), smooth_speed=fitted(smooth.spline(TimeSinceStart, speed)))
ggplot(trkData, aes(TimeSinceStart/60, smooth_speed*3.6)) + geom_smooth() + ggtitle("Joint training speed profile") + ylab("km/h") +xlab("min")
ggplot(trkData, aes(TimeSinceStart/60, 60/(smooth_speed*3.6))) + geom_smooth() + ggtitle("Joint training speed profile") + ylab("pace") +xlab("min")
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment