1 Review Foundation Class

Knowledge Check

  1. Di bawah ini mana pernyataan yang salah terkait sifat pemrograman di R?

[ ] tanda <- berfungsi untuk memasukkan suatu nilai kedalam sebuah objek [ ] bahasa pemrograman R bersifat case sensitive [ ] tanda == digunakan untuk mengecek kesamaan antar 2 buah nilai [x] tanda // diawal sebuah chunk berfungsi sebagai tanda komentar

  1. Tipe data yang tepat untuk kolom yang berisi nama pelanggan adalah?

[x] Character [ ] Logical [ ] Numeric [ ] Integer

  1. Tipe data dari beberapa vector di bawah ini secara berurutan adalah?
  • c(TRUE, 1L, 1/2)
  • c("1", 12, 33.3)
  • c(1,2,3,4L)

[ ] integer, numeric, integer [ ] logical, character, numeric [x] numeric, character, numeric [ ] logical, numeric, integer

  1. Buat sebuah vector yang berisi nama anda, divisi di BCA, lama anda pada divisi tersebut (dalam tahun) simpan pada objek identitas.
# code here
identitas <- c("Victor", "Product", 1)
  1. Buat sebuah data frame yang berisi 3 kolom:
  • product : 3 nama produk swalayan (bebas/yang sering Anda beli)
  • quantity: jumlah pembelian masing-masing produk
  • harga : harga untuk masing-masing produk
# code here
data.frame(product = c("teh","kopi","gula"), 
           quantity = c(1,1,1), 
           harga = c(1000,2000,3000))

2 Working with Data

2.1 Read data

Kiva.org adalah sebuah platform crowdfunding online non-profit internasional yang didirikan pada tahun 2005 di San Fransisco. Crowdfunding (urun dana) adalah kegiatan penggalangan dana modal dari beberapa individu untuk membiayai usaha bisnis baru. Misi dari Kiva adalah untuk menghubungkan masyarakat melalui pemberian pinjaman dan meningkatkan kesejahteraan warga marginal (terutama pengusaha berpenghasilan rendah maupun pelajar).

Berikut adalah rekam data pinjaman yang telah dikelola oleh Kiva.org:

# your code
kiva <- read.csv("loan_kiva.csv")

Berikut ini adalah deskripsi dari variabel/kolom data kiva:

  • id: Unique ID for loan
  • funded_amount: The amount disbursed by Kiva to the field agent (USD)
  • loan_amount: The amount disbursed by the field agent to the borrower (USD)
  • activity: More granular category
  • sector: High level category
  • country: Country in which loan was disbursed
  • region: Full region name within the country
  • currency: The currency in which the loan was disbursed
  • partner_id: ID of partner organization
  • posted_time: The time at which the loan is posted on Kiva by the field agent
  • funded_time: The time at which the loan posted to Kiva gets funded by lenders completely
  • term_in_months: The duration for which the loan was disbursed in months
  • lender_count: The total number of lenders that contributed to this loan
  • repayment_interval: Types of repayment from a lender in accordance with a loan’s terms
    • irregular: no equally spaced interval
    • bullet: lump sum payment, paid at maturity
    • monthly: regular payment at each month

Pada umumnya ketika bekerja dengan data kita ingin melihat data bentuk data secara keseluruhan, hal tersebut dapat dilakukan dengan menggunakan fungsi View().

# your code
# View(kiva)

2.2 Inspect Data

Inspeksi data bertujuan untuk mengetahui kondisi dari data yang akan diolah. Pada tahapan ini kita perlu mengetahui struktur data, jumlah data, tipe data setiap kolom (apakah sudah sesuai konteks data), apakah mengandung missing value, dll.

Cek isi data:

Daripada melihat keseluruhan data, lebih baik kita “mengintip” sebagian baris yang dapat merepresentasikan bentuk keseluruhan data.

  • Data teratas

Fungsi head() untuk melihat beberapa baris teratas pada data (default 6)

# your code
head(kiva)
  • Data terbawah

Fungsi tail() untuk melihat beberapa data terakhir.

# your code
tail(kiva)
  • Isi data secara singkat

Fungsi str() untuk melihat struktur dari dataframe.

# your code
str(kiva)
#> 'data.frame':    323279 obs. of  14 variables:
#>  $ id                : int  653051 653053 653068 653063 653084 653067 653078 653082 653048 653060 ...
#>  $ funded_amount     : num  300 575 150 200 400 200 400 475 625 200 ...
#>  $ loan_amount       : num  300 575 150 200 400 200 400 475 625 200 ...
#>  $ activity          : chr  "Fruits & Vegetables" "Rickshaw" "Transportation" "Embroidery" ...
#>  $ sector            : chr  "Food" "Transportation" "Transportation" "Arts" ...
#>  $ country           : chr  "Pakistan" "Pakistan" "India" "Pakistan" ...
#>  $ region            : chr  "Lahore" "Lahore" "Maynaguri" "Lahore" ...
#>  $ currency          : chr  "PKR" "PKR" "INR" "PKR" ...
#>  $ partner_id        : int  247 247 334 247 245 334 245 245 247 247 ...
#>  $ posted_time       : chr  "2014-01-01 06:12:39" "2014-01-01 06:51:08" "2014-01-01 09:58:07" "2014-01-01 08:03:11" ...
#>  $ funded_time       : chr  "2014-01-02 10:06:32" "2014-01-02 09:17:23" "2014-01-01 16:01:36" "2014-01-01 13:00:00" ...
#>  $ term_in_months    : int  12 11 43 11 14 43 14 14 11 11 ...
#>  $ lender_count      : int  12 14 6 8 16 8 8 19 24 3 ...
#>  $ repayment_interval: chr  "irregular" "irregular" "bullet" "irregular" ...

Cek dimensi data (baris-kolom):

  • Cek baris

Fungsi nrow() untuk mengetahui jumlah baris

# your code
nrow(kiva)
#> [1] 323279
  • Cek kolom

Fungsi ncol() untuk mengetahui jumlah kolom.

# your code
ncol(kiva)
#> [1] 14
  • Cek baris dan kolom secara bersamaan

Fungsi dim() untuk mengetahui dimensi dari dataframe.

# your code
dim(kiva)
#> [1] 323279     14
  • Rangkuman statistik data

Fungsi summary() untuk mengetahui ringkasan/rangkuman statistik dari dataframe.

# your code
summary(kiva)
#>        id          funded_amount       loan_amount         activity        
#>  Min.   : 653047   Min.   :    25.0   Min.   :    25.0   Length:323279     
#>  1st Qu.: 737420   1st Qu.:   275.0   1st Qu.:   275.0   Class :character  
#>  Median : 827056   Median :   500.0   Median :   500.0   Mode  :character  
#>  Mean   : 826774   Mean   :   828.8   Mean   :   828.8                     
#>  3rd Qu.: 915291   3rd Qu.:  1000.0   3rd Qu.:  1000.0                     
#>  Max.   :1002884   Max.   :100000.0   Max.   :100000.0                     
#>     sector            country             region            currency        
#>  Length:323279      Length:323279      Length:323279      Length:323279     
#>  Class :character   Class :character   Class :character   Class :character  
#>  Mode  :character   Mode  :character   Mode  :character   Mode  :character  
#>                                                                             
#>                                                                             
#>                                                                             
#>    partner_id    posted_time        funded_time        term_in_months 
#>  Min.   :  9.0   Length:323279      Length:323279      Min.   :  2.0  
#>  1st Qu.:125.0   Class :character   Class :character   1st Qu.:  8.0  
#>  Median :145.0   Mode  :character   Mode  :character   Median : 13.0  
#>  Mean   :166.7                                         Mean   : 13.9  
#>  3rd Qu.:199.0                                         3rd Qu.: 14.0  
#>  Max.   :469.0                                         Max.   :158.0  
#>   lender_count     repayment_interval
#>  Min.   :   1.00   Length:323279     
#>  1st Qu.:   8.00   Class :character  
#>  Median :  15.00   Mode  :character  
#>  Mean   :  22.85                     
#>  3rd Qu.:  28.00                     
#>  Max.   :2986.00

Pada kolom numerik, ditampilkan ringkasan lima nilai (five number summary). Apakaha ada insight yang menarik:

2.3 Data Cleansing

2.3.1 Explicit Coercion

Jika kita sadari, dengan menggunakan fungsi str() kita juga dapat mengetahui tipe data yang terdapat pada setiap kolom. Jika kita coba lihat kembali, apakah semua kolom sudah memiliki tipe data yang sesuai?

# your code
# str(kiva)

note:

  • kalau jumlah kategori unique cukup sedikit dibandingkan jumlah data, bisa untuk visualisasi, pivot/summary data, machine learning, dll -> factor
  • kalau jumlah kategori unique terlalu banyak dan kurang bermanfaat untuk nanti dilakukan visualisasi/pembuatan model machine learning -> tidak perlu diubah ke factor
# cek dari segi konteks bisnis, kemudian jumlah data vs unique category untuk menentukan perlu/tidaknya diubah ke factor.
nrow(kiva)
#> [1] 323279
length(unique(kiva$partner_id))
#> [1] 299
length(unique(kiva$id))
#> [1] 323279

