##%######################################################%##
#                                                          #
####                  Data Exploration                  ####
#                                                          #
##%######################################################%##



# Loading packages, functions, and data -------------------------------------
library(dlookr)
library(skimr)
library(ggmosaic)
library(tidyverse)
library(tidytext)

source("r101_funs.R")

df <- read_rds("data/games_sales.rds") 

# Descriptives using skimr ---------------------------------------------------

# The core function of skimr is skim(), which is designed to work with (grouped) # 
# data frames, and will try coerce other objects to data frames if possible. 
# Like summary(), skim()’s method for data frames presents results for every column; 
# the statistics it provides depend on the class of the variable.
data_summary <- skim(df)
data_summary
str(data_summary)

# The format of the results are a single wide data frame combining the results, 
# with some additional attributes and two metadata columns:
#  skim_variable: name of the original variable
# skim_type: class of the variable

# skim_df object is pipeable and easy to use for additional manipulation: 
# for example, the user could select all of the variable means, 
# or all summary statistics for a specific variable.
data_summary %>% 
  filter(
    str_detect(skim_variable, "sales")
    )
str(data_summary)

data_summary %>% 
  filter(skim_type == "numeric") %>% 
  select(skim_variable, numeric.mean, numeric.sd)

# skim() also supports grouped data created by dplyr::group_by(). 
# In this case, one additional column for each grouping variable 
# is added to the skim_df object.
df %>% 
  group_by(genre) %>% 
  select(genre, critic_score) %>% 
  skim() %>% 
  arrange(desc(numeric.mean))

# skim_tee() produces the same printed version as skim() but returns the original, 
# unmodified data frame. This allows for continued piping of the original data.
df %>% 
  skim_tee(critic_score, user_score) %>% 
  ungroup()

# First, partition() returns a named list of the wide data frames for each data type. 
# Unlike the original data the partitioned data only has columns corresponding 
# to the skimming functions used for this data type. 
# These data frames are, therefore, not skim_df objects.
data_summary <- df %>%
  skim() %>%
  partition()
str(data_summary)
data_summary

data_summary$factor

# Alternatively, yank() selects only the subtable for a specific type. 
# Think of it like dplyr::select on column types in the original data. 
# Again, unsuitable columns are dropped.
data_summary <- df %>%
  skim() %>%
  yank("numeric")
data_summary

# use focus() to select columns of the skimmed results and keep them as a skim_df; 
# it always keeps the metadata column
data_summary <- df %>%
  skim() %>%
  focus(n_missing, numeric.mean)
data_summary

# To add a statistic for a data type, create an sfl() (a skimr function list) 
# for each class that you want to change:
my_skim <- skim_with(
  base = sfl(
    n_valid = ~sum(!is.na(.))
    ),
  numeric = sfl(
    skew = ~skewness(., na.rm = TRUE),
    kurt = ~kurtosis(., na.rm = TRUE)
    )
  )

df %>% 
  my_skim()

# As the previous example suggests, the default is to append new summary statistics 
# to the preexisting set. This behavior isn’t always desirable, 
# especially when you want lots of changes. To stop appending, set append = FALSE.

my_skim <- skim_with(
  base = sfl(
    complete = ~sum(!is.na(.))
  ),
  numeric = sfl(
    median = ~median(., na.rm = TRUE),
    IQR = ~IQR(., na.rm = TRUE)),
  append = FALSE)
my_skim(df)

# Data exploration using dlookr -------------------------------------------

# General diagnosis of all variables with diagnose()
# diagnose() allows you to diagnose variables on a data frame. 
# Like any other dplyr functions, the first argument is the tibble (or data frame). 
# The second and subsequent arguments refer to variables within the data frame.
diagnose(df)
diagnose(df, ends_with("sales"))
diagnose(df, rating, platform)


# By using with dplyr, variables including missing values can be sorted by 
# the weight of missing values
df %>% 
  diagnose() %>% 
  filter(missing_count > 0) %>%
  arrange(desc(missing_count))

# diagnose_numeric() diagnoses numeric(continuous and discrete) variables in 
# a data frame. Usage is the same as diagnose() but returns more diagnostic information. 
diagnose_numeric(df)

