Last active
December 15, 2017 22:03
-
-
Save holgerbrandl/5595165 to your computer and use it in GitHub Desktop.
Analyze RunKeeper tracks with R
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
## 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