1 Latar Belakang

Data-data dari play store memiliki potensi yang besar untuk dijadikan pedoman dalam kesuksesan pembuatan bisnis berbasis aplikasi. Pada dokumen ini dibuat beberapa contoh visualisasi dari data-data Playstore yang mudah-mudahan dapat memberikan sedikit gambaran manfaat visualisasi dalam bisnis.

Beberapa visualisasi yang akan di tampilkan di antaranya adalah :

  • Melihat jumlah aplikasi berdasarkan kategorinya
  • Visualisasi 3 besar kategori menggunakan facet plot

Harus diakui pada projek kali ini data preprocessing dibuat sedetail mungkin, agar ketika ingin menganalisis dan mengevaluasi lebih jauh, data-data sudah siap untuk diproses.

Data mentah berasal dari kaggle dengan link sebagai berikut : https://www.kaggle.com/lava18/google-play-store-apps

2 Set Up

Seperti biasa set up awal untuk mengeset format chunk pada markdown ini.

options(scipen = 9999)
rm(list=ls())

Set up library yang akan digunakan

library(lubridate)
## 
## Attaching package: 'lubridate'
## The following object is masked from 'package:base':
## 
##     date
library(ggplot2)

3 Data PreProcessing

3.1 Data Masukkan

Proses mengimpor dataset google playstore

# Import Data

gplay <- read.csv("data_input/googleplaystore.csv")

# Mengecek nama untuk tiap kolom pada data frame gplay

names(gplay)
##  [1] "App"            "Category"       "Rating"         "Reviews"       
##  [5] "Size"           "Installs"       "Type"           "Price"         
##  [9] "Content.Rating" "Genres"         "Last.Updated"   "Current.Ver"   
## [13] "Android.Ver"
# Mengecek struktur data frame gplay

str(gplay)
## 'data.frame':    10841 obs. of  13 variables:
##  $ App           : Factor w/ 9660 levels "- Free Comics - Comic Apps",..: 7229 2563 8998 8113 7294 7125 8171 5589 4948 5826 ...
##  $ Category      : Factor w/ 34 levels "1.9","ART_AND_DESIGN",..: 2 2 2 2 2 2 2 2 2 2 ...
##  $ Rating        : num  4.1 3.9 4.7 4.5 4.3 4.4 3.8 4.1 4.4 4.7 ...
##  $ Reviews       : Factor w/ 6002 levels "0","1","10","100",..: 1183 5924 5681 1947 5924 1310 1464 3385 816 485 ...
##  $ Size          : Factor w/ 462 levels "1,000+","1.0M",..: 55 30 368 102 64 222 55 118 146 120 ...
##  $ Installs      : Factor w/ 22 levels "0","0+","1,000,000,000+",..: 8 20 13 16 11 17 17 4 4 8 ...
##  $ Type          : Factor w/ 4 levels "0","Free","NaN",..: 2 2 2 2 2 2 2 2 2 2 ...
##  $ Price         : Factor w/ 93 levels "$0.99","$1.00",..: 92 92 92 92 92 92 92 92 92 92 ...
##  $ Content.Rating: Factor w/ 7 levels "","Adults only 18+",..: 3 3 3 6 3 3 3 3 3 3 ...
##  $ Genres        : Factor w/ 120 levels "Action","Action;Action & Adventure",..: 10 13 10 10 12 10 10 10 10 12 ...
##  $ Last.Updated  : Factor w/ 1378 levels "1.0.19","April 1, 2016",..: 562 482 117 825 757 901 76 726 1317 670 ...
##  $ Current.Ver   : Factor w/ 2834 levels "","0.0.0.2","0.0.1",..: 121 1020 466 2827 279 115 279 2393 1457 1431 ...
##  $ Android.Ver   : Factor w/ 35 levels "","1.0 and up",..: 17 17 17 20 22 10 17 20 12 17 ...

3.2 Perubahan kolom App menjadi bertipe character

Setelah kita berhasil memasukkan data-data google play store tersebut, tahap pertama adalah melakukan perubahan format pada element-element dalam data frame sehingga sesuai dengan isi data tersebut atau sesuai untuk keperluan processing nantinya. Pertama kita bisa melihat bahwa kolom App yang berisi nama-nama aplikasi yang ada dalam google play store masih berupa Factor. Nama-nama tersebut akan kita rubah menjadi bertipe character dengan cara sebagai berikut.

# Tipe kolom App pada data frame gplay sebelum di konversi

class(gplay$App)
## [1] "factor"
# Merubah kolom gplay$App menjadi character

gplay$App <- as.character(gplay$App)

# Tipe kolom App pada data frame gplay setelah di konversi menjadi character

class(gplay$App)
## [1] "character"
# Mengecek 10 baris pertama dari kolom App yang sudah kita ubah

head(gplay$App, 10)
##  [1] "Photo Editor & Candy Camera & Grid & ScrapBook"      
##  [2] "Coloring book moana"                                 
##  [3] "U Launcher Lite â\200“ FREE Live Cool Themes, Hide Apps"
##  [4] "Sketch - Draw & Paint"                               
##  [5] "Pixel Draw - Number Art Coloring Book"               
##  [6] "Paper flowers instructions"                          
##  [7] "Smoke Effect Photo Maker - Smoke Editor"             
##  [8] "Infinite Painter"                                    
##  [9] "Garden Coloring Book"                                
## [10] "Kids Paint Free - Drawing Fun"

3.3 Eliminasi nama-nama aplikasi yang terduplikat

Dari beberapa aplikasi di dalam data base tersebut, ternyata ada beberapa aplikasi yang terduplikasi, mengingat beberapa parameter lainnya berisi nilai-nilai yang cukup identis.

