Alright, let’s see what we can do here. Too much iris
could be boring, so I thought I’d contribute some data by myself. Since my fitbit stopped working early this year, I’ve switched back to my old Garmin forerunner 10, and it turns out that you can downlowd .csv file of previous activities through Garmin connect. Now that’s pretty cool - I’ll just use this data.
The data
library(tidyverse)
library(lubridate)
library(plotly)
input_df <- read_csv("../../static/data/Activities.csv",
na=c("--"),
col_types=list(
Time=col_character(),
`Avg Pace`=col_character(),
`Best Pace`=col_character()))
This is a shabby Forerunner 10 so I don’t get all those fancy metrics such as heart rate and stride. So I’ll remove those useless empty columns. As always, date / time is a mess, so I’ll also manually clean up the duration and pace columns. Let’s see if DT works after cleaning up the data.
df <- input_df[c("Date", "Title", "Distance", "Time", "Avg Pace", "Best Pace", "Elev Gain", "Elev Loss")] %>%
# Time is the duration of runs. Make it numeric and rename to Duration
separate(Time, c("H", "M", "S"), sep=":", fill="left") %>%
replace_na(list(H="0", M="0", S="0")) %>%
mutate(Duration=as.numeric(H) + as.numeric(M) / 60 + as.numeric(S) / 3600) %>%
select(-c(H, M, S)) %>%
# Avg Pace should use unit minute
separate(`Avg Pace`, c("M", "S"), sep=":", fill="left") %>%
replace_na(list(M="0", S="0")) %>%
mutate(`Avg Pace`=as.numeric(M) + as.numeric(S) / 60) %>%
select(-c(M, S)) %>%
# Best Pace should also use unit minute
separate(`Best Pace`, c("M", "S"), sep=":", fill="left") %>%
replace_na(list(M="0", S="0")) %>%
mutate(`Best Pace`=as.numeric(M) + as.numeric(S) / 60) %>%
select(-c(M, S)) %>%
filter(Distance > 0)
# there's this one time I forgot to turn the watch off, and it ended up giving rediculous duration. Remove...
df <- df[df$Date != as_datetime("2017-07-26 08:29:41 UTC"), ]
# Title contains location, parse it out
df <- df %>%
mutate(Location=gsub(" Running", "", Title)) %>%
mutate(Location=ifelse(.$Location == "Untitled", "Durham", .$Location))
# That's pretty much all the cleaning.
DT::datatable(df, options = list(pageLength = 5, scrollX = TRUE))
Make some plots
Has my distance improved? Looks like so.
ggplot(df, aes(Date, Distance)) +
geom_point(aes(color=Location), alpha=0.8) +
theme_light()
Has my pace improved? Not very obvious. Anyways I just want to see if plotly works, so let’s add some text labels.
p <- ggplot(df, aes(Date, `Avg Pace`)) +
geom_point(aes(color=Location,
size=Distance,
text=sprintf("Distance: %skm\nDuration: %sh\nElev Gain: %sm\nElev Loss: %sm", round(Distance, 2), round(Duration,2), `Elev Gain`, `Elev Loss`)),
alpha=0.5) +
geom_smooth(method="loess", span=0.1, se=FALSE, color="orangered", size=0.4) +
ylim(c(4, 10)) +
theme_light()
ggplotly(p, tooltip=c("text", "colour"))
So plotly does work.
Side Notes
blogdown
is pretty easy to use. Yesterday I read the first chapter of theblogdown
book, bought this domain name, registered an account at netlify, typed like 5blogdown
commands, pushed the site to github, linked the repo to netlify and that’s it. I still know nothing about Hugo, which I’m going to learn about in the second chapter of theblogdown
book.I recently realized a lot of R related tools I use are authored by Yihui Xie, 谢益辉, including
knitr
,xaringan
, and thisblogdown
. Looked through his blog over the past like 10 years. 这是个人才啊。