|
@@ -0,0 +1,419 @@
|
|
|
|
+---
|
|
|
|
+title: "2017 Weight Challenge"
|
|
|
|
+author: "Will Koehrsen"
|
|
|
|
+date: "January 7, 2018"
|
|
|
|
+output: html_document
|
|
|
|
+---
|
|
|
|
+
|
|
|
|
+```{r setup, include=FALSE}
|
|
|
|
+knitr::opts_chunk$set(echo = TRUE)
|
|
|
|
+library(googlesheets)
|
|
|
|
+library(tidyverse)
|
|
|
|
+library(slackr)
|
|
|
|
+library(ggthemes)
|
|
|
|
+library(gganimate)
|
|
|
|
+library(prophet)
|
|
|
|
+```
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+# Formatting and Cleaning Weights
|
|
|
|
+
|
|
|
|
+```{r}
|
|
|
|
+weights <- read_csv('weight_data.csv')
|
|
|
|
+# Convert to date only
|
|
|
|
+craig_weights <- weights %>% dplyr::filter(name == 'Craig') %>% arrange(date) %>%
|
|
|
|
+ dplyr::filter(date < as.Date('2018-01-07'))
|
|
|
|
+will_weights <- weights %>% dplyr::filter(name == 'Will') %>% arrange(date) %>%
|
|
|
|
+ dplyr::filter(date < as.Date('2018-01-07'))
|
|
|
|
+
|
|
|
|
+weights <- rbind(craig_weights, will_weights)
|
|
|
|
+```
|
|
|
|
+
|
|
|
|
+# Data Manipulation
|
|
|
|
+We want to have a column representing the weight changes. Therefore we first need
|
|
|
|
+to find the starting weighting for both participants.
|
|
|
|
+
|
|
|
|
+```{r}
|
|
|
|
+# Baseline weights
|
|
|
|
+craig_start <- craig_weights$weight[1]
|
|
|
|
+will_start <- will_weights$weight[1]
|
|
|
|
+
|
|
|
|
+# Create a column of weight changes
|
|
|
|
+weight_change <- function(row) {
|
|
|
|
+ if(row[2] == 'Craig') {
|
|
|
|
+ return(craig_start - as.numeric(row[3]))
|
|
|
|
+ } else {
|
|
|
|
+ return(as.numeric(row[3]) - will_start)
|
|
|
|
+ }
|
|
|
|
+}
|
|
|
|
+weights$change <- apply(weights, MARGIN = 1, FUN = weight_change)
|
|
|
|
+
|
|
|
|
+# Create a column of percentage weight changes
|
|
|
|
+pct_weight_change <- function(row) {
|
|
|
|
+ if (row[2] == 'Craig') {
|
|
|
|
+ return(100 * (craig_start - as.numeric(row[3])) / craig_start)
|
|
|
|
+ } else {
|
|
|
|
+ return(100 * (as.numeric(row[3]) - will_start) / will_start)
|
|
|
|
+ }
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+weights$change_pct <- apply(weights, MARGIN = 1, FUN = pct_weight_change)
|
|
|
|
+
|
|
|
|
+```
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+# Plots
|
|
|
|
+
|
|
|
|
+Start off with a simple graph of the raw weights. We need two separate
|
|
|
|
+axes to represent the varying scales.
|
|
|
|
+
|
|
|
|
+```{r}
|
|
|
|
+ggplot(weights, aes(date)) +
|
|
|
|
+ geom_jitter(data = dplyr::filter(weights, name == 'Craig'),
|
|
|
|
+ aes(y = weight, col = "Craig"),shape = 2, size = 1.2) +
|
|
|
|
+ geom_line(data = dplyr::filter(weights, name == 'Craig'),
|
|
|
|
+ aes(y = weight, col = "Craig"), lwd = 1.2) +
|
|
|
|
+ geom_jitter(data = dplyr::filter(weights, name == 'Will'),
|
|
|
|
+ aes(y = 1.9 * weight, col = "Will"),shape = 2, size = 1.2) +
|
|
|
|
+ geom_line(data = dplyr::filter(weights, name == 'Will'),
|
|
|
|
+ aes(y = 1.9 * weight, col = "Will"), lwd = 1.2) +
|
|
|
|
+ scale_y_continuous(sec.axis = sec_axis(~.*(1/1.9), name = 'Will Weight (lbs)',
|
|
|
|
+ breaks = seq(115, 145, 10)),
|
|
|
|
+ breaks = seq(215, 280, 10), limits = c(215, 275)) +
|
|
|
|
+ scale_color_manual(values = c("midnightblue", "red3"), labels = c('Craig', 'Will')) +
|
|
|
|
+ xlab("") + ylab('Craig Weight (lbs)') +
|
|
|
|
+ labs(color = "Name") + ggtitle("Weight Challenge") +
|
|
|
|
+ theme(axis.text.y = element_text(color = "midnightblue"),
|
|
|
|
+ axis.text.y.right = element_text(color = 'red3')) +
|
|
|
|
+ theme_hc(14)
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+ggplot(weights, aes(date)) +
|
|
|
|
+ geom_point(data = dplyr::filter(weights, name == 'Craig'),
|
|
|
|
+ aes(y = weight, col = "Craig"), size = 2.5) +
|
|
|
|
+ geom_point(data = dplyr::filter(weights, name == 'Will'),
|
|
|
|
+ aes(y = 1.82 * weight, col = "Will"),size = 2.5) +
|
|
|
|
+ scale_y_continuous(sec.axis = sec_axis(~.*(1/1.82), name = 'Will Weight (lbs)',
|
|
|
|
+ breaks = seq(110, 140, 5)),
|
|
|
|
+ breaks = seq(215, 255, 5), limits = c(215, 255)) +
|
|
|
|
+ scale_color_manual(values = c('midnightblue', 'red3'), labels = c('Craig', 'Will')) +
|
|
|
|
+ xlab("") + ylab('Craig Weight (lbs)') +
|
|
|
|
+ labs(color = "") + ggtitle("Full Weight Challenge Results") +
|
|
|
|
+ theme_classic(14) +
|
|
|
|
+ theme(axis.text.y = element_text(color = "midnightblue"),
|
|
|
|
+ axis.text.y.right = element_text(color = 'red3'),
|
|
|
|
+ axis.title.y = element_text(color = 'midnightblue'),
|
|
|
|
+ axis.title.y.right = element_text(color = 'red3'),
|
|
|
|
+ legend.position = 'bottom',
|
|
|
|
+ plot.title = element_text(hjust = 0.5, size = 16),
|
|
|
|
+ axis.text.x = element_text(color = 'black')) +
|
|
|
|
+ geom_smooth(data = dplyr::filter(weights, name == 'Craig'),
|
|
|
|
+ aes(y = weight, col = "Craig"), lwd = 1.6) +
|
|
|
|
+ geom_smooth(data = dplyr::filter(weights, name == 'Will'),
|
|
|
|
+ aes(y = 1.82 * weight, col = "Will"), lwd = 1.6)
|
|
|
|
+```
|
|
|
|
+
|
|
|
|
+We can make plots of the changes in absolute terms to see who
|
|
|
|
+was winning at each stage.
|
|
|
|
+
|
|
|
|
+```{r}
|
|
|
|
+# Absolute change
|
|
|
|
+ggplot(weights, aes(date, change, group = name, col = name)) +
|
|
|
|
+ geom_point(size = 2) +
|
|
|
|
+ scale_color_manual(values = c('midnightblue', 'red3'), labels = c('Craig', 'Will')) +
|
|
|
|
+ xlab('') + ylab('Change (lbs)') + ggtitle('Absolute Weight Change') +
|
|
|
|
+ labs(color = '') + coord_cartesian(ylim = c(0, 20)) +
|
|
|
|
+ theme_classic(14) + theme(legend.position = 'bottom',
|
|
|
|
+ plot.title = element_text(hjust = 0.5,
|
|
|
|
+ size = 16),
|
|
|
|
+ axis.text = element_text(color = 'black'),
|
|
|
|
+ panel.grid.major.y = element_line()) +
|
|
|
|
+ geom_smooth()
|
|
|
|
+
|
|
|
|
+# Percentage change
|
|
|
|
+ggplot(weights, aes(date, round(change_pct, 1), group = name, col = name)) +
|
|
|
|
+ geom_jitter(size = 2) + geom_smooth() +
|
|
|
|
+ scale_color_manual(values = c('midnightblue', 'red3'), labels = c('Craig', 'Will')) +
|
|
|
|
+ xlab('') + ylab('Change %') + ggtitle('Absolute Weight Change Percentage') +
|
|
|
|
+ labs(color = '') + coord_cartesian(ylim = c(0, 10)) +
|
|
|
|
+ theme_classic(14) +
|
|
|
|
+ theme(legend.position = 'bottom',
|
|
|
|
+ plot.title = element_text(hjust = 0.5,
|
|
|
|
+ size = 16),
|
|
|
|
+ axis.text = element_text(color = 'black'),
|
|
|
|
+ panel.grid.major.y = element_line())
|
|
|
|
+
|
|
|
|
+```
|
|
|
|
+
|
|
|
|
+Quantitative results.
|
|
|
|
+
|
|
|
|
+```{r}
|
|
|
|
+craig_final <- dplyr::filter(weights, name == 'Craig' & date == '2018-01-06')
|
|
|
|
+will_final <- dplyr::filter(weights, name == 'Will' & date == '2018-01-06')
|
|
|
|
+
|
|
|
|
+final_results <- rbind(craig_final, will_final) %>% select(name, weight, change,
|
|
|
|
+ change_pct)
|
|
|
|
+
|
|
|
|
+knitr::kable(final_results)
|
|
|
|
+```
|
|
|
|
+
|
|
|
|
+# Modeling
|
|
|
|
+
|
|
|
|
+## Linear Models
|
|
|
|
+
|
|
|
|
+```{r}
|
|
|
|
+# Days since start of competition
|
|
|
|
+craig_weights$days <- as.numeric(lubridate::yday(craig_weights$date) -
|
|
|
|
+ lubridate::yday(craig_weights$date)[1])
|
|
|
|
+# Create a simple linear model
|
|
|
|
+craig_lm <- lm(weight ~ days, craig_weights)
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+will_weights$days <- as.numeric(lubridate::yday(will_weights$date) -
|
|
|
|
+ lubridate::yday(will_weights$date)[1])
|
|
|
|
+will_lm <- lm(weight ~ days, will_weights)
|
|
|
|
+
|
|
|
|
+summary(craig_lm)
|
|
|
|
+
|
|
|
|
+summary(will_lm)
|
|
|
|
+```
|
|
|
|
+Plots of Linear Models
|
|
|
|
+
|
|
|
|
+```{r}
|
|
|
|
+ggplot(weights, aes(date)) +
|
|
|
|
+ geom_point(data = dplyr::filter(weights, name == 'Craig'),
|
|
|
|
+ aes(y = weight, col = "Craig"), size = 2.5) +
|
|
|
|
+ geom_point(data = dplyr::filter(weights, name == 'Will'),
|
|
|
|
+ aes(y = 1.82 * weight, col = "Will"),size = 2.5) +
|
|
|
|
+ scale_y_continuous(sec.axis = sec_axis(~.*(1/1.82), name = 'Will Weight (lbs)',
|
|
|
|
+ breaks = seq(110, 140, 5)),
|
|
|
|
+ breaks = seq(215, 255, 5), limits = c(215, 255)) +
|
|
|
|
+ scale_color_manual(values = c('midnightblue', 'red3'), labels = c('Craig', 'Will')) +
|
|
|
|
+ xlab("") + ylab('Craig Weight (lbs)') +
|
|
|
|
+ labs(color = "") + ggtitle("Weight Challenge Results with Linear Model") +
|
|
|
|
+ theme_classic(14) +
|
|
|
|
+ theme(axis.text.y = element_text(color = "midnightblue"),
|
|
|
|
+ axis.text.y.right = element_text(color = 'red3'),
|
|
|
|
+ axis.title.y = element_text(color = 'midnightblue'),
|
|
|
|
+ axis.title.y.right = element_text(color = 'red3'),
|
|
|
|
+ legend.position = 'bottom',
|
|
|
|
+ plot.title = element_text(hjust = 0.5, size = 16),
|
|
|
|
+ axis.text.x = element_text(color = 'black')) +
|
|
|
|
+ geom_smooth(data = dplyr::filter(weights, name == 'Craig'), method = 'lm',
|
|
|
|
+ aes(y = weight, col = "Craig"), lwd = 1.6) +
|
|
|
|
+ geom_smooth(data = dplyr::filter(weights, name == 'Will'), method = 'lm',
|
|
|
|
+ aes(y = 1.82 * weight, col = "Will"), lwd = 1.6)
|
|
|
|
+
|
|
|
|
+```
|
|
|
|
+
|
|
|
|
+Predictions for January 1, 2019
|
|
|
|
+
|
|
|
|
+```{r}
|
|
|
|
+# Find number of days between start of competition January 1, 2019
|
|
|
|
+days <- as.numeric(as.Date('2019-01-01') - craig_weights$date[1])
|
|
|
|
+
|
|
|
|
+craig_prediction <- predict(craig_lm,
|
|
|
|
+ data.frame(days = days, name = 'Craig', plot = TRUE),
|
|
|
|
+ interval = 'predict')
|
|
|
|
+
|
|
|
|
+will_prediction <- predict(will_lm,
|
|
|
|
+ data.frame(days = days, name = 'Will', plot = TRUE),
|
|
|
|
+ interval = 'predict')
|
|
|
|
+
|
|
|
|
+```
|
|
|
|
+
|
|
|
|
+## Generalized Additive Model
|
|
|
|
+
|
|
|
|
+```{r}
|
|
|
|
+craig_weights$ds <- craig_weights$date
|
|
|
|
+craig_weights$y <- craig_weights$weight
|
|
|
|
+craig_gam <- prophet::prophet(craig_weights)
|
|
|
|
+
|
|
|
|
+will_weights$ds <- will_weights$date
|
|
|
|
+will_weights$y <- will_weights$weight
|
|
|
|
+will_gam <- prophet::prophet(will_weights)
|
|
|
|
+
|
|
|
|
+craig_forecast <- prophet::make_future_dataframe(craig_gam, periods = 365)
|
|
|
|
+craig_forecast <- predict(craig_gam, craig_forecast)
|
|
|
|
+prophet::prophet_plot_components(craig_gam, craig_forecast)
|
|
|
|
+
|
|
|
|
+will_forecast <- prophet::make_future_dataframe(will_gam, periods = 365)
|
|
|
|
+will_forecast <- predict(will_gam, will_forecast)
|
|
|
|
+prophet::prophet_plot_components(will_gam, will_forecast)
|
|
|
|
+
|
|
|
|
+will_forecast$name <- 'Will'
|
|
|
|
+craig_forecast$name <- 'Craig'
|
|
|
|
+forecast <- rbind(will_forecast, craig_forecast)
|
|
|
|
+```
|
|
|
|
+
|
|
|
|
+Predictions for January 1, 2018
|
|
|
|
+
|
|
|
|
+```{r}
|
|
|
|
+short_days <- as.numeric(as.Date('2018-01-01') - as.Date('2017-11-01'))
|
|
|
|
+craig_short_gam <- prophet::prophet(df = dplyr::filter(craig_weights, date < '2017-11-01'))
|
|
|
|
+craig_short_forecast <- prophet::make_future_dataframe(craig_short_gam, periods = short_days)
|
|
|
|
+craig_short_forecast <- predict(craig_short_gam, craig_short_forecast)
|
|
|
|
+
|
|
|
|
+will_short_gam <- prophet::prophet(df = dplyr::filter(will_weights, date < '2017-11-01'))
|
|
|
|
+will_short_forecast <- prophet::make_future_dataframe(will_short_gam, periods = short_days)
|
|
|
|
+will_short_forecast <- predict(will_short_gam, will_short_forecast)
|
|
|
|
+
|
|
|
|
+prophet::prophet_plot_components(craig_short_gam, craig_short_forecast)
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+ggplot(craig_short_forecast, aes(x = ds, y = trend)) +
|
|
|
|
+ geom_ribbon(data = dplyr::filter(craig_short_forecast, ds >= '2017-11-01'),
|
|
|
|
+ aes(ymin = trend_lower, ymax = trend_upper),
|
|
|
|
+ color = 'black', lwd = 1, fill = 'gainsboro') +
|
|
|
|
+ geom_line(color = 'red3', lwd = 1.8) + theme_classic(14) +
|
|
|
|
+ xlab('Date') + ylab('Weight (lbs)') +
|
|
|
|
+ ggtitle('Craig GAM Prediction for Jan 1, 2018') +
|
|
|
|
+ theme(axis.text = element_text(color = 'black'),
|
|
|
|
+ plot.title = element_text(hjust = 0.5, size = 18))
|
|
|
|
+
|
|
|
|
+ggplot(will_short_forecast, aes(x = ds, y = trend)) +
|
|
|
|
+ geom_ribbon(data = dplyr::filter(will_short_forecast, ds >= '2017-11-01'),
|
|
|
|
+ aes(ymin = trend_lower, ymax = trend_upper),
|
|
|
|
+ color = 'black', lwd = 1, fill = 'gainsboro') +
|
|
|
|
+ geom_line(color = 'red3', lwd = 1.8) + theme_classic(14) +
|
|
|
|
+ xlab('Date') + ylab('Weight (lbs)') +
|
|
|
|
+ ggtitle('Will GAM Prediction for Jan 1, 2018') +
|
|
|
|
+ theme(axis.text = element_text(color = 'black'),
|
|
|
|
+ plot.title = element_text(hjust = 0.5, size = 18))
|
|
|
|
+```
|
|
|
|
+
|
|
|
|
+Predictions for Jan 1, 2019
|
|
|
|
+
|
|
|
|
+```{r}
|
|
|
|
+ggplot(craig_forecast, aes(x = ds, y = trend)) +
|
|
|
|
+ geom_ribbon(data = dplyr::filter(craig_forecast, ds >= '2018-01-06'),
|
|
|
|
+ aes(ymin = trend_lower, ymax = trend_upper),
|
|
|
|
+ color = 'black', lwd = 1, fill = 'gainsboro') +
|
|
|
|
+ geom_line(color = 'red3', lwd = 1.8) + theme_classic(14) +
|
|
|
|
+ xlab('Date') + ylab('Weight (lbs)') +
|
|
|
|
+ ggtitle('Craig GAM Prediction for Jan 1, 2019') +
|
|
|
|
+ theme(axis.text = element_text(color = 'black'),
|
|
|
|
+ plot.title = element_text(hjust = 0.5, size = 18))
|
|
|
|
+
|
|
|
|
+ggplot(will_forecast, aes(x = ds, y = trend)) +
|
|
|
|
+ geom_ribbon(data = dplyr::filter(will_forecast, ds >= '2018-01-06'),
|
|
|
|
+ aes(ymin = trend_lower, ymax = trend_upper),
|
|
|
|
+ color = 'black', lwd = 1, fill = 'gainsboro') +
|
|
|
|
+ geom_line(color = 'red3', lwd = 1.8) + theme_classic(14) +
|
|
|
|
+ xlab('Date') + ylab('Weight (lbs)') +
|
|
|
|
+ ggtitle('Will GAM Prediction for Jan 1, 2019') +
|
|
|
|
+ theme(axis.text = element_text(color = 'black'),
|
|
|
|
+ plot.title = element_text(hjust = 0.5, size = 18))
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+```
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+Generalized Additive Model Graphs
|
|
|
|
+
|
|
|
|
+```{r}
|
|
|
|
+
|
|
|
|
+ggplot(forecast, aes(x = as.Date(ds))) +
|
|
|
|
+ geom_line(data = dplyr::filter(forecast, ds < '2018-01-07' & name == 'Craig'),
|
|
|
|
+ aes(y = trend, col = "Craig"), size = 1.4) +
|
|
|
|
+ geom_line(data = dplyr::filter(forecast, ds < '2018-01-07' & name == 'Will'),
|
|
|
|
+ aes(y = 1.82 * trend, col = "Will"),size = 1.4) +
|
|
|
|
+ scale_y_continuous(sec.axis = sec_axis(~.*(1/1.82), name = 'Will Weight (lbs)',
|
|
|
|
+ breaks = seq(110, 140, 5)),
|
|
|
|
+ breaks = seq(215, 255, 5), limits = c(215, 255)) +
|
|
|
|
+ scale_color_manual(values = c('midnightblue', 'red3'), labels = c('Craig', 'Will')) +
|
|
|
|
+ xlab("") + ylab('Craig Weight (lbs)') +
|
|
|
|
+ labs(color = "") + ggtitle("Overall Trends") +
|
|
|
|
+ theme_classic(14) +
|
|
|
|
+ theme(axis.text.y = element_text(color = "midnightblue"),
|
|
|
|
+ axis.text.y.right = element_text(color = 'red3'),
|
|
|
|
+ axis.title.y = element_text(color = 'midnightblue'),
|
|
|
|
+ axis.title.y.right = element_text(color = 'red3'),
|
|
|
|
+ legend.position = 'bottom',
|
|
|
|
+ plot.title = element_text(hjust = 0.5, size = 16),
|
|
|
|
+ axis.text.x = element_text(color = 'black'))
|
|
|
|
+
|
|
|
|
+craig_weekly_forecast <- dplyr::filter(forecast, name == 'Craig')[1:7, c('name', 'weekly')]
|
|
|
|
+will_weekly_forecast <- dplyr::filter(forecast, name == 'Will')[1:7, c('name', 'weekly')]
|
|
|
|
+weekly_forecast <- rbind(craig_weekly_forecast, will_weekly_forecast)
|
|
|
|
+weekly_forecast$day <- factor(rep(c('Sun', 'Mon', 'Tues', 'Wed', 'Thur', 'Fri', 'Sat'), 2),
|
|
|
|
+ levels = c('Mon', 'Tues', 'Wed', 'Thur', 'Fri', 'Sat', 'Sun'))
|
|
|
|
+
|
|
|
|
+ggplot(weekly_forecast, aes(x = day, y = weekly, color = name)) +
|
|
|
|
+ geom_line(aes(group = name), size = 1.4) + geom_point(size = 2) +
|
|
|
|
+ scale_color_manual(values = c('midnightblue', 'red3'), labels = c('Craig', 'Will')) +
|
|
|
|
+ xlab("") + ylab('Change (lbs)') +
|
|
|
|
+ labs(color = "") + ggtitle("Weekly Weight Trends") +
|
|
|
|
+ theme_classic(14) +
|
|
|
|
+ theme(axis.text = element_text(color = "black"),
|
|
|
|
+ axis.title = element_text(color = 'black'),
|
|
|
|
+ legend.position = 'bottom',
|
|
|
|
+ plot.title = element_text(hjust = 0.5, size = 16)) +
|
|
|
|
+ scale_y_continuous(lim = c(-1.0, 1.0), breaks = seq(-1.0, 1.0, 0.25))
|
|
|
|
+
|
|
|
|
+```
|
|
|
|
+Contrast models with reality
|
|
|
|
+```{r}
|
|
|
|
+ggplot(craig_short_forecast, aes(x = ds, y = trend)) +
|
|
|
|
+ geom_ribbon(data = dplyr::filter(craig_short_forecast, ds >= '2017-11-01'),
|
|
|
|
+ aes(ymin = trend_lower, ymax = trend_upper),
|
|
|
|
+ color = 'black', lwd = 1, fill = 'gainsboro') +
|
|
|
|
+ geom_line(aes(color = 'predicted'), lwd = 1.8) + theme_classic(14) +
|
|
|
|
+ xlab('Date') + ylab('Weight (lbs)') +
|
|
|
|
+ ggtitle('Craig Predicted vs Actual') +
|
|
|
|
+ theme(axis.text = element_text(color = 'black'),
|
|
|
|
+ plot.title = element_text(hjust = 0.5, size = 18)) +
|
|
|
|
+ geom_point(data = dplyr::filter(weights, name == 'Craig' & date <= '2018-01-01'),
|
|
|
|
+ aes(x = as.POSIXct(date), y = weight,
|
|
|
|
+ col = 'actual'), size = 2) + labs(color = '') +
|
|
|
|
+ scale_color_manual(values = c('red3', 'darkgreen'))
|
|
|
|
+
|
|
|
|
+ggplot(will_short_forecast, aes(x = ds, y = trend)) +
|
|
|
|
+ geom_ribbon(data = dplyr::filter(will_short_forecast, ds >= '2017-11-01'),
|
|
|
|
+ aes(ymin = trend_lower, ymax = trend_upper),
|
|
|
|
+ color = 'black', lwd = 1, fill = 'gainsboro') +
|
|
|
|
+ geom_line(aes(color = 'predicted'), lwd = 1.8) + theme_classic(14) +
|
|
|
|
+ xlab('Date') + ylab('Weight (lbs)') +
|
|
|
|
+ ggtitle('Will Predicted vs Actual') +
|
|
|
|
+ theme(axis.text = element_text(color = 'black'),
|
|
|
|
+ plot.title = element_text(hjust = 0.5, size = 18)) +
|
|
|
|
+ geom_point(data = dplyr::filter(weights, name == 'Will' & date <= '2018-01-01'),
|
|
|
|
+ aes(x = as.POSIXct(date), y = weight,
|
|
|
|
+ col = 'actual'), size = 2) + labs(color = '') +
|
|
|
|
+ scale_color_manual(values = c('red3', 'darkgreen'))
|
|
|
|
+```
|
|
|
|
+# Animations
|
|
|
|
+
|
|
|
|
+One of the most rewarding parts of a data analysis is animations!
|
|
|
|
+
|
|
|
|
+```{r}
|
|
|
|
+library(gganimate)
|
|
|
|
+weights$week <- lubridate::week(weights$date)
|
|
|
|
+weights[which(lubridate::year(weights$date) == '2018'), ]$week <- 53
|
|
|
|
+craig_trend <- dplyr::filter(craig_forecast, ds <= '2018-01-06')$trend
|
|
|
|
+will_trend <- dplyr::filter(will_forecast, ds <= '2018-01-06')$trend
|
|
|
|
+
|
|
|
|
+craig_trend_pct <- sapply(craig_trend, function(x) {return( abs(100 * (x - craig_start) / craig_start))})
|
|
|
|
+will_trend_pct <- sapply(will_trend, function(x) {return ( 100 * (x - will_start) / will_start)})
|
|
|
|
+weights$trend <- c(craig_trend, will_trend)
|
|
|
|
+weights$trend_pct_change <- c((craig_trend_pct), will_trend_pct)
|
|
|
|
+
|
|
|
|
+p <- ggplot(weights, aes(date, round(change_pct, 1), group = name, col = name,
|
|
|
|
+ frame = week, cumulative = TRUE)) +
|
|
|
|
+ geom_jitter(size = 2) +
|
|
|
|
+ geom_line(aes(date, y = trend_pct_change), lwd = 2) +
|
|
|
|
+ scale_color_manual(values = c('midnightblue', 'red3'), labels = c('Craig', 'Will')) +
|
|
|
|
+ xlab('') + ylab('Change %') + ggtitle('Absolute Weight Change Percentage') +
|
|
|
|
+ labs(color = '') + coord_cartesian(ylim = c(0, 10)) +
|
|
|
|
+ theme_classic(14) +
|
|
|
|
+ theme(legend.position = 'bottom',
|
|
|
|
+ plot.title = element_text(hjust = 0.5,
|
|
|
|
+ size = 20),
|
|
|
|
+ axis.text = element_text(color = 'black',
|
|
|
|
+ size = 16),
|
|
|
|
+ axis.title = element_text(color = 'black', size = 18),
|
|
|
|
+ legend.text = element_text(size = 16))
|
|
|
|
+
|
|
|
|
+gganimate(p, filename = 'animated_weight_change.gif', saver = 'gif',
|
|
|
|
+ interval = 0.4, title_frame = FALSE, fig.height = 4)
|
|
|
|
+```
|