email             :
ntraktir          : https://trakteer.id/contekansial
nyawer          : https://saweria.co/contekansial
github            : https://bit.ly/origin-AL-GitHub
youtube         : https://bit.ly/origin-AL-youtube



1 Introduction

1.1 Latar Belakang

AL.Finance merupakan perusahaan peer to peer lending, sehingga AL.Finance membutuhkan investor untuk memberikan pinjaman kepada calon borrower.

Setiap ada borrower yang mengajukan pinjaman, AL.Finance akan mengunggah loan itu ke marketplace. Lalu kemudian investor yang sudah mendaftar akan melihat loan tersebut, jika ada yang cocok maka mereka akan order lalu bayar. Sehingga investor tersebut membiayai loan yang tadi dipilih.

Pada project kali ini, akan dilakukan analisis terhadap proses investasi dari investor tersebut.

1.2 Tugas dan Langkah

Sebagai seorang data analyst, kamu diminta untuk menganalisis proses investasi dari investor yang terdaftar di AL.Finance.

Pada tugas kali ini, kamu akan menganalisis bagaimana behaviour nya.

Langkah yang akan dilakukan adalah: 1. Eksplorasi data 2. Manipulasi data 3. Analisis proses investasi 4. Analisis waktu sampai investasi pertama 5. Analisis retention invest


2 Package dan Data yang Digunakan

2.1 Package yang Digunakan

Pada analisis kali ini, akan digunakan beberapa package yang membantu kita dalam melakukan analisis data:

  1. Package dplyr, merupakan package yang paling sering digunakan dalam analisis data, sangat membantu dalam manipulasi data, fungsi yang paling sering digunakan adalah :
  • mutate() = membuat variabel baru berdasarkan variabel yang ada
  • select() = memilih variabel berdasarkan namannya
  • filter() = menyaring data berdasarkan nilai dari variabel
  • summarise() = mengubah beberapa nilai menjadi satu ringkasan nilai
  • arrange() = mengurutkan baris data
  1. Package ggplot2, merupakan package yang digunakan untuk membuat plot dengan syntax yang konsisten. Secara umum, untuk membuat plot dengan memanggil fungsi:
ggplot(data) + geom_type(aes(x,y,fill,color)) 

geom_type diganti dengan fungsi sesuai dengan jenis plot yang diharapkan, misalnya geom_line, geom_bar, geom_point, geom_boxplot dan lainnya.

  1. Packages scales, digunakan untuk memformat nilai data numerik menjadi format yang mudah dibaca. Tidak terlalu sering digunakan, tapi membantu ketika eksplorasi data. Fungsi yang biasa dipakai adalah:
  • comma() = mengubah numerik menjadi ada simbol ribuan, misalnya 9000000000 diubah menjadi 9,000,000,000
  • percent() = mengubah numerik menjadi ada format persen, misalnya 0.49139 diubah menjadi 49%

2.2 Package yang Digunakan (cont.)

  1. Packages tidyr, digunakan untuk memformat bentuk data, dari wide menjadi long. Sangat berguna dalam tahap preparasi data. Fungsi yang biasa dipakai adalah:
  • spread() = memformat data.frame menjadi wide, isi dari kolom key diubah menjadi nama kolom, dan isi dari kolom value diubah menjadi isi dari masing-masing kolom baris tersebut
  • gather() = memformat data.frame menjadi long, nama nama kolom yang dipilih dijadikan isi dari kolom key sedangkan yang sebelumnya isi dari kolom-kolom tersebut menjadi isi dari kolom value
  1. Packages lubridate, digunakan untuk mengolah tipe data Date maupun Timestamp. Fungsi yang biasa dipakai adalah:
  • ymd() = mengubah tipe character berformat YearMonthDate menjadi tipe Date
  • ymd_hms() = mengubah tipe character berformat YearMonthDate HourMinuteSecond menjadi tipe Timestamp
  • floor_date() = membulatkan Date/Timestamp kebawah sesuai tipe waktu yang diinput

2.3 Data yang Digunakan

Dataset yang digunakan disediakan dalam format csv sehingga bisa dibaca di R.

Untuk melihat data, gunakan fungsi glimpse() dari package dplyr.

Karena hanya menggunakan 1 fungsi saja, kita bisa memanggilnya tanpa load package nya, yakni dengan menggunakan symbol ::.

Begini :

#membuat variabel dataset
AL.event <- read.csv('https://storage.googleapis.com/dqlab-dataset/event.csv', stringsAsFactors = F)

#melihat isi dataset
dplyr::glimpse(AL.event)
Rows: 33,571
Columns: 4
$ loan_id     <int> 2, 2, 2, 133, 133, 133, 2693, 2693, 2693, 6, 6, 6, 2769, 2…
$ investor_id <int> 114, 114, 114, 114, 114, 114, 8159, 8159, 8159, 163, 163, …
$ nama_event  <chr> "investor_view_loan", "investor_order_loan", "investor_pay…
$ created_at  <chr> "2019-07-07 11:47:58", "2019-07-07 11:48:16", "2019-07-07 …

Terlihat bahwa ada 33,571 baris data (observations) dan ada 4 kolom (variables), yakni:

  1. loan_id : identitas unik dari loan yang diunggah ke marketplace
  2. investor_id : identitas unik dari investor yang terdaftar
  3. nama_event : kegiatan yang dilakukan oleh investor dan perubahan status loan
  4. created_at : waktu (sampai detik) event terjadi

2.4 Mengubah Kolom created_at menjadi Tipe Timestamp

Terlihat bawah created_at berisi timestamp, tetapi tipe datanya adalah chr (character). Untuk memudahkan, ubah dulu tipe data tersebut menjadi tipe timestamp agar nanti bisa diolah dengan lebih baik.

Gunakan fungsi ymd_hms() dari package lubridate untuk mengubah character berformat Year-Month-Date Hour-Minute-Second menjadi tipe timestamp. Setalah load package lubridate, baru jalankan:

AL.event$created_at <- ymd_hms(AL.event$created_at)

lalu jalankan lagi fungsi glimpse() untuk melihat perbedaan tipenya.

dplyr::glimpse(AL.event)

Begini :

#set library yang dibutuhkan
library(lubridate)

#mengubah tipe data
AL.event$created_at <- ymd_hms(AL.event$created_at)

#melihat isi dataset
dplyr::glimpse(AL.event)
Rows: 33,571
Columns: 4
$ loan_id     <int> 2, 2, 2, 133, 133, 133, 2693, 2693, 2693, 6, 6, 6, 2769, 2…
$ investor_id <int> 114, 114, 114, 114, 114, 114, 8159, 8159, 8159, 163, 163, …
$ nama_event  <chr> "investor_view_loan", "investor_order_loan", "investor_pay…
$ created_at  <dttm> 2019-07-07 11:47:58, 2019-07-07 11:48:16, 2019-07-07 13:1…

3 Data per Event

3.1 Summary Event

Karena data yang ada berbentuk log per event, maka kita perlu melihat apa saja isi dari event ini, dan bagaimana flow nya.

Dari data.frame AL.event yang sudah dibuat pada bagian sebelumnya, dikelompokkan dengan group_by() berdasarkan nama_event lalu hitung dengan summarise().

Gunakan package dplyr untuk pengolahan data.

Begini :

#set library yang dibutuhkan
library(dplyr)

#melihat ringkasan
AL.event %>%
  group_by(nama_event) %>%
  summarise(jumlah_event = n(), 
            loan = n_distinct(loan_id), 
            investor = n_distinct(investor_id))
# A tibble: 5 × 4
  nama_event          jumlah_event  loan investor
  <chr>                      <int> <int>    <int>
1 investor_order_loan         3714  3641      804
2 investor_pay_loan           3632  3632      771
3 investor_register          17931     1    17931
4 investor_view_loan          4616  3678     1095
5 loan_to_marketplace         3678  3678        1
  • jumlah_event = untuk mengetahui jumlah terjadinya event, atau ada berapa baris

  • loan = untuk mengetahui jumlah unik loan_id

  • investor = untuk mengetahui jumlah unik investor_id

3.2 Penjelasan Summary Event

Berdasarkan hasil tersebut, ternyata ada 5 event, dengan penjelasan sebagai berikut:

  1. investor_register : Event saat investor register. Jumlah event sama dengan unik investor, artinya setiap investor melakukan event ini hanya 1 kali. Jumlah loan hanya 1, ini isinya NA, karena register ini tidak memerlukan loan

  2. loan_to_marketplace : Event saat loan diunggah ke marketplace. Jumlah event sama dengan jumlah loan, artinya setiap loan diunggah hanya 1 kali. Jumlah investor hanya 1, ini isi NA, karena saat upload ke marketplace tidak berhubungan dengan investor

  3. investor_view_loan : Event saat investor melihat detail loan di marketplace. Jumlah event nya tidak sama dengan unik loan maupun unik investor, artinya 1 investor dapat melihat loan yang sama beberapa kali, dan 1 loan bisa dilihat oleh beberapa investor berbeda

  4. investor_order_loan : Event saat investor memesan loan, menunggu pembayaran. Jumlah event nya tidak sama dengan unik loan maupun unik investor, artinya 1 loan bisa dipesan oleh beberapa investor berbeda (jika pemesanan sebelumnya tidak dibayar)

  5. investor_pay_loan : Event saat investor membayar loan dari pesanan sebelumnya. Jumlah event nya sama dengan unik loan, artinya 1 loan ini hanya bisa dibayar oleh 1 investor. Jumlah investor lebih sedikit daripada jumlah loan artinya 1 investor bisa membeli banyak loan


4 Mengubah Format Data Proses Investasi Loan agar Nama Event menjadi Nama Kolom

4.1 Event Loan di-upload ke Marketplace

Untuk event loan diunggah ke marketplace karena tidak ada investor_id nya, maka bisa diproses sendiri. Untuk memisahkannya, cukup filter() nama event ‘loan_to_marketplace’, lalu ubah nama created_at sebagai marketplace.

Dari data.frame AL.event, filter nama event loan_to_marketplace. Pilih kolom apa saja yang mau diambil, yakni loan_id dan marketplace (ubah nama dari created_at, lakukan saat select). Lalu simpan hasilnya sebagai data.frame baru data.marketplace.

Terakhir tampilkan data.marketplace.

Begini :

#set library yang dibutuhkan
library(dplyr)

#mengubah nama event menjadi nama kolom
data.marketplace <- AL.event %>% 
  filter(nama_event == 'loan_to_marketplace') %>%                       
  select(loan_id, marketplace = created_at) 

#melihat hasil
head(data.marketplace, 9)
  loan_id         marketplace
1       1 2019-07-06 09:03:04
2       2 2019-07-06 09:00:00
3       3 2019-07-06 09:03:04
4       4 2019-07-06 09:03:04
5       5 2019-07-05 11:45:07
6       6 2019-07-08 16:35:28
7       7 2019-07-14 10:16:27
8       8 2019-07-05 11:45:07
9       9 2019-07-05 11:45:07

4.2 Event Investor Melihat Detail Loan

Untuk event investor melihat detail loan, karena investor bisa melihat detail loan berkali-kali maka akan diproses terpisah untuk membuat summary per loan per investor.

Dari data.frame AL.event, filter nama event investor_view_loan kelompokkan per loan_id dan investor_id, hitung dengan summarise():

  • jumlah_view : untuk tahu 1 investor view berapa kali loan tersebut,
  • pertama_view : untuk tahu kapan investor pertama kali melihat detail dari loan tersebut,
  • terakhir_view : untuk tahu kapan investor pertama kali melihat detail dari loan tersebut, nilainya bisa sama dengan pertama_view, lalu simpan hasilnya sebagai data.frame baru data.view_loan.

Terakhir tampilkan data.view_loan.

Begini :

#set library yang dibutuhkan
library(dplyr)

#membuat investor event view loan
data.view_loan <- AL.event %>% 
  filter(nama_event == 'investor_view_loan') %>% 
  group_by(loan_id, investor_id) %>% 
  summarise(jumlah_view = n(), 
            pertama_view = min(created_at), 
            terakhir_view = max(created_at)) 

#melihat hasil
head(data.view_loan, 9)
# A tibble: 9 × 5
# Groups:   loan_id [8]
  loan_id investor_id jumlah_view pertama_view        terakhir_view      
    <int>       <int>       <int> <dttm>              <dttm>             
1       1         107           1 2019-07-07 11:48:11 2019-07-07 11:48:11
2       2         114           1 2019-07-07 11:47:58 2019-07-07 11:47:58
3       3          97           1 2019-07-06 09:50:00 2019-07-06 09:50:00
4       4          97           1 2019-07-06 09:49:20 2019-07-06 09:49:20
5       5         107           1 2019-07-05 12:54:25 2019-07-05 12:54:25
6       6         163           1 2019-07-08 16:40:31 2019-07-08 16:40:31
7       7         133           2 2019-07-14 11:04:46 2019-07-14 11:16:18
8       8          71           1 2019-07-05 11:47:10 2019-07-05 11:47:10
9       8          79           1 2019-07-05 12:05:14 2019-07-05 12:05:14

4.3 Event Investor Pesan dan Bayar Loan

Lalu untuk event investor_order_loan dan investor_pay_loan, karena unik untuk kombinasi loan_id dan investor_id, maka bisa diproses bersamaan, dan akan di-spread menggunakan package tidyr.

Dari data.frame df_event, filter nama event investor_order_loan dan investor_pay_loan, spread kolom nama_event dan created_at agar nama event menjadi nama kolom. Untuk memudahkan ubah nama event tersebut sembari select kolom, agar urutan dan namanya sebagai berikut:

  • loan_id,
  • investor_id,
  • order : investor_order_loan,
  • pay : investor_pay_loan

Lalu simpan hasilnya sebagai data.frame baru data.order.pay.

Terakhir tampilkan data.order.pay.

#set library yang dibutuhkan
library(dplyr)
library("tidyr")

#membuat investor event pesan-bayar
data.order.pay <- AL.event %>% 
  filter(nama_event %in% c('investor_order_loan', 'investor_pay_loan')) %>%
  spread(nama_event, created_at) %>%
  select(loan_id, 
         investor_id, 
         order = investor_order_loan, 
         pay = investor_pay_loan) 

#melihat hasil
head(data.order.pay, 9)
  loan_id investor_id               order                 pay
1       1         107 2019-07-07 11:48:57 2019-07-07 12:02:18
2       2         114 2019-07-07 11:48:16 2019-07-07 13:14:39
3       3          97 2019-07-06 09:50:02 2019-07-06 10:14:44
4       4          97 2019-07-06 09:49:23 2019-07-06 09:59:51
5       5         107 2019-07-05 12:55:15 2019-07-05 13:55:54
6       6         163 2019-07-08 16:42:03 2019-07-08 16:45:56
7       7         133 2019-07-14 11:16:54 2019-07-14 11:22:00
8       8          79 2019-07-05 12:06:21 2019-07-05 17:04:56
9       9          79 2019-07-05 12:11:43 2019-07-05 17:04:52

4.4 Gabungan Data Loan Investasi

Selanjutnya, gabungkan data.marketplace dengan data.view_loan dan data.order_pay yang sudah dibuat sebelumnya untuk membuat data.frame yang berisi waktu untuk masing-masing event dari loan diunggah ke marketplace, dilihat oleh investor, lalu dipesan dan dibayar.

Gunakan fungsi left_join() karena tidak semua loan dan investor ada di setiap data.frame. data.marketplace join dengan data.view_loan menggunakan loan_id, lalu join dengan data.order.pay menggunakan loan_id dan investor_idlalu simpan sebagai data.loan_invest.

Terakhir tampilkan data.loan_invest.

Begini :

#set library yang dibutuhkan
library(dplyr)

#menggabungkan data.frame
data.loan_invest <- data.marketplace %>% 
  left_join(data.view_loan, by = 'loan_id') %>% 
  left_join(data.order.pay, by = c('loan_id','investor_id'))

#melihat hasil
head(data.loan_invest, 9)
  loan_id         marketplace investor_id jumlah_view        pertama_view
1       1 2019-07-06 09:03:04         107           1 2019-07-07 11:48:11
2       2 2019-07-06 09:00:00         114           1 2019-07-07 11:47:58
3       3 2019-07-06 09:03:04          97           1 2019-07-06 09:50:00
4       4 2019-07-06 09:03:04          97           1 2019-07-06 09:49:20
5       5 2019-07-05 11:45:07         107           1 2019-07-05 12:54:25
6       6 2019-07-08 16:35:28         163           1 2019-07-08 16:40:31
7       7 2019-07-14 10:16:27         133           2 2019-07-14 11:04:46
8       8 2019-07-05 11:45:07          71           1 2019-07-05 11:47:10
9       8 2019-07-05 11:45:07          79           1 2019-07-05 12:05:14
        terakhir_view               order                 pay
1 2019-07-07 11:48:11 2019-07-07 11:48:57 2019-07-07 12:02:18
2 2019-07-07 11:47:58 2019-07-07 11:48:16 2019-07-07 13:14:39
3 2019-07-06 09:50:00 2019-07-06 09:50:02 2019-07-06 10:14:44
4 2019-07-06 09:49:20 2019-07-06 09:49:23 2019-07-06 09:59:51
5 2019-07-05 12:54:25 2019-07-05 12:55:15 2019-07-05 13:55:54
6 2019-07-08 16:40:31 2019-07-08 16:42:03 2019-07-08 16:45:56
7 2019-07-14 11:16:18 2019-07-14 11:16:54 2019-07-14 11:22:00
8 2019-07-05 11:47:10                <NA>                <NA>
9 2019-07-05 12:05:14 2019-07-05 12:06:21 2019-07-05 17:04:56

5 Analisis Proses Investasi

5.1 Melihat Hubungan Jumlah View dengan Order

Pada tahap ini, akan dilihat apakah ada hubungan antara berapa kali investor melihat loan dengan keputusan order atau tidak.

Dengan menggunakan data.frame df_loan_invest, buat status_order dengan isi ‘not_order’ jika tidak order (order kosong) dan ‘order’ untuk lainnya. Hitung kombinasi jumlah_view dan status_order yang baru dibuat dengan fungsi count lalu spread status_order sebagai key dengan value n yang merupakan hasil dari count, set fill = 0 agar ketika ada yang kosong diganti dengan 0. Terakhir hitung persen_order yang merupakan nilai order dibagi total dari order dan not_order, format dengan percent agar hasil lebih mudah dibaca.

Begini :

#set library yang dibutuhkan
library(dplyr)
library("tidyr")

#melihat hubungan view dengan order
data.loan_invest %>%
  mutate(status_order = ifelse(is.na(order),'not_order','order')) %>%
  count(jumlah_view, status_order) %>%
  spread(status_order, n, fill = 0) %>%
  mutate(persen_order = scales::percent(order/(order+not_order)))
  jumlah_view not_order order persen_order
1           1       570  3513        86.0%
2           2        20   173        89.6%
3           3         3    23        88.5%
4           4         0     3       100.0%
5           5         1     1        50.0%
6           7         0     1       100.0%
7          40         1     0         0.0%

Dan ternyata tidak ada pola khusus yang menyatakan hubungan banyaknya view dengan keputusan investor memesan loan tersebut. Hampir merata bahwa lebih dari 85% investor yang sudah melihat loan akan memesannya.

Untuk jumlah_view 4 atau lebih, karena sangat sedikit event nya maka bisa diabaikan.

5.2 Berapa Lama Waktu yang Dibutuhkan Investor untuk Pesan Sejak Pertama Melihat Detail Loan

Pada tahap ini, akan dilihat persebaran lama waktu dari pertama melihat detail loan sampai memutuskan untuk order.

Menggunakan data.frame data.loan_invest, filter hanya yang order (tidak kosong) lalu hitung lama_order_view, dengan rumus:

lama_order_view = as.numeric(difftime(order, pertama_view, units = "mins"))

difftime ini merupakan fungsi bawaan (package base) yang digunakan untuk menghitung selisih antara 2 waktu, disini digunakan units “mins” yang berarti output ditampilkan dalam satuan menit. lalu kelompokkan berdasarkan jumlah_view untuk menghitung summary (jumlah transaksi, min, median, mean dan max) dari kolom lama_order_view. Format hasilnya dengan pembulatan 2 digit dibelakang koma agar angkanya seragam, mudah dilihat.

Begini :

#set library yang dibutuhkan
library(dplyr)
library("tidyr")

#melihat waktu untuk pesan
data.loan_invest %>%
  filter(!is.na(order)) %>%
  mutate(lama_order_view = as.numeric(difftime(order, pertama_view, units = "mins"))) %>% 
  group_by(jumlah_view) %>% 
  summarise_at(vars(lama_order_view), funs(total = n(), min, median, mean, max)) %>% 
  mutate_if(is.numeric, funs(round(.,2)))
# A tibble: 6 × 6
  jumlah_view total     min  median    mean    max
        <dbl> <dbl>   <dbl>   <dbl>   <dbl>  <dbl>
1           1  3513    0.03    1.35    2.97   79.6
2           2   173    0.43   22.1    61.1  2446. 
3           3    23    7.25   32.0    66.4   495. 
4           4     3   17.1    33.9    34.1    51.2
5           5     1 1113.   1113.   1113.   1113. 
6           7     1  549.    549.    549.    549. 

Ternyata mayoritas investor langsung memesan loan ketika membuka detailnya, yakni dibawah 5 menit untuk investor yang melihat detail loan 1 kali saja lalu pesan. Untuk yang membuka 2-4 kali waktunya berkisar 30 menitan. Pada jumlah_view 2 dan 3, karena ada outlier pesan lama sampai jauh dari median, ini membuat nilai rata-ratanya terpengaruh menjadi tinggi, 1 jam lebih.

5.3 Rata - rata Waktu Pemesanan Sejak Loan di-upload setiap Minggu nya

Pada tahap ini, yang dihitung adalah lama waktu order sejak loan itu pertama diunggah. Data ini akan dibuat dalam bentuk plot mingguan untuk melihat bagaimana trend nya.

Pertama buat dulu data.frame baru, dengan menggunakan data.frame data.loan_invest, filter hanya yang order (tidak kosong). Buat kolom tanggal yang merupakan pembualatan kebawah dari waktu upload ke marketplace dalam satuan minggu, dengan menggunakan fungsi floor_date() terhadap kolom marketplace.

Lalu hitung lama_order sejak diunggah ke marketplace (dalam jam) dengan rumus:

lama_order = as.numeric(difftime(order, marketplace, units = "hour"))

Lalu kelompokkan berdasarkan kolom tanggal yang baru saja dibuat untuk menghitung median dari kolom lama_order.

Simpan hasilnya sebagai lama.pesan.per.minggu.

Langsung dibuat plotnya menggunakan package ggplot2 yang berisi trend line dari lama order per minggu, berikan label:

  • title : “Rata-rata lama order pada tahun 2020 lebih lama daripada 2019”
  • x : “Tanggal”
  • y : “Waktu di marketplce sampai dipesan (jam)”

Begini :

#set library yang dibutuhkan
library(dplyr)
library(lubridate)
library(ggplot2)

#membuat fata.frame baru
lama.pesan.per.minggu <- data.loan_invest %>% 
  filter(!is.na(order)) %>%
  mutate(tanggal = floor_date(marketplace, 'week'),
         lama_order = as.numeric(difftime(order, marketplace, units = "hour"))) %>% 
  group_by(tanggal) %>%
  summarise(lama_order = median(lama_order)) 

#membuat plot
ggplot(lama.pesan.per.minggu) +
  geom_line(aes(x = tanggal, y = lama_order)) +
  theme_bw() + 
  labs(title = "Rata-rata lama order pada tahun 2020 lebih lama daripada 2019",
       x = "Tanggal",
       y = "Waktu di marketplce sampai dipesan (jam)")

5.4 Apakah Investor Membayar Pesanan yang Dia Buat

Pada tahap ini, yang ingin dilihat adalah berapa persen pesanan yang dibayar oleh investor. Data ini akan dibuat dalam bentuk plot mingguan untuk melihat bagaimana trend nya.

Pertama buat dulu data.frame baru, dengan menggunakan data.frame data.loan_invest, filter hanya yang order (tidak kosong). Buat kolom tanggal yang merupakan pembualatan kebawah dari waktu upload ke marketplace dalam satuan minggu, dengan menggunakan fungsi floor_date() terhadap kolom marketplace.

Lalu kelompokkan berdasarkan kolom tanggal yang baru saja dibuat. Hitung persen_bayar dengan cara menghitung berapa pesanan yang dibayar dari total yang dibayar. Di R, karena FALSE berlnilai 0 dan TRUE itu 1, maka persentase tersebut bisa dihitung dengan cara menghitung rata-rata kondisi benar.

persen_bayar = mean(!is.na(pay))

Jika pay ada isinya (dibayar) maka nilainya 1, kalau kosong nilainya 0. Rata-rata dari nilai ini sama dengan jumlah kondisi benar dibagi total kejadian.

Simpan hasilnya sebagai bayar.per.minggu.

Langsung dibuat plot nya menggunakan package ggplot2 yang berisi trend line dari persen_bayar berdasarkan tanggal, berikan label:

  • title : “Sekitar 95% membayar pesanannya. Di akhir Mei ada outlier karena Lebaran”
  • x : “Tanggal”
  • y : “Pesanan yang dibayar”

Begini :

#set library yang dibutuhkan
library(dplyr)
library(lubridate)
library(ggplot2)

#membuat fata.frame baru
bayar.per.minggu <- data.loan_invest %>% 
  filter(!is.na(order)) %>%
  mutate(tanggal = floor_date(marketplace, 'week')) %>% 
  group_by(tanggal) %>%
  summarise(persen_bayar = mean(!is.na(pay))) 

#membuat plot
ggplot(bayar.per.minggu) +
  geom_line(aes(x = tanggal, y = persen_bayar)) +
  scale_y_continuous(labels = scales::percent) +
  theme_bw() + 
  labs(title = "Sekitar 95% membayar pesanannya. Di akhir Mei ada outlier karena Lebaran",
       x = "Tanggal",
       y = "Pesanan yang dibayar")

5.5 Waktu yang Dibutuhkan Investor untuk Membayar Pesanan

Pada tahap ini, yang ingin dilihat adalah lama waktu pembayaran sejak pesanan dibuat. Data ini akan dibuat dalam bentuk plot mingguan untuk melihat bagaimana trend nya.

Pertama buat dulu data.frame baru, dengan menggunakan data.frame data.loan_invest, filter hanya yang order (tidak kosong). Buat kolom tanggal yang merupakan pembualatan kebawah dari waktu upload ke order dalam satuan minggu, dengan menggunakan fungsi floor_date() terhadap kolom order.

Lalu hitung lama_bayar sejak diunggah ke order dengan rumus:

lama_bayar = as.numeric(difftime(pay, order, units = "hour"))

Lalu kelompokkan berdasarkan kolom tanggal yang baru saja dibuat untuk menghitung median dari kolom lama_bayar.

Simpan hasilnya sebagai lama.bayar.per.minggu.

Langsung dibuat plot nya menggunakan package ggplot2 yang berisi trend line dari lama_bayar per minggu, berikan label:

  • title : “Waktu pembayaran trend nya cenderung memburuk, 2x lebih lama dari sebelumnya”
  • x : “Tanggal”
  • y : “Waktu di pesanan dibayar (jam)”

Begini :

#set library yang dibutuhkan
library(dplyr)
library(lubridate)
library(ggplot2)

#membuat fata.frame baru
lama.bayar.per.minggu <- data.loan_invest %>% 
  filter(!is.na(pay)) %>%
  mutate(tanggal = floor_date(order, 'week'),
         lama_bayar = as.numeric(difftime(pay, order, units = "hour"))) %>% 
  group_by(tanggal) %>%
  summarise(lama_bayar = median(lama_bayar)) 

#membuat plot
ggplot(lama.bayar.per.minggu) +
  geom_line(aes(x = tanggal, y = lama_bayar)) +
  theme_bw() + 
  labs(title = "Waktu pembayaran trennya cenderung memburuk, 2x lebih lama dari sebelumnya",
       x = "Tanggal",
       y = "Waktu di pesanan dibayar (jam)")

5.6 Kesimpulan

Trend pada tahun 2020 cenderung lebih jelek daripada tahun 2019, hal ini mungkin karena adanya pandemi investor menjadi lebih lama untuk memprtimbangkan invest dimana, dan apakah pesanan yang sudah dibuat mau dibayar atau tidak.


6 Analisis Summary Investor

6.1 Trend Investor Register

Di data.frame AL.event ada 1 event yang belum diolah, yakni investor_register. Disini akan dibuat bagaimana trend jumlah investor yang register.

Dari AL.event, filter nama_event investor_register, lalu hitung jumlah investor setiap minggunya. Simpan hasilnya sebagai data.investor.register.

Langsung dibuat plot nya menggunakan package ggplot2 yang berisi trend line dari persen_bayar berdasarkan tanggal, berikan label:

  • title : “Investor register sempat naik di awal 2020 namun sudah turun lagi”
  • x : “Tanggal”
  • y : “Investor Register”

Begini :

#set library yang dibutuhkan
library(dplyr)
library(lubridate)
library(ggplot2)

#membuat fata.frame baru
data.investor.register <- AL.event %>% 
  filter(nama_event == 'investor_register') %>%
  mutate(tanggal = floor_date(created_at, 'week')) %>% 
  group_by(tanggal) %>%
  summarise(investor = n_distinct(investor_id))

#membuat plot
ggplot(data.investor.register) +
  geom_line(aes(x = tanggal, y = investor)) +
  theme_bw() + 
  labs(title = "Investor register sempat naik di awal 2020, namun sudah turun lagi",
       x = "Tanggal",
       y = "Investor Register")

6.2 Trend Investor Investasi Pertama

Setelah mendaftar, tujuan selanjutnya untuk investor adalah agar dia bisa invest. Hal ini biasa disebut conversion, yakni ketika user convert menjadi user yang kita harapkan, atau naik ke funnel yang lebih baik.

Untuk mencari tahu kapan investor convert, perlu dicari kapan investor pertama kali invest dan dibuat tren nya.

Dari data.frame AL.event filter nama event investor_pay_loan, cari tanggal pertama untuk masing-masing investor, simpan sebagai pertama_invest. Dari pertama_invest ini baru diproses seperti sebelum-sebelumnya untuk dhihitung jumlah investor pertama invest setiap minggunya.

Simpan hasilnya sebagai investor.pertama.invest.

Langsung dibuat plot nya menggunakan package ggplot2 yang berisi trend line dari persen_bayar berdasarkan tanggal, berikan label:

  • title : “Ada tren kenaikan jumlah investor invest, namun turun drastis mulai Maret 2020”
  • x : “Tanggal”
  • y : “Investor Pertama Invest”

Begini :

#set library yang dibutuhkan
library(dplyr)
library(lubridate)
library(ggplot2)

#membuat fata.frame baru
investor.pertama.invest <- AL.event %>% 
  filter(nama_event == 'investor_pay_loan') %>%
  group_by(investor_id) %>% 
  summarise(pertama_invest = min(created_at)) %>% 
  mutate(tanggal = floor_date(pertama_invest, 'week')) %>% 
  group_by(tanggal) %>% 
  summarise(investor = n_distinct(investor_id)) 

#membuat plot
ggplot(investor.pertama.invest) +
  geom_line(aes(x = tanggal, y = investor)) +
  theme_bw() + 
  labs(title = "Ada tren kenaikan jumlah investor invest, namun turun drastis mulai Maret 2020",
       x = "Tanggal",
       y = "Investor Pertama Invest")

6.3 Cohort Pertama Invest Berdasarkan Bulan Register

Pada sebelumnya sudah dihitung bagaimana tren investor baru invest setiap minggunya. Selanjutnya akan dilihat conversion invest berdasarkan bulan register.

Step pertama membuat tanggal register per investor register.per.investor. Buat 2 kolom baru, tanggal_register yang merupakan rename() dari created_at, dan bulan_register yang merupakan floor_date() dari tanggal_register, terakhir pilih kolom investor_id, dan 2 kolom yang baru dibuat.

Step kedua adalah membuat tanggal investasi pertama per investor, simpan sebagai pertama.invest.per.investor. Caranya seperti pada bagian sebelumnya, hanya saja ini berhenti ketika mendapatkan nilai pertama_invest.

Step selanjutnya adalah menggabungkan kedua data.frame tersebut dan memprosesnya.

Untuk menggabungkan, gunakan left_join() karena ada investor yang tidak invest. Lalu hitung lama_invest dalam bulan, dengan rumus:

lama_invest = as.numeric(difftime(pertama_invest, tanggal_register, units = "day")) %/% 30

difftime satuan terbesarnya minggu (weeks). Tidak bisa untuk menghitung selish bulan, jadi hitung selisih hari lalu di-div (dibagi dan dibulatkan kebawah) 30.

Lalu kelompokkan berdasarkan bulan_register dan lama_invest untuk menghitung investor_per_bulan yakni distinct() investor per kategori itu. Untuk investor yang belum pernah invest, tetap masuk dalam perhitungan dengan lama_invest yang kosong.

Lalu group_by() bulan_register untuk menghitung total investor dalam bulan register itu.

Lalu lama_invest yang kosong dihilangkan untuk menghilangkan investor yang belum pernah invest. Setelah itu dihitung lagi totalnya, karena yang belum invest sudah dihilangkan, jadi yang bersisa hanya yang sudah invest, sehingga hasilnya adalah total investor yang sudah invest.

Hitung persen_invest dan breakdown_persen_invest untuk nanti ditampilkan dalam value cohort.

Setelah itu hilangkan kolom investor_per_bulan karena tidak dipakai. Kalau tidak dihilangkan akan membuat spread tidak sesuai.

Terakhir spread datanya berdasarkan lama_invest sebagai key dan breakdown_persen_invest sebagai value dari masing-masing key.

Begini :

#set library yang dibutuhkan
library(dplyr)
library(lubridate)
library(tidyr)

#step 1
register.per.investor <- AL.event %>% 
  filter(nama_event == 'investor_register') %>% 
  rename(tanggal_register = created_at) %>%  
  mutate(bulan_register = floor_date(tanggal_register, 'month'))  %>%  
  select(investor_id, tanggal_register, bulan_register)  

#step 2
pertama.invest.per.investor <- AL.event %>% 
  filter(nama_event == 'investor_pay_loan') %>% 
  group_by(investor_id) %>% 
  summarise(pertama_invest = min(created_at))

