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 :
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
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)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 ...
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"
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.
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
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”.
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.
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 ...
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
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
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+"
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
# Konversi tanggal pada kolom Last.Updated menggunakan lubridate
gplay_u_noNan$Last.Updated <- mdy(gplay_u_noNan$Last.Updated)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"
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 ...
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())
g1Grafik 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.
# 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
g2Dari 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”.