# diagnose_category() diagnoses the categorical(factor, ordered, character) 
# variables of a data frame. The usage is similar to diagnose() but returns 
# more diagnostic information
diagnose_category(df) %>% 
  View()

diagnose_category(df, top = 5) %>% 
  View()

# diagnose_outlier() diagnoses the outliers of the numeric (continuous and discrete) 
# variables of the data frame. The usage is the same as diagnose().
diagnose_outlier(df)

# plot_outlier() visualizes outliers of numerical variables(continuous and 
# discrete) of data.frame. Usage is the same diagnose().
plot_outlier(df, global_sales)
plot_outlier(df, global_sales_log10)

# describe() computes descriptive statistics for numerical data. 
# The descriptive statistics help determine the distribution of numerical variables. 
# Like function of dplyr, the first argument is the tibble (or data frame). 
# The second and subsequent arguments refer to variables within that data frame.
describe(df) %>% 
  mutate(across( where(is.numeric), round, digits = 2 )) %>% 
  arrange(desc(abs(skewness)))

# plot_normality() can also specify several variables
plot_normality(df, global_sales,
               left = "1/x", right = "log")

# plot_correlate() visualizes the correlation matrix.
plot_correlate(df)

df %>% 
  group_by(platform_type) %>% 
  plot_correlate(user_score, critic_score)

# Exploratory plots -------------------------------------------------
num_vars <- df %>% 
  select(where(is.numeric)) %>% 
  colnames()

cat_vars <- df %>% 
  select(!where(is.numeric)) %>% 
  colnames()
num_vars
cat_vars

# * Bar plots --------------------------------------------------------------

# To visualize frequency distributions for all discrete features:
dlookr::plot_bar_category(df)

plot_bar(df, var = "genre",  fill = "decade", facet = "handheld")

plot_bar_mult(data = df, var = c("decade", "genre", "rating_short"))

# * Stacked bar plots --------------------------------------------------------
plot_stackbar(df, var = "handheld", fill = "genre")

plot_stackbar_mult(df, var = c("handheld", "decade"), fill = c("rating", "genre"))


# * Histograms ------------------------------------------------------------
plot_histogram(df, "critic_score")
plot_histogram(df, "critic_score", geom = "density")
plot_histogram(df, "critic_score", geom = "freqpoly")

plot_histogram(df, "global_sales_log10", 
               facet = "decade", geom = "density")

plot_histogram(df, "global_sales_log10", 
               facet = "platform_type", geom = "density")

plot_histogram_mult(
  df, c("global_sales_log10", "critic_score", "year_of_release")
)

# * Boxplots --------------------------------------------------------------
plot_box(df, "user_score")
plot_box(df, "user_score", groups = "genre")

plot_box_mult(df, c("user_score", "critic_score"), 
              groups = "genre")


# * Scatterplots ----------------------------------------------------------
plot_scatter(df, xvar = "user_score", yvar = "critic_score", 
             geom = "jitter",  alpha = 0.1, method = "lm")


plot_scatter_mult(df,
                  xvar = c("user_score", "user_score"),
                  yvar = c("critic_score", "global_sales"),
                  alpha = 0.1,
                  geom = "jitter", method = "lm")


# * Mosaic plots ----------------------------------------------------------
plot_mosaic(df, "genre", "rating_short")
plot_mosaic(df %>% filter(!is.na(rating_short)),
            xvar = "genre", yvar = "rating_short")

plot_mosaic_mult(df %>% filter(!is.na(rating_short)), 
                 xvar = "platform_type", 
                 yvar = c("genre", "handheld", "rating_short"))

cat_vars


# Crosstabs ---------------------------------------------------------------
# You can generate frequency tables using the table( ) function, 
# tables of proportions using the prop.table( ) function, 
# and marginal frequencies using margin.table( ).
my_table <-  table(df$platform_type, df$genre)
my_table

margin.table(my_table, 1) # A frequencies (summed over rows)
margin.table(my_table, 2) # B frequencies (summed over columns)

prop.table(my_table) # cell percentages
prop.table(my_table, 1) # row percentages
prop.table(my_table, 2) # column percentages