#gabung data.frame
register.per.investor %>%
  left_join(pertama.invest.per.investor, by = 'investor_id') %>% 
  mutate(lama_invest = as.numeric(difftime(pertama_invest, tanggal_register, units = "day")) %/% 30) %>%  
  group_by(bulan_register, lama_invest) %>% 
  summarise(investor_per_bulan = n_distinct(investor_id)) %>% 
  group_by(bulan_register) %>% 
  mutate(register = sum(investor_per_bulan)) %>% 
  filter(!is.na(lama_invest)) %>% 
  mutate(invest = sum(investor_per_bulan)) %>% 
  mutate(persen_invest = scales::percent(invest/register)) %>% 
  mutate(breakdown_persen_invest = scales::percent(investor_per_bulan/invest)) %>%  
  select(-investor_per_bulan) %>%  
  spread(lama_invest, breakdown_persen_invest)
# A tibble: 11 × 14
# Groups:   bulan_register [11]
   bulan_register      register invest persen_in…¹ `0`   `1`   `2`   `3`   `4`  
   <dttm>                 <int>  <int> <chr>       <chr> <chr> <chr> <chr> <chr>
 1 2019-07-01 00:00:00     2142     73 3%          61.6% 8.2%  6.8%  5.5%  1.4% 
 2 2019-08-01 00:00:00     1458     74 5%          55.4% 8.1%  14.9% 10.8% 4.1% 
 3 2019-09-01 00:00:00     1763     94 5%          67.0% 21.3% 4.3%  2.1%  3.2% 
 4 2019-10-01 00:00:00     1437     83 6%          77.1% 8.4%  4.8%  7.2%  1.2% 
 5 2019-11-01 00:00:00     1607     87 5%          75.9% 11.5% 9.2%  1.1%  1.1% 
 6 2019-12-01 00:00:00     1085     55 5%          69.1% 16.4% 7.3%  5.5%  1.8% 
 7 2020-01-01 00:00:00     1138     78 7%          78.2% 15.4% 3.8%  2.6%  <NA> 
 8 2020-02-01 00:00:00     1520    115 8%          86.0… 6.96% 6.09% 0.87% <NA> 
 9 2020-03-01 00:00:00     2776     53 2%          94%   6%    <NA>  <NA>  <NA> 
10 2020-04-01 00:00:00     2034     51 3%          86%   14%   <NA>  <NA>  <NA> 
11 2020-05-01 00:00:00      971      8 1%          100%  <NA>  <NA>  <NA>  <NA> 
# … with 5 more variables: `5` <chr>, `6` <chr>, `7` <chr>, `8` <chr>,
#   `9` <chr>, and abbreviated variable name ¹​persen_invest

Terihat bahwa untuk total register paling banyak adalah di bulan Maret 2020 seperti pada chart sebelumnya, hanya saja dari sebanyak itu sampai saat ini belum ada 2% yang sudah invest. Sangat jauh dibandingkan bulan sebelumnya, yang bisa mencapai 7% lebih, yang merupakan conversion rate paling tinggi.

Pada umumnya, hanya 5% investor dari semua investor yang mendaftar akan convert. Ketika convert mayoritas mereka melakukannya di bulan pertama (kurang dari 30 hari) sejak registrasi.

6.4 Cohort Retention Invest

Setelah cohort investasi pertama, selanjutnya yang dihitung adalah cohort retention. Yakni apakah investor kembali invest lagi di bulan bulan selanjutnya setelah investasi pertama.

Step pertama membuat tanggal investasi per investor, investasi.per.investor. Dari AL.event filter event yang menggambarkan kejadian investasi, lalu 1 kolom baru, tanggal_invest yang merupakan rename() dari created_at. Lalu pilih kolom investor_id, dan kolom yang baru dibuat.

Step selanjutnya adalah menggabungkan data.frame pertama.invest.per.investor yang dibuat pada bagian sebelumnya, dengan data.frame yang baru saja dibuat. Untuk menggabungkan, bisa gunakan left_join() maupun inner_join() karena data investor pada keduanya adalah sama.

Lalu hitung jarak_invest dalam bulan, dengan rumus:

jarak_invest = as.numeric(difftime(tanggal_invest, pertama_invest, units = "day")) %/% 30

Lalu kelompokkan berdasarkan bulan_pertama_invest dan jarak_invest untuk menghitung investor_per_bulan yakni distinct() investor_id per kategori itu.

Lalu group_by() bulan_pertama_invest saja untuk menghitung berapa total investor sebenarnya. Disini tidak ditotal seperti pada perhitungan sebelumnya, karena jumlah investor bisa berulang pada bulan yang berbeda, jadi kalau ditotal hasilnya jauh lebih besar dari seharusnya, jadi gunakan fungsi max() untuk mencari angka tertinggi pada cohort bulan_pertama_invest itu. Ini ada di jarak_invest ke 0, karena semua investor yang invest tentu saja semuanya investasinya di bulan pertama invest.

Hitung breakdown_persen_invest untuk sebagai value yang dilihat pada persebaran jarak invest dari investasi pertama.

Setelah itu hilangkan kolom investor_per_bulan karena tidak dipakai, kalau tidak dihilangkan akan membuat spread tidak sesuai.

Lalu spread datanya berdasarkan jarak_invest sebagai key dan breakdown_persen_invest sebagai value dari masing-masing key.

Terakhir hilangkan kolom 0 karena hasilnya pasti 100% semua.

Begini :

#set library yang dibutuhkan
library(dplyr)
library(lubridate)
library(tidyr)

#step 1
investasi.per.investor <- AL.event %>%
  filter(nama_event == 'investor_pay_loan') %>%
  rename(tanggal_invest = created_at) %>%
  select(investor_id, tanggal_invest)
  