Kolom yang perlu diperbaiki tipe datanya:

  • sector -> factor
  • country -> factor
  • repayment interval -> factor
  • region -> factor
  • currency -> factor
  • activity -> factor
  • id -> char
  • parner_id -> char
  • funded time -> datetime
  • posted time -> datetime

Untuk mengubah tipe data, dapat menggunakan fungsi as.*() dimana * diisi tipe data.

  • as.factor(): Mengubah menjadi tipe data factor (nilai value yang berulang-ulang)
# your code
kiva$sector <- as.factor(kiva$sector)
kiva$country <- as.factor(kiva$country)
kiva$repayment_interval <- as.factor(kiva$repayment_interval)
kiva$region <- as.factor(kiva$region)
kiva$currency <- as.factor(kiva$currency)
kiva$partner_id <- as.character(kiva$partner_id)
kiva$id <- as.character(kiva$id)
kiva$activity <- as.factor(kiva$activity)
  • as.Date() : Mengubah menjadi tipe data tanggal (YMD)
  • as.POSIXct(): Mengubah menjadi tipe data tanggal-waktu (YMD HMS)

ISO Default: YMD HMS

Parameter format pada as.Date() & as.POSIXct() digunakan untuk menspesifikan format penulisan tanggal pada data, berikut format yang sering digunakan:

  • YEAR
    • %Y = tahun empat digit, contoh: 2022
    • %y = tahun dua digit, contoh: 22
  • MONTH
    • %B = nama bulan, contoh: January
    • %b = nama bulan singkatan, contoh: Jan
    • %m = bulan dua digit, contoh: 01
    • %M = bulan satu digit, contoh: 1
  • DAY
    • %A = nama hari, contoh: Monday
    • %d = tanggal, contoh: 01 sampai 31

Format awal data tanggal kiva:

  • Kolom posted_time: YMD HMS
  • Kolom funded_time: %Y-%m-%d %H:%M:%S
# perbaiki tipe data
kiva$posted_time <- as.POSIXct(kiva$posted_time, format = "%Y-%m-%d %H:%M:%S")
kiva$funded_time <- as.POSIXct(kiva$funded_time, format = "%Y-%m-%d %H:%M:%S")

Tambahan: Kolom dengan tipe data date dapat dioperasikan satu sama lain. Misal kita ingin menghitung durasi waktu antara tangal post permintaan funding (posted_time) dengan waktu funding dipenuhi (funded_time), lalu simpan hasil perhitungan ke kolom Duration.

Fungsi difftime() digunakan untuk menghitung time1 - time2 dengan parameter:

  • time1: waktu end
  • time2: waktu start
  • units: satuan waktu hasil pengurangan, bisa diisi dengan secs, mins, hours, days, weeks
# your code
kiva$duration <- difftime(time1 = kiva$funded_time,
                          time2 = kiva$posted_time,
                          units = "days")

head(kiva$duration)
#> Time differences in days
#> [1] 1.1624190 1.1015625 0.2524190 0.2061227 0.3093981 0.3104977
kiva$duration <- round(x = kiva$duration)
tail(kiva$duration)
#> Time differences in days
#> [1]  1  1  3 27  4  0

Setelah memperbaiki tipe data, mari kita cek summarynya kembali:

# your code
summary(kiva)
#>       id            funded_amount       loan_amount      
#>  Length:323279      Min.   :    25.0   Min.   :    25.0  
#>  Class :character   1st Qu.:   275.0   1st Qu.:   275.0  
#>  Mode  :character   Median :   500.0   Median :   500.0  
#>                     Mean   :   828.8   Mean   :   828.8  
#>                     3rd Qu.:  1000.0   3rd Qu.:  1000.0  
#>                     Max.   :100000.0   Max.   :100000.0  
#>                                                          
#>                       activity              sector             country      
#>  Farming                  : 33610   Agriculture:86509   Philippines: 81199  
#>  General Store            : 31087   Food       :68752   Kenya      : 31947  
#>  Personal Housing Expenses: 15616   Retail     :62118   El Salvador: 20543  
#>  Agriculture              : 14309   Services   :20550   Cambodia   : 13402  
#>  Food Production/Sales    : 13950   Housing    :16318   Peru       : 12799  
#>  Retail                   : 13728   Clothing   :15840   Uganda     : 11832  
#>  (Other)                  :200979   (Other)    :53192   (Other)    :151557  
#>        region          currency       partner_id       
#>  Kaduna   :  5466   PHP    : 81199   Length:323279     
#>  Lahore   :  4322   USD    : 52751   Class :character  
#>  Kisii    :  3324   KES    : 31467   Mode  :character  
#>  Cusco    :  3013   PEN    : 12225                     
#>  Thanh Hoá:  2099   UGX    : 11772                     
#>  (Other)  :278802   PKR    : 11647                     
#>  NA's     : 26253   (Other):122218                     
#>   posted_time                      funded_time                    
#>  Min.   :2014-01-01 04:49:26.00   Min.   :2014-01-01 12:18:55.00  
#>  1st Qu.:2014-07-11 04:09:40.50   1st Qu.:2014-07-24 18:41:26.00  
#>  Median :2015-01-12 12:41:08.00   Median :2015-01-24 16:41:59.00  
#>  Mean   :2015-01-09 01:53:40.06   Mean   :2015-01-23 22:32:18.10  
#>  3rd Qu.:2015-07-09 13:31:04.50   3rd Qu.:2015-07-24 02:21:52.00  
#>  Max.   :2015-12-31 23:04:04.00   Max.   :2016-02-25 13:45:34.00  
#>                                                                   
#>  term_in_months   lender_count     repayment_interval   duration       
#>  Min.   :  2.0   Min.   :   1.00   bullet   : 32653   Length:323279    
#>  1st Qu.:  8.0   1st Qu.:   8.00   irregular:130580   Class :difftime  
#>  Median : 13.0   Median :  15.00   monthly  :160046   Mode  :numeric   
#>  Mean   : 13.9   Mean   :  22.85                                       
#>  3rd Qu.: 14.0   3rd Qu.:  28.00                                       
#>  Max.   :158.0   Max.   :2986.00                                       
#> 

Apakah ada temuan baru yang menarik dari hasil summarynya?

2.3.2 Handle Missing Values

Pada bagian ini kita memastikan tidak ada missing value pada data. terdapat beberapa cara untuk mengatasi missing value yaitu:

  1. complete cases: Membuang observasi/baris yang memiliki missing value (*bila NA <5%)
  2. deletion: Membuang 1 kolom sekaligus (*bila NA >50% pada kolom tersebut)
  3. imputation: Mengisi NA dengan suatu nilai
    • mengisi dengan nilai tertentu sesuai dengan bisnis knowledge
    • numeric: mean/median
    • factor: modus
  • Cek apakah terdapat missing value pada data, secara singkat:

Fungsi anyNA() digunakan untuk mengetahui apakah pada data terdapat missing value.

# your code
anyNA(kiva)
#> [1] TRUE
  • Menghitung jumlah observasi missing value pada setiap kolom:

Fungsi is.na() digunakan untuk mengecek missing value pada setiap nilai. Fungsi colSums() digunakan untuk menjumlahkan nilai pada setiap kolom.

# your code
colSums(is.na(kiva))
#>                 id      funded_amount        loan_amount           activity 
#>                  0                  0                  0                  0 
#>             sector            country             region           currency 
#>                  0                  0              26253                  0 
#>         partner_id        posted_time        funded_time     term_in_months 
#>                  0                  0                  0                  0 
#>       lender_count repayment_interval           duration 
#>                  0                  0                  0

Insight: Imputasi lebih cocok dilakukan karena proporsi data tidak terlalu banyak dan tidak terlalu sedikit.

karena kita tidak memiliki informasi tambahan terkait missing value pada kolom region, kita akan mengisi dengan “No Region”

Note: Melakukan imputation pada data missing value yang bertipe data factor tidak dapat dilakukan secara langsung bila nilai pengisinya tidak terdaftar pada levelsnya.

# ambil baris yang NA pada kolom region
# apakah ada NA/tidak pada cell tertentu
kiva[is.na(kiva$region), "region"] <- "No Region"
#> Warning in `[<-.factor`(`*tmp*`, iseq, value = c("No Region", "No Region", :
#> invalid factor level, NA generated

pesan error invalid factor level, NA generated : menunjukkan bahwa nilai “No Region” tidak ada sebelumnya. sehingga kolom region perlu diubah menjadi character terlebih dahulu, ditambahkan nilai “No Region”, baru diubah ke factor kembali.

# ubah kolom region ke character
kiva$region <- as.character(kiva$region)

# isi nilai NA
kiva[is.na(kiva$region), "region"] <- "No Region"

# ubah kembali menjadi factor
kiva$region <- as.factor(kiva$region)
# cek kembali missing value
anyNA(kiva)
#> [1] FALSE

Dive Deeper

Isi missing value tersebut dengan cara yang tepat:

academy <- data.frame(nama = c("Andi", "Budi", "Ani", "Mawar"), 
           umur = c(22, 23, 22, NA), 
           skor = c(100, 96, 95, 90))

academy

Action Plan: di-isi dengan mean/median

# contoh mengisi dengan nilai tertentu
academy[is.na(academy$umur), "umur"] <- 0
academy
# your code
academy[is.na(academy$umur), "umur"] <- mean(academy$umur, na.rm = T)
academy
# rounding angka / desimal
academy$umur <- round(academy$umur, 0)
academy

2.4 Subsetting

Formula subset data frame: data[baris, kolom]

  • Data indeks ke 10-20, kolom ke 1 dan 3
# your code
 kiva[10:20,c(1,3)]
  • Data indeks ke 10-20, kolom id dan loan_amount
# your code
kiva[10:20,c("id","loan_amount")]

note:

  • gunakan c() bila membutuhkan beberapa nilai
  • gunakan : untuk menandakan “sampai dengan”

2.4.1 Conditional Subsetting

Subsetting dapat dilakukan untuk mengambil data secara spesifik berdasarkan kondisi yang diinginkan. berikut merupakan logical operator yang sering digunakan:

  • > lebih dari
  • < kurang dari
  • >= lebih dari sama dengan
  • <= kurang dari sama dengan
  • == sama dengan
  • != tidak sama dengan
  • & dan
  • | atau
  • %in% include
  1. Tampilkan data peminjam yang berasal dari sector retail dengan jumlah pinjaman lebih dari 1000 USD!
  • cond1 -> sector == “Retail”
  • cond2 -> loan_amount > 1000
  • letakan kondisi di bagian baris (sebelum koma)
kiva[kiva$sector == "Retail" & kiva$loan_amount > 1000, ]
  1. Tampilkan data informasi id, sector, dan country dari peminjam yang memilih repayment_interval bullet!
# your code
head(kiva[kiva$repayment_interval == "bullet", c("id", "sector", "country")])
  1. Tampilkan data peminjam yang berasal dari tipe activity “Beverages”, “Cafe”, “Catering”, “Food”, “Restaurant”!
# your code
head(kiva[kiva$activity == c("Beverages","Cafe","Catering","Food","Restaurant"),])
#> Warning in `==.default`(kiva$activity, c("Beverages", "Cafe", "Catering", :
#> longer object length is not a multiple of shorter object length
#> Warning in is.na(e1) | is.na(e2): longer object length is not a multiple of
#> shorter object length
head(kiva[kiva$activity %in% c("Beverages","Cafe","Catering","Food","Restaurant"),])
  1. Tampilkan pinjaman yang jumlah pemberi pinjamannya (lender_count) di atas rata-rata!
# your code
head(kiva[kiva$lender_count > mean(kiva$lender_count), ])
  1. Tampilkan data dengan nilai funded_amount tertinggi!
# your code
max(kiva$funded_amount)
#> [1] 100000
kiva[kiva$funded_amount==max(kiva$funded_amount),]
  1. Tampilkan data pinjaman paling awal dan paling akhir, dilihat dari tanggal posted_time!
# your code
kiva[kiva$posted_time == max(kiva$posted_time) | kiva$posted_time == min(kiva$posted_time), ]

Dive Deeper: Study Case Retail

Kita akan menganalisis data retail.csv yang terdapat pada folder data_input. Gunakan fungsi read.csv() untuk membaca file CSV ke R, lalu simpanlah ke sebuah object dengan nama retail.

retail <- read.csv("data_input/retail.csv")
str(retail)
#> 'data.frame':    9994 obs. of  15 variables:
#>  $ Row.ID      : int  1 2 3 4 5 6 7 8 9 10 ...
#>  $ Order.ID    : chr  "CA-2016-152156" "CA-2016-152156" "CA-2016-138688" "US-2015-108966" ...
#>  $ Order.Date  : chr  "11/8/16" "11/8/16" "6/12/16" "10/11/15" ...
#>  $ Ship.Date   : chr  "11/11/16" "11/11/16" "6/16/16" "10/18/15" ...
#>  $ Ship.Mode   : chr  "Second Class" "Second Class" "Second Class" "Standard Class" ...
#>  $ Customer.ID : chr  "CG-12520" "CG-12520" "DV-13045" "SO-20335" ...
#>  $ Segment     : chr  "Consumer" "Consumer" "Corporate" "Consumer" ...
#>  $ Product.ID  : chr  "FUR-BO-10001798" "FUR-CH-10000454" "OFF-LA-10000240" "FUR-TA-10000577" ...
#>  $ Category    : chr  "Furniture" "Furniture" "Office Supplies" "Furniture" ...
#>  $ Sub.Category: chr  "Bookcases" "Chairs" "Labels" "Tables" ...
#>  $ Product.Name: chr  "Bush Somerset Collection Bookcase" "Hon Deluxe Fabric Upholstered Stacking Chairs, Rounded Back" "Self-Adhesive Address Labels for Typewriters by Universal" "Bretford CR4500 Series Slim Rectangular Table" ...
#>  $ Sales       : num  262 731.9 14.6 957.6 22.4 ...
#>  $ Quantity    : int  2 3 2 5 2 7 4 6 3 5 ...
#>  $ Discount    : num  0 0 0 0.45 0.2 0 0 0.2 0.2 0 ...
#>  $ Profit      : num  41.91 219.58 6.87 -383.03 2.52 ...