# Mengecek duplikasi dengan membuat data frame baru yang berisi nama aplikasi serta total duplikasinya

gplay_dplct <- as.data.frame(table(gplay$App))

# Melihat 1 contoh aplikasi yang pertama kali muncul dan terduplikasi lebih dari 4 kali

subset(gplay_dplct, gplay_dplct$Freq > 4)[1,]
##            Var1 Freq
## 112 8 Ball Pool    7
# Melihat aplikasi tersebut pada data frame gplay

subset(gplay, gplay$App %in% (subset(gplay_dplct, gplay_dplct$Freq > 4,1)[1,]) )
##              App Category Rating  Reviews Size     Installs Type Price
## 1676 8 Ball Pool     GAME    4.5 14198297  52M 100,000,000+ Free     0
## 1704 8 Ball Pool     GAME    4.5 14198602  52M 100,000,000+ Free     0
## 1756 8 Ball Pool     GAME    4.5 14200344  52M 100,000,000+ Free     0
## 1845 8 Ball Pool     GAME    4.5 14200550  52M 100,000,000+ Free     0
## 1872 8 Ball Pool     GAME    4.5 14201891  52M 100,000,000+ Free     0
## 1971 8 Ball Pool     GAME    4.5 14201604  52M 100,000,000+ Free     0
## 3954 8 Ball Pool   SPORTS    4.5 14184910  52M 100,000,000+ Free     0
##      Content.Rating Genres  Last.Updated Current.Ver  Android.Ver
## 1676       Everyone Sports July 31, 2018       4.0.0 4.0.3 and up
## 1704       Everyone Sports July 31, 2018       4.0.0 4.0.3 and up
## 1756       Everyone Sports July 31, 2018       4.0.0 4.0.3 and up
## 1845       Everyone Sports July 31, 2018       4.0.0 4.0.3 and up
## 1872       Everyone Sports July 31, 2018       4.0.0 4.0.3 and up
## 1971       Everyone Sports July 31, 2018       4.0.0 4.0.3 and up
## 3954       Everyone Sports July 31, 2018       4.0.0 4.0.3 and up

Pada contoh di atas kita mendapatkan aplikasi bernama “8 Ball Pool” yang terduplikasi sebanyak 7 kali. Hampir semua parameter dari total 13 kolom pada aplikasi tersebut sama. Hanya sedikit perbedaan pada kategori (Category) dan jumlah review (Reviews).
Dari data tersebut maka dapat kita simpulkan aplikasi “8 Ball Pool” yang pertama kali muncul pada urutan baris sudah dapat mewakili ke 6 duplikasi lainnya. Oleh karena itu kita bisa menghapus data-data duplikasi tersebut menggunakan fungsi “unique” yang ditunjukkan pada kode di bawah ini.

# Membuat data frame baru yang tidak terdapat aplikasi terduplikat

gplay_u <- gplay[match(unique(gplay$App), gplay$App),]

# Size data frame sebelum eliminasi

dim(gplay)
## [1] 10841    13
# Size data frame setelah eliminasi

dim(gplay_u)
## [1] 9660   13

Dari proses di atas dapat kita lihat bahwa dari 10841 aplikasi pada data original, terdapat total 9660 aplikasi yang unique.

3.4 Eliminasi kolom Genres dan modifikasi kolom Category

Dari data frame gplay_u yang sudah kita dapat, kolom Genres akan kita hilangkan karena sudah diwakili oleh kolom Category, lalu kita modifikasi sedikit cara penulisan dalam kolom Category sehingga berubah menjadi format penulisan standar yang umum.

# Eliminasi kolom ke sepuluh, yaitu kolom Genres 

gplay_u <- gplay_u[,-c(10)]

# Contoh sepuluh sample dari kolom Category sebelum perubahan format penulisan

set.seed(2)
gplay_u[grepl("_AND_", gplay_u$Category),][sample(nrow(gplay_u[grepl("_AND_", gplay_u$Category),]),10),c(1,2,3)]
##                                  App            Category Rating
## 1322  Map My Fitness Workout Trainer  HEALTH_AND_FITNESS    4.4
## 7062                bz Basel E-Paper  NEWS_AND_MAGAZINES    NaN
## 5772                         News.aw  NEWS_AND_MAGAZINES    NaN
## 1293  Runkeeper - GPS Track Run Walk  HEALTH_AND_FITNESS    4.5
## 10013                KMTV 3 News Now  NEWS_AND_MAGAZINES    3.8
## 10009                  ABC15 Arizona  NEWS_AND_MAGAZINES    3.6
## 1228       My CookBook Pro (Ad Free)      FOOD_AND_DRINK    4.6
## 8615               Sweden Newspapers  NEWS_AND_MAGAZINES    NaN
## 4068                         E! News  NEWS_AND_MAGAZINES    4.0
## 5343  Hafizi Quran 15 lines per page BOOKS_AND_REFERENCE    4.7
# Mencari penulisan "_AND_" dalam kolom Category dan menggantinya dengan " & "

gplay_u$Category <- sub("_AND_", " & ", gplay_u$Category)

# Karena Category berubah menjadi karakter setelah proses sub, maka kita kembalikan menjadi faktor

gplay_u$Category <- as.factor(gplay_u$Category)

# Contoh 10 sample setelah proses di atas