#gabung data.frame
pertama.invest.per.investor %>% 
  mutate(bulan_pertama_invest = floor_date(pertama_invest, 'month')) %>%
  inner_join(investasi.per.investor, by = 'investor_id') %>%
  mutate(jarak_invest = as.numeric(difftime(tanggal_invest, pertama_invest, units = "day")) %/% 30) %>%
  group_by(bulan_pertama_invest, jarak_invest) %>%
  summarise(investor_per_bulan = n_distinct(investor_id)) %>%
  group_by(bulan_pertama_invest) %>%
  mutate(investor = max(investor_per_bulan)) %>%
  mutate(breakdown_persen_invest = scales::percent(investor_per_bulan/investor)) %>%
  select(-investor_per_bulan) %>%
  spread(jarak_invest, breakdown_persen_invest) %>%
  select(-`0`)
# A tibble: 11 × 11
# Groups:   bulan_pertama_invest [11]
   bulan_pertama_invest investor `1`   `2`   `3`   `4`   `5`   `6`   `7`   `8`  
   <dttm>                  <int> <chr> <chr> <chr> <chr> <chr> <chr> <chr> <chr>
 1 2019-07-01 00:00:00        31 25.8% 25.8% 19.4% 6.5%  16.1% 16.1% 19.4% 12.9%
 2 2019-08-01 00:00:00        51 35.3% 19.6% 25.5% 19.6% 19.6% 21.6% 9.8%  2.0% 
 3 2019-09-01 00:00:00        70 25.7% 18.6% 18.6% 15.7% 18.6% 10.0% 1.4%  <NA> 
 4 2019-10-01 00:00:00        80 32.5% 28.8% 17.5% 23.7% 8.7%  6.2%  <NA>  <NA> 
 5 2019-11-01 00:00:00        99 30.3% 24.2% 24.2% 8.1%  7.1%  1.0%  <NA>  <NA> 
 6 2019-12-01 00:00:00        63 38.1% 30.2% 3.2%  4.8%  1.6%  <NA>  <NA>  <NA> 
 7 2020-01-01 00:00:00        71 32.4% 12.7% 4.2%  1.4%  <NA>  <NA>  <NA>  <NA> 
 8 2020-02-01 00:00:00       115 16.5% 3.5%  0.9%  <NA>  <NA>  <NA>  <NA>  <NA> 
 9 2020-03-01 00:00:00       102 10.8% 1.0%  <NA>  <NA>  <NA>  <NA>  <NA>  <NA> 
10 2020-04-01 00:00:00        58 5%    <NA>  <NA>  <NA>  <NA>  <NA>  <NA>  <NA> 
11 2020-05-01 00:00:00        31 <NA>  <NA>  <NA>  <NA>  <NA>  <NA>  <NA>  <NA> 
# … with 1 more variable: `10` <chr>

Terihat bahwa pada bulan Febuari terdapat investor yang melakukan investasi pertama paling banyak dibandingkan bulan lainnya. Akan tetapi kelompok tersebut retention nya jelek dibandingkan yang lain.

Pada 1 bulan setelah investasi pertama, hanya 16% investor saja yang investasi lagi. Ini hanya setengah dari tren pada bulan bulan sebelumnya, dimana sekitar 30% investor akan invest lagi 1 bulan setelah investasi pertama.

Cohort yang paling stabil adalah di bulan Agustus 2019. Di sekitar angka 20% setiap bulannya, alaupun pada bulan ketujuh persentasnya ikut turun juga.


7 Penutup

7.1 Kesimpulan

Berdasarkan semua analisis yang telah dilakukan, dapat disimpulkan bahwa :

  • Secara umum, AL.Finance sebenarnya sedang dalam growth yang positif. Fluktuatif naik turun terjadi karena perbedaan behaviour di tanggal tertentu, yang dipengaruhi oleh hal lain (misalnya gajian).
  • Pada bulan Maret, April sampai pertangahan Mei terjadi banyak penurunan pada metriks yang dianalisis. Hal ini mungkin karena adanya pandemi Covid-19. Perlu dianalisis lebih lanjut apakah memang karena itu.
  • Secara Umum, 5% dari total investor yang register setiap bulannya, akan melakukan investasi, dan mayoritas dilakukan pada 30 hari pertama setelah register, dan sebagian kecil di bulan kedua. Di bulan selanjutnya peluangnya sangat kecil untuk bisa convert. Sehingga perlu dipastikan bagaimana journey investor tersebut lancar di bulan pertama, sehingga mau convert invest di AL.Finance.
  • Selenjutnya perlu dilihat juga setelah invest pertama itu invest lagi di bulan-bulan selanjutnya. Secara umum 30% investor akan invest lagi pada bulan berikutnya.
  • Pada bulan Februari, conversion rate nya bagus. Paling tinggi yakni 7.57%. Secara jumlah juga paling banyak, tapi ketika dilihat retention nya, hanya 16% yang invest pada bulan selanjutnya. Itu hanya setengahnya dari kategori bulan bulan lainnya.
  • Perlu dianalisis lebih lanjut darimana dan profil dari investor di bulan Febuari sampai April 2020.

7.2 Hal yang Dipelajari

Setelah melakukan project ini kamu sudah mempelejari beberapa hal, yakni:

  • Memanipulasi data dengan cara menyaring, menghitung agregasi, lalu memilih kolom dan menggabungkan beberapa data untuk bisa mendapatkan data yang diinginkan menggunakan package dplyr
  • Mengubah bentuk data.frame dari panjang kebawah menjadi lebar kesamping sesuai variabel agar berbentuk tidy dan mudah dianalisis menggunakan package dplyr dan tidyr
  • Membuat tabel Cohort yang bisa menggambarkan tren urutan kejadian berdasarkan awal terjadinya kejadian
  • Menghitung Conversion dan Retention untuk menganalisis performa
  • Mengolah tipe data Waktu untuk dibulatkan, maupun mencari selisih antara 2 waktu agar bisa memperoleh summary dan tren dari data dengan menggunakan package lubridate
  • Membuat line chart menggunakan package ggplot2
  • Memformat data yang ditampilkan dengan format yang mudah dibaca menggunakan package scales