Required packages

The following packages were installed and loaded to be used in the report:

library(readr)
library(foreign)
library(gdata)
library(rvest)
library(dplyr)
library(tidyr)
library(knitr)
library(deductive)
library(validate)
library(Hmisc)
library(stringr)
library(outliers)
library(MVN)
library(forecast)
library(infotheo)
library(lubridate)

Executive Summary

The first step of preprocessing the data was to import the data sets into R using the read.csv() function. The next step was to combine the three imported data sets using rbind() to produce the main data set that will be used throughout the process. Checking the data types of the variables followed using glimpse(). Of the twelve variables in the data set, six variables were converted from character to factor using as.factor() with the Is_NF_Original variable being labelled using factor(). Two variables were also converted from character to numeric using as.numeric(). The separate() function was then used to form multiple column from one to tidy the data set. The data set was scanned for missing values by using the sum(is.na()) and colSums(is.na()) to identify the total number of missing values and which columns contain these values, respectively. The missing values in the RT_rating column were imputed using the mean of the variable. The is.special function was created to identify all numerical variables for special values (infinite and NaN) and then using sapply() to scan the data. Boxplots were then used to scan all numerical variables for outliers. The RT_rating variable showed to have outliers which were dealt with by the method of capping using the sapply() function. The distribution of the Average_rating variables was checked using histogram() and was transformed using the BoxCox() fucntion. After completing all of the preprocessing steps the data is then ready for analysis.

Data

The data sets were found on the Kaggle website and can be accessed using the following URL link: https://www.kaggle.com/intandea/netflix2020. The three data sets chosen were of the weekly number one netflix movie and TV show in Australia (AUS_NF), Great Britain (GBR_NF) and The United States of America (USA_NF). The data sets include 12 variables, which are listed below:

The three data sets chosen were imported into R using the read.csv() function as shown below. The argument stringAsFactors = FALSE was used to stipulate to R not to convert all characters into factors. A head of the data sets were produced.

AUS_NF <- read.csv("D:/RMIT/Semester 2 2020/MATH2349/Assignment 2/AUS_NF.csv", stringsAsFactors = FALSE)
print.data.frame(head(AUS_NF))
  week show_type               title    ori_country           genre release_date is_NF_Ori imdb_rating
1   37     Movie    Love, Guaranteed            USA          Comedy    3/09/2020      TRUE         55%
2   37   TV Show                Away            USA Science Fiction    4/09/2020      TRUE         71%
3   36     Movie Mary Queen of Scots United Kingdom           Drama   21/12/2018     FALSE         65%
4   36   TV Show           Cobra Kai            USA          Action    2/05/2018     FALSE         88%
5   35     Movie       The Sleepover            USA          Comedy   21/08/2020      TRUE         55%
6   35   TV Show             Lucifer            USA       Superhero   25/01/2016      TRUE         83%
  rt_rating country_chart                                             show_link Continent
1       50%           AUS          https://flixpatrol.com/title/love-guaranteed       OCE
2       73%           AUS                https://flixpatrol.com/title/away-2020       OCE
3       62%           AUS https://flixpatrol.com/title/mary-queen-of-scots-2018       OCE
4       94%           AUS                https://flixpatrol.com/title/cobra-kai       OCE
5       80%           AUS            https://flixpatrol.com/title/the-sleepover       OCE
6       87%           AUS                  https://flixpatrol.com/title/lucifer       OCE
GBR_NF <- read.csv("D:/RMIT/Semester 2 2020/MATH2349/Assignment 2/GBR_NF.csv", stringsAsFactors = FALSE)
print.data.frame(head(GBR_NF))
  week show_type                             title ori_country           genre release_date is_NF_Ori
1   37     Movie Charlie and the Chocolate Factory         USA         Fantasy    9/07/2005     FALSE
2   37   TV Show                              Away         USA Science Fiction    4/09/2020      TRUE
3   36     Movie                             Venom         USA       Superhero    3/10/2018     FALSE
4   36   TV Show                         Cobra Kai         USA          Action    2/05/2018     FALSE
5   35     Movie                         Bee Movie         USA        Animated   28/10/2007     FALSE
6   35   TV Show                          The Fall     Ireland           Crime   12/05/2013     FALSE
  imdb_rating rt_rating country_chart                                                      show_link
1         67%       83%           GBR https://flixpatrol.com/title/charlie-and-the-chocolate-factory
2         71%       73%           GBR                         https://flixpatrol.com/title/away-2020
3         71%       29%           GBR                        https://flixpatrol.com/title/venom-2018
4         88%       94%           GBR                         https://flixpatrol.com/title/cobra-kai
5         62%       50%           GBR                         https://flixpatrol.com/title/bee-movie
6         82%                     GBR                     https://flixpatrol.com/title/the-fall-2013
  Continent
1       EUR
2       EUR
3       EUR
4       EUR
5       EUR
6       EUR
USA_NF <- read.csv("D:/RMIT/Semester 2 2020/MATH2349/Assignment 2/USA_NF.csv", stringsAsFactors = FALSE)
print.data.frame(head(USA_NF))
  week show_type             title ori_country           genre release_date is_NF_Ori imdb_rating rt_rating
1   37     Movie  Love, Guaranteed         USA          Comedy    3/09/2020      TRUE         55%       50%
2   37   TV Show              Away         USA Science Fiction    4/09/2020      TRUE         71%       73%
3   36     Movie The Frozen Ground         USA                   23/08/2013     FALSE         64%          
4   36   TV Show         Cobra Kai         USA          Action    2/05/2018     FALSE         88%       94%
5   35     Movie     Project Power         USA          Action   14/08/2020      TRUE         61%       63%
6   35   TV Show           Lucifer         USA       Superhero   25/01/2016      TRUE         83%       87%
  country_chart                                      show_link Continent
1           USA   https://flixpatrol.com/title/love-guaranteed       AME
2           USA         https://flixpatrol.com/title/away-2020       AME
3           USA https://flixpatrol.com/title/the-frozen-ground       AME
4           USA         https://flixpatrol.com/title/cobra-kai       AME
5           USA     https://flixpatrol.com/title/project-power       AME
6           USA           https://flixpatrol.com/title/lucifer       AME

The three data sets were merged together to create the main data set for the report using the rbind() function. The options(max.print = 10000) function was used to increase the limit of max.print so that rows were not omitted when combining the data sets. The arrange(desc())function was used to order the combined data in desceding order so all results for week 37, etc. were together.

options(max.print = 10000)
combined <- GBR_NF %>% rbind(USA_NF, AUS_NF)
NF_combined <- combined %>% arrange(desc(week))
print.data.frame(head(NF_combined))
  week show_type                             title ori_country           genre release_date is_NF_Ori
1   37     Movie Charlie and the Chocolate Factory         USA         Fantasy    9/07/2005     FALSE
2   37   TV Show                              Away         USA Science Fiction    4/09/2020      TRUE
3   37     Movie                  Love, Guaranteed         USA          Comedy    3/09/2020      TRUE
4   37   TV Show                              Away         USA Science Fiction    4/09/2020      TRUE
5   37     Movie                  Love, Guaranteed         USA          Comedy    3/09/2020      TRUE
6   37   TV Show                              Away         USA Science Fiction    4/09/2020      TRUE
  imdb_rating rt_rating country_chart                                                      show_link
1         67%       83%           GBR https://flixpatrol.com/title/charlie-and-the-chocolate-factory
2         71%       73%           GBR                         https://flixpatrol.com/title/away-2020
3         55%       50%           USA                   https://flixpatrol.com/title/love-guaranteed
4         71%       73%           USA                         https://flixpatrol.com/title/away-2020
5         55%       50%           AUS                   https://flixpatrol.com/title/love-guaranteed
6         71%       73%           AUS                         https://flixpatrol.com/title/away-2020
  Continent
1       EUR
2       EUR
3       AME
4       AME
5       OCE
6       OCE

The colnames() function was used to change the column names in the main data set.

colnames(NF_combined) <- c("Week", "Show_type", "Title", "Origin_country", 
                           "Genre", "Release_date", "Is_NF_original", 
                           "IMDB_rating(%)", "RT_rating(%)", "Country_chart",
                           "Show_link", "Continent")
print.data.frame(head(NF_combined))
  Week Show_type                             Title Origin_country           Genre Release_date
1   37     Movie Charlie and the Chocolate Factory            USA         Fantasy    9/07/2005
2   37   TV Show                              Away            USA Science Fiction    4/09/2020
3   37     Movie                  Love, Guaranteed            USA          Comedy    3/09/2020
4   37   TV Show                              Away            USA Science Fiction    4/09/2020
5   37     Movie                  Love, Guaranteed            USA          Comedy    3/09/2020
6   37   TV Show                              Away            USA Science Fiction    4/09/2020
  Is_NF_original IMDB_rating(%) RT_rating(%) Country_chart
1          FALSE            67%          83%           GBR
2           TRUE            71%          73%           GBR
3           TRUE            55%          50%           USA
4           TRUE            71%          73%           USA
5           TRUE            55%          50%           AUS
6           TRUE            71%          73%           AUS
                                                       Show_link Continent
1 https://flixpatrol.com/title/charlie-and-the-chocolate-factory       EUR
2                         https://flixpatrol.com/title/away-2020       EUR
3                   https://flixpatrol.com/title/love-guaranteed       AME
4                         https://flixpatrol.com/title/away-2020       AME
5                   https://flixpatrol.com/title/love-guaranteed       OCE
6                         https://flixpatrol.com/title/away-2020       OCE

Understand

The dimensions and structure of the data set were checked using the glimpse() function which showed the dimensions to be 154 rows and 12 columns. The same function was used to check the data types of the variables in the data set. It showed that column one is a numeric variable, column sevel is a logical variable and the other ten columns are all character variables. Multiple variables require data type conversion.

glimpse(NF_combined)
Rows: 154
Columns: 12
$ Week             <int> 37, 37, 37, 37, 37, 37, 36, 36, 36, 36, 36, 36, 35, 35, 35, 35, 35, 35, 34, 34,...
$ Show_type        <chr> "Movie", "TV Show", "Movie", "TV Show", "Movie", "TV Show", "Movie", "TV Show",...
$ Title            <chr> "Charlie and the Chocolate Factory", "Away", "Love, Guaranteed", "Away", "Love,...
$ Origin_country   <chr> "USA", "USA", "USA", "USA", "USA", "USA", "USA", "USA", "USA", "USA", "United K...
$ Genre            <chr> "Fantasy", "Science Fiction", "Comedy", "Science Fiction", "Comedy", "Science F...
$ Release_date     <chr> "9/07/2005", "4/09/2020", "3/09/2020", "4/09/2020", "3/09/2020", "4/09/2020", "...
$ Is_NF_original   <lgl> FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, ...
$ `IMDB_rating(%)` <chr> "67%", "71%", "55%", "71%", "55%", "71%", "71%", "88%", "64%", "88%", "65%", "8...
$ `RT_rating(%)`   <chr> "83%", "73%", "50%", "73%", "50%", "73%", "29%", "94%", "", "94%", "62%", "94%"...
$ Country_chart    <chr> "GBR", "GBR", "USA", "USA", "AUS", "AUS", "GBR", "GBR", "USA", "USA", "AUS", "A...
$ Show_link        <chr> "https://flixpatrol.com/title/charlie-and-the-chocolate-factory", "https://flix...
$ Continent        <chr> "EUR", "EUR", "AME", "AME", "OCE", "OCE", "EUR", "EUR", "AME", "AME", "OCE", "O...

The following variables were converted from character to factor using the as.factor() function. The levels() function was used to check the levels of the factor variable and see if any of the variables needed to be labelled and/or ordered.

NF_combined$Show_type <- as.factor(NF_combined$Show_type)
levels(NF_combined$Show_type)
[1] "Documentary"    "Documentary TV" "Movie"          "TV Show"       
NF_combined$Origin_country <- as.factor(NF_combined$Origin_country)
levels(NF_combined$Origin_country)
[1] "Canada"         "France"         "Ireland"        "Poland"         "Spain"          "Switzerland"   
[7] "United Kingdom" "USA"           
NF_combined$Genre <- as.factor(NF_combined$Genre)
levels(NF_combined$Genre)
 [1] ""                "Action"          "Adventure"       "Animated"        "Comedy"         
 [6] "Crime"           "Documentary"     "Drama"           "Fantasy"         "Horror"         
[11] "Mystery"         "Reality-Show"    "Romance"         "Science Fiction" "Superhero"      
[16] "Thriller"       
NF_combined$Country_chart <- as.factor(NF_combined$Country_chart)
levels(NF_combined$Country_chart)
[1] "AUS" "GBR" "USA"
NF_combined$Continent <- as.factor(NF_combined$Continent)
levels(NF_combined$Continent)
[1] "AME" "EUR" "OCE"

The variable Is_NF_original was converted from a logical data type to a factor data type using the as.factor() function. The levels() function was used to check the levels of the factor variable. The factor() function was then used to change the labels assigned to the different levels of the variable. Lastly, levels() function was used again to check the new levels of the variable.

NF_combined$Is_NF_original <- as.factor(NF_combined$Is_NF_original)
levels(NF_combined$Is_NF_original)
[1] "FALSE" "TRUE" 
NF_combined$Is_NF_original <- NF_combined$Is_NF_original %>% 
  factor(levels = c("FALSE", "TRUE"), 
         labels = c("Not Netflix Original", "Netflix Original"))
levels(NF_combined$Is_NF_original)
[1] "Not Netflix Original" "Netflix Original"    

The following two variables were converted from character to numeric using the as.numeric() function. The sub() function was used to remove the “%” in the rows so that the variable could be changed to a numeric data type. The “%” was not needed at the column name explains that the numeric value in the row is a percentage.

NF_combined$`IMDB_rating(%)` <- 
  as.numeric(sub("%", "", NF_combined$`IMDB_rating(%)`))
NF_combined$`RT_rating(%)` <- 
  as.numeric(sub("%", "", NF_combined$`RT_rating(%)`))

Once all the data type conversions were completed, the glimpse() function was used to check that all variables had been changed into the correct data type. This is shown below.

glimpse(NF_combined)
Rows: 154
Columns: 12
$ Week             <int> 37, 37, 37, 37, 37, 37, 36, 36, 36, 36, 36, 36, 35, 35, 35, 35, 35, 35, 34, 34,...
$ Show_type        <fct> Movie, TV Show, Movie, TV Show, Movie, TV Show, Movie, TV Show, Movie, TV Show,...
$ Title            <chr> "Charlie and the Chocolate Factory", "Away", "Love, Guaranteed", "Away", "Love,...
$ Origin_country   <fct> USA, USA, USA, USA, USA, USA, USA, USA, USA, USA, United Kingdom, USA, USA, Ire...
$ Genre            <fct> Fantasy, Science Fiction, Comedy, Science Fiction, Comedy, Science Fiction, Sup...
$ Release_date     <chr> "9/07/2005", "4/09/2020", "3/09/2020", "4/09/2020", "3/09/2020", "4/09/2020", "...
$ Is_NF_original   <fct> Not Netflix Original, Netflix Original, Netflix Original, Netflix Original, Net...
$ `IMDB_rating(%)` <dbl> 67, 71, 55, 71, 55, 71, 71, 88, 64, 88, 65, 88, 62, 82, 61, 83, 55, 83, 61, 82,...
$ `RT_rating(%)`   <dbl> 83, 73, 50, 73, 50, 73, 29, 94, NA, 94, 62, 94, 50, NA, 63, 87, 80, 87, 63, NA,...
$ Country_chart    <fct> GBR, GBR, USA, USA, AUS, AUS, GBR, GBR, USA, USA, AUS, AUS, GBR, GBR, USA, USA,...
$ Show_link        <chr> "https://flixpatrol.com/title/charlie-and-the-chocolate-factory", "https://flix...
$ Continent        <fct> EUR, EUR, AME, AME, OCE, OCE, EUR, EUR, AME, AME, OCE, OCE, EUR, EUR, AME, AME,...

Tidy & Manipulate Data I

One of the common problems with messy data sets is that multiple variables are stored in one column. This does not conform with the tidy data principles. The NF_combined data set shows this messy problem as the release_date column has the day, month and year stored in one column. In order to separate these three variables into multiple columns, the separate() function from the tidyr package was used. The sep argument was used to tell R where to separate the variable into multiple columns. The data set was renamed Tidy_NF. Head() was used to show the new columns of the tidy data set.

Tidy_NF <- NF_combined %>% 
  separate(Release_date,into = c("Release_day","Release_month","Release_year"), 
           sep = "/")
print.data.frame(head(Tidy_NF))
  Week Show_type                             Title Origin_country           Genre Release_day Release_month
1   37     Movie Charlie and the Chocolate Factory            USA         Fantasy           9            07
2   37   TV Show                              Away            USA Science Fiction           4            09
3   37     Movie                  Love, Guaranteed            USA          Comedy           3            09
4   37   TV Show                              Away            USA Science Fiction           4            09
5   37     Movie                  Love, Guaranteed            USA          Comedy           3            09
6   37   TV Show                              Away            USA Science Fiction           4            09
  Release_year       Is_NF_original IMDB_rating(%) RT_rating(%) Country_chart
1         2005 Not Netflix Original             67           83           GBR
2         2020     Netflix Original             71           73           GBR
3         2020     Netflix Original             55           50           USA
4         2020     Netflix Original             71           73           USA
5         2020     Netflix Original             55           50           AUS
6         2020     Netflix Original             71           73           AUS
                                                       Show_link Continent
1 https://flixpatrol.com/title/charlie-and-the-chocolate-factory       EUR
2                         https://flixpatrol.com/title/away-2020       EUR
3                   https://flixpatrol.com/title/love-guaranteed       AME
4                         https://flixpatrol.com/title/away-2020       AME
5                   https://flixpatrol.com/title/love-guaranteed       OCE
6                         https://flixpatrol.com/title/away-2020       OCE

Scan I

The Tidy_NF data set was scanned for missing values first using the sum(is.na()) functions to show the total count of missing values in the data. The colSums(is.na()) functions were then use to see which columns in the data set contained the missing values. The two functions showed that there was a total of 40 missing values in the data and were all contained in the RT_rating(%) column. The methodology above was chosen to see which columns of the data set had the missing values and to determine what would be the correct actions for dealing with the missing values according to the data type of the variables.

sum(is.na(Tidy_NF))
[1] 40
colSums(is.na(Tidy_NF))
          Week      Show_type          Title Origin_country          Genre    Release_day  Release_month 
             0              0              0              0              0              0              0 
  Release_year Is_NF_original IMDB_rating(%)   RT_rating(%)  Country_chart      Show_link      Continent 
             0              0              0             40              0              0              0 

The action taken to deal with the missing values was to use the impute() function from the Hmisc package. The decision was to impute the mean for the missing values in the RT_rating(%) column. This action was made as it is a natural way of replacing missing values for numeric variables. The round() function was used to tidy up the column and prepare values that can be used for analysis.

Tidy_NF$`RT_rating(%)` <- impute(Tidy_NF$`RT_rating(%)`, fun = mean)
Tidy_NF$`RT_rating(%)` <- round(Tidy_NF$`RT_rating(%)`)

The RT_rating(%) variable was re-converted to a numeric data type after imputing of missing values was completed. This was to help with the scanning of outliers in the further steps of preprocessing.

Tidy_NF$`RT_rating(%)` <- as.numeric(Tidy_NF$`RT_rating(%)`)

Special values were scanned by first establishing a is.special function, which checks every numerical column to identify whether they have infinite or NaN values. The sapply() function, from the apply family functions, was then used to scan the data for any special values. This is shown below.

is.special <- function(x){
  if (is.numeric(x)) (is.infinite(x) | is.nan(x))
}
sapply(Tidy_NF, is.special)
$Week
  [1] FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE
 [18] FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE
 [35] FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE
 [52] FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE
 [69] FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE
 [86] FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE
[103] FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE
[120] FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE
[137] FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE
[154] FALSE

$Show_type
NULL

$Title
NULL

$Origin_country
NULL

$Genre
NULL

$Release_day
NULL

$Release_month
NULL

$Release_year
NULL

$Is_NF_original
NULL

$`IMDB_rating(%)`
  [1] FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE
 [18] FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE
 [35] FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE
 [52] FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE
 [69] FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE
 [86] FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE
[103] FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE
[120] FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE
[137] FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE
[154] FALSE

$`RT_rating(%)`
  [1] FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE
 [18] FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE
 [35] FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE
 [52] FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE
 [69] FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE
 [86] FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE
[103] FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE
[120] FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE
[137] FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE
[154] FALSE

$Country_chart
NULL

$Show_link
NULL

$Continent
NULL

Tidy & Manipulate Data II

A new variable was created and added to the data set from two existing variables. The new variable, Average_rating, was created from the IMDB_rating(%) and RT_rating(%) variables using the mutate() function. The two existing variables were added together and then divided by 2 to give an average rating for each movie/show in the data set. The head() function was used to show the new variable in the data set.

Tidy_NF <- 
  mutate(Tidy_NF, 
         Average_rating = (Tidy_NF$`IMDB_rating(%)` + Tidy_NF$`RT_rating(%)`)/2)
print.data.frame(head(Tidy_NF))
  Week Show_type                             Title Origin_country           Genre Release_day Release_month
1   37     Movie Charlie and the Chocolate Factory            USA         Fantasy           9            07
2   37   TV Show                              Away            USA Science Fiction           4            09
3   37     Movie                  Love, Guaranteed            USA          Comedy           3            09
4   37   TV Show                              Away            USA Science Fiction           4            09
5   37     Movie                  Love, Guaranteed            USA          Comedy           3            09
6   37   TV Show                              Away            USA Science Fiction           4            09
  Release_year       Is_NF_original IMDB_rating(%) RT_rating(%) Country_chart
1         2005 Not Netflix Original             67           83           GBR
2         2020     Netflix Original             71           73           GBR
3         2020     Netflix Original             55           50           USA
4         2020     Netflix Original             71           73           USA
5         2020     Netflix Original             55           50           AUS
6         2020     Netflix Original             71           73           AUS
                                                       Show_link Continent Average_rating
1 https://flixpatrol.com/title/charlie-and-the-chocolate-factory       EUR           75.0
2                         https://flixpatrol.com/title/away-2020       EUR           72.0
3                   https://flixpatrol.com/title/love-guaranteed       AME           52.5
4                         https://flixpatrol.com/title/away-2020       AME           72.0
5                   https://flixpatrol.com/title/love-guaranteed       OCE           52.5
6                         https://flixpatrol.com/title/away-2020       OCE           72.0

The Average.rating variable was converted from impute to numeric data type to allow for scanning of outliers in the further steps of preprocessing the data. This was completed by using the as.numeric() function as shown below.

Tidy_NF$Average_rating <- as.numeric(Tidy_NF$Average_rating)

Scan II

To scan for outliers in the numerical variable columns, the “Tukey’s method of outlier detection” in the boxplot was used. Boxplots were chosen as the methodology as the variables were univariate. Outliers are those values that are outside the “outlier fences” and are depicted as an “o” symbol on the boxplot. Four numerical variables in the data set were scanned for outliers using boxplots as shown below.

Tidy_NF$Week %>% boxplot(main = "Box Plot of Week", 
                         ylab = "Week", col = "grey")

Tidy_NF$`IMDB_rating(%)` %>% boxplot(main = "Box Plot of IMDB Rating", 
                                     ylab = "IMDB Rating", col = "grey")

Tidy_NF$`RT_rating(%)` %>% boxplot(main = "Box Plot of RT Rating", 
                                   ylab = "RT Rating", col = "grey")

Tidy_NF$Average_rating %>% boxplot(main = "Box Plot of Average Rating", 
                                   ylab = "Average Rating", col = "grey")

As shown above, the only numerical variable containing outliers is the RT_rating. This may be due to the imputation of the mean for missing values earlier in the preprocessing steps. The chosen method of dealing with the outliers was capping. This was done by establishing the cap function and then using the sapply() function as shown below. The summary() function was then used to show the summary statistics of the RT_rating(%) variable.

cap <- function(x){
    quantiles <- quantile( x, c(.05, 0.25, 0.75, .95 ) )
    x[ x < quantiles[2] - 1.5*IQR(x) ] <- quantiles[1]
    x[ x > quantiles[3] + 1.5*IQR(x) ] <- quantiles[4]
    x
}
Tidy_NF$`RT_rating(%)` <- sapply(Tidy_NF$`RT_rating(%)`, FUN = cap)
summary(Tidy_NF$`RT_rating(%)`)
   Min. 1st Qu.  Median    Mean 3rd Qu.    Max. 
  19.00   63.00   67.00   66.86   80.00  100.00 

Transform

The variable that was chosen to be transformed was Average_rating. This variable was chosen as it has a slight left-skewness as shown below by using the histogram() function.

histogram(Tidy_NF$Average_rating)

The chosen transformation function for the Average_rating variable was Box-Cox transformation. This was chosen as the data shows slight non-normal distribution and requires transformation to a more “normal” distribution. The BoxCox() function was used along with the histogram() function to show the transformation of the Average_rating variable as shown below. The distribution has changed from a slight left-skewed to one that is similar to bi-modal. This new distribution will help provide understanding about average rating across the top movies/TV shows in the three countries.

boxcox_NF <- BoxCox(Tidy_NF$Average_rating, lambda = "auto")
histogram(boxcox_NF)

LS0tDQp0aXRsZTogIk1BVEgyMzQ5IERhdGEgV3JhbmdsaW5nIg0KYXV0aG9yOiAiTGFpbmUgSGVpZGVucmVpY2ggczM4NjY0NjMiDQpzdWJ0aXRsZTogQXNzaWdubWVudCAyDQpvdXRwdXQ6DQogIGh0bWxfbm90ZWJvb2s6IGRlZmF1bHQNCiAgaHRtbF9kb2N1bWVudDoNCiAgICBkZl9wcmludDogcGFnZWQNCiAgcGRmX2RvY3VtZW50OiBkZWZhdWx0DQogIHdvcmRfZG9jdW1lbnQ6IGRlZmF1bHQNCi0tLQ0KDQojIyBSZXF1aXJlZCBwYWNrYWdlcyANCg0KVGhlIGZvbGxvd2luZyBwYWNrYWdlcyB3ZXJlIGluc3RhbGxlZCBhbmQgbG9hZGVkIHRvIGJlIHVzZWQgaW4gdGhlIHJlcG9ydDogDQoNCmBgYHtyIHdhcm5pbmc9RkFMU0V9DQpsaWJyYXJ5KHJlYWRyKQ0KbGlicmFyeShmb3JlaWduKQ0KbGlicmFyeShnZGF0YSkNCmxpYnJhcnkocnZlc3QpDQpsaWJyYXJ5KGRwbHlyKQ0KbGlicmFyeSh0aWR5cikNCmxpYnJhcnkoa25pdHIpDQpsaWJyYXJ5KGRlZHVjdGl2ZSkNCmxpYnJhcnkodmFsaWRhdGUpDQpsaWJyYXJ5KEhtaXNjKQ0KbGlicmFyeShzdHJpbmdyKQ0KbGlicmFyeShvdXRsaWVycykNCmxpYnJhcnkoTVZOKQ0KbGlicmFyeShmb3JlY2FzdCkNCmxpYnJhcnkoaW5mb3RoZW8pDQpsaWJyYXJ5KGx1YnJpZGF0ZSkNCmBgYA0KDQoNCiMjIEV4ZWN1dGl2ZSBTdW1tYXJ5IA0KDQpUaGUgZmlyc3Qgc3RlcCBvZiBwcmVwcm9jZXNzaW5nIHRoZSBkYXRhIHdhcyB0byBpbXBvcnQgdGhlIGRhdGEgc2V0cyBpbnRvIFIgdXNpbmcgdGhlIHJlYWQuY3N2KCkgZnVuY3Rpb24uIFRoZSBuZXh0IHN0ZXAgd2FzIHRvIGNvbWJpbmUgdGhlIHRocmVlIGltcG9ydGVkIGRhdGEgc2V0cyB1c2luZyByYmluZCgpIHRvIHByb2R1Y2UgdGhlIG1haW4gZGF0YSBzZXQgdGhhdCB3aWxsIGJlIHVzZWQgdGhyb3VnaG91dCB0aGUgcHJvY2Vzcy4gQ2hlY2tpbmcgdGhlIGRhdGEgdHlwZXMgb2YgdGhlIHZhcmlhYmxlcyBmb2xsb3dlZCB1c2luZyBnbGltcHNlKCkuIE9mIHRoZSB0d2VsdmUgdmFyaWFibGVzIGluIHRoZSBkYXRhIHNldCwgc2l4IHZhcmlhYmxlcyB3ZXJlIGNvbnZlcnRlZCBmcm9tIGNoYXJhY3RlciB0byBmYWN0b3IgdXNpbmcgYXMuZmFjdG9yKCkgd2l0aCB0aGUgSXNfTkZfT3JpZ2luYWwgdmFyaWFibGUgYmVpbmcgbGFiZWxsZWQgdXNpbmcgZmFjdG9yKCkuIFR3byB2YXJpYWJsZXMgd2VyZSBhbHNvIGNvbnZlcnRlZCBmcm9tIGNoYXJhY3RlciB0byBudW1lcmljIHVzaW5nIGFzLm51bWVyaWMoKS4gVGhlIHNlcGFyYXRlKCkgZnVuY3Rpb24gd2FzIHRoZW4gdXNlZCB0byBmb3JtIG11bHRpcGxlIGNvbHVtbiBmcm9tIG9uZSB0byB0aWR5IHRoZSBkYXRhIHNldC4gVGhlIGRhdGEgc2V0IHdhcyBzY2FubmVkIGZvciBtaXNzaW5nIHZhbHVlcyBieSB1c2luZyB0aGUgc3VtKGlzLm5hKCkpIGFuZCBjb2xTdW1zKGlzLm5hKCkpIHRvIGlkZW50aWZ5IHRoZSB0b3RhbCBudW1iZXIgb2YgbWlzc2luZyB2YWx1ZXMgYW5kIHdoaWNoIGNvbHVtbnMgY29udGFpbiB0aGVzZSB2YWx1ZXMsIHJlc3BlY3RpdmVseS4gVGhlIG1pc3NpbmcgdmFsdWVzIGluIHRoZSBSVF9yYXRpbmcgY29sdW1uIHdlcmUgaW1wdXRlZCB1c2luZyB0aGUgbWVhbiBvZiB0aGUgdmFyaWFibGUuIFRoZSBpcy5zcGVjaWFsIGZ1bmN0aW9uIHdhcyBjcmVhdGVkIHRvIGlkZW50aWZ5IGFsbCBudW1lcmljYWwgdmFyaWFibGVzIGZvciBzcGVjaWFsIHZhbHVlcyAoaW5maW5pdGUgYW5kIE5hTikgYW5kIHRoZW4gdXNpbmcgc2FwcGx5KCkgdG8gc2NhbiB0aGUgZGF0YS4gQm94cGxvdHMgd2VyZSB0aGVuIHVzZWQgdG8gc2NhbiBhbGwgbnVtZXJpY2FsIHZhcmlhYmxlcyBmb3Igb3V0bGllcnMuIFRoZSBSVF9yYXRpbmcgdmFyaWFibGUgc2hvd2VkIHRvIGhhdmUgb3V0bGllcnMgd2hpY2ggd2VyZSBkZWFsdCB3aXRoIGJ5IHRoZSBtZXRob2Qgb2YgY2FwcGluZyB1c2luZyB0aGUgc2FwcGx5KCkgZnVuY3Rpb24uIFRoZSBkaXN0cmlidXRpb24gb2YgdGhlIEF2ZXJhZ2VfcmF0aW5nIHZhcmlhYmxlcyB3YXMgY2hlY2tlZCB1c2luZyBoaXN0b2dyYW0oKSBhbmQgd2FzIHRyYW5zZm9ybWVkIHVzaW5nIHRoZSBCb3hDb3goKSBmdWNudGlvbi4gQWZ0ZXIgY29tcGxldGluZyBhbGwgb2YgdGhlIHByZXByb2Nlc3Npbmcgc3RlcHMgdGhlIGRhdGEgaXMgdGhlbiByZWFkeSBmb3IgYW5hbHlzaXMuIA0KDQoNCg0KIyMgRGF0YSANCg0KVGhlIGRhdGEgc2V0cyB3ZXJlIGZvdW5kIG9uIHRoZSBLYWdnbGUgd2Vic2l0ZSBhbmQgY2FuIGJlIGFjY2Vzc2VkIHVzaW5nIHRoZSBmb2xsb3dpbmcgVVJMIGxpbms6IGh0dHBzOi8vd3d3LmthZ2dsZS5jb20vaW50YW5kZWEvbmV0ZmxpeDIwMjAuIFRoZSB0aHJlZSBkYXRhIHNldHMgY2hvc2VuIHdlcmUgb2YgdGhlIHdlZWtseSBudW1iZXIgb25lIG5ldGZsaXggbW92aWUgYW5kIFRWIHNob3cgaW4gQXVzdHJhbGlhIChBVVNfTkYpLCBHcmVhdCBCcml0YWluIChHQlJfTkYpIGFuZCBUaGUgVW5pdGVkIFN0YXRlcyBvZiBBbWVyaWNhIChVU0FfTkYpLiBUaGUgZGF0YSBzZXRzIGluY2x1ZGUgMTIgdmFyaWFibGVzLCB3aGljaCBhcmUgbGlzdGVkIGJlbG93OiANCg0KKiBXZWVrOiB3ZWVrIHdoZW4gdGhlIG1vdmllL3Nob3cgd2FzICMxDQoqIFNob3dfdHlwZTogdHlwZSBvZiBzaG93IChtb3ZpZSwgVFYgc2hvdywgZG9jdW1lbnRhcnksIGV0Yy4pDQoqIFRpdGxlOiB0aXRsZSBvZiB0aGUgbW92aWUvc2hvdw0KKiBPcmlfY291bnRyeTogY291bnRyeSB3aGVyZSB0aGUgc2hvdyBpcyBmcm9tDQoqIEdlbnJlOiBnZW5yZSBvZiB0aGUgbW92aWUvc2hvdw0KKiBSZWxlYXNlX2RhdGU6IHJlbGVhc2UgZGF0ZSBvZiBtb3ZpZS9zaG93DQoqIElzTkZPcmk6IGlzIHRoZSBtb3ZpZS9zaG93IGEgTmV0ZmxpeCBvcmlnaW5hbD8NCipJbWRiX3JhdGluZzogSU1EQiByYXRpbmcgb2YgdGhlIG1vdmllL3Nob3cNCiogUnRfcmF0aW5nOiBSb3R0ZW4gVG9tYXRvZXMgcmF0aW5nIG9mIHRoZSBtb3ZpZS9zaG93DQoqIENvdW50cnlfY2hhcnQ6IHdoYXQgY291bnRyeSB0aGUgbW92aWUvc2hvdyBpcyAjMSANCiogU2hvd19saW5rOiBVUkwgZm9yIGRlc2NyaXB0aW9uIG9mIHRoZSBtb3ZpZS9zaG93IGluIEZsaXhQYXRyb2wNCiogQ29udGluZW50OiBjb250aW5lbnQgb2YgdGhlIGNvdW50cnkgY2hhcnQgDQoNClRoZSB0aHJlZSBkYXRhIHNldHMgY2hvc2VuIHdlcmUgaW1wb3J0ZWQgaW50byBSIHVzaW5nIHRoZSByZWFkLmNzdigpIGZ1bmN0aW9uIGFzIHNob3duIGJlbG93LiBUaGUgYXJndW1lbnQgc3RyaW5nQXNGYWN0b3JzID0gRkFMU0Ugd2FzIHVzZWQgdG8gc3RpcHVsYXRlIHRvIFIgbm90IHRvIGNvbnZlcnQgYWxsIGNoYXJhY3RlcnMgaW50byBmYWN0b3JzLiBBIGhlYWQgb2YgdGhlIGRhdGEgc2V0cyB3ZXJlIHByb2R1Y2VkLiANCg0KYGBge3J9DQpBVVNfTkYgPC0gcmVhZC5jc3YoIkQ6L1JNSVQvU2VtZXN0ZXIgMiAyMDIwL01BVEgyMzQ5L0Fzc2lnbm1lbnQgMi9BVVNfTkYuY3N2Iiwgc3RyaW5nc0FzRmFjdG9ycyA9IEZBTFNFKQ0KcHJpbnQuZGF0YS5mcmFtZShoZWFkKEFVU19ORikpDQpgYGANCg0KYGBge3J9DQpHQlJfTkYgPC0gcmVhZC5jc3YoIkQ6L1JNSVQvU2VtZXN0ZXIgMiAyMDIwL01BVEgyMzQ5L0Fzc2lnbm1lbnQgMi9HQlJfTkYuY3N2Iiwgc3RyaW5nc0FzRmFjdG9ycyA9IEZBTFNFKQ0KcHJpbnQuZGF0YS5mcmFtZShoZWFkKEdCUl9ORikpDQpgYGANCg0KYGBge3J9DQpVU0FfTkYgPC0gcmVhZC5jc3YoIkQ6L1JNSVQvU2VtZXN0ZXIgMiAyMDIwL01BVEgyMzQ5L0Fzc2lnbm1lbnQgMi9VU0FfTkYuY3N2Iiwgc3RyaW5nc0FzRmFjdG9ycyA9IEZBTFNFKQ0KcHJpbnQuZGF0YS5mcmFtZShoZWFkKFVTQV9ORikpDQpgYGANCg0KVGhlIHRocmVlIGRhdGEgc2V0cyB3ZXJlIG1lcmdlZCB0b2dldGhlciB0byBjcmVhdGUgdGhlIG1haW4gZGF0YSBzZXQgZm9yIHRoZSByZXBvcnQgdXNpbmcgdGhlIHJiaW5kKCkgZnVuY3Rpb24uIFRoZSBvcHRpb25zKG1heC5wcmludCA9IDEwMDAwKSBmdW5jdGlvbiB3YXMgdXNlZCB0byBpbmNyZWFzZSB0aGUgbGltaXQgb2YgbWF4LnByaW50IHNvIHRoYXQgcm93cyB3ZXJlIG5vdCBvbWl0dGVkIHdoZW4gY29tYmluaW5nIHRoZSBkYXRhIHNldHMuIFRoZSBhcnJhbmdlKGRlc2MoKSlmdW5jdGlvbiB3YXMgdXNlZCB0byBvcmRlciB0aGUgY29tYmluZWQgZGF0YSBpbiBkZXNjZWRpbmcgb3JkZXIgc28gYWxsIHJlc3VsdHMgZm9yIHdlZWsgMzcsIGV0Yy4gd2VyZSB0b2dldGhlci4gDQoNCmBgYHtyfQ0Kb3B0aW9ucyhtYXgucHJpbnQgPSAxMDAwMCkNCmNvbWJpbmVkIDwtIEdCUl9ORiAlPiUgcmJpbmQoVVNBX05GLCBBVVNfTkYpDQpORl9jb21iaW5lZCA8LSBjb21iaW5lZCAlPiUgYXJyYW5nZShkZXNjKHdlZWspKQ0KcHJpbnQuZGF0YS5mcmFtZShoZWFkKE5GX2NvbWJpbmVkKSkNCmBgYA0KDQpUaGUgY29sbmFtZXMoKSBmdW5jdGlvbiB3YXMgdXNlZCB0byBjaGFuZ2UgdGhlIGNvbHVtbiBuYW1lcyBpbiB0aGUgbWFpbiBkYXRhIHNldC4gDQoNCmBgYHtyfQ0KY29sbmFtZXMoTkZfY29tYmluZWQpIDwtIGMoIldlZWsiLCAiU2hvd190eXBlIiwgIlRpdGxlIiwgIk9yaWdpbl9jb3VudHJ5IiwgDQogICAgICAgICAgICAgICAgICAgICAgICAgICAiR2VucmUiLCAiUmVsZWFzZV9kYXRlIiwgIklzX05GX29yaWdpbmFsIiwgDQogICAgICAgICAgICAgICAgICAgICAgICAgICAiSU1EQl9yYXRpbmcoJSkiLCAiUlRfcmF0aW5nKCUpIiwgIkNvdW50cnlfY2hhcnQiLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgIlNob3dfbGluayIsICJDb250aW5lbnQiKQ0KcHJpbnQuZGF0YS5mcmFtZShoZWFkKE5GX2NvbWJpbmVkKSkNCmBgYA0KDQoNCiMjIFVuZGVyc3RhbmQgDQoNClRoZSBkaW1lbnNpb25zIGFuZCBzdHJ1Y3R1cmUgb2YgdGhlIGRhdGEgc2V0IHdlcmUgY2hlY2tlZCB1c2luZyB0aGUgZ2xpbXBzZSgpIGZ1bmN0aW9uIHdoaWNoIHNob3dlZCB0aGUgZGltZW5zaW9ucyB0byBiZSAxNTQgcm93cyBhbmQgMTIgY29sdW1ucy4gVGhlIHNhbWUgZnVuY3Rpb24gd2FzIHVzZWQgdG8gY2hlY2sgdGhlIGRhdGEgdHlwZXMgb2YgdGhlIHZhcmlhYmxlcyBpbiB0aGUgZGF0YSBzZXQuIEl0IHNob3dlZCB0aGF0IGNvbHVtbiBvbmUgaXMgYSBudW1lcmljIHZhcmlhYmxlLCBjb2x1bW4gc2V2ZWwgaXMgYSBsb2dpY2FsIHZhcmlhYmxlIGFuZCB0aGUgb3RoZXIgdGVuIGNvbHVtbnMgYXJlIGFsbCBjaGFyYWN0ZXIgdmFyaWFibGVzLiBNdWx0aXBsZSB2YXJpYWJsZXMgcmVxdWlyZSBkYXRhIHR5cGUgY29udmVyc2lvbi4gDQoNCmBgYHtyfQ0KZ2xpbXBzZShORl9jb21iaW5lZCkNCmBgYA0KVGhlIGZvbGxvd2luZyB2YXJpYWJsZXMgd2VyZSBjb252ZXJ0ZWQgZnJvbSBjaGFyYWN0ZXIgdG8gZmFjdG9yIHVzaW5nIHRoZSBhcy5mYWN0b3IoKSBmdW5jdGlvbi4gVGhlIGxldmVscygpIGZ1bmN0aW9uIHdhcyB1c2VkIHRvIGNoZWNrIHRoZSBsZXZlbHMgb2YgdGhlIGZhY3RvciB2YXJpYWJsZSBhbmQgc2VlIGlmIGFueSBvZiB0aGUgdmFyaWFibGVzIG5lZWRlZCB0byBiZSBsYWJlbGxlZCBhbmQvb3Igb3JkZXJlZC4gDQoNCiogU2hvd190eXBlIA0KDQpgYGB7cn0NCk5GX2NvbWJpbmVkJFNob3dfdHlwZSA8LSBhcy5mYWN0b3IoTkZfY29tYmluZWQkU2hvd190eXBlKQ0KbGV2ZWxzKE5GX2NvbWJpbmVkJFNob3dfdHlwZSkNCmBgYA0KDQoqIE9yaWdpbl9jb3VudHJ5ICANCg0KYGBge3J9DQpORl9jb21iaW5lZCRPcmlnaW5fY291bnRyeSA8LSBhcy5mYWN0b3IoTkZfY29tYmluZWQkT3JpZ2luX2NvdW50cnkpDQpsZXZlbHMoTkZfY29tYmluZWQkT3JpZ2luX2NvdW50cnkpDQpgYGANCg0KKiBHZW5yZSANCg0KYGBge3J9DQpORl9jb21iaW5lZCRHZW5yZSA8LSBhcy5mYWN0b3IoTkZfY29tYmluZWQkR2VucmUpDQpsZXZlbHMoTkZfY29tYmluZWQkR2VucmUpDQpgYGANCg0KKiBDb3VudHJ5X2NoYXJ0ICANCg0KYGBge3J9DQpORl9jb21iaW5lZCRDb3VudHJ5X2NoYXJ0IDwtIGFzLmZhY3RvcihORl9jb21iaW5lZCRDb3VudHJ5X2NoYXJ0KQ0KbGV2ZWxzKE5GX2NvbWJpbmVkJENvdW50cnlfY2hhcnQpDQpgYGANCg0KKiBDb250aW5lbnQgDQoNCmBgYHtyfQ0KTkZfY29tYmluZWQkQ29udGluZW50IDwtIGFzLmZhY3RvcihORl9jb21iaW5lZCRDb250aW5lbnQpDQpsZXZlbHMoTkZfY29tYmluZWQkQ29udGluZW50KQ0KYGBgDQoNClRoZSB2YXJpYWJsZSBJc19ORl9vcmlnaW5hbCB3YXMgY29udmVydGVkIGZyb20gYSBsb2dpY2FsIGRhdGEgdHlwZSB0byBhIGZhY3RvciBkYXRhIHR5cGUgdXNpbmcgdGhlIGFzLmZhY3RvcigpIGZ1bmN0aW9uLiBUaGUgbGV2ZWxzKCkgZnVuY3Rpb24gd2FzIHVzZWQgdG8gY2hlY2sgdGhlIGxldmVscyBvZiB0aGUgZmFjdG9yIHZhcmlhYmxlLiBUaGUgZmFjdG9yKCkgZnVuY3Rpb24gd2FzIHRoZW4gdXNlZCB0byBjaGFuZ2UgdGhlIGxhYmVscyBhc3NpZ25lZCB0byB0aGUgZGlmZmVyZW50IGxldmVscyBvZiB0aGUgdmFyaWFibGUuIExhc3RseSwgbGV2ZWxzKCkgZnVuY3Rpb24gd2FzIHVzZWQgYWdhaW4gdG8gY2hlY2sgdGhlIG5ldyBsZXZlbHMgb2YgdGhlIHZhcmlhYmxlLiANCg0KYGBge3J9DQpORl9jb21iaW5lZCRJc19ORl9vcmlnaW5hbCA8LSBhcy5mYWN0b3IoTkZfY29tYmluZWQkSXNfTkZfb3JpZ2luYWwpDQpsZXZlbHMoTkZfY29tYmluZWQkSXNfTkZfb3JpZ2luYWwpDQpORl9jb21iaW5lZCRJc19ORl9vcmlnaW5hbCA8LSBORl9jb21iaW5lZCRJc19ORl9vcmlnaW5hbCAlPiUgDQogIGZhY3RvcihsZXZlbHMgPSBjKCJGQUxTRSIsICJUUlVFIiksIA0KICAgICAgICAgbGFiZWxzID0gYygiTm90IE5ldGZsaXggT3JpZ2luYWwiLCAiTmV0ZmxpeCBPcmlnaW5hbCIpKQ0KbGV2ZWxzKE5GX2NvbWJpbmVkJElzX05GX29yaWdpbmFsKQ0KYGBgDQoNClRoZSBmb2xsb3dpbmcgdHdvIHZhcmlhYmxlcyB3ZXJlIGNvbnZlcnRlZCBmcm9tIGNoYXJhY3RlciB0byBudW1lcmljIHVzaW5nIHRoZSBhcy5udW1lcmljKCkgZnVuY3Rpb24uIFRoZSBzdWIoKSBmdW5jdGlvbiB3YXMgdXNlZCB0byByZW1vdmUgdGhlICIlIiBpbiB0aGUgcm93cyBzbyB0aGF0IHRoZSB2YXJpYWJsZSBjb3VsZCBiZSBjaGFuZ2VkIHRvIGEgbnVtZXJpYyBkYXRhIHR5cGUuIFRoZSAiJSIgd2FzIG5vdCBuZWVkZWQgYXQgdGhlIGNvbHVtbiBuYW1lIGV4cGxhaW5zIHRoYXQgdGhlIG51bWVyaWMgdmFsdWUgaW4gdGhlIHJvdyBpcyBhIHBlcmNlbnRhZ2UuIA0KDQoqIElNREJfcmF0aW5nKCUpDQoNCmBgYHtyfQ0KTkZfY29tYmluZWQkYElNREJfcmF0aW5nKCUpYCA8LSANCiAgYXMubnVtZXJpYyhzdWIoIiUiLCAiIiwgTkZfY29tYmluZWQkYElNREJfcmF0aW5nKCUpYCkpDQpgYGANCg0KKiBSVF9yYXRpbmcoJSkNCg0KYGBge3J9DQpORl9jb21iaW5lZCRgUlRfcmF0aW5nKCUpYCA8LSANCiAgYXMubnVtZXJpYyhzdWIoIiUiLCAiIiwgTkZfY29tYmluZWQkYFJUX3JhdGluZyglKWApKQ0KYGBgDQoNCk9uY2UgYWxsIHRoZSBkYXRhIHR5cGUgY29udmVyc2lvbnMgd2VyZSBjb21wbGV0ZWQsIHRoZSBnbGltcHNlKCkgZnVuY3Rpb24gd2FzIHVzZWQgdG8gY2hlY2sgdGhhdCBhbGwgdmFyaWFibGVzIGhhZCBiZWVuIGNoYW5nZWQgaW50byB0aGUgY29ycmVjdCBkYXRhIHR5cGUuIFRoaXMgaXMgc2hvd24gYmVsb3cuIA0KDQpgYGB7cn0NCmdsaW1wc2UoTkZfY29tYmluZWQpDQpgYGANCg0KDQojIwlUaWR5ICYgTWFuaXB1bGF0ZSBEYXRhIEkgDQoNCk9uZSBvZiB0aGUgY29tbW9uIHByb2JsZW1zIHdpdGggbWVzc3kgZGF0YSBzZXRzIGlzIHRoYXQgbXVsdGlwbGUgdmFyaWFibGVzIGFyZSBzdG9yZWQgaW4gb25lIGNvbHVtbi4gVGhpcyBkb2VzIG5vdCBjb25mb3JtIHdpdGggdGhlIHRpZHkgZGF0YSBwcmluY2lwbGVzLiBUaGUgTkZfY29tYmluZWQgZGF0YSBzZXQgc2hvd3MgdGhpcyBtZXNzeSBwcm9ibGVtIGFzIHRoZSByZWxlYXNlX2RhdGUgY29sdW1uIGhhcyB0aGUgZGF5LCBtb250aCBhbmQgeWVhciBzdG9yZWQgaW4gb25lIGNvbHVtbi4gSW4gb3JkZXIgdG8gc2VwYXJhdGUgdGhlc2UgdGhyZWUgdmFyaWFibGVzIGludG8gbXVsdGlwbGUgY29sdW1ucywgdGhlIHNlcGFyYXRlKCkgZnVuY3Rpb24gZnJvbSB0aGUgdGlkeXIgcGFja2FnZSB3YXMgdXNlZC4gVGhlIHNlcCBhcmd1bWVudCB3YXMgdXNlZCB0byB0ZWxsIFIgd2hlcmUgdG8gc2VwYXJhdGUgdGhlIHZhcmlhYmxlIGludG8gbXVsdGlwbGUgY29sdW1ucy4gVGhlIGRhdGEgc2V0IHdhcyByZW5hbWVkIFRpZHlfTkYuIEhlYWQoKSB3YXMgdXNlZCB0byBzaG93IHRoZSBuZXcgY29sdW1ucyBvZiB0aGUgdGlkeSBkYXRhIHNldC4gDQoNCmBgYHtyfQ0KVGlkeV9ORiA8LSBORl9jb21iaW5lZCAlPiUgDQogIHNlcGFyYXRlKFJlbGVhc2VfZGF0ZSxpbnRvID0gYygiUmVsZWFzZV9kYXkiLCJSZWxlYXNlX21vbnRoIiwiUmVsZWFzZV95ZWFyIiksIA0KICAgICAgICAgICBzZXAgPSAiLyIpDQpwcmludC5kYXRhLmZyYW1lKGhlYWQoVGlkeV9ORikpDQpgYGANCg0KIyMJU2NhbiBJIA0KDQpUaGUgVGlkeV9ORiBkYXRhIHNldCB3YXMgc2Nhbm5lZCBmb3IgbWlzc2luZyB2YWx1ZXMgZmlyc3QgdXNpbmcgdGhlIHN1bShpcy5uYSgpKSBmdW5jdGlvbnMgdG8gc2hvdyB0aGUgdG90YWwgY291bnQgb2YgbWlzc2luZyB2YWx1ZXMgaW4gdGhlIGRhdGEuIFRoZSBjb2xTdW1zKGlzLm5hKCkpIGZ1bmN0aW9ucyB3ZXJlIHRoZW4gdXNlIHRvIHNlZSB3aGljaCBjb2x1bW5zIGluIHRoZSBkYXRhIHNldCBjb250YWluZWQgdGhlIG1pc3NpbmcgdmFsdWVzLiBUaGUgdHdvIGZ1bmN0aW9ucyBzaG93ZWQgdGhhdCB0aGVyZSB3YXMgYSB0b3RhbCBvZiA0MCBtaXNzaW5nIHZhbHVlcyBpbiB0aGUgZGF0YSBhbmQgd2VyZSBhbGwgY29udGFpbmVkIGluIHRoZSBSVF9yYXRpbmcoJSkgY29sdW1uLiBUaGUgbWV0aG9kb2xvZ3kgYWJvdmUgd2FzIGNob3NlbiB0byBzZWUgd2hpY2ggY29sdW1ucyBvZiB0aGUgZGF0YSBzZXQgaGFkIHRoZSBtaXNzaW5nIHZhbHVlcyBhbmQgdG8gZGV0ZXJtaW5lIHdoYXQgd291bGQgYmUgdGhlIGNvcnJlY3QgYWN0aW9ucyBmb3IgZGVhbGluZyB3aXRoIHRoZSBtaXNzaW5nIHZhbHVlcyBhY2NvcmRpbmcgdG8gdGhlIGRhdGEgdHlwZSBvZiB0aGUgdmFyaWFibGVzLiANCg0KYGBge3J9DQpzdW0oaXMubmEoVGlkeV9ORikpDQpjb2xTdW1zKGlzLm5hKFRpZHlfTkYpKQ0KYGBgDQoNClRoZSBhY3Rpb24gdGFrZW4gdG8gZGVhbCB3aXRoIHRoZSBtaXNzaW5nIHZhbHVlcyB3YXMgdG8gdXNlIHRoZSBpbXB1dGUoKSBmdW5jdGlvbiBmcm9tIHRoZSBIbWlzYyBwYWNrYWdlLiBUaGUgZGVjaXNpb24gd2FzIHRvIGltcHV0ZSB0aGUgbWVhbiBmb3IgdGhlIG1pc3NpbmcgdmFsdWVzIGluIHRoZSBSVF9yYXRpbmcoJSkgY29sdW1uLiBUaGlzIGFjdGlvbiB3YXMgbWFkZSBhcyBpdCBpcyBhIG5hdHVyYWwgd2F5IG9mIHJlcGxhY2luZyBtaXNzaW5nIHZhbHVlcyBmb3IgbnVtZXJpYyB2YXJpYWJsZXMuIFRoZSByb3VuZCgpIGZ1bmN0aW9uIHdhcyB1c2VkIHRvIHRpZHkgdXAgdGhlIGNvbHVtbiBhbmQgcHJlcGFyZSB2YWx1ZXMgdGhhdCBjYW4gYmUgdXNlZCBmb3IgYW5hbHlzaXMuIA0KDQpgYGB7cn0NClRpZHlfTkYkYFJUX3JhdGluZyglKWAgPC0gaW1wdXRlKFRpZHlfTkYkYFJUX3JhdGluZyglKWAsIGZ1biA9IG1lYW4pDQpUaWR5X05GJGBSVF9yYXRpbmcoJSlgIDwtIHJvdW5kKFRpZHlfTkYkYFJUX3JhdGluZyglKWApDQpgYGANCg0KVGhlIFJUX3JhdGluZyglKSB2YXJpYWJsZSB3YXMgcmUtY29udmVydGVkIHRvIGEgbnVtZXJpYyBkYXRhIHR5cGUgYWZ0ZXIgaW1wdXRpbmcgb2YgbWlzc2luZyB2YWx1ZXMgd2FzIGNvbXBsZXRlZC4gVGhpcyB3YXMgdG8gaGVscCB3aXRoIHRoZSBzY2FubmluZyBvZiBvdXRsaWVycyBpbiB0aGUgZnVydGhlciBzdGVwcyBvZiBwcmVwcm9jZXNzaW5nLiANCg0KYGBge3J9DQpUaWR5X05GJGBSVF9yYXRpbmcoJSlgIDwtIGFzLm51bWVyaWMoVGlkeV9ORiRgUlRfcmF0aW5nKCUpYCkNCmBgYA0KDQoNClNwZWNpYWwgdmFsdWVzIHdlcmUgc2Nhbm5lZCBieSBmaXJzdCBlc3RhYmxpc2hpbmcgYSBpcy5zcGVjaWFsIGZ1bmN0aW9uLCB3aGljaCBjaGVja3MgZXZlcnkgbnVtZXJpY2FsIGNvbHVtbiB0byBpZGVudGlmeSB3aGV0aGVyIHRoZXkgaGF2ZSBpbmZpbml0ZSBvciBOYU4gdmFsdWVzLiBUaGUgc2FwcGx5KCkgZnVuY3Rpb24sIGZyb20gdGhlIGFwcGx5IGZhbWlseSBmdW5jdGlvbnMsIHdhcyB0aGVuIHVzZWQgdG8gc2NhbiB0aGUgZGF0YSBmb3IgYW55IHNwZWNpYWwgdmFsdWVzLiBUaGlzIGlzIHNob3duIGJlbG93LiANCg0KYGBge3J9DQppcy5zcGVjaWFsIDwtIGZ1bmN0aW9uKHgpew0KICBpZiAoaXMubnVtZXJpYyh4KSkgKGlzLmluZmluaXRlKHgpIHwgaXMubmFuKHgpKQ0KfQ0Kc2FwcGx5KFRpZHlfTkYsIGlzLnNwZWNpYWwpDQpgYGANCg0KDQojIwlUaWR5ICYgTWFuaXB1bGF0ZSBEYXRhIElJIA0KDQpBIG5ldyB2YXJpYWJsZSB3YXMgY3JlYXRlZCBhbmQgYWRkZWQgdG8gdGhlIGRhdGEgc2V0IGZyb20gdHdvIGV4aXN0aW5nIHZhcmlhYmxlcy4gVGhlIG5ldyB2YXJpYWJsZSwgQXZlcmFnZV9yYXRpbmcsIHdhcyBjcmVhdGVkIGZyb20gdGhlIElNREJfcmF0aW5nKCUpIGFuZCBSVF9yYXRpbmcoJSkgdmFyaWFibGVzIHVzaW5nIHRoZSBtdXRhdGUoKSBmdW5jdGlvbi4gVGhlIHR3byBleGlzdGluZyB2YXJpYWJsZXMgd2VyZSBhZGRlZCB0b2dldGhlciBhbmQgdGhlbiBkaXZpZGVkIGJ5IDIgdG8gZ2l2ZSBhbiBhdmVyYWdlIHJhdGluZyBmb3IgZWFjaCBtb3ZpZS9zaG93IGluIHRoZSBkYXRhIHNldC4gVGhlIGhlYWQoKSBmdW5jdGlvbiB3YXMgdXNlZCB0byBzaG93IHRoZSBuZXcgdmFyaWFibGUgaW4gdGhlIGRhdGEgc2V0LiANCg0KYGBge3J9DQpUaWR5X05GIDwtIA0KICBtdXRhdGUoVGlkeV9ORiwgDQogICAgICAgICBBdmVyYWdlX3JhdGluZyA9IChUaWR5X05GJGBJTURCX3JhdGluZyglKWAgKyBUaWR5X05GJGBSVF9yYXRpbmcoJSlgKS8yKQ0KcHJpbnQuZGF0YS5mcmFtZShoZWFkKFRpZHlfTkYpKQ0KYGBgDQoNClRoZSBBdmVyYWdlLnJhdGluZyB2YXJpYWJsZSB3YXMgY29udmVydGVkIGZyb20gaW1wdXRlIHRvIG51bWVyaWMgZGF0YSB0eXBlIHRvIGFsbG93IGZvciBzY2FubmluZyBvZiBvdXRsaWVycyBpbiB0aGUgZnVydGhlciBzdGVwcyBvZiBwcmVwcm9jZXNzaW5nIHRoZSBkYXRhLiBUaGlzIHdhcyBjb21wbGV0ZWQgYnkgdXNpbmcgdGhlIGFzLm51bWVyaWMoKSBmdW5jdGlvbiBhcyBzaG93biBiZWxvdy4gDQpgYGB7cn0NClRpZHlfTkYkQXZlcmFnZV9yYXRpbmcgPC0gYXMubnVtZXJpYyhUaWR5X05GJEF2ZXJhZ2VfcmF0aW5nKQ0KYGBgDQoNCg0KIyMJU2NhbiBJSQ0KDQpUbyBzY2FuIGZvciBvdXRsaWVycyBpbiB0aGUgbnVtZXJpY2FsIHZhcmlhYmxlIGNvbHVtbnMsIHRoZSAiVHVrZXkncyBtZXRob2Qgb2Ygb3V0bGllciBkZXRlY3Rpb24iIGluIHRoZSBib3hwbG90IHdhcyB1c2VkLiBCb3hwbG90cyB3ZXJlIGNob3NlbiBhcyB0aGUgbWV0aG9kb2xvZ3kgYXMgdGhlIHZhcmlhYmxlcyB3ZXJlIHVuaXZhcmlhdGUuIE91dGxpZXJzIGFyZSB0aG9zZSB2YWx1ZXMgdGhhdCBhcmUgb3V0c2lkZSB0aGUgIm91dGxpZXIgZmVuY2VzIiBhbmQgYXJlIGRlcGljdGVkIGFzIGFuICJvIiBzeW1ib2wgb24gdGhlIGJveHBsb3QuIEZvdXIgbnVtZXJpY2FsIHZhcmlhYmxlcyBpbiB0aGUgZGF0YSBzZXQgd2VyZSBzY2FubmVkIGZvciBvdXRsaWVycyB1c2luZyBib3hwbG90cyBhcyBzaG93biBiZWxvdy4gDQoNCiogV2VlayANCg0KYGBge3J9DQpUaWR5X05GJFdlZWsgJT4lIGJveHBsb3QobWFpbiA9ICJCb3ggUGxvdCBvZiBXZWVrIiwgDQogICAgICAgICAgICAgICAgICAgICAgICAgeWxhYiA9ICJXZWVrIiwgY29sID0gImdyZXkiKQ0KYGBgDQoNCiogSU1EQl9yYXRpbmcoJSkNCg0KYGBge3J9DQpUaWR5X05GJGBJTURCX3JhdGluZyglKWAgJT4lIGJveHBsb3QobWFpbiA9ICJCb3ggUGxvdCBvZiBJTURCIFJhdGluZyIsIA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHlsYWIgPSAiSU1EQiBSYXRpbmciLCBjb2wgPSAiZ3JleSIpDQpgYGANCg0KKiBSVF9yYXRpbmcoJSkNCg0KYGBge3J9DQpUaWR5X05GJGBSVF9yYXRpbmcoJSlgICU+JSBib3hwbG90KG1haW4gPSAiQm94IFBsb3Qgb2YgUlQgUmF0aW5nIiwgDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHlsYWIgPSAiUlQgUmF0aW5nIiwgY29sID0gImdyZXkiKQ0KYGBgDQoNCiogQXZlcmFnZV9yYXRpbmcgDQoNCmBgYHtyfQ0KVGlkeV9ORiRBdmVyYWdlX3JhdGluZyAlPiUgYm94cGxvdChtYWluID0gIkJveCBQbG90IG9mIEF2ZXJhZ2UgUmF0aW5nIiwgDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHlsYWIgPSAiQXZlcmFnZSBSYXRpbmciLCBjb2wgPSAiZ3JleSIpDQpgYGANCg0KQXMgc2hvd24gYWJvdmUsIHRoZSBvbmx5IG51bWVyaWNhbCB2YXJpYWJsZSBjb250YWluaW5nIG91dGxpZXJzIGlzIHRoZSBSVF9yYXRpbmcuIFRoaXMgbWF5IGJlIGR1ZSB0byB0aGUgaW1wdXRhdGlvbiBvZiB0aGUgbWVhbiBmb3IgbWlzc2luZyB2YWx1ZXMgZWFybGllciBpbiB0aGUgcHJlcHJvY2Vzc2luZyBzdGVwcy4gVGhlIGNob3NlbiBtZXRob2Qgb2YgZGVhbGluZyB3aXRoIHRoZSBvdXRsaWVycyB3YXMgY2FwcGluZy4gVGhpcyB3YXMgZG9uZSBieSBlc3RhYmxpc2hpbmcgdGhlIGNhcCBmdW5jdGlvbiBhbmQgdGhlbiB1c2luZyB0aGUgc2FwcGx5KCkgZnVuY3Rpb24gYXMgc2hvd24gYmVsb3cuIFRoZSBzdW1tYXJ5KCkgZnVuY3Rpb24gd2FzIHRoZW4gdXNlZCB0byBzaG93IHRoZSBzdW1tYXJ5IHN0YXRpc3RpY3Mgb2YgdGhlIFJUX3JhdGluZyglKSB2YXJpYWJsZS4gDQoNCmBgYHtyfQ0KY2FwIDwtIGZ1bmN0aW9uKHgpew0KICAgIHF1YW50aWxlcyA8LSBxdWFudGlsZSggeCwgYyguMDUsIDAuMjUsIDAuNzUsIC45NSApICkNCiAgICB4WyB4IDwgcXVhbnRpbGVzWzJdIC0gMS41KklRUih4KSBdIDwtIHF1YW50aWxlc1sxXQ0KICAgIHhbIHggPiBxdWFudGlsZXNbM10gKyAxLjUqSVFSKHgpIF0gPC0gcXVhbnRpbGVzWzRdDQogICAgeA0KfQ0KVGlkeV9ORiRgUlRfcmF0aW5nKCUpYCA8LSBzYXBwbHkoVGlkeV9ORiRgUlRfcmF0aW5nKCUpYCwgRlVOID0gY2FwKQ0Kc3VtbWFyeShUaWR5X05GJGBSVF9yYXRpbmcoJSlgKQ0KYGBgDQoNCg0KIyMJVHJhbnNmb3JtIA0KDQpUaGUgdmFyaWFibGUgdGhhdCB3YXMgY2hvc2VuIHRvIGJlIHRyYW5zZm9ybWVkIHdhcyBBdmVyYWdlX3JhdGluZy4gVGhpcyB2YXJpYWJsZSB3YXMgY2hvc2VuIGFzIGl0IGhhcyBhIHNsaWdodCBsZWZ0LXNrZXduZXNzIGFzIHNob3duIGJlbG93IGJ5IHVzaW5nIHRoZSBoaXN0b2dyYW0oKSBmdW5jdGlvbi4NCg0KYGBge3J9DQpoaXN0b2dyYW0oVGlkeV9ORiRBdmVyYWdlX3JhdGluZykNCmBgYA0KDQpUaGUgY2hvc2VuIHRyYW5zZm9ybWF0aW9uIGZ1bmN0aW9uIGZvciB0aGUgQXZlcmFnZV9yYXRpbmcgdmFyaWFibGUgd2FzIEJveC1Db3ggdHJhbnNmb3JtYXRpb24uIFRoaXMgd2FzIGNob3NlbiBhcyB0aGUgZGF0YSBzaG93cyBzbGlnaHQgbm9uLW5vcm1hbCBkaXN0cmlidXRpb24gYW5kIHJlcXVpcmVzIHRyYW5zZm9ybWF0aW9uIHRvIGEgbW9yZSAibm9ybWFsIiBkaXN0cmlidXRpb24uIFRoZSBCb3hDb3goKSBmdW5jdGlvbiB3YXMgdXNlZCBhbG9uZyB3aXRoIHRoZSBoaXN0b2dyYW0oKSBmdW5jdGlvbiB0byBzaG93IHRoZSB0cmFuc2Zvcm1hdGlvbiBvZiB0aGUgQXZlcmFnZV9yYXRpbmcgdmFyaWFibGUgYXMgc2hvd24gYmVsb3cuIFRoZSBkaXN0cmlidXRpb24gaGFzIGNoYW5nZWQgZnJvbSBhIHNsaWdodCBsZWZ0LXNrZXdlZCB0byBvbmUgdGhhdCBpcyBzaW1pbGFyIHRvIGJpLW1vZGFsLiBUaGlzIG5ldyBkaXN0cmlidXRpb24gd2lsbCBoZWxwIHByb3ZpZGUgdW5kZXJzdGFuZGluZyBhYm91dCBhdmVyYWdlIHJhdGluZyBhY3Jvc3MgdGhlIHRvcCBtb3ZpZXMvVFYgc2hvd3MgaW4gdGhlIHRocmVlIGNvdW50cmllcy4gDQoNCmBgYHtyfQ0KYm94Y294X05GIDwtIEJveENveChUaWR5X05GJEF2ZXJhZ2VfcmF0aW5nLCBsYW1iZGEgPSAiYXV0byIpDQpoaXN0b2dyYW0oYm94Y294X05GKQ0KYGBgDQoNCg==