Projek ini merupakan implementasi dari proposal E-Commerce Optimization Strategies yang sebelumnya telah dibuat. Prodposal tersebut berisi tentang latar belakang projek hingga tujuan maupun luaran dari projek ini. Alangkah baiknya, pembaca untuk membaca proposal tersebut terlebih dahulu agar dapat memahami projek ini secara keseluruhan. Terdapat beberapa bagian dari projek ini, yakni:
Adapun pada bagian ini akan berfokus pada Data Preparation and Exploratory Analysis untuk mempersiapkan data pada proses selanjutnya serta memahami data dengan lebih baik.
Dataset yang digunakan merupakan data riwayat jual beli dari e-commerce di Pakistan yang diambil dari situs Kaggle dengan judul Pakistan’s Largest E-Commerce Dataset. Dataset ini merupakan kumpulan riwayat pesanan/transaksi dari beberapa merchant di e-commerce mulai Maret 2016 hingga Agustus 2018. Adapun dataset ini terdiri atas beberapa informasi inti sebagai berikut: (NB: Pemilik dataset tidak memberikan deskripsi dari tiap kolom yang diberikan)
Mari kita panggil packages yang dibutuhkan serta dataset e-commerce di Pakistan yang telah dipilih.
library(dplyr)
library(lubridate)
library(ggplot2)
library(padr)
library(zoo)
library(plotly)
library(glue)
library(paletti)
Data terdiri atas 1.048.5775 baris dengan 26 kolom. Sebanyak empat kolom terakhir hanya berisi missing value
.
Pemilik tidak memberikan deskripsi dari tiap kolom pada dataset yang diberikan. Selain itu, nama kolom pada dataset berbeda dengan nama kolom yang disebutkan oleh pemilik dataset dan jumlahnya jauh lebih banyak. Pemilik dataset juga menyatakan bahwa data hanya terdiri dari kurang lebih setengah juta baris. Maka, kita akan coba mencari tahu isi dari tiap kolomnya dan memberikan deskripsi dari tiap kolom.
Sebagaimana hasil Explorartory Data Analysis pada proposal E-Commerce Optimization Strategies, kita dapatkan deskripsi dari tiap kolom adalah sebagai berikut:
Order_Status
: Status dari pembelian (Completed, Cancelled, Refund)
Date_of_Order
: Tanggal pemesanan produk
SKU
: Barcode, kode, atau nama unik yang mewakili produk tertentu
Price
: Harga produk
Quantity
: Jumlah dari produk yang dibeli
Grand_Total
: Total pembayaran yang diberikan oleh pelanggan dalam satu Invoice
increment_id
: Id dari invoice
Category
: Kategori atau jenis E-Commerce
Discount_Amount
: Nilai diskon yang didapatkan pelanggan pada tiap produk
Payment_Method
: Metode pembayaran
BI.Status
: Representasi kolom Order_Status
BI.Status
= “Gross” ====> Order_Status
= “canceled”BI.Status
= “Net” ====> Order_Status
= “complete”BI.Status
= “Valid” ====> Order_Status
= “refund”.MV
: hasil perkalian antara kolom Price
dengan Quantity
Year
: Tahun, nilai ini didapat dari Date_of_Order
Month
: Bulan, nilai ini didapat dari Date_of_Order
Customer.Since
: Umur pelanggan, didapat dari riwayat belanja pertama kali yang dilakukan oleh pelanggan
M.Y
: Bulan-Tahun, nilai ini didapat dari Date_of_Order
yang merupakan gabungan dari kolom Year
dan Month
Customer_ID
: ID dari pelanggan
Terdapat beberapa kolom yang belum diketahui secara pasti maknanya, yakni:
sales_commission_code
FY
Dua kolom yang tidak diketahui maknanya akan dibuang, karena kita tidak dapat menggunakan kolom tersebut, sebagai akibat tidak tahu maknanya.
Berdasarkan hasil Exploratory Data Analysis pada proposal E-Commerce Optimization Strategies, kita akan melakukan beberapa preparasi pada data mentah kita.
Sebelumnya, mari kita rubah nama tiap kolom dari data kita sesuai deskripsi yang telah disebutkan sebelumnya. Perubahan nama kolom ini dilakukan agar lebih representatif dari nilai kolom yang terkait.
data <- data %>%
rename("Item_ID" = "item_id",
"Order_Status" = "status",
"Date_of_Order" = "created_at",
"SKU" = "sku",
"Price" = "price",
"Quantity" = "qty_ordered",
"Grand_Total" = "grand_total",
"Category" = "category_name_1",
"Payment_Method" = "payment_method",
"Customer_ID" = "Customer.ID",
"Invoice_ID" = "increment_id",
"Discount_Amount" = "discount_amount",
"BI_Status" = "BI.Status",
"Revenue" = "MV",
"Customer_Since" = "Customer.Since",
"Month_Year" = "M.Y")
Kita lakukan cek bersama terkait tipe data serta ringkasan dari data kita.
#> Rows: 1,048,575
#> Columns: 26
#> $ Item_ID <int> 211131, 211133, 211134, 211135, 211136, 211137, ~
#> $ Order_Status <chr> "complete", "canceled", "canceled", "complete", ~
#> $ Date_of_Order <chr> "7/1/2016", "7/1/2016", "7/1/2016", "7/1/2016", ~
#> $ SKU <chr> "kreations_YI 06-L", "kcc_Buy 2 Frey Air Freshen~
#> $ Price <dbl> 1950.00, 240.00, 2450.00, 360.00, 555.00, 80.00,~
#> $ Quantity <int> 1, 1, 1, 1, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, ~
#> $ Grand_Total <dbl> 1950.00, 240.00, 2450.00, 60.00, 1110.00, 80.00,~
#> $ Invoice_ID <chr> "100147443", "100147444", "100147445", "10014744~
#> $ Category <chr> "Women's Fashion", "Beauty & Grooming", "Women's~
#> $ sales_commission_code <chr> "\\N", "\\N", "\\N", "R-FSD-52352", "\\N", "\\N"~
#> $ Discount_Amount <dbl> 0, 0, 0, 300, 0, 0, 300, 0, 0, 0, 0, 0, 0, 0, 0,~
#> $ Payment_Method <chr> "cod", "cod", "cod", "cod", "cod", "cod", "cod",~
#> $ Working.Date <chr> "7/1/2016", "7/1/2016", "7/1/2016", "7/1/2016", ~
#> $ BI_Status <chr> "#REF!", "Gross", "Gross", "Net", "Valid", "Gros~
#> $ Revenue <chr> " 1,950 ", " 240 ", " 2,450 ", " 360 ", " 1,110 ~
#> $ Year <int> 2016, 2016, 2016, 2016, 2016, 2016, 2016, 2016, ~
#> $ Month <int> 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, ~
#> $ Customer_Since <chr> "2016-7", "2016-7", "2016-7", "2016-7", "2016-7"~
#> $ Month_Year <chr> "7-2016", "7-2016", "7-2016", "7-2016", "7-2016"~
#> $ FY <chr> "FY17", "FY17", "FY17", "FY17", "FY17", "FY17", ~
#> $ Customer_ID <chr> "1", "2", "3", "4", "5", "6", "7", "6", "8", "8"~
#> $ X <lgl> NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, ~
#> $ X.1 <lgl> NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, ~
#> $ X.2 <lgl> NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, ~
#> $ X.3 <lgl> NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, ~
#> $ X.4 <lgl> NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, ~
#> Item_ID Order_Status Date_of_Order SKU
#> Min. :211131 Length:1048575 Length:1048575 Length:1048575
#> 1st Qu.:395001 Class :character Class :character Class :character
#> Median :568425 Mode :character Mode :character Mode :character
#> Mean :565667
#> 3rd Qu.:739106
#> Max. :905208
#> NA's :464051
#> Price Quantity Grand_Total Invoice_ID
#> Min. : 0 Min. : 1.0 Min. : -1594 Length:1048575
#> 1st Qu.: 360 1st Qu.: 1.0 1st Qu.: 945 Class :character
#> Median : 899 Median : 1.0 Median : 1960 Mode :character
#> Mean : 6349 Mean : 1.3 Mean : 8531
#> 3rd Qu.: 4070 3rd Qu.: 1.0 3rd Qu.: 6999
#> Max. :1012626 Max. :1000.0 Max. :17888000
#> NA's :464051 NA's :464051 NA's :464051
#> Category sales_commission_code Discount_Amount Payment_Method
#> Length:1048575 Length:1048575 Min. : -599.5 Length:1048575
#> Class :character Class :character 1st Qu.: 0.0 Class :character
#> Mode :character Mode :character Median : 0.0 Mode :character
#> Mean : 499.5
#> 3rd Qu.: 160.5
#> Max. :90300.0
#> NA's :464051
#> Working.Date BI_Status Revenue Year
#> Length:1048575 Length:1048575 Length:1048575 Min. :2016
#> Class :character Class :character Class :character 1st Qu.:2017
#> Mode :character Mode :character Mode :character Median :2017
#> Mean :2017
#> 3rd Qu.:2018
#> Max. :2018
#> NA's :464051
#> Month Customer_Since Month_Year FY
#> Min. : 1.0 Length:1048575 Length:1048575 Length:1048575
#> 1st Qu.: 4.0 Class :character Class :character Class :character
#> Median : 7.0 Mode :character Mode :character Mode :character
#> Mean : 7.2
#> 3rd Qu.:11.0
#> Max. :12.0
#> NA's :464051
#> Customer_ID X X.1 X.2 X.3
#> Length:1048575 Mode:logical Mode:logical Mode:logical Mode:logical
#> Class :character NA's:1048575 NA's:1048575 NA's:1048575 NA's:1048575
#> Mode :character
#>
#>
#>
#>
#> X.4
#> Mode:logical
#> NA's:1048575
#>
#>
#>
#>
#>
Melalui glimpse()
dan summary()
dapat kita pastikan bahwa 5 kolom terakhir yang hanya berisi NA
dan sebanyak 464.051 baris juga berupa NA
. Dari segi tipe data, terdapat beberapa tipe data yang perlu dilakukan penyesuaian. akan tetapi proses tersebut akan kita lakukan setelah membersihkan data kita.
Sebagaimana pengecekan yang kita lakukan sebelumnya, kita akan membuang lima kolom terakhir serta 464.051 baris yang berupa NA
.
1. Membuang 5 kolom terakhir yang hanya berisi NA
2. Membuang 464.051 baris yang berupa NA
Kita juga akan melakukan beberapa pembersihan pada kolom-kolom tertentu, berdasarkan hasil Exploratory Data Analysis pada proposal E-Commerce Optimization Strategies. Pemebersihan data tersebut sebagai berikut:
1. Membuang baris dengan nilai kolom BI.Status
== #REF!
Nilai #REF!
pada kolom BI.Status
tidak merepresentasikan apapun, sehingga data ini harus dibuang.
2. Membuang kolom Working.Date
, sales_commission_code
, dan FY
Kolom Working.Date
memiliki nilai yang sama persis dengan kolom Date_of_Order
, sehingga kolom ini dibuang untuk menghindari redundant. Adapun kolom sales_commission_code
dan FY
tidak diketahui secara pasti makna yang dikandung, sehingga kita akan membuangnya.
3. Membuang nilai baris dari kolom Order_Status
yang tidak relevan
Beberapa nilai dari kolom Order_Status
tidak dapat dimaknai serta tidak sama dengan keterangan pemilik dataset, maka kita hanya akan mengambil baris pada kolom Order_status
yang bernilai complete
, canceled
, dan refund
sebagaiman keterangan pemilik dataset.
data <- data %>%
filter(Order_Status %in% c("complete", "canceled", "refund", "order_refunded")) %>%
mutate(Order_Status = ifelse(Order_Status == "order_refunded",
"refund",
Order_Status))
4. Membuang nilai "“,”Others" dan “\N” pada kolom Category
Pada kolom Category
yang mana merepresentasikan kategori dari merchants, terdapat beberapa nilai yang tidak relevan atau tidak diketahui secara pasti barang yang dijual oleh merchants.Oleh karena itu, kita akan membuang beberapa baris pada kolom Category
ini.
5. Membuang nilai "" dan “\N” pada kolom Customer_ID
, Ivoice_ID
, ‘SKU’
Kita juga akan memastikan nilai-nilai NA
dan \\N
tidak terdapat pada kolom-kolom yang sangat penting untuk analisis kedepannya.
Terdapat beberapa nilai duplikat pada data kita, sebagaimana kita ketahui dari hasil Exploratory Data Analysis pada proposal E-Commerce Optimization Strategies. Selain itu, kita ketahui juga bahwa kolom Item_ID
hanya representasi dari indeks dari baris. Sehingga, untuk memepermudah pembuangan data duplikat, kita juga akan membuang kolom Item_ID
.
Membuang baris terduplikat dan kolom Item_ID
Baiklah, mari kita konversi beberapa tipe data dari kolom kita, serta melakukan pengisian ulang pada beberapa kolom feature
yang berasal dari dataset mentah guna memastikan kebenaran isi datanya.
data <- data %>%
mutate(Date_of_Order = mdy(Date_of_Order),
Month = month(Date_of_Order, label = T, abbr = T),
Year = year(Date_of_Order),
Month_Year = as.yearmon(paste(Month, Year)),
Order_Status = as.factor(Order_Status),
BI_Status = as.factor(BI_Status),
Category = as.factor(Category),
Revenue = as.double(Revenue))
Pada sesi ini, kita akan melihat bersama bagaimana kondisi perusahaan secara mendalam, sehingga luaran yang akan dihasilkan dari projek ini diharapkan dapat mengoptimasi strategi bisnis untuk meningkatkan pendapatan perusahaan.
Sebelumnya, kita akan membuat theme
sendiri sebagai identitas kita.
Kustomisasi theme()
# Kustomisasi Warna dan Visualisasi chart
my_color <- c(
col1="#fcf800",
col2="#fce700",
col3="#fcdb03",
col4="#e3c502",
col5="#fcbe03",
col6="#fc9d03",
col7="#fc5d00"
)
my_theme_fill <- get_scale_fill(get_pal(my_color))
my_theme_color <- get_scale_color(get_pal(my_color))
my_theme_hex <- get_hex(my_color)
color_dark_text = "#222629"
# MY PLOT THEME
my_plot_theme <- function (base_size, base_family="Segoe UI Semibold"){
dark_color="#222629"
facet_header = "#78767647"
dark_text = "#222629"
half_line <- base_size/2
theme_algoritma <- theme(
plot.background = element_rect(fill= "#faf6e3", colour = "#faf6e3"), #background plot
plot.title = element_text(size = rel(1.5), margin = margin(b = half_line * 1.2),
color= dark_text, hjust = 0, family=base_family, face = "bold"),
plot.subtitle = element_text(size = rel(1.0), margin = margin(b = half_line * 1.2), color= dark_text, hjust=0),
plot.margin=unit(c(0.5,0.5,0.5,0.5),"cm"),
#plot.margin=unit(c(0.5,r=5,1,0.5),"cm"),
panel.background = element_rect(fill="#18181800",colour = "#e8e8e8"), #background chart
panel.border = element_rect(fill=NA,color = NA),
panel.grid.minor.x = element_blank(),
panel.grid.major.x = element_blank(),
panel.grid.major.y = element_line(color="#e8e8e8", linetype=2),
panel.grid.minor.y = element_blank(),
#panel.margin = unit(0.8*half_line, "mm"),
panel.margin.x = NULL,
panel.margin.y = NULL,
panel.ontop = FALSE,
panel.spacing = unit(1.2,"lines"),
legend.background = element_rect(fill="#18181800",colour = NA),
legend.text = element_text(size = rel(0.7),color=dark_text),
legend.title = element_text(colour = dark_text, size = base_size, lineheight = 0.8),
legend.box = NULL,
# text = element_text(colour = "white", size = base_size, lineheight = 0.9,
# angle = 0, margin = margin(), debug = FALSE),
axis.text = element_text(size = rel(0.8), color=dark_text),
axis.text.x = element_text(colour = dark_text, size = base_size, margin = margin(t = 0.8 * half_line/2)),
axis.text.y = element_text(colour = dark_text, size = base_size, margin = margin(r = 0.8 * half_line/2)),
axis.title.x = element_text(colour = dark_text, size = base_size, lineheight = 0.8,
margin = margin(t = 0.8 * half_line, b = 0.8 * half_line/2)),
axis.title.y = element_text(colour = dark_text, size = base_size, lineheight = 0.8,
angle = 90, margin = margin(r = 0.8 * half_line, l = 0.8 * half_line/2)),
axis.ticks = element_blank(),
strip.background = element_rect(fill=facet_header,colour = NA),
strip.text = element_text(colour = dark_text, size = rel(0.8)),
strip.text.x = element_text(margin = margin(t = half_line*0.8, b = half_line*0.8)),
strip.text.y = element_text(angle = -90, margin = margin(l = half_line, r = half_line)),
strip.switch.pad.grid = unit(0.1, "cm"),
strip.switch.pad.wrap = unit(0.1, "cm"),
complete = TRUE
)
}
Baiklah, sekarang mari kita lihat bersama kondisi perusahaan E-Commerce ini.
Bagaimana pertumbuhan pendapatan dari E-Commerce?
Kita dapat mengetahui pendapatan yang diterima dari E-Commerce melalui kolom Grand_Total
. Nilai dari kolom Grand_Total
merepresentasikan biaya yang dibayarkan pelanggan dalam satu invoice. Biaya ini telah dipotong diskon yang diberikan dan merupakan total dari semua produk yang dibeli.
Kita akan melihat pendapatan harian dan bulanannya.
plot_daily_revenue <- data %>%
select(Date_of_Order, Grand_Total, Invoice_ID, Order_Status) %>%
distinct() %>%
group_by(Date_of_Order, Order_Status) %>%
summarise(`Total Pendapatan` = sum(Grand_Total)) %>%
mutate(label = paste0(as.character(round(`Total Pendapatan`/1000000, 2)), "M"),
popup = glue("Status: {Order_Status}
Date: {Date_of_Order}
Total Pendapatan: {label}")) %>%
ggplot(aes(x = Date_of_Order, y = `Total Pendapatan`)) +
geom_line(aes(color = Order_Status), linewidth = 1) +
geom_line(aes(text = popup)) +
labs(title = "Pendapatan Harian E-Commerce",
x = NULL,
y = "Total Pendapatan",
color = "Status Pesanan") +
my_theme_color(reverse = T) +
my_plot_theme(10)
ggplotly(plot_daily_revenue, tooltip = "text")
plot_monthly_revenue <- data %>%
select(Month_Year, Grand_Total, Invoice_ID, Order_Status) %>%
distinct() %>%
group_by(Month_Year, Order_Status) %>%
summarise(`Total Pendapatan` = sum(Grand_Total)) %>%
mutate(label = paste0(as.character(round(`Total Pendapatan`/1000000, 2)), "M"),
popup = glue("Status: {Order_Status}
Date: {Month_Year}
Total Pendapatan: {label}")) %>%
ggplot(aes(x = Month_Year, y = `Total Pendapatan`)) +
geom_line(aes(color = Order_Status), linewidth = 1) +
geom_line(aes(text = popup)) +
geom_smooth(aes(x = Month_Year,
y = `Total Pendapatan`,
color = Order_Status),
method ="lm", se = FALSE, linewidth = 0.5, linetype = 2) +
labs(title = "Pendapatan Bulanan E-Commerce",
x = NULL,
y = "Total Pendapatan",
color = "Status Pesanan") +
my_theme_color(reverse = T) +
my_plot_theme(10)
ggplotly(plot_monthly_revenue, tooltip = "text")
Wow… Sungguh tragis. Kita dapat lihat bersama, bahwasannya memang pertumbuhan pendapatan dari E-Commerce ialah positif, akan tetapi banyak pesanan yang dibatalkan. Bahkan gradien pertumbuhan dari total pendapatan pesanan dibatalkan, jauh lebih tinggi daripada pesanan yang terselesaikan. Kondisi ini perlu diperhatikan dan menjadi red flag bagi perusahaan. Perlu dilakukan analisa terkait strategi untuk mengurangi terjadi pembatalan maupun pengembalian pesanan.
Berapa jumlah pelanggan baru pada tiap harinya serta bulannya ?
Kita akan melihat bersama terkait penambahan jumlah pelanggan baru pada tiap hari dan bulannya pada E-Commerce di pakistan ini.
old_customer_daily <- data %>%
select(Date_of_Order, Customer_ID) %>%
distinct() %>%
select(Customer_ID) %>%
duplicated() %>%
which()
plot_cust_daily_rate <- data %>%
select(Date_of_Order, Customer_ID) %>%
distinct() %>%
filter(!row_number() %in% c(old_customer_daily)) %>%
pad() %>%
group_by(Date_of_Order) %>%
summarise(`Total Pelanggan Baru` = length(unique(Customer_ID))) %>%
rename("Date" = "Date_of_Order") %>%
ggplot(aes(x = Date, y = `Total Pelanggan Baru`)) +
geom_line(col = my_color["col5"], linewidth = 1) +
geom_line(aes(text = glue("Date: {Date}
Total Pelanggan Baru: {`Total Pelanggan Baru`}"))) +
labs(title = "Pertumbuhan Pelanggan Baru Harian",
x = NULL,
y = "Total Pelanggan") +
# scale_color_manual(values = "#e3c502") +
my_plot_theme(10)
ggplotly(plot_cust_daily_rate, tooltip = "text")
old_customer_monthly <- data %>%
select(Month_Year, Customer_ID) %>%
distinct() %>%
select(Customer_ID) %>%
duplicated() %>%
which()
plot_cust_monthly_rate <- data %>%
select(Month_Year, Customer_ID) %>%
distinct() %>%
filter(!row_number() %in% c(old_customer_monthly)) %>%
group_by(Month_Year) %>%
summarise(`Total Pelanggan Baru` = length(unique(Customer_ID))) %>%
rename("Date" = "Month_Year") %>%
ggplot(aes(x = Date, y = `Total Pelanggan Baru`)) +
geom_line(col = my_color["col5"], linewidth = 1) +
geom_line(aes(text = glue("Date: {Date}
Total Pelanggan Baru: {`Total Pelanggan Baru`}"))) +
geom_smooth(method ="lm", se = FALSE, col = "red", linewidth = 0.5, linetype = 2) +
labs(title = "Pertumbuhan Pelanggan Bulanan",
x = NULL,
y = "Total Pelanggan") +
my_plot_theme(10)
ggplotly(plot_cust_monthly_rate, tooltip = "text")
Yups, kita dapat lihat bersama bahwa jumlah pelanggan baru semakin hari semakin menurun atau dengan kata lain pertumbuhan pelanggan baru adalh negatif. Kondisi ini menuntun perusahaan agar menerapkan strategi untuk meningkatkan nilai dari pelanggan yang telah ada, sehingga meskipun pertumbuhan jumlah pelanggan negatif akan tetapi pendapatan perusahaan positif.
Seberapa banyak transaksi yang terjadi pada tiap hari dan bulannya?
Disini kita akan melihat banyaknya transaksi atau pergerakan pertumbuhan jumlah transaksi yang terjadi pada perusahaan E-Commerce ini.
plot_daily_trans <- data %>%
# filter(Order_Status == "complete") %>%
pad() %>%
group_by(Date_of_Order, Order_Status) %>%
summarise(`Total Transaksi` = length(unique(Invoice_ID))) %>%
rename("Date" = "Date_of_Order") %>%
ggplot(aes(x = Date, y = `Total Transaksi`)) +
geom_line(aes(color = Order_Status), linewidth = 1) +
geom_line(aes(text = glue("Status:{Order_Status}
Date: {Date}
Total Transaksi: {`Total Transaksi`}"))) +
labs(title = "Total Transaksi Harian",
x = NULL,
y = "Total Transaksi",
color = "Status Pesanan") +
my_theme_color(reverse = T) +
my_plot_theme(10)
ggplotly(plot_daily_trans, tooltip = "text")
plot_trans_monthly <- data %>%
# filter(Order_Status == "complete") %>%
group_by(Month_Year, Order_Status) %>%
summarise(`Total Transaksi` = length(unique(Invoice_ID))) %>%
rename("Date" = "Month_Year") %>%
ggplot(aes(x = Date, y = `Total Transaksi`)) +
geom_line(aes(color = Order_Status), linewidth = 1) +
geom_line(aes(text = glue("Status: {Order_Status}
Date: {Date}
Total Transaksi: {`Total Transaksi`}"))) +
geom_smooth(aes(color = Order_Status),
method ="lm", se = FALSE, linewidth = 0.5, linetype = 2) +
labs(title = "Total Transaksi per Bulan",
x = NULL,
y = "Total Transaksi",
color = "Status Pesanan") +
my_theme_color(reverse = T) +
my_plot_theme(10)
ggplotly(plot_trans_monthly, tooltip = "text")
Kondisi perusahaan E-Commerce ini menunjukkan sangat membutuhkan strategi pengurangan terjadinya pembatalan dan pengembalian pesanan. Sebagaimana dapat kita lihat bersama, bahwasannya tren jumlah transaksi komplit adalah negatif. Adapun tren jumlah transaksi dibatalkan adalah positif. Kembali lagi, kondisi ini merupakan red flag bagi perusahaan.
Bagiamana dengan jumlah pelanggan yang melakukan transaksi pada tiap hari dan bulannya?
Selanjutnya, mari kita coba lihat banyaknya pelanggan yang melakukan transaksi pada tiap hari dan bulannya pada perusahaan E-Commerce ini.
plot_cust_daily <- data %>%
# filter(Order_Status == "complete") %>%
pad() %>%
group_by(Date_of_Order, Order_Status) %>%
summarise(`Total Pelanggan` = length(unique(Customer_ID))) %>%
rename("Date" = "Date_of_Order") %>%
ggplot(aes(x = Date, y = `Total Pelanggan`)) +
geom_line(aes(color = Order_Status), linewidth = 1) +
geom_line(aes(text = glue("Status: {Order_Status}
Date: {Date}
Total Pelanggan: {`Total Pelanggan`}"))) +
labs(title = "Total Pelanggan Harian",
x = NULL,
y = "Total Pelanggan",
color = "Status Pesanan") +
my_theme_color(reverse = T) +
my_plot_theme(10)
ggplotly(plot_cust_daily, tooltip = "text")
plot_cust_monthly <- data %>%
# filter(Order_Status == "complete") %>%
group_by(Month_Year, Order_Status) %>%
summarise(`Total Pelanggan` = length(unique(Customer_ID))) %>%
rename("Date" = "Month_Year") %>%
ggplot(aes(x = Date, y = `Total Pelanggan`)) +
geom_line(aes(color = Order_Status), linewidth = 1) +
geom_line(aes(text = glue("Status: {Order_Status}
Date: {Date}
Total Pelanggan: {`Total Pelanggan`}"))) +
geom_smooth(aes(color = Order_Status),
method = "lm", se = FALSE, linewidth = 0.5, linetype = 2) +
labs(title = "Total Pelanggan per Bulan",
x = NULL,
y = "Total Pelanggan",
color = "Status Pesanan") +
my_theme_color(reverse = T) +
my_plot_theme(10)
ggplotly(plot_cust_monthly, tooltip = "text")
Wow.. Semakin hari jumlah pelanggan yang melakukan pembatalan dan pengembalian pesanan semakin meningkat, sedangkan jumlah pelanggan yang menyelesaikan pesanannya semakin menurun. Bahkan, akhir periode di tahun 2018, sekitar bulan Juni hingga Agustus, menunjukkan hampir semua pelanggan melakukan pembatalan pesanan.
Selanjutnya, mari kita lihat dari segi merchants yang terdapat pada E-Commerce Pakistan ini.
Siapa kategori merchant yang paling banyak menjual barang?
# Banyak pembelian produk/barang yang terjadi pada masing-masing kategori merchants
quant_per_cat <- data %>%
filter(Order_Status == "complete") %>%
group_by(Category) %>%
summarise(amount = sum(Quantity)) %>%
ggplot(aes(x = amount, y = reorder(Category, amount), fill = amount)) +
geom_col(aes(text = glue("Kategori: {Category}
Total Produk Terjual: {amount}"))) +
labs(title = "Total Pembelian Produk oleh Pelanggan pada Setiap Kategori Merchants",
y = NULL,
x = "Total Produk") +
scale_fill_gradient(low = my_color["col1"], high = my_color["col7"]) +
my_plot_theme(10)+
theme(legend.position = "none",
plot.title = element_text(size = rel(1.5), margin = margin(b = 10/2 * 1.2),
color= "#222629", hjust = 1, family = "Segoe UI Semibold",
face = "bold"))
ggplotly(quant_per_cat, tooltip = "text")
Siapa kategori merchant yang paling sering terjadi transaksi?
# Banyaknya transaksi yang terjadi pada masing-masing kategori e-commerce
trans_per_cat <- data %>%
group_by(Category) %>%
summarise(amount_inc = length(unique(Invoice_ID))) %>%
ggplot(aes(x = amount_inc, y = reorder(Category, amount_inc), fill = amount_inc)) +
geom_col(aes(text = glue("Kategori: {Category}
Total Transaksi: {amount_inc}"))) +
labs(title = "Total Transaksi pada Setiap Kategori Merchants",
y = NULL,
x = "Total Transaksi") +
scale_fill_gradient(low = my_color["col1"], high = my_color["col7"]) +
my_plot_theme(10)+
theme(legend.position = "none")
ggplotly(trans_per_cat, tooltip = "text")
Siapa kategori merchant yang paling banyak memiliki pelanggan?
cust_per_cat <- data %>%
group_by(Category) %>%
summarise(amount_customer = length(unique(Customer_ID))) %>%
ggplot(aes(x = amount_customer, y = reorder(Category, amount_customer), fill = amount_customer)) +
geom_col(aes()) +
geom_col(aes(text = glue("Kategori: {Category}
Jumlah Pelanggan: {amount_customer}")))+
labs(title = "Total Pelanggan pada Setiap Kategori Merchants",
y = NULL,
x = "Total Pelanggan") +
scale_fill_gradient(low = my_color["col1"], high = my_color["col7"]) +
my_plot_theme(10)+
theme(legend.position = "none")
ggplotly(cust_per_cat, tooltip = "text")
Siapa kategori merchant yang paling tinggi pendapatannya?
# Total 'Grand_total' pada masing-masing kategori merchants
rev_per_cat <- data %>%
filter(Order_Status == "complete") %>%
group_by(Category, Invoice_ID) %>%
summarise(total_revenue = sum(Grand_Total)) %>%
ungroup() %>%
group_by(Category) %>%
summarise(total_revenue = sum(total_revenue)) %>%
mutate(label = paste0(as.character(round(total_revenue/1000000, 2)), "M")) %>%
ggplot(aes(x = total_revenue, y = reorder(Category, total_revenue), fill = total_revenue)) +
geom_col(aes(text = glue("Kategori: {Category}
Total Pendapatan: {label}")))+
labs(title = "Total Pendapatan pada Setiap Kategori Merchants",
y = NULL,
x = "Total Pendapatan") +
scale_fill_gradient(low = my_color["col1"], high = my_color["col7"]) +
my_plot_theme(10)+
theme(legend.position = "none")
ggplotly(rev_per_cat, tooltip = "text")
Berdasarkan plot pada tiap kategori merchants, kita mendapatkan insights yang menarik. Kategori merchants “Mobiles & Tablets” selalu menempati top-1 pada semua parameter, yakni tingkat pendapatan, total pelanggan, total transaksi, dan juga total produk yang terjual. Adapun kategori merchants “Books” berbanding terbalik, yaitu selalu menempati urutan terbawah. Kemudian, kategori merchants “Men’s Fashion”, “Women’s Fashion”, dan “Appliances” hampir selalu berada di dalam rentang top-5, yakni kecuali pada kategori total produk yang terjual. Fakta ini sangat menarik, karena meskipun barang-barang tersebut merupakan barang yang seperti harus dicoba dulu sebelum dibeli, jika kita mengingat jual beli tradisional, namun mampu selalu menempati peringkat teratas.
Selanjutnya mari kita coba lihat banyaknya barang yang dibeli oleh plenggan tiap kali melakukan transaksi.
getmodus <- function(v) {
uniqv <- unique(v)
uniqv[which.max(tabulate(match(v, uniqv)))]
}
df_basket <- data %>%
group_by(Customer_ID, Invoice_ID) %>%
summarise(baskets = sum(Quantity)) %>%
ungroup() %>%
group_by(Customer_ID) %>%
summarise(
freq = n(),
baskets = round(mean(baskets), 0))%>%
ungroup() %>%
mutate( Customer_ID = Customer_ID,
popup=glue("Customer ID : {Customer_ID}
Trans. Frequency : {freq}
Avg. basket : {baskets}"))
plot_baskets <- df_basket %>%
ggplot(aes(x = Customer_ID,y = baskets)) +
geom_point(aes(color=baskets, size=baskets, text=popup), show.legend = FALSE)+
geom_hline(yintercept = getmodus(df_basket$baskets),
linetype="dashed",
color = "black",
size=0.5,
text = getmodus(df_basket$baskets))+
annotate(geom = "text",
x = as.double(max(df_basket$Customer_ID)) - 2 / length(df_basket$Customer_ID)*0.5,
y = getmodus(df_basket$baskets) + 99,
size=3,
label=paste0("Modus: ",getmodus(df_basket$baskets),", Total: ",
round(as.numeric(((tabulate(match(df_basket$baskets,
unique(df_basket$baskets))) %>%
sort(decreasing = T) %>%
.[1])/length(df_basket$Customer_ID))*100),2),
"% cust"),
color="black")+
labs(title="Average baskets for each customer",
x = "Customer",
y = "Average Baskets")+
my_plot_theme(10)+
theme(
axis.text.x = element_blank()
)+
scale_color_gradient(low=my_theme_hex("col2"),
na.value = "#C0C0C0",
high=my_theme_hex("col7"))
ggplotly(plot_baskets, tooltip="text") %>%
layout(showlegend=FALSE)