# table() can also generate multidimensional tables based on 3 or more 
# categorical variables. In this case, use the ftable( ) function to print 
# the results more attractively.
my_table <- table(df$decade, df$platform_type, df$genre)
my_table
ftable(my_table)

# The xtabs( ) function allows you to create crosstabulations 
# using formula style input.
xtabs(~ genre, data = df)
xtabs(~ genre + platform_type + decade, data = df)
xtabs(~ decade + platform_type + genre, data = df) %>% 
  ftable()

crosstabs(df, "genre", "rating_short") %>% 
  View()

crosstabs(df, "platform_type", "genre") %>% 
  View()

# Example --------------------------------------------------------------

# Pro kterou platformu bylo vydáno nejvíce her?
plot_bar(df, "platform")

# Ve kterých letech bylo vydáno nejvíce her
plot_histogram(df, "year_of_release", binwidth = 1)

# Jaké byly tržby z prodeje her v jednotlivých lete?
df %>% 
  count(year_of_release, wt = global_sales, name = "sales") %>% 
  ggplot(aes(year_of_release, sales)) +
  geom_col() 

# Zdá se, že největší tržby byly okolo roku 2008.
# Platí to ale pro každou oblast?

df %>% 
  select(year_of_release, ends_with("sales"), -global_sales) %>% 
  pivot_longer(
    cols = -year_of_release,
    names_to = "region",
    values_to = "sales"
  ) %>% 
  count(
    year_of_release, region, wt = sales, name = "sales"
  ) %>% 
  ggplot(aes(year_of_release, sales)) +
  geom_col() +
  facet_wrap(~region, scales = "free_y")

# Zdá se, že ano, ale Japonsko se mírně odlišuje, distribuce vypadá bimodálně
# s vrcholy v roce 1996 a 2006

# * Srovnání platforem ------------------------------------------------------

# Podíváme se na tržby podle platformy
df %>% 
  group_by(platform) %>% 
  summarise(
    across(ends_with("sales"), sum)
  ) %>% 
  select(-global_sales) %>% 
  pivot_longer(
    cols = -platform,
    names_to = "region",
    values_to = "sales"
  ) %>% 
  ggplot(
    aes(
      x = fct_reorder(platform, sales, .fun = sum), 
      y = sales, 
      fill = region)) +
  geom_col()


# Nejvíce vydělaly hry pro PS2, ale musíme vzít v úvahu také to, 
# že PS2 byl na trhu dlouhou dobu, zatímco modernější konzole jsou 
# na trhu kratší dobu

# Vzpočteme si tedy průměrné tržby ročně, 
# tj. celkové tržby vzdělíme počtem let konzole na trhu
df %>% 
  group_by(platform) %>% 
  summarise(
    total_sales = sum(global_sales),
    age = n_distinct(year_of_release)
  ) %>% 
  mutate(
    avg_sales_per_year = total_sales / age
  ) %>% 
  ggplot(
    aes(
      x = fct_reorder(platform, avg_sales_per_year), 
      y = avg_sales_per_year)
    ) +
  geom_col()

# PS2 stále vede

# * Srovnání generací konzolí ---------------------------------------------------
gens <- df %>% 
  filter(
    platform %in% c("GC", "PS2", "XB", "PS3", "Wii", "X360", "PS4", "WiiU", "XOne")
    ) %>% 
  group_by(year_of_release, console_gen, platform_type) %>% 
  summarise(
    n_games = n(),
    sales = sum(global_sales),
    saler_per_game = sales / n_games
  )

# Celkové tržby
gens %>% 
  ggplot(aes(year_of_release, sales, color = platform_type)) +
  geom_line(size = 1.5) +
  facet_wrap(~console_gen, scales = "free_x")

  
gens %>% 
  ggplot(aes(year_of_release, sales, color = platform_type, linetype = console_gen)) +
  geom_line(size = 1.5) +
  scale_linetype_manual(values = c(3, 1, 6)) +
  scale_x_continuous(breaks = seq(2000, 2020, by = 2),
                     limits = c(2000, 2018)) +
  theme(
    legend.key.width = unit(2, units = "cm"),
    legend.position = c(.9, .8)
  )