set.seed(2)
gplay_u[grepl("&", gplay_u$Category),][sample(nrow(gplay_u[grepl("&", gplay_u$Category),]),10),c(1,2,3)]
##                                  App          Category Rating
## 1322  Map My Fitness Workout Trainer  HEALTH & FITNESS    4.4
## 7062                bz Basel E-Paper  NEWS & MAGAZINES    NaN
## 5772                         News.aw  NEWS & MAGAZINES    NaN
## 1293  Runkeeper - GPS Track Run Walk  HEALTH & FITNESS    4.5
## 10013                KMTV 3 News Now  NEWS & MAGAZINES    3.8
## 10009                  ABC15 Arizona  NEWS & MAGAZINES    3.6
## 1228       My CookBook Pro (Ad Free)      FOOD & DRINK    4.6
## 8615               Sweden Newspapers  NEWS & MAGAZINES    NaN
## 4068                         E! News  NEWS & MAGAZINES    4.0
## 5343  Hafizi Quran 15 lines per page BOOKS & REFERENCE    4.7

3.5 Eliminasi aplikasi yang memiliki nilai NaN

Dari proses sebelumnya kita dapat melihat bahwa ada beberapa aplikasi yang tidak memiliki nilai rating atau NaN. Demi menghindari ambiguitas saat kita melakukan analisis, aplikasi-aplikasi yang memiliki NaN atau Na akan kita eliminasi baik itu dari kolom rating ataupun kolom-kolom lainnya.

Jika kita menggunakan fungsi is.na, terdeteksi NaN pada kolom “Rating”, akan tetapi jika kita teliti lebih detail ternyata terdapat pula NaN pada kolom lainnya seperti kolom “Type”,“Current.Ver”,dan “Android.Ver” yang tidak terdeteksi.

# Mendeteksi NaN pada data frame gplay_u

colSums(is.na(gplay_u))
##            App       Category         Rating        Reviews           Size 
##              0              0           1463              0              0 
##       Installs           Type          Price Content.Rating   Last.Updated 
##              0              0              0              0              0 
##    Current.Ver    Android.Ver 
##              0              0
# Terdapat pula NaN pada kolom lain jika dibuktikan dengan kode ini, contoh pada kolom "Type"

summary(gplay_u$Type)
##    0 Free  NaN Paid 
##    1 8902    1  756
# Jika kita jabarkan aplikasi yang mengandung NaN pada kolom "Type"

gplay_u[grepl(NaN, gplay_u$Type),c(1,2,7)]
##                            App Category Type
## 9149 Command & Conquer: Rivals   FAMILY  NaN
# Atau untuk membuktikan apakah kode di atas sama dengan fungsi is.na untuk kolom "Rating"

dim(gplay_u[grepl(NaN, gplay_u$Rating),])[1]
## [1] 1463

Hasil jumlah baris yang mengandung NaN berdasar kolom “Rating” menggunakan fungsi “is.na” ataupun dengan kode di atas berjumlah sama yaitu 1463 baris. Dari hal tersebut artinya kita bisa menggunakan kode diatas untuk mengeliminasi kolom-kolom yang mengandung NaN pada data frame gplay_u.

Lalu haruskah kita spesifikasi satu persatu tiap kolom untuk dapat menggunakan kode tersebut ? Hal tersebut mungkin dilakukan, akan tetapi akan kurang efisien. Untuk itu bisa kita gunakan fungsi loop “for” serta fungsi conditional “if”

# Pembuatan dataframe baru yang akan berisi nilai-nilai NaN yang sudah dieliminasi
gplay_u_noNan <- gplay_u

# Looping untuk mencari nilai NaN pada tiap kolom data gplay_u/gplay_u_noNan dan mengeliminasinya

for (i in 1:dim(gplay_u_noNan)[2]) {
  if (dim(gplay_u_noNan[(grepl(NaN, gplay_u_noNan[,i])),])[1] > 0) {
    gplay_u_noNan <- gplay_u_noNan[!(grepl(NaN, gplay_u_noNan[,i])),]
  }
  else {
    gplay_u_noNan <- gplay_u_noNan
  }
}

# Tampilan 5 sample pada data setelah eliminasi NaN

set.seed(2)
gplay_u_noNan[grepl("&", gplay_u_noNan$Category),][sample(nrow(gplay_u_noNan[grepl("&", gplay_u_noNan$Category),]),5),c(1,2,3)]
##                                                    App         Category
## 1278              Runtastic Running App & Mile Tracker HEALTH & FITNESS
## 6478                                       BM Pharmacy HEALTH & FITNESS
## 4760 X Launcher Pro - IOS Style Theme & Control Center     ART & DESIGN
## 1255                   foodpanda - Local Food Delivery     FOOD & DRINK
## 9952                       EV Trip Optimizer for Tesla  AUTO & VEHICLES
##      Rating
## 1278    4.5
## 6478    4.9
## 4760    4.8
## 1255    4.0
## 9952    3.2
#Perbandingan dimensi dataframe sebelum dan sesudah eliminasi NaN
dim(gplay_u)
## [1] 9660   12
dim(gplay_u_noNan)
## [1] 8192   12
dim(gplay_u) - dim(gplay_u_noNan)
## [1] 1468    0

Terlihat bahwa sebelum eliminasi NaN terdapat sejumlah 9660 aplikasi sedangkan setelah eliminasi NaN menjadi 8192 aplikasi, yang berarti sejumlah 1468 aplikasi telah dieliminasi.

# Pengecekan pada salah satu kolom (Type), yang sebelumnya terdapat NaN
summary(gplay_u_noNan$Type)
##    0 Free  NaN Paid 
##    1 7589    0  602

Terbukti bahwa NaN sudah berhasil dieliminasi untuk semua baris pada kolom “Type”.

3.6 Eliminasi aplikasi yang memiliki elemen kosong

Selain NaN, kolom yang mengandung elemen kosong atau “” juga akan mengganggu saat dilakukan proses analisis nantinya. Untuk itu dapat kita cari dan eliminasi dengan cara berikut :

# Mencari kolom-kolom yang memiliki elemen kosong
colSums(gplay_u_noNan == "")
##            App       Category         Rating        Reviews           Size 
##              0              0              0              0              0 
##       Installs           Type          Price Content.Rating   Last.Updated 
##              0              0              0              1              0 
##    Current.Ver    Android.Ver 
##              1              1

Terdapat elemen kosong pada kolom “Content.Rating”,“Current.Ver”, dan “Android.Ver”.
Selanjutnya coba kita tampilkan aplikasi apakah yang memiliki elemen kosong tersebut.

# Pemfilteran aplikasi yang memiliki elemen kosong
gplay_u_noNan_empty <- gplay_u_noNan[gplay_u_noNan$Content.Rating == "" | gplay_u_noNan$Current.Ver == "" | gplay_u_noNan$Android.Ver == "",]

gplay_u_noNan_empty[,c(1,7,9,11,12)]
##                                           App Type Content.Rating
## 1554                     Market Update Helper Free       Everyone
## 10473 Life Made WI-Fi Touchscreen Photo Frame    0               
##       Current.Ver Android.Ver
## 1554               1.5 and up
## 10473  4.0 and up

Kita dapatkan ternyata ada dua aplikasi yang berisi elemen kosong.
Selanjutnya kita dapat mengeliminasi aplikasi tersebut dari data frame kita.

# Eliminasi aplikasi yang memiliki elemen kosong
gplay_u_noNan <- subset(gplay_u_noNan, !gplay_u_noNan$App %in% gplay_u_noNan_empty$App)

# Pengecekan kembali terdapatnya elemen kosong
colSums(gplay_u_noNan == "")
##            App       Category         Rating        Reviews           Size 
##              0              0              0              0              0 
##       Installs           Type          Price Content.Rating   Last.Updated 
##              0              0              0              0              0 
##    Current.Ver    Android.Ver 
##              0              0

Elemen kosong berhasil di eliminasi dari data frame yang akan kita gunakan.

3.7 Merubah format kolom “Reviews” menjadi integer

Jika kita perhatikan, kolom Reviews pada data frame masih berupa faktor. Seperti yang kita tahu di dalam kolom tersebut berisi jumlah review yang terdapat pada tiap-tiap aplikasi. Oleh karena itu kolom itu seharusnya berformat Integer karena review akan selalu bilangan bulat.

# Merubah kolom "Reviews" ke format Integer

gplay_u_noNan$Reviews <- as.integer(gplay_u_noNan$Reviews)

#Mengecek hasil perubahan format kolom Reviews

str(gplay_u_noNan$Reviews)
##  int [1:8190] 1183 5924 5681 1947 5924 1310 1464 3385 816 485 ...

3.8 Konversi pada kolom size

Agar nantinya kita bisa menentukan termasuk aplikasi yang berukuran besar atau tidak, kita perlu merubah faktor pada kolom size ke bentuk numerik. Akan tetapi kita tidak bisa melakukan ini secara langsung karena level-level pada factor size tidak berformat angka, dan juga tidak berurutan.

Untuk itu pertama kita harus mengkonversi tiap-tiap level pada size ke format angka.

# Membuat variabel baru yang hanya berisi bermacam-macam nama level dari factor Size

z <- as.character(levels(gplay_u_noNan$Size))

# Jalankan fungsi loop yang akan mengkonversi nilai-nilai berdasarkan abjad sizenya(ex: M = 1000000 bytes, k = 1000 bytes)

# Maksud fungsi di bawah adalah, jika pada looping pertama ditemukan karakter "M" pada data ke i di variabel z, maka ambil karakter yang berisi angka saja, konversikan kedalam numerik, kalikan dengan 1000000 dan masukkan nilai itu ke data ke i pada variabel z. Begitu pula selanjutnya, bila "M" tidak ditemukan, jika terdapat "k", kalikan dengan 1000 dan updata data ke i pada variabel z, dan seterusnya.

for (i in 1:length(z)) {
   if (substr(z[i],nchar(z[i]),nchar(z[i])) == "M") {
   z[i] <- as.numeric(substr(z[i],1,nchar(z[i])-1))*1000000
  }
  
  else if (substr(z[i],nchar(z[i]),nchar(z[i])) == "k") {
   z[i] <- as.numeric(substr(z[i],1,nchar(z[i])-1))*1000
  }
  
  else if (substr(z[i],nchar(z[i]),nchar(z[i])) == "+") {
   z[i] <- as.numeric(substr(z[i],1,1))
  }
  
  else {
    
    z[i] <- z[i]
  }
}

# Komparasi hasil sebelum dan sesudah konversi

head(as.character(levels(gplay_u_noNan$Size)),10)
##  [1] "1,000+" "1.0M"   "1.1M"   "1.2M"   "1.3M"   "1.4M"   "1.5M"  
##  [8] "1.6M"   "1.7M"   "1.8M"
head(z,10)
##  [1] "1"       "1000000" "1100000" "1200000" "1300000" "1400000" "1500000"
##  [8] "1600000" "1700000" "1800000"
tail(as.character(levels(gplay_u_noNan$Size)),10)
##  [1] "97M"                "980k"               "981k"              
##  [4] "982k"               "986k"               "98M"               
##  [7] "992k"               "994k"               "99M"               
## [10] "Varies with device"
tail(z,10)
##  [1] "97000000"           "980000"             "981000"            
##  [4] "982000"             "986000"             "98000000"          
##  [7] "992000"             "994000"             "99000000"          
## [10] "Varies with device"
# Langkah selanjutnya adalah mengupdate nama-nama levels yang sudah di konversi tersebut kedalam data frame utama kita yaiut gplay_u_noNan

levels(gplay_u_noNan$Size) <- c(z)

# Selanjutnya kita bisa tambah kolom size yang bertipe numerik pada dataframe

gplay_u_noNan$SizeNmr <- as.numeric(as.character(gplay_u_noNan$Size))
## Warning: NAs introduced by coercion
# Na akan muncul dikarenakan coercion dari elemen yang bukan angka yaitu "Varies with device"
# Bisa dibuktikan dengan melihat jumlah elemen yang berisi "Varies with device" dan Na setelah konversi

dim(gplay_u_noNan[grepl("Varies with device", gplay_u_noNan$Size),])[1]
## [1] 1169
sum(is.na(gplay_u_noNan$SizeNmr))
## [1] 1169
# Lalu selanjutnya bisa kita rubah nilai Na pada kolom Size bertipe numerik tersebut, untuk kali ini kita akan assign suatu angka yang sangat tinggi yang berbeda jauh dari persebaran nilai-nilai Size



# Kita bisa konversi terlebih dahulu dari bytes ke ukuran Mega Bytes (anggap 1 MB ~ 1000000 Bytes)

gplay_u_noNan$SizeNmr <- gplay_u_noNan$SizeNmr/1000000

summary(gplay_u_noNan$SizeNmr)
##     Min.  1st Qu.   Median     Mean  3rd Qu.     Max.     NA's 
##   0.0085   4.9000  13.0000  21.7675  31.0000 100.0000     1169
# Assign value 999 sebagai identitas dari aplikasi yang memiliki size "Varies with device"
gplay_u_noNan["SizeNmr"][is.na(gplay_u_noNan["SizeNmr"])] <- 999

# Melihat total value 999 pada kolom SizeNmr
dim(gplay_u_noNan[grepl(999, gplay_u_noNan$SizeNmr),])[1]
## [1] 1169

3.9 Menambahkan kolom baru yang membagi size ke 4 kategori

Agar lebih mudah pengklasifikasian aplikasi berdasarkan “Size”-nya, maka dibuat kolom baru yang berisi 4 kategori size, yaitu “Small Size App”, “Medium Size App”, “Big Size App” dan “Varies with device”.

Small diketegorikan dengan aplikasi yang memiliki ukuran kurang dari 20 MB, Medium adalah aplikasi berukuran 20 MB hingga kurang dari 50 MB, Big adalah aplikasi yang berukuran 50 MB hingga 100 MB, dan diluar itu adalah aplikasi yang memiliki ukuran bervariasi yang sebelumnya di assign dengan nilai 999.

# Pembuatan kolom baru 
gplay_u_noNan$SizeCatg <- as.character(gplay_u_noNan$SizeNmr)

# Proses pengklasifikasian aplikasi berdasarkan size
for (i in 1:length(gplay_u_noNan$SizeCatg)) {
  if (gplay_u_noNan[i,"SizeNmr"] < 20) {
    gplay_u_noNan[i,"SizeCatg"] <- "Small Size App"
  }
  else if (gplay_u_noNan[i,"SizeNmr"] >= 20 & gplay_u_noNan[i,"SizeNmr"] < 50) {
    gplay_u_noNan[i,"SizeCatg"] <- "Medium Size App"
  }
  else if (gplay_u_noNan[i,"SizeNmr"] >= 50 & gplay_u_noNan[i,"SizeNmr"] <= 100) {
    gplay_u_noNan[i,"SizeCatg"] <- "Big Size App"
  }
  else {
    gplay_u_noNan[i,"SizeCatg"] <- "Varies with device"
  }
}

# Mengemblakikan klasifikasi ke format factor
gplay_u_noNan$SizeCatg <- as.factor(gplay_u_noNan$SizeCatg)

# Total masing-masing kategori size aplikasi
summary(gplay_u_noNan$SizeCatg)
##       Big Size App    Medium Size App     Small Size App 
##                866               1892               4263 
## Varies with device 
##               1169

3.10 Reorder kategori pada kolom Installs

Pada kolom Installs terdapat kategori jumlah perkiraan install tiap-tiap aplikasi. Kategori tersebut belum terorder dengan baik, oleh karena itu perlu dilakukan sorting dari levels pada kolom Installs.

# Mengecek kategori pada kolom installs
levels(gplay_u_noNan$Installs)
##  [1] "0"              "0+"             "1,000,000,000+" "1,000,000+"    
##  [5] "1,000+"         "1+"             "10,000,000+"    "10,000+"       
##  [9] "10+"            "100,000,000+"   "100,000+"       "100+"          
## [13] "5,000,000+"     "5,000+"         "5+"             "50,000,000+"   
## [17] "50,000+"        "50+"            "500,000,000+"   "500,000+"      
## [21] "500+"           "Free"
# Membuang kategori-kategori yang sudah tidak terpakai

gplay_u_noNan$Installs <- factor(gplay_u_noNan$Installs)

# Mengecek ulang kategori yang masih dipertahankan

levels(gplay_u_noNan$Installs)
##  [1] "1,000,000,000+" "1,000,000+"     "1,000+"         "1+"            
##  [5] "10,000,000+"    "10,000+"        "10+"            "100,000,000+"  
##  [9] "100,000+"       "100+"           "5,000,000+"     "5,000+"        
## [13] "5+"             "50,000,000+"    "50,000+"        "50+"           
## [17] "500,000,000+"   "500,000+"       "500+"
# Menyusun ulang urutan tingkat kategori pada kolom Installs

