Skip to content

Instantly share code, notes, and snippets.

@danielecook
Last active January 16, 2017 17:47
Show Gist options
  • Star 3 You must be signed in to star a gist
  • Fork 2 You must be signed in to fork a gist
  • Save danielecook/6c555937144d4955073b to your computer and use it in GitHub Desktop.
Save danielecook/6c555937144d4955073b to your computer and use it in GitHub Desktop.
This R Script will plot all of your runkeeper data. It uses cluster analysis to group activities by location as needed, and outputs a graph for each location. For example - I have run in Iowa City, Boston, and Chicago - and this script is able to identify those locations and output separately.
# Special thanks for insights from flowingdata.com regarding this.
library(plotKML)
library(plyr)
library(dplyr)
library(fpc)
num_locations <- 5
# Usage: Place this script in the directory containing your runkeeper data. You can run from terminal using 'Rscript map_runkeeper.R', or
# set your working directory to the location and run within RStudio (use setwd("~/location/of/runkeeper/data")).
# See below on how to set the number of clusters.
# GPX files downloaded from Runkeeper
files <- dir(pattern = "\\.gpx")
# Generate vectors for data frame
index <- c()
latitude <- c()
longitude <- c()
file <- c()
c <- 1 # Set up Counter
#
for (f in 1:length(files)) {
curr_route <- readGPX(files[f])
# Treat interrupted GPS paths as seperate routes (useful if you occasionally stop running..walk for a bit, and start again like I do.)
for (i in curr_route$tracks[[1]]) {
c <- c + 1
location <- i
file <- c(file,rep(files[f], dim(location)[1]))
index <- c(index, rep(c, dim(location)[1]))
latitude <- c(latitude, location$lat)
longitude <- c(longitude, location$lon)
}
}
routes <- data.frame(cbind(index, latitude, longitude,file))
# Because the routes dataframe takes a while to generate for some folks - save it!
save(routes, file="routes.Rdata")
# Use to load as needed.
load("routes.Rdata")
# Fix data types
routes$file <- as.character(routes$file)
routes$latitude <- as.numeric(levels(routes$latitude)[routes$latitude])
routes$longitude <- as.numeric(levels(routes$longitude)[routes$longitude])
routes <- transform(routes, index = as.numeric(index))
# Load Meta Data
meta_data <- read.csv("cardioActivities.csv", stringsAsFactors=FALSE)
meta_data <- rename(meta_data, c("GPX.File" = "file"))
# Bind routes
routes <- left_join(routes, meta_data, by="file") %.%
arrange(index)
# Use this function specify activity color if you have multiple activities.
activity_color <- function(activity) {
if (activity=="Cycling") {
color = "#00000060"
} else if (activity=="Hiking") {
color = "#00000060"
} else {
color = "#0080ff60"
}
color
}
# Identify clusters of points, which will correspond to locations you have run. For example,
# I have run in Boston, Iowa City, Chicago, and a few other cities. You will want to set the minimum krange
# to the number of cities you have run in (5 in my case).
clusters <- pamk(routes[,c("latitude", "longitude")], krange=num_locations:20, diss=T, usepam=F)$pamobject$medoids
# Plot Everything
for (r in 1:max(row(clusters))) {
print(r)
lat_range <- clusters[r,][1] + rnorm(20, sd=0.1)
lon_range <-clusters[r,][2] + rnorm(20, sd=0.1)
setroutes <- filter(routes, (latitude > min(lat_range) & latitude < max(lat_range)),
longitude > min(lon_range) & longitude < max(lon_range))
routeIds <- unique(setroutes$index)
# Albers projection
locProj <- mapproject(setroutes$longitude, setroutes$latitude, "rectangular", par=38)
setroutes$latproj <- locProj$x
setroutes$lonproj <- locProj$y
# Map the projected points
pdf(sprintf("%s-all.pdf", r))
plot(setroutes$latproj, setroutes$lonproj, type="n", asp=1, axes=FALSE, xlab="", ylab="")
for (i in routeIds) {
currRoute <- subset(setroutes, index==i)
lines(currRoute$latproj, currRoute$lonproj, col=activity_color(currRoute$Type), lwd=0.4)
}
dev.off()
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment