Introduction

What do Top Indonesian Youtube channels have in common? Sure they all have massive amount of followings, but it turns out that they too (at least in general) upload at the same time. This analysis will examine data from 66 Youtube channels ranked by the amount of subscribers. Channels that belong to a media company or record label and those who mainly upload WatchMojo-esque video will not be included.

Preparation

List of channel

What exactly are those channels that will be analyzed? You, as the reader, can see it for yourselves just by clicking the “code” button located near this sentence. Data for the ranking of Youtube channels by the amount of subscribers was obtained from Social Blade (https://www.socialblade.com).

channel_a = c("Atta Halilintar", "Ricis Official", "GEN HALILINTAR",
              "Rans Entertainment", "Jess No Limit", "SAAIHALILINTAR",
              "Baim Paula", "Frost Diamond", "MiawAug",
              "Arif muhammad", "Raditya Dika", "Dyland PROS",
              "Deddy Corbuzier", "Naisa Alifia Yuriza (N.A.Y)" 
              )

channel_b = c("tanboy kun", "Yudist Ardhana", "Zuni and Family", 
              "kemas pake z", "PANJI PETUALANG", "FrontaL Gaming",
              "Maell Lee", "Nessie Judge", "animasinopal",
              "Erpan1140", "Angga Candra", "Nussa Official",
              "The Onsu Family", "Rendy Rangers"
              )

channel_c = c("FATEH HALILINTAR", "Mainan Anak LetsPlay", "hasanjr11",
              "TRI SUAKA CHANNEL", "Najwa Shihab", "GadgetIn",
              "Rizky Riplay", "fikrifadlu", "deHakims", 
              "Hi Patrick", "WAWAN MKS", "Sara Wijayanto",
              "Ani Nurhayani", "Monica Fiusnaini"
              )

channel_d = c("musisi jogja project", "SULE Channel", "jurnalrisa",
              "Vincent Raditya", "Edho Zell", "Thariq Halilintar",
              "Natasha Wilona", "Hanin Dhiya", "LetDa Hyper",
              "Nofin Asia", "syam kapuk", "HALILINTAR LENGGOGENI",
              "Putih Abu-Abu", "Ibu dan Balita Indonesia"
              )

channel_e = c("Maul Ibra", "dunia MANJI", "Andhika Gemintang",
              "Ismi n Hidayah", "Hobby Makan", "Afif Yulistian",
              "Diva The Series", "tasya farasya", "MILYHYA",
              "Glenn Julifer"
              )

channel = c(channel_a, channel_b, channel_c, channel_d, channel_e)

#Since data was inputted manually, categorization was done to make counting and spotting mistakes easier. It will bear no effect on the analysis.

List of channel IDs

Channel ID is a unique tag for each Youtube channels that differentiates one from the other. It can be seen in the URL when visiting a channel homepage. As an example, the URL for Atta Halilintar Youtube Channel is “https://www.youtube.com/channel/UCaKLg1ELiX0zTJ6Je3c5esA”, while its Channel ID is “UCaKLg1ELiX0zTJ6Je3c5esA”.

url_a = c("UCaKLg1ELiX0zTJ6Je3c5esA", "UC4tS4Q_Cno5JVcIUXxQOOpA", "UCfRNJiafEm1LBBGFTTq4cXw",   
          "UCvA9_f5Lwk-poMynabtrZPg", "UCvh1at6xpV1ytYOAzxmqUsA", "UCEIdGryox368qWinrZ9eA8A",    
          "UC5xAPCVizxOfnMECMXkal2Q", "UC4hGmH5sABOA70D4fGb8qNQ", "UC3J4Q1grz46bdJ7NJLd4DGw",    
          "UCfx3oPv3cJm2aCJ7UnhKx8A", "UC0rzsIrAxF4kCsALP6J2EsA", "UCXdmo_q4SawYMz-dmeKEHPQ",    
          "UCYk4LJI0Pr6RBDWowMm-KUw", "UCtjFp8VXWIscsqQ2wokpo3Q"
          )

url_b = c("UC8rHUssNDJ9YEjfduAqJBmw", "UCvc00uetYIML9D-7BBrEXLA", "UCAelPgCHWYyEs8-TFuOVRtg", 
          "UCCEs4SbttY3l73m0WsZix3g", "UCK80fj7o9HUEWvobSVp2J-Q", "UCW6fcXU68QShoXPkxnPxATw",
          "UCgYmNAhjfv5GYWBOfzp831Q", "UC_SBt2BFBkExq_azj-P5lNA", "UC5IA7MpYcbhbA28RgyQrV0A",
          "UCHtehvb3p55uRCQBDCwF-ow", "UCJdzixqmMBoCMoMkrQ8F8FQ", "UCV2jNjJEtO0Hr3b1Es3xPJg",
          "UCJvQLi9uJEGBpD8t3DZyHpw", "UCg_GNu-J5_naq-k1kUfq1Rw"
          )

url_c = c("UCi_ujFc2fgNt21RgVY5hvGg", "UCnN-PlxUJifRxrtyb2vgk7w", "UCgqAMw2V_Ddy4SfmovUTh8Q",
          "UCxHRAILTOBZNR8J9GZFaniw", "UCo8h2TY_uBkAVUIc14m_KCA", "UC1dI4tO13ApuSX0QeX8pHng",
          "UC7GWXKxiy9_AU9TytEh00eg", "UC4AXZK3XiR-kz1Nk01LhxmQ", "UC7-sh4gtS5oJkwqOyt8s3CQ",
          "UCZB0J8mVXqPe3ej6UYlS4DQ", "UCXT5s05a6LQsP9q83W5hY_A", "UCa3k1_nfBeXbf7be6Dcy_vQ",
          "UCs89kFyfKM24SFFAb_vqpBQ", "UC-ZrKLhOyohhDYm_0HGRR_A"
          )

url_d = c("UCUE-BF1Q5E6Sz1KidSnSRYw", "UCZWk_k207M--sLScrLdM3JQ", "UCKFC1LYWw1fbe9LNfm2vEPg",
          "UCww1ChPmojYTXoor8q5tsqQ", "UC_ZTmAt4G3AotY5RtfDK3Pg", "UC4yFyIPBcHKXplfjsEZ_t8A",
          "UCciyMo0ShVMAlYp3SWAaBcw", "UCrmaNLTz1x931Ig5Yuauf2w", "UCCsHdU66sCbEtklvSVAGPsQ",
          "UCBRTQnz0s56WFUrTaR-9Dug", "UCujcefJzhIMthewp1l5Rc7Q", "UC2lCrx1QJF_hLT4atkZf6Ew",
          "UCIqzqfsgUqctbM-MANntwuQ", "UC72YzxWLsng_rTrTMYlFLgw"
          )

url_e = c("UCPgrYeWcpOkyejYpKWf22zQ", "UCxvwscmR_VAfBY-ZI2VGuKw", "UCJHf0urdptElA1dbLu2zpcQ",
          "UCe2MSygA15htoLQvflJabmA", "UCNYvkAHBuLfOzUBuR1Uvv9w", "UCWfIdNrwmczMu8T7261X8hg",
          "UCG9eNeLwgczW2cI1X51y1fw", "UCJCSL8IJfD4d5nunRrmrT1Q", "UC0ohl1eKTtlJNqbD-HWRQVg",
          "UConZUB9SoH7H1Sp5wvzEEpg"
          )

url = c(url_a, url_b, url_c, url_d, url_e)

#Categorization is still of no importance.

List of days.

This analysis will be showing upload time on each day. Therefore, it will be beneficial to list the name of the days.

days = c("Monday", "Tuesday", "Wednesday", 
         "Thursday", "Friday", "Saturday", 
         "Sunday")

#Inputting the name in order is important since Monday MUST be followed by Tuesday.

Obtaining the data

After the channels that will be analyzed have been specified, the next step is to be done is obtaining the data of their uploaded videos. This analysis will consider each channels’ 50 most recent uploaded videos as the sample.

# API_key      = #personal key
# youtube_base = "https://www.googleapis.com/youtube/v3"
# 
# data_all = lapply(url, function(a){
#                         sub = paste0(youtube_base, "/", sprintf("search?key=%s&channelId=%s&part=snippet,id&order=date&maxResults=50", API_key, a))
#                         result = fromJSON(sub)
#                         })
# saveRDS(data_all, "dataallyt.rds")
# dataallyt = readRDS("dataallyt.rds")


#Data can be collected through Youtube API or utilizing "tuber" package on R.
#In this analysis, will be doing queries directly on Youtube API.
#The process of doing query for each channel ID was automated and then collected on "data_all".
#In this analysis, data_all needs to be saved and then imported since web scraping is not allowed. It is saved into "dataallyt"
#dataallyt is a list comprised of some informations on each channel's 50 most recent uploaded videos.

Cleaning, transforming, and reorganizing the data

In this analysis, only each channel’s name and publication time of their videos are needed. Therefore, some cleaning and transformation on the data were done to make data analysis easier. You are encouraged to see the process by clicking the “code” button.

dataallyt = readRDS("dataallyt.rds")
data2 = lapply(dataallyt, FUN = "[[", "items")


#Channel name
name = data2 %>%
                lapply(FUN = "[[", "snippet") %>%
                        lapply(FUN = "[[", "channelTitle") %>%
                                unlist()

#video upload time
wib = 60*60*7
pt = data2 %>%
        lapply(FUN = "[[", "snippet") %>%
                lapply(FUN = "[[", "publishedAt") %>%
                        unlist() %>%
                                str_replace("T", " ") %>%
                                str_remove_all(".000Z") %>%
                                str_remove_all("Z") %>%
                                as.POSIXct(format = "%Y-%m-%d %H:%M:%S") %>%
                                + wib

#Video upload day
day = pt %>%
        weekdays() %>%
                factor(levels = days)


#Video upload hour
time = pt %>%
        round_date("hour") %>%
                format("%H") %>%
                        as.numeric()


#Organizing the data
df = data.frame(day, time, name)
colnames(df) = c("Day", "Hour", "Channel")



#When you look closely, it can be seen that I added the value of "wib" into "pt". It was done to convert the time to UTC+7 or Waktu Indonesia Barat since YouTube stores the time value according to ISO 8601.

Data visualization and analysis

This section will be split into two sub-sections: Overall Time Pattern and Time Pattern of Each Channel.

Overall Time Pattern

ggplot(df, aes(x = Day, y = Hour, fill = Day)) +
        labs(x = "Day", y = "Hour (UTC+7)", title = "Overall Time Pattern") +
        geom_boxplot(show.legend = F) +
        expand_limits(x = 0, y = 0) +
        scale_y_continuous(breaks = seq(0, 23, by = 2)) +
        theme_bw()

This graph shows that in general, Indonesian top Youtubers upload their video at around 4 PM on the weekdays(Monday - Friday), at 5 PM on Saturday, and at 3 PM on Sunday.

There are lots of possible explanations on this. Maybe, these channels adjust their upload time on regular working hours which ends on around 5 PM in order to maximize the number of views. Another possibility is that they spend some time editing their video in the morning and then upload it in the late afternoon.

Each Channel

This sub-section (consists of 66 graphs) shows each channel’s upload time on any given day. It can be seen that some channels have a specific upload time, while others don’t. Beware, the result is long.

lapply(channel, function(a){
              ggplot(df %>% filter(Channel == a), aes(x = Day, y = Hour, fill = Day)) +
              labs(x = "Day", y = "Hour (UTC+7)", title = paste("Upload Time of", a, sep = " ")) +
              geom_dotplot(binaxis = "y", binwidth = 0.6, stackdir = "centerwhole", stackratio = 0.5, show.legend = F) +
              expand_limits(x = 0, y = 0) +
              scale_y_continuous(breaks = seq(0, 23, by = 2)) +
              theme_bw()
              })
## [[1]]

## 
## [[2]]

## 
## [[3]]

## 
## [[4]]

## 
## [[5]]

## 
## [[6]]

## 
## [[7]]

## 
## [[8]]

## 
## [[9]]

## 
## [[10]]

## 
## [[11]]

## 
## [[12]]

## 
## [[13]]

## 
## [[14]]

## 
## [[15]]

## 
## [[16]]

## 
## [[17]]

## 
## [[18]]

## 
## [[19]]

## 
## [[20]]

## 
## [[21]]

## 
## [[22]]

## 
## [[23]]

## 
## [[24]]

## 
## [[25]]

## 
## [[26]]

## 
## [[27]]

## 
## [[28]]

## 
## [[29]]

## 
## [[30]]

## 
## [[31]]

## 
## [[32]]

## 
## [[33]]

## 
## [[34]]

## 
## [[35]]

## 
## [[36]]

## 
## [[37]]

## 
## [[38]]

## 
## [[39]]

## 
## [[40]]

## 
## [[41]]

## 
## [[42]]

## 
## [[43]]

## 
## [[44]]

## 
## [[45]]

## 
## [[46]]

## 
## [[47]]

## 
## [[48]]

## 
## [[49]]

## 
## [[50]]

## 
## [[51]]

## 
## [[52]]

## 
## [[53]]

## 
## [[54]]

## 
## [[55]]

## 
## [[56]]

## 
## [[57]]

## 
## [[58]]

## 
## [[59]]

## 
## [[60]]

## 
## [[61]]

## 
## [[62]]

## 
## [[63]]

## 
## [[64]]

## 
## [[65]]

## 
## [[66]]