# PS dominuje 6. i 8. generaci.
# Co se týče 7. generacie (PS3, Wii, X360), tržby jsou docela vyrovnané
# Wii mělo obdivuhodný nástup okolo roku 2008, pak tržby poklesly

# Ps2 is clearly ahead of the market for Gen6 and Gen8,as for 7th genreation , 
# things are a bit more complicated,X360 and Ps3 are quite competitive, 
# Wii had seom impressive sales around 2008, just to drop after that.

# Tržby na hru
gens %>% 
  ggplot(aes(year_of_release, saler_per_game, color = platform_type)) +
  geom_line(size = 1.5) +
  facet_wrap(~console_gen, scales = "free_x")

# I když tržby dělíme počtem vydaných her, zdá se, že PS vede, pokud jde generaci 6 a 8
# u generace 7 má mírně navrch XBox

# Podíváme se na vydavatele a žánry
df %>% 
  summarise(n_distinct(publisher))

# Celkem máme 581 herních vydavatelů
# Vybereme ty, kteří mají alespoň 50 releases

df %>% 
  count(publisher) %>% 
  filter(n > 50, !is.na(publisher)) %>% 
  ggplot(aes(fct_reorder(publisher, n), n)) +
  geom_col() +
  coord_flip()

# Nejvíce tutilů vydalo EA

# Jaké jsou průměrné tržby na jeden herní release?
df %>% 
  group_by(publisher) %>% 
  filter(n() > 50, !is.na(publisher)) %>% 
  summarise(
    sales = sum(global_sales),
    n_games = n(),
    sales_per_game = sales / n_games
  ) %>% 
  ggplot(aes(fct_reorder(publisher, sales_per_game), sales_per_game)) +
  geom_col() +
  coord_flip()

# Nintendo jasně vede

# A jaké jsou průměrné tržby na jeden herní titul?
df %>% 
  group_by(publisher) %>% 
  filter(n() > 50, !is.na(publisher)) %>% 
  summarise(
    sales = sum(global_sales),
    n_games = n_distinct(name),
    sales_per_game = sales / n_games
  ) %>% 
  ggplot(aes(fct_reorder(publisher, sales_per_game), sales_per_game)) +
  geom_col() +
  coord_flip()

# Zde vede Bethesha, v těsném závěsu za ní je Nintendo

# * Tržby v závislosti na žánru a regionu -----------------------------------

# Jaké jsou tržby dle herních žándů a regionů
sales_by_genre_region <- df %>% 
  select(genre, ends_with("sales"), -global_sales) %>% 
  pivot_longer(
    cols = -genre,
    names_to = "region",
    values_to = "sales"
  ) %>% 
  count(
    genre, region, wt = sales, name = "sales"
  )

sales_by_genre_region %>% 
  ggplot(aes(genre, sales, fill = region)) +
  geom_col()

sales_by_genre_region %>% 
  plot_mosaic(xvar = "region", yvar = "genre", weight = "sales")

# Vypadá to, že Evropa a Severní Amerika mají podobné preference,
# Japonsko se odlišuje výraznou preferencí RPG her

# Na jaké žánry se zaměřují různí vydavatelé?
df %>% 
  filter(!is.na(genre), !is.na(publisher)) %>% 
  count(genre, publisher) %>% 
  group_by(genre) %>% 
  slice_max(order_by = n, n = 10) %>% 
  ggplot(aes(n, reorder_within(publisher, n, within = genre))) +
  geom_col() +
  facet_wrap(~genre, scales = "free") +
  scale_y_reordered()


# * Vztah platforem a žánrů -------------------------------------------------
plot_mosaic(df, xvar = "platform_type", yvar = "genre")

main_platforms <- c("PC", "GC", "Wii", "WiiU", "PS2", "PS3", "PS4", "XB", "X360", "XOne")

df %>% 
  filter(platform %in% main_platforms) %>% 
  mutate(platform = factor(platform, levels = main_platforms)) %>% 
  plot_mosaic(xvar = "platform", yvar = "genre")


