library(dplyr)
##
## Attaching package: 'dplyr'
## The following objects are masked from 'package:stats':
##
## filter, lag
## The following objects are masked from 'package:base':
##
## intersect, setdiff, setequal, union
library(readr)
BK <- read_csv("D:/bike_sales_100k.csv")
## Rows: 100000 Columns: 11
## ── Column specification ────────────────────────────────────────────────────────
## Delimiter: ","
## chr (5): Date, Bike_Model, Store_Location, Payment_Method, Customer_Gender
## dbl (6): Sale_ID, Customer_ID, Price, Quantity, Salesperson_ID, Customer_Age
##
## ℹ Use `spec()` to retrieve the full column specification for this data.
## ℹ Specify the column types or set `show_col_types = FALSE` to quiet this message.
str(BK)
## spc_tbl_ [100,000 × 11] (S3: spec_tbl_df/tbl_df/tbl/data.frame)
## $ Sale_ID : num [1:100000] 1 2 3 4 5 6 7 8 9 10 ...
## $ Date : chr [1:100000] "11-07-2022" "03-05-2024" "01-09-2022" "28-09-2022" ...
## $ Customer_ID : num [1:100000] 9390 3374 2689 3797 1633 ...
## $ Bike_Model : chr [1:100000] "Cruiser" "Hybrid Bike" "Folding Bike" "Mountain Bike" ...
## $ Price : num [1:100000] 318 3093 4248 1722 3941 ...
## $ Quantity : num [1:100000] 1 4 3 3 3 5 4 1 3 5 ...
## $ Store_Location : chr [1:100000] "Philadelphia" "Chicago" "San Antonio" "San Antonio" ...
## $ Salesperson_ID : num [1:100000] 589 390 338 352 580 829 916 291 906 562 ...
## $ Payment_Method : chr [1:100000] "Apple Pay" "Apple Pay" "PayPal" "Apple Pay" ...
## $ Customer_Age : num [1:100000] 70 37 59 19 67 42 20 57 62 65 ...
## $ Customer_Gender: chr [1:100000] "Female" "Male" "Female" "Male" ...
## - attr(*, "spec")=
## .. cols(
## .. Sale_ID = col_double(),
## .. Date = col_character(),
## .. Customer_ID = col_double(),
## .. Bike_Model = col_character(),
## .. Price = col_double(),
## .. Quantity = col_double(),
## .. Store_Location = col_character(),
## .. Salesperson_ID = col_double(),
## .. Payment_Method = col_character(),
## .. Customer_Age = col_double(),
## .. Customer_Gender = col_character()
## .. )
## - attr(*, "problems")=<externalptr>
data_types_summary <- tibble(
Ten_Cot = c("Sale_ID", "Date", "Customer_ID", "Bike_Model", "Price",
"Quantity", "Store_Location", "Salesperson_ID", "Payment_Method",
"Customer_Age", "Customer_Gender"),
Loai_Du_lieu_trong_R = c("num", "chr",
"num", "chr",
"num", "num",
"chr", "num)",
"chr", "num",
"chr"),
Giai_thich = c("Mã số bán hàng.", "Ngày bán hàng (cần chuyển sang Date).",
"Mã khách hàng.", "Tên hoặc loại xe đạp.", "Giá bán.",
"Số lượng bán.", "Vị trí cửa hàng.", "Mã nhân viên bán hàng.",
"Phương thức thanh toán.", "Tuổi của khách hàng.",
"Giới tính của khách hàng.")
)
print(data_types_summary)
## # A tibble: 11 × 3
## Ten_Cot Loai_Du_lieu_trong_R Giai_thich
## <chr> <chr> <chr>
## 1 Sale_ID num Mã số bán hàng.
## 2 Date chr Ngày bán hàng (cần chuyển sang Date).
## 3 Customer_ID num Mã khách hàng.
## 4 Bike_Model chr Tên hoặc loại xe đạp.
## 5 Price num Giá bán.
## 6 Quantity num Số lượng bán.
## 7 Store_Location chr Vị trí cửa hàng.
## 8 Salesperson_ID num) Mã nhân viên bán hàng.
## 9 Payment_Method chr Phương thức thanh toán.
## 10 Customer_Age num Tuổi của khách hàng.
## 11 Customer_Gender chr Giới tính của khách hàng.
library(knitr)
kable(data_types_summary,
caption = "Bảng Tóm Tắt Loại Dữ liệu",
col.names = c("Tên Cột", "Loại Dữ liệu trong R (R Type)", "Giải thích"))
| Tên Cột | Loại Dữ liệu trong R (R Type) | Giải thích |
|---|---|---|
| Sale_ID | num | Mã số bán hàng. |
| Date | chr | Ngày bán hàng (cần chuyển sang Date). |
| Customer_ID | num | Mã khách hàng. |
| Bike_Model | chr | Tên hoặc loại xe đạp. |
| Price | num | Giá bán. |
| Quantity | num | Số lượng bán. |
| Store_Location | chr | Vị trí cửa hàng. |
| Salesperson_ID | num) | Mã nhân viên bán hàng. |
| Payment_Method | chr | Phương thức thanh toán. |
| Customer_Age | num | Tuổi của khách hàng. |
| Customer_Gender | chr | Giới tính của khách hàng. |
dim(BK)
## [1] 100000 11
colSums(is.na(BK))
## Sale_ID Date Customer_ID Bike_Model Price
## 0 0 0 0 0
## Quantity Store_Location Salesperson_ID Payment_Method Customer_Age
## 0 0 0 0 0
## Customer_Gender
## 0
sum(duplicated(BK))
## [1] 0
table(BK$Payment_Method)
##
## Apple Pay Cash Credit Card Debit Card Google Pay PayPal
## 16751 16692 16653 16738 16613 16553
BK1 <- BK %>%
mutate(Month = as.numeric(format(as.Date(Date), "%m")))
BK2 <- BK1 %>%
mutate(
Quarter = case_when(
Month %in% 1:3 ~ "Q1",
Month %in% 4:6 ~ "Q2",
Month %in% 7:9 ~ "Q3",
Month %in% 10:12 ~ "Q4"
))
BK4 <- BK2 %>%
mutate(
# Tạo cột Age_Group
Age_Group = case_when(
# Nhóm Young: 18 đến 35 tuổi
Customer_Age >= 18 & Customer_Age <= 35 ~ "Young",
# Nhóm Middle-Aged: 36 đến 55 tuổi
Customer_Age >= 36 & Customer_Age <= 55 ~ "Middle-Aged",
# Nhóm Senior: 56 tuổi trở lên
Customer_Age >= 56 ~ "Senior",
# Xử lý các trường hợp còn lại (ví dụ: tuổi nhỏ hơn 18 hoặc NA)
TRUE ~ "Other/Unknown"
)
)
BK %>%
summarise(
Gia_Tri_Lon_Nhat = max(Price, na.rm = TRUE),
Gia_Tri_Nho_Nhat = min(Price, na.rm = TRUE),
Gia_Tri_Trung_Binh = mean(Price, na.rm = TRUE),
Gia_Tri_Trung_Vi = median(Price, na.rm = TRUE),
Phuong_Sai = var(Price, na.rm = TRUE)
)
## # A tibble: 1 × 5
## Gia_Tri_Lon_Nhat Gia_Tri_Nho_Nhat Gia_Tri_Trung_Binh Gia_Tri_Trung_Vi
## <dbl> <dbl> <dbl> <dbl>
## 1 5000. 200. 2598. 2599.
## # ℹ 1 more variable: Phuong_Sai <dbl>
BK1 %>%
group_by(Month) %>%
summarise(
Gia_Tri_Lon_Nhat = max(Price, na.rm = TRUE),
Gia_Tri_Nho_Nhat = min(Price, na.rm = TRUE),
Gia_Tri_Trung_Binh = mean(Price, na.rm = TRUE),
Gia_Tri_Trung_Vi = median(Price, na.rm = TRUE),
Phuong_Sai = var(Price, na.rm = TRUE)
)
## # A tibble: 12 × 6
## Month Gia_Tri_Lon_Nhat Gia_Tri_Nho_Nhat Gia_Tri_Trung_Binh Gia_Tri_Trung_Vi
## <dbl> <dbl> <dbl> <dbl> <dbl>
## 1 1 4999. 200. 2577. 2533.
## 2 2 4999. 200. 2589. 2602.
## 3 3 5000. 200. 2594. 2610.
## 4 4 5000. 201. 2625. 2668.
## 5 5 4999. 200. 2598. 2610.
## 6 6 4999. 200. 2597. 2588.
## 7 7 5000. 200. 2597. 2580.
## 8 8 5000. 200. 2586. 2562.
## 9 9 4999. 200. 2601. 2604.
## 10 10 4999. 201. 2593. 2599.
## 11 11 5000. 200. 2627. 2624.
## 12 12 5000. 200. 2598. 2599.
## # ℹ 1 more variable: Phuong_Sai <dbl>
BK1 %>%
group_by(Price, Month) %>%
summarise(
Giao_Dich_Trung_Binh = mean(Price, na.rm = TRUE),
Giao_Dich_Trung_Vi = median(Price, na.rm = TRUE),
Phuong_Sai = var(Price, na.rm = TRUE)
) %>%
arrange(Month, Price)
## `summarise()` has grouped output by 'Price'. You can override using the
## `.groups` argument.
## # A tibble: 99,132 × 5
## # Groups: Price [90,336]
## Price Month Giao_Dich_Trung_Binh Giao_Dich_Trung_Vi Phuong_Sai
## <dbl> <dbl> <dbl> <dbl> <dbl>
## 1 200. 1 200. 200. NA
## 2 200. 1 200. 200. NA
## 3 201. 1 201. 201. NA
## 4 201. 1 201. 201. NA
## 5 201. 1 201. 201. NA
## 6 202. 1 202. 202. NA
## 7 202. 1 202. 202. NA
## 8 202. 1 202. 202. NA
## 9 203. 1 203. 203. NA
## 10 203. 1 203. 203. NA
## # ℹ 99,122 more rows
BK3 <- BK2 %>%
group_by(Quarter) %>%
summarise(
Tong_Giao_Dich = sum(Price, na.rm = TRUE),
Giao_Dich_Lon_Nhat = max(Price, na.rm = TRUE),
Giao_Dich_Nho_Nhat = min(Price, na.rm = TRUE),
Giao_Dich_Trung_Binh = mean(Price, na.rm = TRUE),
Giao_Dich_Trung_Vi = median(Price, na.rm = TRUE),
Phuong_Sai = var(Price, na.rm = TRUE),
So_Luong_Giao_Dich = n()
) %>%
arrange(Quarter)
print(BK3, n = Inf)
## # A tibble: 4 × 8
## Quarter Tong_Giao_Dich Giao_Dich_Lon_Nhat Giao_Dich_Nho_Nhat
## <chr> <dbl> <dbl> <dbl>
## 1 Q1 67234561. 5000. 200.
## 2 Q2 68775426. 5000. 200.
## 3 Q3 68184828. 5000. 200.
## 4 Q4 55623419. 5000. 200.
## # ℹ 4 more variables: Giao_Dich_Trung_Binh <dbl>, Giao_Dich_Trung_Vi <dbl>,
## # Phuong_Sai <dbl>, So_Luong_Giao_Dich <int>
BK2 %>%
group_by(Quarter, Price) %>%
summarise(
Tong_Giao_Dich = sum(Price, na.rm = TRUE),
Giao_Dich_Trung_Binh = mean(Price, na.rm = TRUE),
Giao_Dich_Trung_Vi = median(Price, na.rm = TRUE),
Phuong_Sai = var(Price, na.rm = TRUE),
So_Luong_Giao_Dich = n()
) %>%
arrange(Quarter, Price)
## `summarise()` has grouped output by 'Quarter'. You can override using the
## `.groups` argument.
## # A tibble: 97,465 × 7
## # Groups: Quarter [4]
## Quarter Price Tong_Giao_Dich Giao_Dich_Trung_Binh Giao_Dich_Trung_Vi
## <chr> <dbl> <dbl> <dbl> <dbl>
## 1 Q1 200. 200. 200. 200.
## 2 Q1 200. 200. 200. 200.
## 3 Q1 200. 400. 200. 200.
## 4 Q1 200. 200. 200. 200.
## 5 Q1 200. 200. 200. 200.
## 6 Q1 201. 201. 201. 201.
## 7 Q1 201. 201. 201. 201.
## 8 Q1 201. 201. 201. 201.
## 9 Q1 201. 201. 201. 201.
## 10 Q1 201. 201. 201. 201.
## # ℹ 97,455 more rows
## # ℹ 2 more variables: Phuong_Sai <dbl>, So_Luong_Giao_Dich <int>
library(ggplot2)
library(dplyr) # Cần thiết cho %>% và count(), mutate()
# Đảm bảo bạn đã định nghĩa BK2 (data frame gốc)
# Tùy thuộc vào code gốc của bạn, nếu BK2 là tên data frame đã làm sạch, thì OK.
BK5 <- BK2 %>%
count(Customer_Gender) %>%
mutate(percentage = n / sum(n))
# Sửa lỗi: Thay gender_counts bằng BK5
ggplot(BK5, aes(x = "", y = n, fill = Customer_Gender)) +
geom_bar(stat = "identity", width = 1) +
coord_polar("y", start = 0) + # Chuyển sang biểu đồ tròn
labs(
title = "Tỷ lệ Khách hàng theo Giới tính",
fill = "Giới tính"
) +
theme_void() + # Loại bỏ các yếu tố trục và lưới
geom_text(aes(label = scales::percent(percentage)),
position = position_stack(vjust = 0.5),
color = "black")
BK6 <- BK2 %>%
group_by(Store_Location) %>%
summarise(Total_Quantity = sum(Quantity, na.rm = TRUE)) %>%
ungroup() %>%
arrange(desc(Total_Quantity))
# Tạo biểu đồ cột
ggplot(BK6, aes(x = reorder(Store_Location, -Total_Quantity), y = Total_Quantity)) +
geom_bar(stat = "identity", fill = "lightgreen", color = "darkgreen") +
labs(
title = "Tổng Số lượng Xe Bán ra theo Vị trí Cửa hàng",
x = "Vị trí Cửa hàng (Store Location)",
y = "Tổng Số lượng (Quantity)"
) +
theme_classic()