library(tidyverse)
library(reshape2)

# Set working directory.
#setwd("~/.../Code_and_Data_v1")

# Data:
df_bpm <- read.csv("BPM/df_bpm.csv")
length(unique(df_bpm$player_link))
#[1] 3075

# So, first filter the players who don't belong to that test set:
df_bpm1 <- df_bpm %>%
  filter(season != "2018")
df_bpm2 <- df_bpm %>%
  filter(season == "2018")
players_test <- intersect(df_bpm1$player_link, df_bpm2$player_link)
length(players_test)
#[1] 385

# Test data frame:
df_test <- df_bpm2 %>%
  filter(player_link %in% players_test) 

# Load dif2 vectors for each method:
load("Validation/pred_ropes.RData")
load("Validation/pred_naive.RData")
load("Validation/pred_average.RData")
load("Validation/PACE/pred_pace.RData")

# MAE values:
#mean(round(abs(pred_ropes - df_test$bpm), 2))
#[1] 1.888208
#mean(round(abs(pred_naive - df_test$bpm), 2))
#[1] 1.934026
#mean(round(abs(pred_average - df_test$bpm), 2))
#[1] 2.054312
#mean(round(abs(pred_pace - df_test$bpm), 2))
#[1] 1.319091

# Seeing as the goal here is to display each method's accuracy in different game score intervals, I think it'd 
# be better for each method to have a boxplot where the x axis represents predicted game score intervals, and the 
# y axis represents actual game scores.
# https://stackoverflow.com/questions/44647612/compare-boxplots-with-a-single-value
# http://r-statistics.co/Top50-Ggplot2-Visualizations-MasterList-R-Code.html

df_test1 <- df_test %>%
  mutate(ropes = pred_ropes,
         naive = pred_naive,
         average = pred_average,
         pace = pred_pace) %>%
  select(-player_link, -age, -season) %>%
  rename(actual = bpm)

range(df_test1$actual)
#[1] -13.7  10.9

brks <- seq(-14, 11, 5)
df_test1$interv_num <- findInterval(df_test1$actual, brks)
df_test1$interv <- plyr::mapvalues(df_test1$interv_num, 
                                   from = as.character(1:5), 
                                   to = c("[-14,-9)", "[-9,-4)", "[-4,1)", "[1,6)", "[6,11)"))
df_test2 <- df_test1 %>%
  select(-interv_num) 

df_test3 <- melt(df_test2)                                    
df_test4 <- df_test3 %>%
  arrange(interv) %>%
  rename(method = variable) %>%
  mutate(method = as.character(method)) %>%
  mutate(interv = factor(interv, levels = c("[-14,-9)", "[-9,-4)", "[-4,1)", "[1,6)", "[6,11)")))


ggplot(data = df_test4, aes(x = interv, y = value, color = method)) + 
  geom_boxplot() +
  labs(x = "BPM observed", y = "BPM predicted") +
  coord_flip() +
  theme(legend.title = element_blank())
ggsave("Figures/Fig4.eps", width = 6)


# -----------------------

# BARPLOTS:
df_test1 <- df_test %>%
  mutate(ropes = pred_ropes,
         naive = pred_naive,
         average = pred_average,
         pace = pred_pace) %>%
  select(-player_link, -age, -season) %>%
  rename(actual = bpm)

range(df_test1$actual)
#[1] -13.7  10.9

df_bar1 <- data.frame()
for (i in 1:4) {
  df_bar <- cbind.data.frame(actual = df_test1$actual, 
                             interv = findInterval(df_test1$actual, brks), 
                             dif2 = (df_test1$actual - df_test1[,i + 1])^2) %>%
    mutate(interv = plyr::mapvalues(interv, from = as.character(1:5), 
                                    to = c("[-14,-9)", "[-9,-4)", "[-4,1)", "[1,6)", "[6,11)"))) %>%
    group_by(interv) %>%
    summarise(MSE = round(mean(dif2), 2), counts = n()) %>%
    mutate(counts = factor(counts, levels = counts)) %>% # This is the way to avoid that the levels of the 
    # factor are ordered. If they are ordered, then the values of the legend in the barplot are not right.
    mutate(facet = colnames(df_test1)[i + 1])
  
  df_bar1 <- bind_rows(df_bar1, df_bar)
}
df_bar1$interv <- factor(df_bar1$interv, levels = c("[-14,-9)", "[-9,-4)", "[-4,1)", "[1,6)", "[6,11)"))
df_bar1$facet <- factor(df_bar1$facet, levels = c("average", "naive", "pace", "ropes"))

ggplot(df_bar1, aes(interv, MSE, fill = counts)) +
  facet_wrap(~facet, nrow = 2) + 
  geom_bar(stat = "identity") +
  scale_fill_grey() + 
  geom_text(aes(label = MSE), vjust = -0.03, size = 4) +
  xlab("") +
  theme(strip.text = element_text(size = 20))
ggsave("Figures/mse_interv.eps", width = 8, height = 7)


# ------------------

# TABLE COMPARISON:
df_table <- df_test %>%
  mutate(ropes = pred_ropes,
         pace = pred_pace,
         average = pred_average,
         naive = pred_naive) %>%
  rename(actual = bpm) %>%
  select(-season) %>%
  select(player_link, age, everything())

#mean(round((df_table$ropes - df_table$actual)^2, 2))
#[1] 6.728753
#mean(round((df_table$pace - df_table$actual)^2, 2))
#[1] 3.239948

df_table1 <- df_table %>%
  mutate(ropes_dif2 = round((ropes - actual)^2, 2)) %>%
  mutate(pace_dif2 = round((pace - actual)^2, 2)) %>%
  mutate(average_dif2 = round((average - actual)^2, 2)) %>%
  mutate(naive_dif2 = round((naive - actual)^2, 2)) %>%
  select(player_link, age, actual, ropes, ropes_dif2, pace, pace_dif2, 
         average, average_dif2, naive, naive_dif2)

# Actual BPM:
mean(df_table1$actual) ; sd(df_table1$actual) 

# ROPES:
mean(df_table1$ropes) ; sd(df_table1$ropes)
mean(df_table1$ropes_dif2) ; sd(df_table1$ropes_dif2)

# PACE:
mean(df_table1$pace) ; sd(df_table1$pace)
mean(df_table1$pace_dif2) ; sd(df_table1$pace_dif2) 

# Average:
mean(df_table1$average) ; sd(df_table1$average)
mean(df_table1$average_dif2) ; sd(df_table1$average_dif2)

# Naive:
mean(df_table1$naive) ; sd(df_table1$naive)
mean(df_table1$naive_dif2) ; sd(df_table1$naive_dif2)

df_table1[c(1, 193, 385),]