Deskripsi kolom:

  • Row.ID = Nomer baris
  • Order.ID = Unique ID pemesanan
  • Order.Date = Tanggal pemesanan
  • Ship.Date = Tanggal pengiriman barang
  • Ship.Mode = Jenis pengiriman yang dipilih customer
  • Customer.ID = Unique ID customer
  • Segment = Segmentasi/kategori custoemr
  • Product.ID = Unique ID barang
  • Category = Kateogri barang
  • Sub.Category = Sub Kategori barang
  • Product.Name = Nama produk barang
  • Sales = Total sales dari barang yang dibeli oleh customer
  • Quantity = Total barang yang dibeli oleh customer
  • Discount = Total diskon yang diberikan kepada customer
  • Profit = Total keuntungan yang didapatkan oleh perusahaan

Sebagai seorang analis yang hendak menelusuri performa penjualan suatu perusahaan. Sebelum melakukan analisa, mari kita coba persiapkan data kita terlebih dahulu

Persiapan Data

  1. Apakah pada data retail terdapat missing value?
# your code
anyNA(retail)
#> [1] FALSE
  1. Apakah terdapat kolom yang belum sesuai denga tipe datanya?

Kolom apa saja yang belum sesuai?

Menjadi Factor - Ship.Mode - Segment - Category - Sub.Category

Menjadi Date - Order.Date - Ship.Date