gplay_u_noNan$Installs <- factor(gplay_u_noNan$Installs, levels = c("1+","5+","10+","50+","100+","500+","1,000+","5,000+","10,000+","50,000+",
                            "100,000+","500,000+","1,000,000+","5,000,000+","10,000,000+","50,000,000+",
                            "100,000,000+","500,000,000+","1,000,000,000+"))

# Mengecek susunan level kategori pada kolom Installs

levels(gplay_u_noNan$Installs)
##  [1] "1+"             "5+"             "10+"            "50+"           
##  [5] "100+"           "500+"           "1,000+"         "5,000+"        
##  [9] "10,000+"        "50,000+"        "100,000+"       "500,000+"      
## [13] "1,000,000+"     "5,000,000+"     "10,000,000+"    "50,000,000+"   
## [17] "100,000,000+"   "500,000,000+"   "1,000,000,000+"

3.11 Merubah kolom Price menjadi Numerik

Lalu kita ingin melakukan perubahan pada kolom Price menjadi numerik agar analisis harga dapat dilakukan lebih mendetail

# Contoh 3 sample Price sebelum konversi

set.seed(3)
gplay_u_noNan[sample(nrow(gplay_u_noNan), 3), c("App","Price")]
##                      App Price
## 1802 MARVEL Strike Force     0
## 8725     DRAGON QUEST II $4.99
## 4170                  Go $0.99
# Merubah kolom Price menjadi character

gplay_u_noNan$Price <- as.character(gplay_u_noNan$Price)

# Menghilangkan tanda $ pada kolom Price

gplay_u_noNan$Price <- gsub("[$]","",gplay_u_noNan$Price)

# Mengkonveris kolom Price menjadi kategori Numerik

gplay_u_noNan$Price <- as.numeric(gplay_u_noNan$Price)

# Contoh 3 sample setelah konversi

set.seed(3)
gplay_u_noNan[sample(nrow(gplay_u_noNan), 3), c("App","Price")]
##                      App Price
## 1802 MARVEL Strike Force  0.00
## 8725     DRAGON QUEST II  4.99
## 4170                  Go  0.99

3.12 Konversi tanggal pada kolom Last Updated

# Konversi tanggal pada kolom Last.Updated menggunakan lubridate

gplay_u_noNan$Last.Updated <- mdy(gplay_u_noNan$Last.Updated)

3.13 Final QC : Mengecek leftover pada level-level di factor

Dalam data frame yang kita miliki, variabel yang bertipe factor dapat memiliki kelas yang berupa data kosong, atau Na/NaN. Untuk itu kita bisa mengecek kembali satu-satu, atau langsung kembali assign format factor agar kelas-kelas dalam faktor itu terupdate.

# Kita tidak membutuhkan kolom Size lagi karena sudah ada kolom Sizenumerik dan Kategori, dan kita tidak akan mengolah kolom Current.ver dan ANdroid.ver

gplay_u_noNan <- subset(gplay_u_noNan, select = -c(5,11,12))

# Category
summary(gplay_u_noNan$Category)
##               1.9      ART & DESIGN   AUTO & VEHICLES            BEAUTY 
##                 0                60                73                42 
## BOOKS & REFERENCE          BUSINESS            COMICS     COMMUNICATION 
##               169               263                54               256 
##            DATING         EDUCATION     ENTERTAINMENT            EVENTS 
##               134               118               102                45 
##            FAMILY           FINANCE      FOOD & DRINK              GAME 
##              1607               302                94               912 
##  HEALTH & FITNESS      HOUSE & HOME  LIBRARIES & DEMO         LIFESTYLE 
##               244                62                63               301 
## MAPS & NAVIGATION           MEDICAL  NEWS & MAGAZINES         PARENTING 
##               118               290               204                50 
##   PERSONALIZATION       PHOTOGRAPHY      PRODUCTIVITY          SHOPPING 
##               296               263               301               180 
##            SOCIAL            SPORTS             TOOLS    TRAVEL & LOCAL 
##               203               260               717               187 
##     VIDEO_PLAYERS           WEATHER 
##               148                72
# Update index kelas-kelas dalam kolom Category

gplay_u_noNan$Category <- factor(gplay_u_noNan$Category)

summary(gplay_u_noNan$Category)
##      ART & DESIGN   AUTO & VEHICLES            BEAUTY BOOKS & REFERENCE 
##                60                73                42               169 
##          BUSINESS            COMICS     COMMUNICATION            DATING 
##               263                54               256               134 
##         EDUCATION     ENTERTAINMENT            EVENTS            FAMILY 
##               118               102                45              1607 
##           FINANCE      FOOD & DRINK              GAME  HEALTH & FITNESS 
##               302                94               912               244 
##      HOUSE & HOME  LIBRARIES & DEMO         LIFESTYLE MAPS & NAVIGATION 
##                62                63               301               118 
##           MEDICAL  NEWS & MAGAZINES         PARENTING   PERSONALIZATION 
##               290               204                50               296 
##       PHOTOGRAPHY      PRODUCTIVITY          SHOPPING            SOCIAL 
##               263               301               180               203 
##            SPORTS             TOOLS    TRAVEL & LOCAL     VIDEO_PLAYERS 
##               260               717               187               148 
##           WEATHER 
##                72
levels(gplay_u_noNan$Category)
##  [1] "ART & DESIGN"      "AUTO & VEHICLES"   "BEAUTY"           
##  [4] "BOOKS & REFERENCE" "BUSINESS"          "COMICS"           
##  [7] "COMMUNICATION"     "DATING"            "EDUCATION"        
## [10] "ENTERTAINMENT"     "EVENTS"            "FAMILY"           
## [13] "FINANCE"           "FOOD & DRINK"      "GAME"             
## [16] "HEALTH & FITNESS"  "HOUSE & HOME"      "LIBRARIES & DEMO" 
## [19] "LIFESTYLE"         "MAPS & NAVIGATION" "MEDICAL"          
## [22] "NEWS & MAGAZINES"  "PARENTING"         "PERSONALIZATION"  
## [25] "PHOTOGRAPHY"       "PRODUCTIVITY"      "SHOPPING"         
## [28] "SOCIAL"            "SPORTS"            "TOOLS"            
## [31] "TRAVEL & LOCAL"    "VIDEO_PLAYERS"     "WEATHER"
# Installs

