Pengantar Data Sciences
Project Kelompok
| Kontak | : \(\downarrow\) |
| : sausan.ramadhani@student.matanauniversity.ac.id | |
| RPubs | : https://rpubs.com/sausanramadhani/ |
| Prodi | : Statistika Bisnis 2021 |
| Nama | : Sausan Ramadhani |
Project Kelompok oleh :
1. Dhela Asafiani Agatha
2. Sausan Ramadhani
3. Valensius Jimy
Pengenalan Project
 Pada kesempatan project kelompok kali ini, kami akan melakukan proses import data, cleaning and wragling data dan visualisasi data untuk mencari informasi mengenai sebuah penjualan perusahaan online retail. Berikut adalah perpustakaan yang kami gunakan untuk project kali ini.
library(tidyverse)
library(lubridate)
library(scales)
library(zoo)
library(readxl)
library(plotly)
library(ggplot2)
library(glue)Import Data
getwd()## [1] "C:/Users/hp/Documents/SEMESTER 2/PENGANTAR DATA SCIENCE"
df_input <- read_csv("C:/Users/hp/Documents/SEMESTER 2/PENGANTAR DATA SCIENCE/data_ecommerce.csv")## Rows: 541909 Columns: 8
## -- Column specification --------------------------------------------------------
## Delimiter: ","
## chr (5): InvoiceNo, StockCode, Description, InvoiceDate, Country
## dbl (3): Quantity, UnitPrice, CustomerID
##
## i Use `spec()` to retrieve the full column specification for this data.
## i Specify the column types or set `show_col_types = FALSE` to quiet this message.
df_inputuntuk memudahkan mengelola datanya, kami memilih menggunakan huruf kecil untuk setiap variabel yang ada pada data tersebut. Berikut ini adalah hasilnya.
colnames(df_input) <- tolower(colnames(df_input))
df_input <- df_input %>%
rename("invoice_no" = invoiceno,
"stock_code" = stockcode,
"Invoice_Date" = invoicedate,
"unit_price" = unitprice,
"customer_id" = customerid)
colnames(df_input)## [1] "invoice_no" "stock_code" "description" "quantity" "Invoice_Date"
## [6] "unit_price" "customer_id" "country"
data.frame(
invoice_unique = df_input$invoice_no %>% unique() %>% length(),
stock_code_unique = df_input$stock_code %>% unique() %>% length(),
description_unique = df_input$description %>% unique() %>% length(),
country_unique = df_input$country %>% unique() %>% length(),
customer_unique = df_input$customer_id %>% unique() %>% length()
)
Berikut adalah Link penjelasan pengerjaan kelompok kami https://drive.google.com/file/d/1nh-KZdwI7UK48iPcmyWgmLJ2y4GByvQZ/view
Data Cleansing
Transaksi Batal
 Berdasarkan informasi yang kami dapat dapat diartikan bahwa InvoiceNo yang diawali dengan huruf C berarti transaksi tersebut bersifat cancel atau batal, maka kita harus cek apakah pada data ini terdapat transaksi yang gagal:
df_input %>% filter(grepl("C", df_input$invoice_no)) %>% summarise(total_cancelled_transaction = n())terdapat 9288 transaksi yang bersifat cancel, sehingga kita dapat remove untuk transaksi tersebut dengan cara:
df_input <- df_input %>% filter(!grepl("C", df_input$invoice_no))Transaksi Tidak Valid
Berdasarkan Invoice
 Transaksi yang valid harus memiliki InvoiceNo yang terdiri dari 6 digit angka, maka kita harus cek pada data ini.
df_input %>% filter(nchar(invoice_no)>6)terdapat 3 data yang tidak valid, sehingga dapat kita remove.
df_input <- df_input %>%
filter(nchar(invoice_no)<=6) %>%
mutate(invoice_no_check = as.integer(invoice_no)) %>%
filter(!is.na(invoice_no_check))Berdasarkan Kuantitas
 Ketika ada kuantitas yang bernilai nol, maka sudah dipastikan tidak valid dengan alasan tidak mungkin transaksi dapat berjalan tanpa adanya barang yang keluar atau terjual.