Jika sudah mengetahui kolom apa saja yang belum sesuai, silahkan simpan kedalam object `retail_clean``

# your code
retail$Ship.Mode <- as.factor(retail$Ship.Mode)
retail$Segment <- as.factor(retail$Segment)
retail$Category <- as.factor(retail$Category)
retail$Sub.Category <- as.factor(retail$Sub.Category)
retail$Order.Date <- as.Date(retail$Order.Date, format = "%m/%d/%y")
retail$Ship.Date <- as.Date(retail$Ship.Date, format = "%m/%d/%y")

Setelah selesai melakukan persiapan data, mari kita coba melakuakan analisis untuk beberapa pertanyaan dibawah ini.

Analisis Data

  1. Berdasarkan data retail berapa banyak Category Furniture, yang dikirim (Ship.Mode) dengan tipe Standard Class ?
# your code
nrow(retail[retail$Category == "Furniture" & retail$Ship.Mode == "Standard Class",])
#> [1] 1248
  1. Berapa banyak data Category Furniture yang memiliki Profit kurang dari 0?
# your code
nrow(retail[retail$Category == "Furniture" & retail$Profit < 0,])
#> [1] 714

2.5 Data Aggregation

Selain subsetting, hal yang sering dilakukan ketika kita melakukan analisis adalah aggregasi data, yaitu membuat tabel rangkuman.

2.5.1 table()

Fungsi table() untuk menampilkan frekuensi tiap kategori

Contoh: Sector apa yang menyumbang paling banyak transaksi pinjaman di Kiva? Berapa banyak transaksi yang dihasilkan?

# your code
table(kiva$sector)
#> 
#>    Agriculture           Arts       Clothing   Construction      Education 
#>          86509           5324          15840           3377          15752 
#>  Entertainment           Food         Health        Housing  Manufacturing 
#>            373          68752           3686          16318           3656 
#>   Personal Use         Retail       Services Transportation      Wholesale 
#>          12836          62118          20550           7831            357
# sort(): mengurutkan nilai
sort(table(kiva$sector), decreasing = T)
#> 
#>    Agriculture           Food         Retail       Services        Housing 
#>          86509          68752          62118          20550          16318 
#>       Clothing      Education   Personal Use Transportation           Arts 
#>          15840          15752          12836           7831           5324 
#>         Health  Manufacturing   Construction  Entertainment      Wholesale 
#>           3686           3656           3377            373            357
# names(): mengambil nama dari setiap nilai pada vector
names(sort(table(kiva$sector), decreasing = T))[1]
#> [1] "Agriculture"

Additional: Pembuatan Fungsi Manual (DIY)

# template coding utk buat fungsi manual (fun {snippet})
highest_count <- function(x) {
  
  names(sort(table(x), decreasing = T))[1]
  
}
# gunakan fungsi highest_count utk kolom lainnya
highest_count(kiva$country)
#> [1] "Philippines"
names(sort(table(kiva$country), decreasing = T))[1]
#> [1] "Philippines"

2.5.2 prop.table()

Mengubah tabel frekuensi menjadi tabel proporsi/persentase untuk tiap kategori.

Sintaks: prop.table(table(...))

Contoh: Sector apa yang menyumbang paling banyak transaksi pinjaman di Kiva? Berapa persen proporsinya dibanding keseluruhan data?

prop.table(table(kiva$sector))
#> 
#>    Agriculture           Arts       Clothing   Construction      Education 
#>    0.267598576    0.016468747    0.048997924    0.010446085    0.048725714 
#>  Entertainment           Food         Health        Housing  Manufacturing 
#>    0.001153802    0.212670789    0.011401916    0.050476523    0.011309117 
#>   Personal Use         Retail       Services Transportation      Wholesale 
#>    0.039705641    0.192149815    0.063567383    0.024223658    0.001104309
# kalikan 100 untuk dapat persentase
prop.table(table(kiva$sector))*100
#> 
#>    Agriculture           Arts       Clothing   Construction      Education 
#>     26.7598576      1.6468747      4.8997924      1.0446085      4.8725714 
#>  Entertainment           Food         Health        Housing  Manufacturing 
#>      0.1153802     21.2670789      1.1401916      5.0476523      1.1309117 
#>   Personal Use         Retail       Services Transportation      Wholesale 
#>      3.9705641     19.2149815      6.3567383      2.4223658      0.1104309

2.5.3 xtab()

Fungsi xtabs() untuk menampilkan jumlah (sum) suatu variabel numerik untuk tiap kategori.

Sintaks: xtabs(formula = ..., data = ...)

Parameter:

  • formula dituliskan dengan numerik ~ kategorik (simbol ~ disebut tilde)
  • data dituliskan dengan nama object data yang digunakan

Contoh: Sector apa yang memiliki jumlah dana pinjaman (funded_amount) terbanyak di Kiva? Berapa jumlah dana pinjaman pada Sector tersebut?

# your code
xtabs(formula = funded_amount ~ sector, data = kiva)
#> sector
#>    Agriculture           Arts       Clothing   Construction      Education 
#>       68080475        5624125       17797150        3467950       15508575 
#>  Entertainment           Food         Health        Housing  Manufacturing 
#>         403850       58259475        4300600       11457425        3220025 
#>   Personal Use         Retail       Services Transportation      Wholesale 
#>        6453975       46750825       20835175        5233950         547500
# bisa kah diexport? bisa ke bentuk data frame
xtab_data <- as.data.frame(xtabs(formula = funded_amount ~ sector + activity + country,
                                 data = kiva))

xtab_data

Mengapa di hasil xtabs data frame semua nilainya 0? karena memang kebetulan tidak ada pasangan untuk country Afghanistan, untuk sector dan activity yg ditampilkan di preview data:

# dari data awal, memang hanya ada untuk activity Textiles, sector Arts
kiva[kiva$country == "Afghanistan", ] 
# untuk menampilkan hanya yang memiliki nilai (Freq = 0 dihilangkan)
xtab_data[xtab_data$Freq != 0,]

2.5.4 aggregate()

Untuk melakukan aggregasi data dengan fungsi yang lebih fleksibel, kita dapat menggunakan fungsi aggregate().

Fungsi aggregate() untuk menghitung nilai statistik tertentu (jumlah, rata-rata, dll) berdasarkan kolom kategori dalam data.

Sintaks: aggregate(formula = ..., data = ..., FUN = ...)

Parameter:

  • formula dituliskan dengan numerik ~ kategorik
  • data dituliskan dengan nama object data yang digunakan
  • FUN dituliskan dengan nama fungsi:
    • sum: jumlah
    • min: nilai minimum
    • max: nilai maksimum
    • mean: nilai rata-rata
    • median: nilai tengah
    • length: count (menghitung frekuensi)

Contoh: Tampilkan rata-rata pinjaman (loan_amount) dari setiap sector dan negara. Pasangan negara dan sector apa yang memiliki rata-rata pinjaman tertinggi?

# your code
data_agg <- aggregate(loan_amount ~ sector + country, data = kiva, FUN = mean)

head(data_agg)
# mengurutkan data menggunakan order()
# order akan menyimpan indeks data yang sudah terurut
# indeks nya kita gunakan dengan fungsi subsetting data
# contoh dibawah: order berdasarkan loan_amount

data_agg[order(data_agg$loan_amount, decreasing = T),]

Dive Deeper!

  1. Tampilkan rata rata pinjaman yang diberikan oleh kiva (funded_amount) untuk masing-masing sector, dan urutkan dari yang terbesar hingga terkecil! Sector apa yang menerima umumnya mendapatkan pembiayaan dalam jumlah besar dari kiva?
  • tahap 1: aggregasi data - rata2
  • tahap 2: pengurutan data
# your code
data1 <- aggregate(funded_amount ~ sector, data = kiva, FUN = mean)
data1[order(data1$funded_amount, decreasing = T), ]

Jawaban:

  1. Tampilkan jumlah transaksi pinjaman dari setiap sector pada negara Indonesia dan urutkan dari yang terbesar hingga terkecil! Sector apa yang paling banyak melakukan pinjaman dari negara Indonesia?
# your code
dd2 <- aggregate(x = loan_amount ~ sector + country, data = kiva, FUN = length)
dd21 <- dd2[dd2$country == "Indonesia",]
dd21[order(dd21$loan_amount, decreasing = T), ]
# cara 2
kiva_indonesia <- kiva[kiva$country=="Indonesia",]
kiva_indonesia_agg <- aggregate(loan_amount ~ sector, kiva_indonesia, FUN = length)
kiva_indonesia_agg[order(kiva_indonesia_agg$loan_amount, decreasing = T),]
# cara 3
data_indo <- kiva[kiva$country=="Indonesia",]
sort(table(data_indo$sector), decreasing = T)
#> 
#>         Retail       Services    Agriculture        Housing           Food 
#>            667            553            492            256            195 
#>   Personal Use      Education           Arts Transportation   Construction 
#>            158            122             72             14             13 
#>       Clothing         Health  Manufacturing  Entertainment      Wholesale 
#>              7              4              2              1              1

Jawaban:

  1. Tampilkan 5 negara yang mendapatkan jumlah pinjaman (sum of funded_amount) tertinggi untuk sector retail!
kiva_retail <- kiva[kiva$sector == "Retail",]
kiva_retail_agg <- aggregate(funded_amount ~ country, kiva_retail, sum)
kiva_retail_order <- kiva_retail_agg[order(kiva_retail_agg$funded_amount, decreasing = T),]
head(kiva_retail_order, 5)

Jawaban:

  1. Tampikan durasi maksimum (paling lambat) suatu pinjaman dibiayai oleh kiva (term_in_months) untuk tiap sector nya?
# your code
agg4 <- aggregate(term_in_months ~ sector, data = kiva, FUN = max)
agg4[order(agg4$term_in_months, decreasing=T),]
  1. Tampikan durasi minimum (paling cepat) suatu pinjaman dibiayai oleh kiva (term_in_months) untuk tiap sector nya?
# aggregasi kemudian order
agg5 <- aggregate(term_in_months ~ sector, data = kiva, FUN = min)
agg5[order(agg5$term_in_months, decreasing = F),]
# untuk ambil 1 data saja (pakai head/tail) -> ini sudah jadi sector paling cepat dibiayai, bukan data tiap sector
head(agg5[order(agg5$term_in_months, decreasing = F),],1)

2.6 Sampling

Fungsi sample() digunakan untuk mengambil beberapa baris secara acak pada data. Biasanya digunakan pada proses machine learning.

# contoh sampling sederhana menggunakan vector
student <- c("A", "B", "C", "D")
sample(student, 3)
#> [1] "D" "B" "C"

Fungsi set.seed() digunakan untuk mengunci random number generator sehingga hasil sampling tidak berubah setiap kali run code. Nilai seed yang digunakan bebas, maksimal 10 digit.

set.seed(100)
sample(student, 3)
#> [1] "B" "C" "D"

Tambahan: Untuk sampling dari data.frame, harus dibuat objek berisi index baris yang akan diambil. Index baris dibuat secara random, kemudian diambil baris sesuai index yang sudah dibuat.

Sample 5 observasi dari data kiva:

# mengambil 5 baris/observasi dari data kiva

# sample index random
set.seed(100)
index <- sample(nrow(kiva), 5)

# ambil data
kiva[index,]

Sampling 10% data dari data kiva:

# sample index random
set.seed(100)
index10 <- sample(nrow(kiva), nrow(kiva)*0.1)

# ambil data
kiva[index10,]