summary(gplay_u_noNan$Installs)
##             1+             5+            10+            50+           100+ 
##              3              9             69             56            303 
##           500+         1,000+         5,000+        10,000+        50,000+ 
##            199            696            424            986            456 
##       100,000+       500,000+     1,000,000+     5,000,000+    10,000,000+ 
##           1094            503           1414            607            937 
##    50,000,000+   100,000,000+   500,000,000+ 1,000,000,000+ 
##            202            188             24             20
# Update

gplay_u_noNan$Installs <- factor(gplay_u_noNan$Installs)

summary(gplay_u_noNan$Installs)
##             1+             5+            10+            50+           100+ 
##              3              9             69             56            303 
##           500+         1,000+         5,000+        10,000+        50,000+ 
##            199            696            424            986            456 
##       100,000+       500,000+     1,000,000+     5,000,000+    10,000,000+ 
##           1094            503           1414            607            937 
##    50,000,000+   100,000,000+   500,000,000+ 1,000,000,000+ 
##            202            188             24             20
levels(gplay_u_noNan$Installs)
##  [1] "1+"             "5+"             "10+"            "50+"           
##  [5] "100+"           "500+"           "1,000+"         "5,000+"        
##  [9] "10,000+"        "50,000+"        "100,000+"       "500,000+"      
## [13] "1,000,000+"     "5,000,000+"     "10,000,000+"    "50,000,000+"   
## [17] "100,000,000+"   "500,000,000+"   "1,000,000,000+"
# Type 

summary(gplay_u_noNan$Type)
##    0 Free  NaN Paid 
##    0 7588    0  602
# Update

gplay_u_noNan$Type <- factor(gplay_u_noNan$Type)

summary(gplay_u_noNan$Type)
## Free Paid 
## 7588  602
levels(gplay_u_noNan$Type)
## [1] "Free" "Paid"
# Content Rating

summary(gplay_u_noNan$Content.Rating)
##                 Adults only 18+        Everyone    Everyone 10+ 
##               0               3            6612             305 
##      Mature 17+            Teen         Unrated 
##             357             912               1
# Update

gplay_u_noNan$Content.Rating <- factor(gplay_u_noNan$Content.Rating)

summary(gplay_u_noNan$Content.Rating)
## Adults only 18+        Everyone    Everyone 10+      Mature 17+ 
##               3            6612             305             357 
##            Teen         Unrated 
##             912               1
levels(gplay_u_noNan$Content.Rating)
## [1] "Adults only 18+" "Everyone"        "Everyone 10+"    "Mature 17+"     
## [5] "Teen"            "Unrated"
gplay_u_noNan$Content.Rating <- factor(gplay_u_noNan$Content.Rating, levels = c("Everyone","Everyone 10+","Teen","Unrated","Mature 17+","Adults only 18+"))

levels(gplay_u_noNan$Content.Rating)
## [1] "Everyone"        "Everyone 10+"    "Teen"            "Unrated"        
## [5] "Mature 17+"      "Adults only 18+"
# SizeCatg

summary(gplay_u_noNan$SizeCatg)
##       Big Size App    Medium Size App     Small Size App 
##                866               1892               4263 
## Varies with device 
##               1169
#Update

gplay_u_noNan$SizeCatg <- factor(gplay_u_noNan$SizeCatg)

summary(gplay_u_noNan$SizeCatg)
##       Big Size App    Medium Size App     Small Size App 
##                866               1892               4263 
## Varies with device 
##               1169
levels(gplay_u_noNan$SizeCatg)
## [1] "Big Size App"       "Medium Size App"    "Small Size App"    
## [4] "Varies with device"

3.14 Membuat data frame dengan nama baru

Agar lebih nyaman dalam penggunaan serta analisis data nantinya, data frame yang telah selesai diproses dibuatkan data frame baru dengan nama yang sesuai.

gplay_processed <- gplay_u_noNan
str(gplay_processed)
## 'data.frame':    8190 obs. of  11 variables:
##  $ App           : chr  "Photo Editor & Candy Camera & Grid & ScrapBook" "Coloring book moana" "U Launcher Lite â\200“ FREE Live Cool Themes, Hide Apps" "Sketch - Draw & Paint" ...
##  $ Category      : Factor w/ 33 levels "ART & DESIGN",..: 1 1 1 1 1 1 1 1 1 1 ...
##  $ Rating        : num  4.1 3.9 4.7 4.5 4.3 4.4 3.8 4.1 4.4 4.7 ...
##  $ Reviews       : int  1183 5924 5681 1947 5924 1310 1464 3385 816 485 ...
##  $ Installs      : Factor w/ 19 levels "1+","5+","10+",..: 9 12 14 16 11 10 10 13 13 9 ...
##  $ Type          : Factor w/ 2 levels "Free","Paid": 1 1 1 1 1 1 1 1 1 1 ...
##  $ Price         : num  0 0 0 0 0 0 0 0 0 0 ...
##  $ Content.Rating: Factor w/ 6 levels "Everyone","Everyone 10+",..: 1 1 1 3 1 1 1 1 1 1 ...
##  $ Last.Updated  : Date, format: "2018-01-07" "2018-01-15" ...
##  $ SizeNmr       : num  19 14 8.7 25 2.8 5.6 19 29 33 3.1 ...
##  $ SizeCatg      : Factor w/ 4 levels "Big Size App",..: 3 3 3 2 3 3 3 2 2 3 ...