df_input %>% filter(quantity<=0) %>% nrow()## [1] 1336
ternyata terdapat 1336 transaksi dengan kuantitas yang bernilai nol, sehingga kita dapat melakukan remove untuk transaksi tersebut.
df_input <- df_input %>% filter(quantity>0)Berdasarkan Harga
 Pada kasus ini tidak dijelaskan apakah ada promo atau hal lainnya yang membuat harga penjualan menjadi nol, sehingga kita dapat asumsikan bahwa ketika transaksi yang memiliki nilai nol adalah gagal dan dapat kita remove.
df_input %>% filter(unit_price<=0) %>% nrow()## [1] 1179
ternyata terdapat 1179 transaksi yang memiliki harga nol.
df_input <- df_input %>% filter(unit_price>0)Berdasarkan Stock Kode
 Berdasarkan informasi yang kami dapat juga ternyata Stock Code yang valid terdiri dari 5 digit angka. Mari kita lakukan pengecekan untuk hal ini.
df_input <- df_input %>% mutate(stock_code = toupper(stock_code))
df_input <- df_input %>% mutate(stock_code_nchar = nchar(stock_code))
df_input %>%
group_by(stock_code_nchar) %>%
summarise(row_count = n())ternyata terdapat transaksi yang Stock Code terdiri lebih dari 5 digit, sehingga harus kita bersihkan untuk masalah ini.
Cek stock_kode berdigit 1 sampai 4
df_input %>% filter(stock_code_nchar %in% c(1,2,3,4)) %>%
select(stock_code,description) %>%
distinct() %>% arrange(stock_code)terdapat 6 transaksi dan kita bisa remove.
df_input <- df_input %>% filter(!stock_code_nchar %in% c(1,2,3,4))Cek stock_kode berdigit 5
df_input %>% filter(stock_code_nchar %in% c(5)) %>%
select(stock_code,description) %>%
distinct() %>% arrange(stock_code)inilah transaksi yang valid karena memiliki 5 digit angka saja.
Cek stock_kode berdigit 6
df_input %>% filter(stock_code_nchar %in% c(6)) %>%
select(stock_code,description) %>%
distinct() %>% arrange(stock_code)transaksi yang memiliki digit 6 ini tidak perlu dihapus karena digit angka terdiri dari 5 dan 1 adalah huruf. Pada kasus ini jika ditelaah dengan baik terdapat produk yang sama, tetapi berbeda ada huruf saja dan ini menandakan bahwa 6 digit ini menandakan produk dengan warna yang berbeda dengan satu produk sama. Sehingga kita tidak perlu remove.
Cek stock_kode berdigit lebih dari 6
df_input %>% filter(nchar(stock_code)>6) %>%
select(stock_code,description) %>%
distinct() %>% arrange(stock_code)terdapat yang lebih dari 6 sehingga kita remove hal tersebut.
df_input %>% filter(!nchar(stock_code)>6)Missing Values
 Dalam mengolah sebuah data dan ingin memberikan sebuah informasi dari data yang kita olah, maka kita harus mengatasi yang namanya Missing Values yang kerapkali ditemukan ketika mengolah data yang banyak. Kita cek pada data yang saat ini sedang diolah:
colSums(is.na(df_input))## invoice_no stock_code description quantity
## 0 0 0 0
## Invoice_Date unit_price customer_id country
## 0 0 131454 0
## invoice_no_check stock_code_nchar
## 0 0
terdapat 131454 data customer_id yang hilang atau missing. Oleh karena itu, kita tidak dapat mengetahui siapa customernya dan harus kita berikan solusi untuk masalah ini. Dan kami memilih untuk remove customer_id yang missing dan kita membutuhkan total nilai setiap transaksi untuk dianalisa pada tahap akhir.
df_input <- df_input %>% mutate(total_amount = quantity * unit_price) %>%
select(invoice_no,Invoice_Date,customer_id,country,stock_code,
description,quantity,unit_price,total_amount)df_customer_transaction <- drop_na(df_input)
df_customer_transactiondf_customer_transaction <- separate(df_customer_transaction,
col = Invoice_Date,
into = c("Invoice_Date", "Time"),
sep = " "
)
df_customer_transactiondf_customer_transaction$month <- sapply(df_customer_transaction$Invoice_Date, FUN = function(x) {strsplit(x, split = '[/]')[[1]][1]})
df_customer_transaction$year <- sapply(df_customer_transaction$Invoice_Date, FUN = function(x) {strsplit(x, split = '[/]')[[1]][3]})
df_customer_transaction$hourOfDay <- sapply(df_customer_transaction$Time, FUN = function(x) {strsplit(x, split = '[:]')[[1]][1]})
df_customer_transaction$Invoice_Date <- as.Date(df_customer_transaction$Invoice_Date, "%m/%d/%Y")
library(lubridate)
df_customer_transaction$dayOfWeek <- wday(df_customer_transaction$Invoice_Date, label=TRUE)kita telah mendapat data yang bersih, sehingga dapat kita olah dalam bentuk visual untuk memberikan informasi yang baik dan jelas kepada orang lain.
Visualisasi Data
Most 10 Popular Product by Frequency Order
plot_most_frequency <- df_customer_transaction %>% group_by(stock_code,description) %>%
summarise(frequency = n()) %>%
ungroup() %>%
arrange(desc(frequency)) %>%
head(10) %>%
mutate(description = as.factor(description),
description = reorder(description,frequency)) %>%
ggplot(aes(x=description, y=frequency))+
geom_bar(stat="identity", aes(fill=description, text=frequency), show.legend = FALSE)+
labs(title="Most 10 Popular Product by Frequency Order",
x=NULL)+
coord_flip()## `summarise()` has grouped output by 'stock_code'. You can override using the `.groups` argument.
## Warning: Ignoring unknown aesthetics: text
ggplotly(plot_most_frequency, tooltip="text") %>%
layout(showlegend=FALSE) %>%
config(displayModeBar = F, scrollzoom = F)## Warning: 'config' objects don't have these attributes: 'scrollzoom'
## Valid attributes include:
## 'autosizable', 'displaylogo', 'displayModeBar', 'doubleClick', 'doubleClickDelay', 'editable', 'edits', 'fillFrame', 'frameMargins', 'globalTransforms', 'linkText', 'locale', 'locales', 'logging', 'mapboxAccessToken', 'modeBarButtons', 'modeBarButtonsToAdd', 'modeBarButtonsToRemove', 'notifyOnLogging', 'plotGlPixelRatio', 'plotlyServerURL', 'queueLength', 'responsive', 'scrollZoom', 'sendData', 'setBackground', 'showAxisDragHandles', 'showAxisRangeEntryBoxes', 'showEditInChartStudio', 'showLink', 'showSendToCloud', 'showSources', 'showTips', 'staticPlot', 'toImageButtonOptions', 'topojsonURL', 'watermark'
Note: Dapat disimpulkan bahwa 10 produk teratas/terpopuler berdasarkan frekuensi pesanannya. Dimana produk yang paling populer/terbanyak di pesan adalah produk WHITE HANGING HEART T-LIGHT HOLDER.
Most 10 Popular Product by Total Customer
plot_most_customer <- df_customer_transaction %>%
select(customer_id, stock_code,description) %>%
distinct() %>%
group_by(stock_code,description) %>%
summarise(total_customer = n()) %>%
ungroup() %>%
arrange(desc(total_customer)) %>%
head(10) %>%
mutate(description = as.factor(description),
description = reorder(description,total_customer)) %>%
ggplot(aes(x=description, y=total_customer))+
geom_bar(stat="identity", aes(fill=description, text=total_customer), show.legend = FALSE)+
labs(title="Most 10 Popular Product by Total Customer",
x=NULL)+
coord_flip()## `summarise()` has grouped output by 'stock_code'. You can override using the `.groups` argument.
## Warning: Ignoring unknown aesthetics: text
ggplotly(plot_most_customer, tooltip = "text") %>%
layout(showlegend=FALSE) %>%
config(displayModeBar = F, scrollzoom = F)## Warning: 'config' objects don't have these attributes: 'scrollzoom'
## Valid attributes include:
## 'autosizable', 'displaylogo', 'displayModeBar', 'doubleClick', 'doubleClickDelay', 'editable', 'edits', 'fillFrame', 'frameMargins', 'globalTransforms', 'linkText', 'locale', 'locales', 'logging', 'mapboxAccessToken', 'modeBarButtons', 'modeBarButtonsToAdd', 'modeBarButtonsToRemove', 'notifyOnLogging', 'plotGlPixelRatio', 'plotlyServerURL', 'queueLength', 'responsive', 'scrollZoom', 'sendData', 'setBackground', 'showAxisDragHandles', 'showAxisRangeEntryBoxes', 'showEditInChartStudio', 'showLink', 'showSendToCloud', 'showSources', 'showTips', 'staticPlot', 'toImageButtonOptions', 'topojsonURL', 'watermark'
Note: Grafik diatas menunjukkan 10 produk penjualan yang teratas/terpopuler berdasarkan customer yang melakukan transaksi. Barang produk yang paling populer adalah REGENCY CAKESTAND 3 TIER.
customer shopping habits
df_customer_transaction <- df_customer_transaction %>% mutate(total_amount = quantity * unit_price)
library(ggthemes)## Warning: package 'ggthemes' was built under R version 4.1.2
df_customer_transaction%>%
group_by(hourOfDay) %>%
count() %>%
arrange(desc(n)) %>%
head(20) %>%
ggplot() + geom_col(aes(y = reorder(hourOfDay,n), x = n,fill = factor(hourOfDay))) +
geom_label(aes(y = reorder(hourOfDay,n), x = n, label = n)) +
labs(title = 'Frekuensi minat jam belanja customer',
x = 'frequency',
y = 'Hour',
fill = 'hour of day') +
theme_minimal()
Note: Dari data diatas, dapat disimpulkan bahwa banyak customer yang melakukan transaksi pada pukul 12 siang. Sedangkan waktu yang paling jarang digunakan untuk melakukan transaksi adalah pukul 6 pagi.
Top Customer
library(treemap)## Warning: package 'treemap' was built under R version 4.1.2
treemap(df_customer_transaction,
index = c("country"),
vSize = "quantity",
title = "",
palette = "Set2",
border.col = "grey40")
Note: Berdasarkan data di atas, dapat disimpulkan bahwa negara UK memiliki customer yang paling banyak melakukan transaksi. NEgara terbesar kedua adalah Netherlands.
Number of Transactions by Day of the Week
weekdaySummary <- df_customer_transaction %>%
group_by(Invoice_Date, dayOfWeek) %>%
summarise(revenue = sum(total_amount), transactions = n_distinct(invoice_no)) %>%
mutate(aveOrdVal = (round((revenue / transactions),2))) %>%
ungroup()## `summarise()` has grouped output by 'Invoice_Date'. You can override using the `.groups` argument.
head(weekdaySummary, n = 10)ggplot(weekdaySummary, aes(x = dayOfWeek, y = transactions)) + geom_boxplot(fill = c("steelblue1", "gold3", "orangered3","red","green","grey")) + labs(x = 'Day of the Week', y = 'Number of Daily Transactions', title = 'Number of Transactions by Day of the Week')Note: Dari data yang telah diolah, dapat di simpulkan bahwa banyak customer yang melakukan transaksi pada hari Kamis.
Total Transactions by Order per Month
weekdaySummary1 <- weekdaySummary %>%
mutate(yearmonth = as.yearmon(Invoice_Date),
yearmonth = format(yearmonth))%>%
group_by(Invoice_Date,yearmonth) %>%
ungroup()
library(dplyr) # untuk manipulasi data
library(ggplot2) # untuk visualisasi
library(scales) # menentukan jeda atau label secara otomatis
# menghitung gaji rata-rata untuk setiap jabatan
plotdata <- weekdaySummary1 %>%
group_by(yearmonth)%>%
mutate(n = sum(transactions))
plotdata%>%
tidyr::unite("yearmonth",
yearmonth:n,
sep=":",
remove=FALSE)%>%
treemap(.,
index=c("yearmonth"),
vSize = "n",
type="index",
palette = "Set2",
title="Total Transactions by Order per Month",
fontsize.title = 14)
Note: Dari data penjualan yang telah di olah, dapat disimpulkan bahwa total transaksi yang telah dilakukan customer banyak dilakukan pada bulan November tahun 2011. Total transaksi yang dilakukan adalah 2751 transaksi.