4 Data Processing dan Plotting

4.1 Melihat persebaran aplikasi berdasarkan kategori di google play store

temp1 <- as.data.frame(table(gplay_processed$Category))

g1 <- ggplot(temp1, mapping = aes(x=reorder(Var1,Freq), y=Freq, fill=Freq))+
  geom_col()+
  scale_fill_gradient(low = "#f8d979",high = "#363fe6" )+
  coord_flip()+
  geom_text(aes(label = temp1$Freq),nudge_y = 60,col = "#040b5b")+
  geom_hline(yintercept = mean(temp1$Freq), linetype = 5, col = "Red")+
  labs(title="Jumlah Aplikasi Google Play Store Berdasarkan Kategori",subtitle = "Aplikasi berkategori Family merupakan yang terbanyak beredar di Google Play",x="Kategori", y="Jumlah Aplikasi", caption = "Source : Playstore dataset-Kaggle, PW")+
  theme(legend.position = "right",panel.grid.major.y = element_blank())
  

g1

Grafik di atas menggambarkan sebaran jumlah aplikasi yang beredar pada google play store berdasarkan kategorinya. Semakin banyak suatu aplikasi muncul dalam suatu kategori semakin ungu warna yang ditunjukkan, sedangkan semakin sedikit akan semakin kuning. Ternyata aplikasi berkategori “FAMILY” yang banyak beredar di google play store dengan jumlah aplikasi mencapai 1607, sedangkan aplikasi kecantikan “BEAUTY” merupakan yang paling sedikit dengan jumlah 42 aplikasi. Garis merah pada grafik menunjukkan rata-rata jumlah aplikasi untuk setiap kategorinya, yaitu sejumlah 249.

4.2 Membuat facet plot dari top 3 kategori di google play store

# Membuat variable baru yang tidak berisi aplikasi bersize 999 (Varies with device)
temp2 <- gplay_processed[gplay_processed$SizeNmr!= 999,]

# Mengambil aplikasi yang berada dalam top three kategori terbanyak

temp2 <- temp2[temp2$Category == "FAMILY" | temp2$Category == "GAME" | temp2$Category == "TOOLS",]


# Membuat facet plot
g2 <- ggplot(data = temp2, aes(x=Last.Updated, y=SizeCatg))+
  geom_jitter(aes(col=Rating, size = SizeNmr))+
  scale_color_gradient(low = "Red", high = "Green")+
  scale_x_date(date_labels = "%y", date_breaks = "2 years")+
  facet_grid(Content.Rating~Category)+
  scale_size(range=c(0,3))+
  labs(title = "Top Three Category in Google Play Store", x="App Update Date", y="Categories of App Size",caption = "Source : Playstore dataset-Kaggle, PW")+
  guides(size=guide_legend(title = "Size (MB)"))+
  theme(strip.text=element_text(size=7))

# Menampilkan facet plot
g2

Dari facet plot yang ditampilkan di atas, dapat kita tarik beberapa kesimpulan. Secara umum dari ketiga top kategori, tahun 2010 hingga 2012 tidak banyak update-update yang dilakukan pada aplikasi yang terdapat di play store, hal ini masuk akal karena pada tahun itu aplikasi-aplikasi barulah bermunculan, akan tetapi setelah tahun 2012 update-update mulai banyak bermunculan terutama dari aplikasi berukuran sedana ke besar.

Dari ketiga top kategori, tidak banyak aplikasi yang memiliki rating jelek (“1”). Yang jelas terlihat adalah kategori Tools, dengan aplikasi berukuran kecil ke sedang yang berkonten rating “Everyone”. Aplikasi tersebut mulai tidak disukai saat mengalami update sekitar tahun 2018.

List aplikasi tersebut dapat kita panggil dengan cara di bawah

temp2[temp2$Rating == 1 & temp2$Category == "TOOLS",]
##                                                    App Category Rating
## 8821                                    DS Creator 2.0    TOOLS      1
## 8876                                    DT future1 cam    TOOLS      1
## 10592 Lottery Ticket Checker - Florida Results & Lotto    TOOLS      1
##       Reviews Installs Type Price Content.Rating Last.Updated SizeNmr
## 8821     1745     500+ Free     0       Everyone   2018-03-23     4.4
## 8876        2      50+ Free     0       Everyone   2018-03-27    24.0
## 10592    2855     500+ Free     0       Everyone   2017-12-12    41.0
##              SizeCatg
## 8821   Small Size App
## 8876  Medium Size App
## 10592 Medium Size App

Lalu dari ketiga kategori tersebut, kategori FAMILY dan GAME memiliki keidentisan yang cukup tinggi dimana kedua kategori tersebut tidak meiliki aplikasi yang berating “Unrated”, sedangkan untuk kategori TOOLS aplikasi banyak ditujukan untuk seluruh orang dengan mayoritas berating “Everyone”, hanya beberapa aplikasi yang dilabeli “Teen”.