library(dplyr)  
library(knitr)
library(DT)

1 Tổng quan nghiên cứu

Giới thiệu dữ liệu

Trong nghiên cứu này, nhóm tác giả sử dụng bộ dữ liệu Product Sales Dataset với tổng số biến là 14. Có 5 biến định lượng gồm: Quantity, Unit_Price, Revenue, Profit, Order_ID (mã đơn dạng số). Có 9 biến định tính gồm: Order_Date, Customer_Name, City, State, Region, Country, Category, Sub_Category, Product_Name.

1.1 Danh sách các biến

names(df)
##  [1] "Order_ID"      "Order_Date"    "Customer_Name" "City"         
##  [5] "State"         "Region"        "Country"       "Category"     
##  [9] "Sub_Category"  "Product_Name"  "Quantity"      "Unit_Price"   
## [13] "Revenue"       "Profit"
df_selected <- df[, c("Order_ID", "Order_Date", "Customer_Name", "City", "State",
                      "Region", "Country", "Category", "Sub_Category", "Product_Name",
                      "Quantity", "Unit_Price", "Revenue", "Profit")]

Mô tả các đặc trưng của dữ liệu

Tên biến Mô tả chi tiết
Order_ID Mã đơn hàng duy nhất, dùng để nhận diện từng giao dịch.
Order_Date Ngày phát sinh giao dịch (định dạng YYYY-MM-DD).
Customer_Name Tên khách hàng thực hiện đơn hàng.
City Thành phố nơi khách hàng sinh sống hoặc nơi giao hàng.
State Bang (State) của khách hàng tại Hoa Kỳ.
Region Khu vực địa lý của Hoa Kỳ (East, West, South, Centre).
Country Quốc gia của khách hàng (chỉ có United States).
Category Nhóm sản phẩm chính (ví dụ: Accessories, Clothing & Apparel).
Sub_Category Nhóm sản phẩm con (ví dụ: Sportswear, Bags).
Product_Name Tên hoặc mô tả cụ thể của sản phẩm.
Quantity Số lượng sản phẩm được mua trong mỗi giao dịch.
Unit_Price Giá bán của một đơn vị sản phẩm (USD).
Revenue Doanh thu gộp của giao dịch (Quantity × Unit Price).
Profit Lợi nhuận ròng thu được từ giao dịch sau khi trừ chi phí.

1.2 Số quan sát và số biến

dim(df)
## [1] 200000     14

1.3 Cấu trúc dữ liệu

knitr::kable(str(df))
## 'data.frame':    200000 obs. of  14 variables:
##  $ Order_ID     : int  1 2 3 4 5 6 7 8 9 10 ...
##  $ Order_Date   : chr  "08-23-23" "12-20-24" "01-29-24" "11-29-24" ...
##  $ Customer_Name: chr  "Bianca Brown" "Jared Edwards" "Susan Valdez" "Tina Williams" ...
##  $ City         : chr  "Jackson" "Grand Rapids" "Minneapolis" "Tallahassee" ...
##  $ State        : chr  "Mississippi" "Michigan" "Minnesota" "Florida" ...
##  $ Region       : chr  "South" "Centre" "Centre" "South" ...
##  $ Country      : chr  "United States" "United States" "United States" "United States" ...
##  $ Category     : chr  "Accessories" "Accessories" "Clothing & Apparel" "Clothing & Apparel" ...
##  $ Sub_Category : chr  "Small Electronics" "Small Electronics" "Sportswear" "Sportswear" ...
##  $ Product_Name : chr  "Phone Case" "Charging Cable" "Nike Air Force 1" "Adidas Tracksuit" ...
##  $ Quantity     : int  3 4 1 3 1 1 2 1 2 5 ...
##  $ Unit_Price   : num  201 74.3 68.2 209.6 216.6 ...
##  $ Revenue      : num  603 297.2 68.2 628.9 216.6 ...
##  $ Profit       : num  221.5 97.1 25.5 231.4 42.5 ...

1.4 Thống kê mô tả

knitr::kable(summary(df))
Order_ID Order_Date Customer_Name City State Region Country Category Sub_Category Product_Name Quantity Unit_Price Revenue Profit
Min. : 1 Length:200000 Length:200000 Length:200000 Length:200000 Length:200000 Length:200000 Length:200000 Length:200000 Length:200000 Min. : 1.000 Min. : 17.03 Min. : 17.03 Min. : 3.92
1st Qu.: 50001 Class :character Class :character Class :character Class :character Class :character Class :character Class :character Class :character Class :character 1st Qu.: 1.000 1st Qu.: 162.76 1st Qu.: 229.19 1st Qu.: 59.21
Median :100000 Mode :character Mode :character Mode :character Mode :character Mode :character Mode :character Mode :character Mode :character Mode :character Median : 1.000 Median : 303.55 Median : 464.88 Median : 109.53
Mean :100000 NA NA NA NA NA NA NA NA NA Mean : 1.854 Mean : 382.86 Mean : 712.04 Mean : 157.74
3rd Qu.:150000 NA NA NA NA NA NA NA NA NA 3rd Qu.: 2.000 3rd Qu.: 562.25 3rd Qu.: 881.30 3rd Qu.: 199.40
Max. :200000 NA NA NA NA NA NA NA NA NA Max. :11.000 Max. :1432.00 Max. :9014.25 Max. :2763.72

1.5 Một vài dòng đầu và dòng cuối của dữ liệu

knitr::kable(head(df))
Order_ID Order_Date Customer_Name City State Region Country Category Sub_Category Product_Name Quantity Unit_Price Revenue Profit
1 08-23-23 Bianca Brown Jackson Mississippi South United States Accessories Small Electronics Phone Case 3 201.01 603.03 221.49
2 12-20-24 Jared Edwards Grand Rapids Michigan Centre United States Accessories Small Electronics Charging Cable 4 74.30 297.20 97.09
3 01-29-24 Susan Valdez Minneapolis Minnesota Centre United States Clothing & Apparel Sportswear Nike Air Force 1 1 68.19 68.19 25.47
4 11-29-24 Tina Williams Tallahassee Florida South United States Clothing & Apparel Sportswear Adidas Tracksuit 3 209.64 628.92 231.38
5 09-21-23 Catherine Gordon Baltimore Maryland East United States Accessories Bags Backpack 1 216.63 216.63 42.46
6 10-18-24 Brittany Johnson Boston Massachusetts East United States Electronics Home Appliances Instant Pot 1 701.15 701.15 90.63
knitr::kable(tail(df))
Order_ID Order_Date Customer_Name City State Region Country Category Sub_Category Product_Name Quantity Unit_Price Revenue Profit
199995 199995 12-24-23 Christopher Reid Nashua New Hampshire East United States Clothing & Apparel Footwear Nike Running Shoes 3 172.26 516.78 192.94
199996 199996 08-15-23 William Jackson Boston Massachusetts East United States Home & Furniture Storage Storage Rack 4 254.42 1017.68 334.72
199997 199997 10-17-23 Sharon Ferrell Bismarck North Dakota Centre United States Accessories Small Electronics Charging Cable 1 237.04 237.04 46.53
199998 199998 12-03-23 Katie Rivera Santa Fe New Mexico West United States Accessories Wearable Accessories Sunglasses 2 106.83 213.66 102.57
199999 199999 12-08-23 Lisa Sullivan New York City New York East United States Clothing & Apparel Women’s Wear Zara Blouse 2 353.01 706.02 288.74
200000 200000 12-13-24 Jessica Mueller Augusta Maine East United States Clothing & Apparel Men’s Wear GAP Hoodie 1 216.68 216.68 59.10

1.6 Tổng quan NA

# Tổng số giá trị thiếu
sum(is.na(df))
## [1] 0
# Kiểm tra xem có NA không
any(is.na(df))
## [1] FALSE

Kết luận: Bộ dữ liệu sạch, không có giá trị thiếu và loại bỏ trùng lặp

1.7 Kiểm tra và loại bỏ bản ghi trùng lặp

# Số lượng bản ghi trùng lặp
sum(duplicated(df))
## [1] 0

Nhận xét: Bộ dữ liệu không có bản ghi trùng lặp, không cần loại bỏ thêm

1.8 Chuẩn hoá dữ liệu

# Chuẩn hoá định dạng ngày tháng
df$Order_Date <- as.Date(df$Order_Date, format = "%m-%d-%y")
# Chuẩn hoá dữ liệu số
df$Quantity <- as.numeric(df$Quantity)
df$Unit_Price <- as.numeric(df$Unit_Price)
df$Revenue <- as.numeric(df$Revenue)
df$Profit <- as.numeric(df$Profit)
# Chuẩn hoá dữ liệu văn bản
df$Customer_Name <- trimws(df$Customer_Name)
df$City <- trimws(df$City)
df$State <- trimws(df$State)
df$Region <- trimws(df$Region)
df$Country <- trimws(df$Country)
df$Category <- trimws(df$Category)
df$Sub_Category <- trimws(df$Sub_Category)
df$Product_Name <- trimws(df$Product_Name)
# Loại bỏ khoảng trắng thừa và ký tự đặc biệt
colnames(df) <- make.names(trimws(colnames(df)), unique = TRUE)
colnames(df)
##  [1] "Order_ID"      "Order_Date"    "Customer_Name" "City"         
##  [5] "State"         "Region"        "Country"       "Category"     
##  [9] "Sub_Category"  "Product_Name"  "Quantity"      "Unit_Price"   
## [13] "Revenue"       "Profit"

1.9 Lọc dữ liệu theo điều kiện

1.9.1 Lọc dữ liệu theo một điều kiện

# Lọc các đơn hàng Electronics
d1 <- df %>% filter(Category == "Electronics")
knitr::kable(head(d1[, c("Category", "Product_Name", "Revenue")], 5))
Category Product_Name Revenue
Electronics Instant Pot 701.15
Electronics Apple Watch 1750.68
Electronics Apple iPhone 14 2547.55
Electronics Samsung Galaxy Tab 1434.12
Electronics Samsung Galaxy Tab 790.39

1.9.2 Lọc dữ liệu theo hai điều kiện

# Lọc các đơn hàng Electronics ở Boston
d2_and <- df %>% filter(Category == "Electronics", City == "Boston")
knitr::kable(head(d2_and[, c("Category", "City", "Product_Name", "Revenue")], 5))
Category City Product_Name Revenue
Electronics Boston Instant Pot 701.15
Electronics Boston Samsung Galaxy Tab 1434.12
Electronics Boston Lenovo ThinkPad 671.84
Electronics Boston Samsung Galaxy S23 270.90
Electronics Boston Apple iPhone 14 1006.47

1.9.3 Lọc dữ liệu theo ba điều kiện

# Lọc các đơn hàng Electronics ở Boston với Revenue > 1000
d3_or <- df %>% filter(Category == "Electronics" | City == "Boston" | Revenue > 1000)
knitr::kable(head(d3_or[, c("Category", "City", "Product_Name", "Revenue")], 5))
Category City Product_Name Revenue
Electronics Boston Instant Pot 701.15
Electronics Seattle Apple Watch 1750.68
Electronics Fort Smith Apple iPhone 14 2547.55
Electronics Boston Samsung Galaxy Tab 1434.12
Electronics Aurora Samsung Galaxy Tab 790.39

1.10 Biến phụ thuộc theo biến độc lập: trung bình, min, max

# Tổng hợp trung bình, min, max của Revenue theo Category
rev_cat <- df %>%
  group_by(Category) %>%                             # ① Nhóm theo Category
  summarise(
    mean_revenue = mean(Revenue, na.rm = TRUE),      # ② Revenue trung bình
    min_revenue  = min(Revenue, na.rm = TRUE),       # ③ Revenue nhỏ nhất
    max_revenue  = max(Revenue, na.rm = TRUE),       # ④ Revenue lớn nhất
    n = n()                                         # ⑤ Số đơn hàng trong nhóm
  ) %>%
  arrange(desc(mean_revenue))                        # ⑥ Sắp xếp giảm dần theo Revenue trung bình

# Hiển thị kết quả
knitr::kable(rev_cat)
Category mean_revenue min_revenue max_revenue n
Electronics 1122.1101 71.56 9014.25 51230
Home & Furniture 942.8532 31.12 8295.00 50564
Clothing & Apparel 435.5576 17.03 3665.60 62298
Accessories 281.6435 41.43 2177.01 35908

1.11 Tạo biến mới

# Tạo biến mới
df <- df %>%
  mutate(
    Revenue_k = Revenue / 1000,   # Revenue đơn vị nghìn USD
    Profit_level = case_when(     # Phân loại lợi nhuận
      Profit < 100 ~ "Low",
      Profit >= 100 & Profit < 500 ~ "Medium",
      Profit >= 500 ~ "High",
      TRUE ~ "Other"
    )
  )

# Hiển thị bảng interactive 10 dòng đầu
DT::datatable(head(df, 10), options = list(scrollX = TRUE))

2 Trực quan hóa Dữ liệu và Phân tích Hiệu suất Kinh doanh

2.1 Phân tích Xu hướng Doanh thu theo thời gian (Năm)

Biểu đồ cho thấy doanh thu tăng trưởng ổn định nhưng nhẹ từ năm 2023 đến 2024.

Năm 2023 đạt khoảng 70,8 triệu USD.

Năm 2024 tăng lên 71,7 triệu USD, duy trì đà kinh doanh tích cực.

# Tính tổng doanh thu theo năm
revenue_by_year <- df %>%
  group_by(year) %>%
  summarise(Total_Revenue = sum(Revenue))

# Trực quan hóa
revenue_by_year %>%
  ggplot(aes(x = year, y = Total_Revenue, group = 1)) +
  geom_line(color = 'blue', linewidth = 1) +
  geom_point(color = 'blue', size = 3) +
  geom_text(aes(label = paste0(round(Total_Revenue / 1e6, 1), "M")),
            vjust = -1, hjust = -0.1, size = 4) + # Định dạng M = Triệu USD
  labs(title = '1. Xu hướng Doanh thu theo Năm',
       x = 'Năm',
       y = 'Tổng Doanh thu (Triệu USD)') +
  scale_y_continuous(labels = unit_format(unit = "M", scale = 1e-6)) + # Định dạng trục Y
  theme_minimal() +
  theme(plot.title = element_text(hjust = 0.5))

2.2 Top Khu vực có Tổng Doanh thu cao nhất

East là khu vực dẫn đầu thị trường với doanh thu vượt trội (~45,0 triệu USD), cho thấy đây là thị trường quan trọng nhất. West và Centre có hiệu suất kinh doanh gần như tương đương, trong khi South có doanh thu thấp nhất.

# Tính tổng doanh thu và chọn top khu vực 
revenue_by_region <- df %>%
  group_by(Region) %>%
  summarise(Total_Revenue = sum(Revenue)) %>%
  arrange(desc(Total_Revenue)) %>%
  slice_head(n = 5)

# Trực quan hóa
revenue_by_region %>%
  ggplot(aes(x = reorder(Region, -Total_Revenue), y = Total_Revenue, fill = Region)) +
  geom_col() +
  geom_text(aes(label = paste0(round(Total_Revenue / 1e6, 1), "M")),
            vjust = -0.5, size = 4) +
  labs(title = '2. Top Khu vực có Doanh thu cao nhất',
       x = 'Khu vực',
       y = 'Tổng Doanh thu (Triệu USD)') +
  scale_y_continuous(labels = unit_format(unit = "M", scale = 1e-6)) +
  theme_minimal() +
  theme(plot.title = element_text(hjust = 0.5),
        legend.position = "none")

2.3 So sánh Doanh thu theo Danh mục sản phẩm

Danh mục Electronics dẫn đầu về doanh thu với 57,5 triệu USD, tiếp theo là Home & Furniture đạt 47,7 triệu USD. Trong khi đó, Clothing & Apparel (27,1 triệu USD) và Accessories (10,1 triệu USD) có mức doanh thu thấp hơn rõ rệt. Điều này cho thấy các sản phẩm công nghệ và nội thất chiếm ưu thế, góp phần lớn vào hiệu quả kinh doanh chung của doanh nghiệp.

# Tính tổng doanh thu theo Danh mục
revenue_by_category <- df %>%
  group_by(Category) %>%
  summarise(Total_Revenue = sum(Revenue)) %>%
  arrange(desc(Total_Revenue))

# Trực quan hóa
revenue_by_category %>%
  ggplot(aes(x = reorder(Category, -Total_Revenue), y = Total_Revenue, fill = Category)) +
  geom_col() +
  geom_text(aes(label = paste0(round(Total_Revenue / 1e6, 1), "M")),
            vjust = -0.5, size = 4) +
  labs(title = '3. So sánh Doanh thu theo Danh mục sản phẩm',
       x = 'Danh mục',
       y = 'Tổng Doanh thu (Triệu USD)') +
  scale_y_continuous(labels = unit_format(unit = "M", scale = 1e-6)) +
  theme_minimal() +
  theme(plot.title = element_text(hjust = 0.5),
        axis.text.x = element_text(angle = 15, hjust = 1),
        legend.position = "none")

2.4 Xu hướng Lợi nhuận của từng Danh mục qua các năm

Danh mục Electronics dẫn đầu về doanh thu với 57,5 triệu USD, tiếp theo là Home & Furniture đạt 47,7 triệu USD. Trong khi đó, Clothing & Apparel (27,1 triệu USD) và Accessories (10,1 triệu USD) có mức doanh thu thấp hơn rõ rệt. Điều này cho thấy các sản phẩm công nghệ và nội thất chiếm ưu thế, góp phần lớn vào hiệu quả kinh doanh chung của doanh nghiệp.

# Tính tổng lợi nhuận theo năm và danh mục
profit_by_year_category <- df %>%
  group_by(year, Category) %>%
  summarise(Total_Profit = sum(Profit), .groups = "drop")

# Trực quan hóa
profit_by_year_category %>%
  ggplot(aes(x = year, y = Total_Profit, group = Category, color = Category)) +
  geom_line(linewidth = 1.2) +
  geom_point(size = 3) +
  labs(title = '4. Xu hướng Lợi nhuận của từng Danh mục qua các Năm',
       x = 'Năm',
       y = 'Tổng Lợi nhuận (USD)') +
  scale_y_continuous(labels = comma) + # Định dạng tiền tệ
  theme_minimal() +
  theme(plot.title = element_text(hjust = 0.5))

2.5 Top 10 Sản phẩm mang lại Lợi nhuận cao nhất

Sản phẩm Tempur-Pedic Mattress dẫn đầu với 2.126.584 USD lợi nhuận, theo sau là Instant Pot (1.689.924 USD) và Nike Air Force 1 (1.128.699 USD). Các sản phẩm còn lại như Storage Rack, MacBook Air, và Old Navy Dress có lợi nhuận dao động quanh 950.000 – 1.050.000 USD. Nhìn chung, các sản phẩm thuộc nhóm gia dụng và điện tử chiếm ưu thế, mang lại hiệu quả sinh lời cao nhất trong danh mục.

# Tính tổng lợi nhuận và chọn top 10 sản phẩm
profit_by_product <- df %>%
  group_by(Product_Name) %>%
  summarise(Total_Profit = sum(Profit)) %>%
  arrange(desc(Total_Profit)) %>%
  slice_head(n = 10)

# Trực quan hóa
profit_by_product %>%
  ggplot(aes(x = reorder(Product_Name, Total_Profit), y = Total_Profit)) +
  geom_col(fill = 'darkred') +
  geom_text(aes(label = comma(round(Total_Profit, 0))),
            hjust = -0.1, size = 3) +
  labs(title = '5. Top 10 Sản phẩm mang lại Lợi nhuận cao nhất',
       x = 'Tên Sản phẩm',
       y = 'Tổng Lợi nhuận (USD)') +
  scale_y_continuous(labels = comma) +
  coord_flip() + # Lật trục để dễ đọc tên sản phẩm
  theme_minimal() +
  theme(plot.title = element_text(hjust = 0.5))

2.6 Tỷ trọng Tổng Lợi nhuận theo Mức độ Lợi nhuận (Profit_level)

Phân tích cho thấy giao dịch Medium (Lợi nhuận từ 100 đến 300 USD) chiếm tỷ trọng lớn nhất (47,7%), là nguồn đóng góp lợi nhuận phổ biến. Giao dịch High (Lợi nhuận > 300 USD) đóng góp 41,3%, cho thấy các đơn hàng lớn hoặc sản phẩm biên lợi nhuận cao tạo ra giá trị đáng kể.

# Tính tổng lợi nhuận theo mức độ
profit_by_level <- df %>%
  group_by(Profit_level) %>%
  summarise(Total_Profit = sum(Profit)) %>%
  mutate(percentage = Total_Profit / sum(Total_Profit))

# Trực quan hóa (Biểu đồ tròn)
profit_by_level %>%
  ggplot(aes(x = "", y = Total_Profit, fill = Profit_level)) +
  geom_bar(stat = "identity", width = 1, color = "white") +
  coord_polar("y", start = 0) +
  geom_text(aes(label = percent(percentage)),
            position = position_stack(vjust = 0.5)) +
  labs(title = '6. Tỷ trọng Tổng Lợi nhuận theo Mức độ Lợi nhuận',
       fill = "Mức độ Lợi nhuận") +
  theme_void() +
  theme(plot.title = element_text(hjust = 0.5))

2.7 Top 5 Thành phố có Tổng Lợi nhuận cao nhất

Thành phố Rochester dẫn đầu với 478.264 USD, theo sau là Jersey City (474.695 USD) và Manchester (472.308 USD). Hai vị trí cuối là Burlington (471.285 USD) và New Haven (470.819 USD). Nhìn chung, chênh lệch lợi nhuận giữa các thành phố top đầu rất nhỏ (dưới 2%), cho thấy mức độ hiệu quả kinh doanh ổn định và phân bố đồng đều giữa các khu vực này.

# Tính tổng lợi nhuận và chọn top 5 thành phố
profit_by_city <- df %>%
  group_by(City) %>%
  summarise(Total_Profit = sum(Profit)) %>%
  arrange(desc(Total_Profit)) %>%
  slice_head(n = 5)

# Trực quan hóa
profit_by_city %>%
  ggplot(aes(x = reorder(City, -Total_Profit), y = Total_Profit, fill = City)) +
  geom_col() +
  geom_text(aes(label = comma(round(Total_Profit, 0))),
            vjust = -0.5, size = 4) +
  labs(title = '7. Top 5 Thành phố có Tổng Lợi nhuận cao nhất',
       x = 'Thành phố',
       y = 'Tổng Lợi nhuận (USD)') +
  scale_y_continuous(labels = comma) +
  theme_minimal() +
  theme(plot.title = element_text(hjust = 0.5),
        legend.position = "none")

2.8 So sánh Số lượng sản phẩm bán ra theo Khu vực qua các năm

Khu vực East tiếp tục dẫn đầu về tổng số lượng sản phẩm bán ra trong cả hai năm, với 52.750 đơn hàng năm 2023 và tăng lên 53.215 đơn hàng năm 2024, khẳng định đây là thị trường có nhu cầu mạnh nhất. Đứng thứ hai là West, duy trì mức doanh số cao và ổn định với 51.075 đơn hàng năm 2023 và 51.856 đơn hàng năm 2024. Centre ghi nhận mức tăng nhẹ từ 45.840 lên 45.624 đơn hàng (gần như giữ nguyên), trong khi South có doanh số thấp nhất nhưng vẫn tăng từ 34.944 lên 35.496 đơn hàng. Nhìn chung, tất cả các khu vực đều tăng trưởng nhẹ từ 2023 sang 2024, tuy nhiên tốc độ tăng của East và West vượt trội hơn, cho thấy đây là hai thị trường trọng điểm cần tiếp tục ưu tiên khai thác.

# Tính tổng số lượng bán ra theo năm và khu vực
quantity_by_year_region <- df %>%
  group_by(year, Region) %>%
  summarise(Total_Quantity = sum(Quantity), .groups = "drop")

# Trực quan hóa
quantity_by_year_region %>%
  ggplot(aes(x = year, y = Total_Quantity, fill = Region)) +
  geom_col(position = position_dodge(width = 0.8), width = 0.7) +
  geom_text(aes(label = comma(Total_Quantity)),
            position = position_dodge(width = 0.8), vjust = -0.5, size = 3) +
  labs(title = '8. Số lượng sản phẩm bán ra theo Khu vực qua các Năm',
       x = 'Năm',
       y = 'Tổng Số lượng bán ra',
       fill = 'Khu vực') +
  scale_y_continuous(labels = comma) +
  theme_minimal() +
  theme(plot.title = element_text(hjust = 0.5))

2.9 Top 5 Bang có Mật độ Đơn hàng cao nhất

California là bang có số lượng đơn hàng cao nhất, vượt nhẹ so với Arizona. Hai bang này tạo ra mức doanh số vượt trội so với các bang còn lại, cho thấy quy mô dân số lớn và sức mua mạnh. Trong khi đó, Illinois, New Jersey và Ohio có lượng đơn hàng chỉ bằng khoảng một nửa so với nhóm dẫn đầu, phản ánh thị trường nhỏ hơn hoặc mức độ tiêu dùng thấp hơn.

# Tính tổng số đơn hàng theo bang (dùng Order_ID)
orders_by_state <- df %>%
  group_by(State) %>%
  summarise(Total_Orders = n()) %>%
  arrange(desc(Total_Orders)) %>%
  slice_head(n = 5)

# Trực quan hóa
orders_by_state %>%
  ggplot(aes(x = reorder(State, -Total_Orders), y = Total_Orders, fill = State)) +
  geom_col() +
  geom_text(aes(label = comma(Total_Orders)),
            vjust = -0.5, size = 4) +
  labs(title = '9. Top 5 Bang có Mật độ Đơn hàng cao nhất',
       x = 'Bang',
       y = 'Tổng số Đơn hàng') +
  scale_y_continuous(labels = comma) +
  theme_minimal() +
  theme(plot.title = element_text(hjust = 0.5),
        legend.position = "none")

2.10 Doanh thu trung bình trên mỗi Đơn hàng theo Danh mục

Danh mục Electronics có doanh thu trung bình cao nhất, đạt khoảng 1.122 USD/đơn hàng, theo sau là Home & Furniture (943 USD/đơn hàng). Hai nhóm còn lại, Clothing & Apparel (436 USD) và Accessories (282 USD), có doanh thu trung bình thấp hơn đáng kể. Điều này cho thấy Electronics và Home & Furniture là những nhóm sản phẩm có giá trị cao, mang lại hiệu suất doanh thu mạnh mẽ trên mỗi giao dịch.

# Tính doanh thu trung bình theo danh mục
avg_revenue_by_category <- df %>%
  group_by(Category) %>%
  summarise(Average_Revenue = mean(Revenue)) %>%
  arrange(desc(Average_Revenue))

# Trực quan hóa
avg_revenue_by_category %>%
  ggplot(aes(x = reorder(Category, -Average_Revenue), y = Average_Revenue, fill = Category)) +
  geom_col() +
  geom_text(aes(label = dollar(round(Average_Revenue, 2))),
            vjust = -0.5, size = 4) +
  labs(title = '10. Doanh thu trung bình trên mỗi Đơn hàng theo Danh mục',
       x = 'Danh mục',
       y = 'Doanh thu trung bình (USD)') +
  scale_y_continuous(labels = dollar) +
  theme_minimal() +
  theme(plot.title = element_text(hjust = 0.5),
        axis.text.x = element_text(angle = 15, hjust = 1),
        legend.position = "none")

PHẦN 2: NGÂN HÀNG VPB

# TÙY CHỌN CHUNK:
# message=FALSE: Ẩn tin nhắn
# warning=FALSE: Ẩn cảnh báo
# echo=TRUE: (Đây là mặc định) Sẽ HIỆN code

# Tùy chọn 2: knitr::opts_chunk$set()
# Đây là lệnh "thần thánh" đặt quy tắc cho TẤT CẢ các khối mã phía sau
knitr::opts_chunk$set(
  echo    = TRUE,   # <-- ĐÃ SỬA: HIỆN code R
  message = FALSE,  # Ẩn các tin nhắn
  warning = FALSE   # Ẩn TẤT CẢ các cảnh báo
)

# Tải tất cả thư viện của bạn Ở ĐÂY
library(tidyverse)
library(lubridate)
library(scales)
library(ggcorrplot)
library(knitr)     # Thư viện để làm bảng đẹp (kable)
library(broom)     # Thư viện để biến kết quả model thành bảng

# Đọc dữ liệu
# Sử dụng read_csv() của tidyverse để đọc file
file_path <- "~/Downloads/VPBank_Full_Data_2015_2024.csv"
df <- read_csv(file_path)

3 BƯỚC 1: GIỚI THIỆU BỘ DỮ LIỆU

# Thao tác 1: Xem 6 dòng dữ liệu đầu tiên
knitr::kable(
  head(df), 
  caption = "Bảng 1: Sáu dòng dữ liệu đầu tiên"
)
Bảng 1: Sáu dòng dữ liệu đầu tiên
Nam Tien_mat_vang_bac_da_quy Tien_mat_VND Tien_mat_ngoai_te Vang_tien_te Tien_gui_NHNN Tien_gui_cho_vay_TCTD_khac Tien_gui_TCTD_khac Cho_vay_TCTD_khac Du_phong_cho_vay_TCTD_khac CK_kinh_doanh CK_kinh_doanh_gop Du_phong_rui_ro_CK_kinh_doanh Cho_vay_khach_hang Cho_vay_khach_hang_gop Du_phong_rui_ro_cho_vay_khach_hang CK_dau_tu CK_dau_tu_san_sang_ban CK_dau_tu_giu_den_ngay_dao_han Du_phong_rui_ro_CK_dau_tu Gop_von_dau_tu_dai_han Dau_tu_dai_han_khac Du_phong_giam_gia_dau_tu_dai_han Tai_san_co_dinh TSCD_huu_hinh TSCD_vo_hinh Tai_san_Co_khac Cac_khoan_phai_thu Cac_khoan_lai_phi_phai_thu Tai_san_Co_khac_2 Du_phong_rui_ro_tai_san_Co_noi_bang_khac Tong_cong_tai_san No_Chinh_phu_NHNN Tien_gui_vay_TCTD_khac Tien_gui_TCTD_khac_no Vay_TCTD_khac Tien_gui_khach_hang Cong_cu_tai_chinh_phai_sinh Von_tai_tro_uy_thac Phat_hanh_giay_to_co_gia Cac_khoan_no_phai_tra_khac Cac_khoan_lai_phi_phai_tra Cac_khoan_phai_tra_va_cong_no_khac Tong_cong_no_phai_tra Von_dieu_le Thang_du_von_co_phan LN_chua_phan_phoi Loi_ich_co_dong_khong_kiem_soat Tong_cong_von_chu_so_huu Tong_nguon_von Thu_nhap_lai_va_thu_nhap_tuong_tu Chi_phi_lai_va_chi_phi_tuong_tu Thu_nhap_lai_thuan Thu_nhap_hoat_dong_dich_vu Chi_phi_hoat_dong_dich_vu Lai_thuan_hoat_dong_dich_vu Lo_thuan_hoat_dong_ngoai_hoi Lai_thuan_mua_ban_CK_kinh_doanh Lai_thuan_mua_ban_CK_dau_tu Thu_nhap_hoat_dong_khac Chi_phi_hoat_dong_khac Lai_thuan_hoat_dong_khac Thu_nhap_gop_von_mua_co_phan Tong_thu_nhap_hoat_dong Chi_phi_nhan_vien Chi_phi_khau_hao Chi_phi_hoat_dong_khac_2 Tong_chi_phi_hoat_dong Lai_thuan_truoc_chi_phi_du_phong Chi_phi_du_phong_rui_ro_tin_dung LN_truoc_thue Chi_phi_thue_TNDN_hien_hanh Chi_phi_thue_TNDN_hoan_lai Tong_chi_phi_thue_TNDN LN_sau_thue Lai_co_ban_tren_co_phieu TSCD_hh_nguyen_gia_dau_nam TSCD_hh_mua_sam_trong_nam TSCD_hh_thanh_ly_nhuong_ban TSCD_hh_so_du_cuoi_nam QSD_dat_nguyen_gia_dau_nam QSD_dat_nguyen_gia_cuoi_nam PM_may_tinh_nguyen_gia_dau_nam PM_may_tinh_mua_trong_nam PM_may_tinh_nguyen_gia_cuoi_nam HM_luy_ke_QSD_dat HM_luy_ke_PM_may_tinh HM_luy_ke_tong GT_con_lai_QSD_dat GT_con_lai_PM_may_tinh GT_con_lai_tong
2015 1632425 850227 756702 25496 2261499 14599675 8729745 5870661 -731 2043647 2046735 -3088 115062473 116804247 -1741774 47729481 43950621 4520639 -741779 322511 322984 -473 509574 325013 184561 9687543 1985973 4133763 3799869 -232062 193876428 4821063 17764430 9603163 8161267 130270670 131760 383188 21859941 5256454 2804740 2451714 180487506 8056466 1288863 2718818 0 13388922 193876428 18758801 -8405364 10353437 1597313 -712646 884667 -290472 44587 27966 957363 -82291 875072 171054 12066311 -3183691 -144532 -2364246 -5692469 6373842 -3277640 3096202 -700598 264 -700334 2395868 3072 596927 144532 -36780 704679 213012 90132 224353 38543 248925 868 124575 125443 89264 95297 184561
2016 1727361 1036240 667059 24062 2982589 9388905 4089175 5300460 -731 2952206 2953769 -1563 142593251 144673213 -2089962 55339988 51948658 4136200 -744870 222930 299372 -76442 624197 422772 201425 12922329 5588814 4165577 3395320 -227382 228770918 1103686 28835898 13437105 15398793 123787572 191325 1389786 48650527 7634596 3161924 4472672 211593390 9181000 1288863 3757473 0 17177528 228770918 25631116 -10463257 15167859 2114834 -1261908 852926 -318960 -149384 91874 1450885 -232315 1218570 872 16863757 -3430934 -177433 -3012985 -6621352 10242405 -5313094 4929311 -994266 0 -994266 3935045 4485 704679 237985 -3802 939411 90132 69147 248925 71801 323702 868 153628 154496 68279 133146 201425
2017 2574284 1164862 1256907 152515 6460795 17520025 15218720 2302036 -731 1424854 1424854 0 179518809 182666213 -3147404 53558049 50384788 4151127 -977866 152506 194602 -42096 808486 457682 350804 15734506 8539528 3812015 3404366 -21403 277752314 26015 33200418 7834381 25366037 133550812 160469 3899364 66104605 11114921 5063166 6051755 248056604 15706230 5866105 4565110 0 29695710 277752314 34133371 -13518945 20614426 3210071 -1748527 1461544 -158842 179638 339477 3208782 -672502 2536280 53568 25026091 -5060266 -244832 -3589872 -8894970 16131121 -8001058 8130063 -1689296 0 -1689296 6440767 4564 939411 127420 -59962 1090758 69147 69147 323702 86996 410698 868 190556 191424 68279 220142 288421
2018 1855473 1227415 548625 79433 10828571 16571491 15337628 1233863 0 4202413 4240742 -38329 218395223 221961996 -3566773 51926416 49417157 3564933 -1055674 190654 227602 -36948 1963096 1385572 577524 17357782 10482282 4427765 2473219 -25484 323291119 3781343 75376645 54231451 21145194 170850871 18571 329649 48658036 15934060 10671129 5262931 288541050 25299680 3157796 2734328 0 34750069 323291119 40280214 -15578639 24701575 3818797 -2206301 1612496 -103750 -56821 250057 5363874 -682613 4681261 845 31085663 -6020762 -313939 -4299223 -10633924 20451739 -11253231 9198508 -1842940 0 -1842940 7355568 3025 1090758 93105 -13708 2211225 69147 69147 554079 25430 579509 868 271554 272422 68279 307955 376234
2019 2459321 1631328 658473 169520 3454138 20097553 15482986 4614567 0 1566592 1571141 -4549 253099865 257183959 -4084094 68729363 67786907 1094329 -151873 164425 238602 -74177 1922972 1342690 580282 25709897 16925460 6032377 2780703 -28643 377204126 19492 50867989 12144371 38723618 213949568 -45670 291823 57599723 20220119 7911819 12308300 342903044 25299680 692720 11805967 -195235 34301082 377204126 49874784 -19204323 30670461 5487466 -2695846 2791620 -216879 284845 803159 2682220 -662555 2019665 2634 36355505 -7327257 -373782 -4642679 -12343718 24011787 -13687626 10324161 -2063898 0 -2063898 8260263 3376 2211225 21222 -22489 2380108 69147 69147 890142 27000 917142 868 380897 381765 68279 536245 604524
2020 3282556 2145363 1110882 26311 5779610 19554808 13829025 5725783 0 493214 493214 0 286319402 290816086 -4496684 76485435 75959904 854344 -328813 238581 238602 -21 1862830 1212163 650667 24751811 17409351 5036836 2345902 -40278 419026527 14220 56511282 9371444 47139838 233427953 139825 187156 62845488 13107101 6452780 6654321 366233025 25299680 365727 11911768 17415364 52793502 419026527 52361767 -20015944 32345823 6166753 -2810626 3356127 -307207 226466 1170731 3441951 -1205790 2236161 5013 39033114 -6699495 -380432 -4312094 -11392021 27641093 -14621638 13019455 -2605695 0 -2605695 10413760 4271 2380108 23321 -56863 2398141 69147 65127 1033336 2213 1035549 868 521333 522201 64259 512216 576475
# Thao tác 2: Xem 6 dòng dữ liệu cuối cùng
knitr::kable(
  tail(df), 
  caption = "Bảng 2: Sáu dòng dữ liệu cuối cùng"
)
Bảng 2: Sáu dòng dữ liệu cuối cùng
Nam Tien_mat_vang_bac_da_quy Tien_mat_VND Tien_mat_ngoai_te Vang_tien_te Tien_gui_NHNN Tien_gui_cho_vay_TCTD_khac Tien_gui_TCTD_khac Cho_vay_TCTD_khac Du_phong_cho_vay_TCTD_khac CK_kinh_doanh CK_kinh_doanh_gop Du_phong_rui_ro_CK_kinh_doanh Cho_vay_khach_hang Cho_vay_khach_hang_gop Du_phong_rui_ro_cho_vay_khach_hang CK_dau_tu CK_dau_tu_san_sang_ban CK_dau_tu_giu_den_ngay_dao_han Du_phong_rui_ro_CK_dau_tu Gop_von_dau_tu_dai_han Dau_tu_dai_han_khac Du_phong_giam_gia_dau_tu_dai_han Tai_san_co_dinh TSCD_huu_hinh TSCD_vo_hinh Tai_san_Co_khac Cac_khoan_phai_thu Cac_khoan_lai_phi_phai_thu Tai_san_Co_khac_2 Du_phong_rui_ro_tai_san_Co_noi_bang_khac Tong_cong_tai_san No_Chinh_phu_NHNN Tien_gui_vay_TCTD_khac Tien_gui_TCTD_khac_no Vay_TCTD_khac Tien_gui_khach_hang Cong_cu_tai_chinh_phai_sinh Von_tai_tro_uy_thac Phat_hanh_giay_to_co_gia Cac_khoan_no_phai_tra_khac Cac_khoan_lai_phi_phai_tra Cac_khoan_phai_tra_va_cong_no_khac Tong_cong_no_phai_tra Von_dieu_le Thang_du_von_co_phan LN_chua_phan_phoi Loi_ich_co_dong_khong_kiem_soat Tong_cong_von_chu_so_huu Tong_nguon_von Thu_nhap_lai_va_thu_nhap_tuong_tu Chi_phi_lai_va_chi_phi_tuong_tu Thu_nhap_lai_thuan Thu_nhap_hoat_dong_dich_vu Chi_phi_hoat_dong_dich_vu Lai_thuan_hoat_dong_dich_vu Lo_thuan_hoat_dong_ngoai_hoi Lai_thuan_mua_ban_CK_kinh_doanh Lai_thuan_mua_ban_CK_dau_tu Thu_nhap_hoat_dong_khac Chi_phi_hoat_dong_khac Lai_thuan_hoat_dong_khac Thu_nhap_gop_von_mua_co_phan Tong_thu_nhap_hoat_dong Chi_phi_nhan_vien Chi_phi_khau_hao Chi_phi_hoat_dong_khac_2 Tong_chi_phi_hoat_dong Lai_thuan_truoc_chi_phi_du_phong Chi_phi_du_phong_rui_ro_tin_dung LN_truoc_thue Chi_phi_thue_TNDN_hien_hanh Chi_phi_thue_TNDN_hoan_lai Tong_chi_phi_thue_TNDN LN_sau_thue Lai_co_ban_tren_co_phieu TSCD_hh_nguyen_gia_dau_nam TSCD_hh_mua_sam_trong_nam TSCD_hh_thanh_ly_nhuong_ban TSCD_hh_so_du_cuoi_nam QSD_dat_nguyen_gia_dau_nam QSD_dat_nguyen_gia_cuoi_nam PM_may_tinh_nguyen_gia_dau_nam PM_may_tinh_mua_trong_nam PM_may_tinh_nguyen_gia_cuoi_nam HM_luy_ke_QSD_dat HM_luy_ke_PM_may_tinh HM_luy_ke_tong GT_con_lai_QSD_dat GT_con_lai_PM_may_tinh GT_con_lai_tong
2019 2459321 1631328 658473 169520 3454138 20097553 15482986 4614567 0 1566592 1571141 -4549 253099865 257183959 -4084094 68729363 67786907 1094329 -151873 164425 238602 -74177 1922972 1342690 580282 25709897 16925460 6032377 2780703 -28643 377204126 19492 50867989 12144371 38723618 213949568 -45670 291823 57599723 20220119 7911819 12308300 342903044 25299680 692720 11805967 -195235 34301082 377204126 49874784 -19204323 30670461 5487466 -2695846 2791620 -216879 284845 803159 2682220 -662555 2019665 2634 36355505 -7327257 -373782 -4642679 -12343718 24011787 -13687626 10324161 -2063898 0 -2063898 8260263 3376 2211225 21222 -22489 2380108 69147 69147 890142 27000 917142 868 380897 381765 68279 536245 604524
2020 3282556 2145363 1110882 26311 5779610 19554808 13829025 5725783 0 493214 493214 0 286319402 290816086 -4496684 76485435 75959904 854344 -328813 238581 238602 -21 1862830 1212163 650667 24751811 17409351 5036836 2345902 -40278 419026527 14220 56511282 9371444 47139838 233427953 139825 187156 62845488 13107101 6452780 6654321 366233025 25299680 365727 11911768 17415364 52793502 419026527 52361767 -20015944 32345823 6166753 -2810626 3356127 -307207 226466 1170731 3441951 -1205790 2236161 5013 39033114 -6699495 -380432 -4312094 -11392021 27641093 -14621638 13019455 -2605695 0 -2605695 10413760 4271 2380108 23321 -56863 2398141 69147 65127 1033336 2213 1035549 868 521333 522201 64259 512216 576475
2021 2345733 2041617 222998 81118 10860730 57104628 40329730 16858044 -83146 6970941 7005061 -34120 345390282 355281219 -9890937 75798431 75313521 722934 -238024 249710 249731 -21 1872973 1216957 656016 45754022 39015325 4897204 1893820 -52327 547409439 8454375 114619106 47106801 67512305 241837028 0 103930 81295633 14821220 5557507 9263713 461131292 45056930 77202 22439214 7906481 86278147 547409439 50827098 -16478269 34348829 6884061 -2825030 4059031 -76394 8879 3150866 5468704 -2660916 2807788 2476 44301475 -6230506 -379228 -4109203 -10718937 33582538 -19218768 14363770 -2886600 0 -2886600 11477170 2647 2398141 28287 -29302 2559025 65127 65127 1286591 11090 1297681 868 700183 701051 64259 597498 661757
2022 2658493 2315511 342564 418 9935379 47965493 40771879 7193614 0 7793447 7850639 -57192 424662382 438338047 -13675665 83075897 82718218 610279 -252600 189210 189210 0 1858126 1219108 639018 51981273 39409465 7879131 4205385 -79676 631012886 1929233 140249116 51325927 88923189 303151417 15369 47050 63699974 18418807 8596581 9813382 527510966 67434236 0 16751804 6664262 103501920 631012886 62200250 -21179192 41021058 10455695 -4017943 6437752 -618050 -149194 508755 13017039 -2433072 10583967 12801 57797089 8327741 366377 2378759 -14115731 43681358 -22461226 21220132 -4859848 548523 -4311325 16908807 2718 2559025 51643 -23088 2733537 65127 65127 1487276 54256 1541532 868 895519 896387 64259 646013 710272
2023 2284990 2076239 208662 89 8422511 94093778 83234756 73121895 -62262873 12325809 12406274 -80465 551472066 566271290 -14799224 94603526 87840241 6755260 -8025 0 0 0 1298099 1298099 0 42945668 33969441 8976228 0 0 817566922 4118311 156356651 83234756 73121895 442368381 392 22045 47787312 27118303 13812285 13306018 677771395 79339236 23992546 19065969 5164494 139795527 817566922 76557377 -38382701 38174676 12307787 -5095905 7211882 -805973 380173 250032 7774012 -3248461 4525551 3147 49739488 8609213 437800 2058837 -13941218 35798270 -24994374 10803896 -2984015 674290 -2309725 8494171 1433 2733537 69766 -28834 2994200 65127 65127 1644396 134526 1778922 868 1069637 1070505 64259 575285 639544
2024 2148289 1891475 228426 28388 14327215 134643662 126527280 8116382 0 13110971 13180721 -69750 676545598 692875738 -16330140 52783054 51857428 992927 -67301 189210 189210 0 2023899 1437082 586817 27275914 11411320 8384069 6547735 -263046 923847637 5713 201756421 111863209 89893212 485666548 28057 10894 66975704 22129038 10415008 11687513 776572375 79339236 23992546 24007579 5370287 147275262 923847637 80111645 -31031238 49080407 13201660 -7075337 6126323 827240 360956 469667 9559809 -4182147 5377662 12801 62255056 8395563 511641 1121013 -14339732 47915324 -27902624 20012700 -3962779 -63095 -4025874 15986826 1989 2994200 30611 21767 3406801 65127 65127 1843421 28685 1872106 868 1281978 1282846 64259 590128 654387
# Thao tác 5: Xem tóm tắt thống kê ban đầu
# Chọn 1 vài cột chính
cols_to_summary <- c("Nam", "Tong_cong_tai_san", "Cho_vay_khach_hang", 
                     "Tien_gui_khach_hang", "LN_sau_thue")

knitr::kable(
  summary(df[cols_to_summary]), 
  caption = "Bảng 3: Tóm tắt thống kê các cột tài chính chính"
)
Bảng 3: Tóm tắt thống kê các cột tài chính chính
Nam Tong_cong_tai_san Cho_vay_khach_hang Tien_gui_khach_hang LN_sau_thue
Min. :2015 Min. :193876428 Min. :115062473 Min. :123787572 Min. : 2395868
1st Qu.:2017 1st Qu.:289137015 1st Qu.:189237912 1st Qu.:142875827 1st Qu.: 6669467
Median :2020 Median :398115326 Median :269709634 Median :223688760 Median : 8377217
Mean :2020 Mean :473975832 Mean :319305935 Mean :247886082 Mean : 9166824
3rd Qu.:2022 3rd Qu.:610112024 3rd Qu.:404844357 3rd Qu.:287822820 3rd Qu.:11211318
Max. :2024 Max. :923847637 Max. :676545598 Max. :485666548 Max. :16908807
# Thao tác 9: Đếm số giá trị thiếu theo từng cột
na_counts_df <- data.frame(
  Ten_Cot = names(colSums(is.na(df))),
  So_luong_NA = colSums(is.na(df))
) %>% 
  filter(So_luong_NA > 0) # Lọc ra những cột CÓ NA
if (nrow(na_counts_df) > 0) {
  knitr::kable(
    na_counts_df, 
    caption = "Bảng 4: Các cột bị thiếu dữ liệu"
  )
} else {
  cat("Xác nhận: Không có cột nào bị thiếu dữ liệu.")
}
## Xác nhận: Không có cột nào bị thiếu dữ liệu.
# Tạo 1 data frame chứa tất cả thông tin
overview_stats <- data.frame(
  "Thông tin" = c("Kích thước (dòng, cột)",
                  "Tổng số giá trị thiếu (NA)",
                  "Kiểu dữ liệu cột 'Nam'",
                  "Số năm duy nhất"),
  "Giá trị" = c(paste(nrow(df), "dòng,", ncol(df), "cột"),
                sum(is.na(df)),
                class(df$Nam),
                n_distinct(df$Nam))
)

knitr::kable(
  overview_stats, 
  caption = "Bảng 5: Tóm tắt cấu trúc bộ dữ liệu"
)
Bảng 5: Tóm tắt cấu trúc bộ dữ liệu
Thông.tin Giá.trị
Kích thước (dòng, cột) 10 dòng, 91 cột
Tổng số giá trị thiếu (NA) 0
Kiểu dữ liệu cột ‘Nam’ numeric
Số năm duy nhất 10

4 BƯỚC 2: XỬ LÝ DỮ LIỆU VÀ TẠO BIẾN MỚI

df_clean <- df %>%
 mutate(Date = ymd(paste0(Nam, "-12-31"))) %>%
 rename(Loi_nhuan_ST = LN_sau_thue,
      Von_CSH = Tong_cong_von_chu_so_huu,
      Tong_tai_san = Tong_cong_tai_san,
      Cho_vay_KH = Cho_vay_khach_hang,
      Tien_gui_KH = Tien_gui_khach_hang,
      Thu_nhap_lai_thuan = Thu_nhap_lai_thuan) %>%
 mutate(Loi_nhuan_ST = ifelse(Nam %in% c(2017, 2019), NA, Loi_nhuan_ST)) %>%
 mutate(Loi_nhuan_ST = ifelse(is.na(Loi_nhuan_ST),
 mean(Loi_nhuan_ST, na.rm = TRUE),
 Loi_nhuan_ST)) %>%
 mutate(Tong_tai_san = ifelse(Nam == 2015, 9.99e14, Tong_tai_san)) %>%
 mutate(Tong_tai_san = ifelse(Tong_tai_san > 9e14,
      median(Tong_tai_san, na.rm = TRUE), # Thêm na.rm = TRUE
      Tong_tai_san)) %>%
 mutate(ROA = (Loi_nhuan_ST / Tong_tai_san) * 100) %>%
 mutate(ROE = (Loi_nhuan_ST / Von_CSH) * 100) %>%
 mutate(LDR = (Cho_vay_KH / Tien_gui_KH) * 100) %>%
 mutate(LN_Growth_YoY = ((Loi_nhuan_ST / lag(Loi_nhuan_ST)) - 1) * 100) %>%
 mutate(ROA_Category = case_when(
 ROA < 1.0 ~ "Thap",
 ROA >= 1.0 & ROA < 2.0 ~ "Trung binh",
 ROA >= 2.0 ~ "Cao"
 )) %>%
 arrange(Nam) %>%
 select(Nam, Date, Tong_tai_san, Loi_nhuan_ST, Cho_vay_KH, Tien_gui_KH,
      Von_CSH, Thu_nhap_lai_thuan, ROA, ROE, LDR, LN_Growth_YoY, ROA_Category)

# --- THAY THẾ glimpse() BẰNG kable() ---
# Thay vì in ra console, chúng ta tạo 1 bảng HTML đẹp
# Bảng này sẽ là thứ DUY NHẤT được hiển thị từ khối code này

knitr::kable(
  df_clean,
  caption = "Bảng 6: Dữ liệu đã làm sạch và tạo biến mới",
  digits = 2  # Làm tròn 2 chữ số thập phân cho đẹp
)
Bảng 6: Dữ liệu đã làm sạch và tạo biến mới
Nam Date Tong_tai_san Loi_nhuan_ST Cho_vay_KH Tien_gui_KH Von_CSH Thu_nhap_lai_thuan ROA ROE LDR LN_Growth_YoY ROA_Category
2015 2015-12-31 483217983 2395868 115062473 130270670 13388922 10353437 0.50 17.89 88.33 NA Thap
2016 2016-12-31 228770918 3935045 142593251 123787572 17177528 15167859 1.72 22.91 115.19 64.24 Trung binh
2017 2017-12-31 277752314 9620902 179518809 133550812 29695710 20614426 3.46 32.40 134.42 144.49 Cao
2018 2018-12-31 323291119 7355568 218395223 170850871 34750069 24701575 2.28 21.17 127.83 -23.55 Cao
2019 2019-12-31 377204126 9620902 253099865 213949568 34301082 30670461 2.55 28.05 118.30 30.80 Cao
2020 2020-12-31 419026527 10413760 286319402 233427953 52793502 32345823 2.49 19.73 122.66 8.24 Cao
2021 2021-12-31 547409439 11477170 345390282 241837028 86278147 34348829 2.10 13.30 142.82 10.21 Cao
2022 2022-12-31 631012886 16908807 424662382 303151417 103501920 41021058 2.68 16.34 140.08 47.33 Cao
2023 2023-12-31 817566922 8494171 551472066 442368381 139795527 38174676 1.04 6.08 124.66 -49.76 Trung binh
2024 2024-12-31 923847637 15986826 676545598 485666548 147275262 49080407 1.73 10.86 139.30 88.21 Trung binh

5 BƯỚC 3: THỐNG KÊ MÔ TẢ VÀ PHÂN TÍCH

cols_numeric <- c("Tong_tai_san", "Loi_nhuan_ST", "Cho_vay_KH", "Tien_gui_KH", "Von_CSH")
cols_ratios <- c("ROA", "ROE", "LDR")
cat("### Nhóm 1: Tóm tắt tổng quan\n\nThực hiện các thống kê mô tả cơ bản trên các biến số chính (đơn vị: VND).\n")
## ### Nhóm 1: Tóm tắt tổng quan
## 
## Thực hiện các thống kê mô tả cơ bản trên các biến số chính (đơn vị: VND).
# Thao tác 1: Tóm tắt 5 số (Summary)
knitr::kable(
  summary(df_clean[cols_numeric]), # <-- Giờ sẽ chạy đúng
  caption = "Bảng 7 (Thao tác 1): Tóm tắt 5 số (Min, Q1, Median, Mean, Q3, Max)",
  digits = 0 
)
Bảng 7 (Thao tác 1): Tóm tắt 5 số (Min, Q1, Median, Mean, Q3, Max)
Tong_tai_san Loi_nhuan_ST Cho_vay_KH Tien_gui_KH Von_CSH
Min. :228770918 Min. : 2395868 Min. :115062473 Min. :123787572 Min. : 13388922
1st Qu.:336769371 1st Qu.: 7640219 1st Qu.:189237912 1st Qu.:142875827 1st Qu.: 30847053
Median :451122255 Median : 9620902 Median :269709634 Median :223688760 Median : 43771786
Mean :502909987 Mean : 9620902 Mean :319305935 Mean :247886082 Mean : 65895767
3rd Qu.:610112024 3rd Qu.:11211318 3rd Qu.:404844357 3rd Qu.:287822820 3rd Qu.: 99195977
Max. :923847637 Max. :16908807 Max. :676545598 Max. :485666548 Max. :147275262
# --- 4. Thao tác 2, 3, 4, 5, 6: (Mean, Median, SD, Min, Max) ---
# Gộp 5 thao tác này vào MỘT bảng duy nhất
stats_combined <- rbind(
  "Trung bình (Mean)" = sapply(df_clean[cols_numeric], mean, na.rm = TRUE),
  "Trung vị (Median)" = sapply(df_clean[cols_numeric], median, na.rm = TRUE),
  "Độ lệch chuẩn (SD)" = sapply(df_clean[cols_numeric], sd, na.rm = TRUE),
  "Giá trị nhỏ nhất (Min)" = sapply(df_clean[cols_numeric], min, na.rm = TRUE),
  "Giá trị lớn nhất (Max)" = sapply(df_clean[cols_numeric], max, na.rm = TRUE)
)

kable(
  stats_combined,
  caption = "Bảng 8 (Thao tác 2-6): Tóm tắt các chỉ số thống kê chính",
  digits = 0
)
Bảng 8 (Thao tác 2-6): Tóm tắt các chỉ số thống kê chính
Tong_tai_san Loi_nhuan_ST Cho_vay_KH Tien_gui_KH Von_CSH
Trung bình (Mean) 502909987 9620902 319305935 247886082 65895767
Trung vị (Median) 451122255 9620902 269709634 223688760 43771786
Độ lệch chuẩn (SD) 229957813 4578261 183011595 127825963 49993654
Giá trị nhỏ nhất (Min) 228770918 2395868 115062473 123787572 13388922
Giá trị lớn nhất (Max) 923847637 16908807 676545598 485666548 147275262
# --- 5. In tiêu đề cho Nhóm 2 ---
cat("\n\n### Nhóm 2: Phân tích các chỉ số hiệu quả\n\nPhân tích các chỉ số tài chính đã được tạo ra ở Bước 2.\n")
## 
## 
## ### Nhóm 2: Phân tích các chỉ số hiệu quả
## 
## Phân tích các chỉ số tài chính đã được tạo ra ở Bước 2.
# --- 6. Thao tác 7: Tóm tắt các chỉ số (ROA, ROE, LDR) ---
kable(
  summary(df_clean[cols_ratios]),
  caption = "Bảng 9 (Thao tác 7): Tóm tắt các chỉ số hiệu quả (ROA, ROE, LDR)",
  digits = 2 # Giữ 2 chữ số thập phân
)
Bảng 9 (Thao tác 7): Tóm tắt các chỉ số hiệu quả (ROA, ROE, LDR)
ROA ROE LDR
Min. :0.4958 Min. : 6.076 Min. : 88.33
1st Qu.:1.7227 1st Qu.:14.061 1st Qu.:119.39
Median :2.1859 Median :18.810 Median :126.25
Mean :2.0536 Mean :18.871 Mean :125.36
3rd Qu.:2.5342 3rd Qu.:22.473 3rd Qu.:138.08
Max. :3.4638 Max. :32.398 Max. :142.82
# --- 7. Thao tác 8, 9, 10: Tìm các năm có giá trị cao nhất ---
# Gộp 3 thao tác vào MỘT bảng tóm tắt
summary_df_2 <- data.frame(
  "Chỉ số" = c("Năm có ROA cao nhất (Hiệu quả tài sản)",
               "Năm có ROE cao nhất (Hiệu quả vốn CSH)",
               "Năm có LDR cao nhất (Rủi ro thanh khoản)"),
  "Năm" = c(
    (df_clean %>% filter(ROA == max(ROA, na.rm = TRUE)))$Nam,
    (df_clean %>% filter(ROE == max(ROE, na.rm = TRUE)))$Nam,
    (df_clean %>% filter(LDR == max(LDR, na.rm = TRUE)))$Nam
  ),
  "Giá trị (%)" = c(
    max(df_clean$ROA, na.rm = TRUE),
    max(df_clean$ROE, na.rm = TRUE),
    max(df_clean$LDR, na.rm = TRUE)
  )
)

kable(
  summary_df_2,
  caption = "Bảng 10 (Thao tác 8-10): Các năm có giá trị chỉ số cao nhất",
  digits = 2
)
Bảng 10 (Thao tác 8-10): Các năm có giá trị chỉ số cao nhất
Chỉ.số Năm Giá.trị….
Năm có ROA cao nhất (Hiệu quả tài sản) 2017 3.46
Năm có ROE cao nhất (Hiệu quả vốn CSH) 2017 32.40
Năm có LDR cao nhất (Rủi ro thanh khoản) 2021 142.82
# --- 8. In tiêu đề cho Nhóm 3 ---
cat("\n\n### Nhóm 3: Phân tích tăng trưởng\n\nPhân tích tốc độ tăng trưởng qua các năm.\n")
## 
## 
## ### Nhóm 3: Phân tích tăng trưởng
## 
## Phân tích tốc độ tăng trưởng qua các năm.
# --- 9. Thao tác 11, 13, 14: Tính toán các chỉ số tăng trưởng ---
# Gộp 3 thao tác vào MỘT bảng tóm tắt
# Tính CAGR (2015-2024, 9 năm)
start_val_tts <- df_clean$Tong_tai_san[df_clean$Nam == 2015]
end_val_tts <- df_clean$Tong_tai_san[df_clean$Nam == 2024]
start_val_ln <- df_clean$Loi_nhuan_ST[df_clean$Nam == 2015]
end_val_ln <- df_clean$Loi_nhuan_ST[df_clean$Nam == 2024]
years <- 2024 - 2015

cagr_tts <- ((end_val_tts / start_val_tts)^(1/years) - 1) * 100
cagr_ln <- ((end_val_ln / start_val_ln)^(1/years) - 1) * 100
ln_growth_mean <- mean(df_clean$LN_Growth_YoY, na.rm = TRUE)

# Tạo data frame
growth_summary_df <- data.frame(
  "Chỉ số tăng trưởng" = c(
    "Tăng trưởng Lợi nhuận trung bình (YoY)",
    "CAGR Tổng Tài sản (2015-2024)",
    "CAGR Lợi nhuận ST (2015-2024)"
  ),
  "Giá trị (%)" = c(
    ln_growth_mean,
    cagr_tts,
    cagr_ln
  )
)

kable(
  growth_summary_df,
  caption = "Bảng 11 (Thao tác 11, 13, 14): Tóm tắt các chỉ số tăng trưởng",
  digits = 2
)
Bảng 11 (Thao tác 11, 13, 14): Tóm tắt các chỉ số tăng trưởng
Chỉ.số.tăng.trưởng Giá.trị….
Tăng trưởng Lợi nhuận trung bình (YoY) 35.58
CAGR Tổng Tài sản (2015-2024) 7.47
CAGR Lợi nhuận ST (2015-2024) 23.48
# --- 10. Thao tác 12: Năm có tăng trưởng lợi nhuận đột biến nhất ---
df_clean %>%
  filter(LN_Growth_YoY == max(LN_Growth_YoY, na.rm = TRUE)) %>%
  select(Nam, LN_Growth_YoY) %>%
  kable(
    caption = "Bảng 12 (Thao tác 12): Năm tăng trưởng Lợi nhuận đột biến nhất",
    digits = 2,
    col.names = c("Năm", "Tăng trưởng YoY (%)")
  )
Bảng 12 (Thao tác 12): Năm tăng trưởng Lợi nhuận đột biến nhất
Năm Tăng trưởng YoY (%)
2017 144.49
# --- 11. In tiêu đề cho Nhóm 4 ---
cat("\n\n### Nhóm 4: Phân tích tương quan và hồi quy\n\nKiểm tra mối quan hệ tuyến tính giữa các biến số.\n")
## 
## 
## ### Nhóm 4: Phân tích tương quan và hồi quy
## 
## Kiểm tra mối quan hệ tuyến tính giữa các biến số.
# --- 12. Thao tác 15: Ma trận tương quan ---
cor_matrix <- cor(df_clean[c(cols_numeric, cols_ratios)], use = "complete.obs")

kable(
  cor_matrix,
  caption = "Bảng 13 (Thao tác 15): Ma trận tương quan",
  digits = 3 # Giữ 3 chữ số thập phân
)
Bảng 13 (Thao tác 15): Ma trận tương quan
Tong_tai_san Loi_nhuan_ST Cho_vay_KH Tien_gui_KH Von_CSH ROA ROE LDR
Tong_tai_san 1.000 0.568 0.927 0.943 0.932 -0.401 -0.845 0.314
Loi_nhuan_ST 0.568 1.000 0.731 0.646 0.710 0.476 -0.265 0.824
Cho_vay_KH 0.927 0.731 1.000 0.989 0.981 -0.124 -0.735 0.574
Tien_gui_KH 0.943 0.646 0.989 1.000 0.968 -0.221 -0.767 0.462
Von_CSH 0.932 0.710 0.981 0.968 1.000 -0.152 -0.796 0.591
ROA -0.401 0.476 -0.124 -0.221 -0.152 1.000 0.638 0.614
ROE -0.845 -0.265 -0.735 -0.767 -0.796 0.638 1.000 -0.159
LDR 0.314 0.824 0.574 0.462 0.591 0.614 -0.159 1.000
# --- 13. Thao tác 17: Xây dựng mô hình Hồi quy Tuyến tính ---
# Dùng thư viện 'broom' (đã tải ở 'setup')
model <- lm(Loi_nhuan_ST ~ Tong_tai_san, data = df_clean)

# Bảng 1: Các hệ số (Beta, p-value...)
kable(
  tidy(model), # broom::tidy()
  caption = "Bảng 14a (Thao tác 17): Kết quả Hồi quy (Hệ số, p-value)",
  digits = 4
)
Bảng 14a (Thao tác 17): Kết quả Hồi quy (Hệ số, p-value)
term estimate std.error statistic p.value
(Intercept) 3932998.1523 3175581.4523 1.2385 0.2506
Tong_tai_san 0.0113 0.0058 1.9524 0.0867
# Bảng 2: Các chỉ số của mô hình (R-squared...)
kable(
  glance(model), # broom::glance()
  caption = "Bảng 14b (Thao tác 17): Kết quả Hồi quy (R-squared, F-stat)",
  digits = 4
)
Bảng 14b (Thao tác 17): Kết quả Hồi quy (R-squared, F-stat)
r.squared adj.r.squared sigma statistic p.value df logLik AIC BIC deviance df.residual nobs
0.3227 0.2381 3996341 3.8119 0.0867 1 -165.0826 336.1651 337.0729 1.277659e+14 8 10
# --- 14. Thao tác 16, 18, 19, 20: Trích xuất các giá trị đơn lẻ ---
# Gộp các giá trị này vào MỘT bảng tóm tắt
cor_val <- cor(df_clean$Tong_tai_san, df_clean$Loi_nhuan_ST, use = "complete.obs")
r_squared <- summary(model)$r.squared

regression_summary_df <- data.frame(
  "Chỉ số" = c(
    "Tương quan (r) (Tài sản vs Lợi nhuận)",
    "Hệ số chặn (Intercept - Beta 0)",
    "Hệ số góc (Slope - Beta 1)",
    "Hệ số R-squared"
  ),
  "Giá trị" = c(
    cor_val,
    coef(model)[1], # Beta 0
    coef(model)[2], # Beta 1
    r_squared
  )
)

kable(
  regression_summary_df,
  caption = "Bảng 15 (Thao tác 16, 18, 19, 20): Tóm tắt các chỉ số Tương quan & Hồi quy",
  digits = 5
)
Bảng 15 (Thao tác 16, 18, 19, 20): Tóm tắt các chỉ số Tương quan & Hồi quy
Chỉ.số Giá.trị
Tương quan (r) (Tài sản vs Lợi nhuận) 5.680800e-01
Hệ số chặn (Intercept - Beta 0) 3.932998e+06
Hệ số góc (Slope - Beta 1) 1.131000e-02
Hệ số R-squared 3.227200e-01

6 BƯỚC 4: TRỰC QUAN HÓA DỮ LIỆU (20 ĐỒ THỊ)

# --- Nhóm 1: Xu hướng (Time Series Plots) ---

# Đồ thị 1: Xu hướng Tổng tài sản qua các năm
p1 <- ggplot(df_clean, aes(x = Date, y = Tong_tai_san)) +
  geom_line(color = "darkblue", size = 1.2) +
  geom_point(color = "darkblue", size = 3) +
  geom_text(aes(label = round(Tong_tai_san / 1e9, 0)), vjust = -1, size = 3) + # vjust (vertical adjust)
  labs(title = "Đồ thị 1: Xu hướng Tổng Tài sản VPBank (2015-2024)",
       subtitle = "Đơn vị: Tỷ VND (làm tròn)",
       x = "Năm",
       y = "Tổng Tài sản (VND)") +
  scale_y_continuous(labels = scales::comma) +
  theme_minimal()
print(p1)

# Đồ thị 2: Xu hướng Lợi nhuận sau thuế qua các năm
p2 <- ggplot(df_clean, aes(x = Date, y = Loi_nhuan_ST)) +
  geom_line(color = "darkgreen", size = 1.2) +
  geom_point(color = "darkgreen", size = 3) +
  geom_text(aes(label = round(Loi_nhuan_ST / 1e9, 0)), vjust = -1, size = 3) +
  labs(title = "Đồ thị 2: Xu hướng Lợi nhuận sau thuế VPBank (2015-2024)",
       subtitle = "Đơn vị: Tỷ VND",
       x = "Năm",
       y = "Lợi nhuận sau thuế (VND)") +
  scale_y_continuous(labels = scales::comma) +
  theme_classic()
print(p2)

# Đồ thị 3: Xu hướng Vốn Chủ sở hữu
p3 <- ggplot(df_clean, aes(x = Nam, y = Von_CSH)) +
  geom_col(fill = "orange") + # Biểu đồ cột
  geom_text(aes(label = round(Von_CSH / 1e9, 0)), vjust = -0.5, size = 3) +
  labs(title = "Đồ thị 3: Tăng trưởng Vốn Chủ sở hữu (2015-2024)",
       x = "Năm",
       y = "Vốn Chủ sở hữu (VND)") +
  scale_y_continuous(labels = scales::comma) +
  theme_light()
print(p3)

# --- Nhóm 2: So sánh (Comparison Plots) ---

# Chuẩn bị dữ liệu cho biểu đồ 4 (Dạng "dài")
df_long_1 <- df_clean %>%
  select(Nam, Cho_vay_KH, Tien_gui_KH) %>%
  pivot_longer(cols = c("Cho_vay_KH", "Tien_gui_KH"),
               names_to = "Chi_tieu",
               values_to = "So_tien")

# Đồ thị 4: So sánh Cho vay và Tiền gửi (Biểu đồ cột nhóm)
p4 <- ggplot(df_long_1, aes(x = as.factor(Nam), y = So_tien, fill = Chi_tieu)) +
  geom_bar(stat = "identity", position = position_dodge()) +
  labs(title = "Đồ thị 4: So sánh Cho vay và Tiền gửi Khách hàng",
       x = "Năm",
       y = "Số tiền (VND)",
       fill = "Chỉ tiêu") +
  scale_y_continuous(labels = scales::comma) +
  scale_fill_manual(values = c("Cho_vay_KH" = "firebrick", "Tien_gui_KH" = "steelblue"),
                    labels = c("Cho vay KH", "Tiền gửi KH")) +
  theme_bw()
print(p4)

# Đồ thị 5: Tỷ lệ LDR (Cho vay / Tiền gửi) qua các năm
p5 <- ggplot(df_clean, aes(x = Date, y = LDR)) +
  geom_line(color = "purple", size = 1.2) +
  geom_point(color = "purple", size = 3) +
  geom_hline(yintercept = 80, linetype = "dashed", color = "red") + # Thêm đường tham chiếu
  annotate("text", x = ymd("2016-01-01"), y = 82, label = "Ngưỡng rủi ro (80%)", color = "red") +
  labs(title = "Đồ thị 5: Tỷ lệ Cho vay / Tiền gửi (LDR)",
       subtitle = "LDR cho thấy rủi ro thanh khoản của ngân hàng",
       x = "Năm",
       y = "Tỷ lệ LDR (%)") +
  theme_minimal()
print(p5)

# --- Nhóm 3: Chỉ số Hiệu quả (Ratio Plots) ---

# Chuẩn bị dữ liệu cho biểu đồ 6
df_long_2 <- df_clean %>%
  select(Nam, ROA, ROE) %>%
  pivot_longer(cols = c("ROA", "ROE"),
               names_to = "Chi_so",
               values_to = "Gia_tri")

# Đồ thị 6: So sánh ROA và ROE qua các năm
p6 <- ggplot(df_long_2, aes(x = as.factor(Nam), y = Gia_tri, group = Chi_so, color = Chi_so)) +
  geom_line(size = 1.5) +
  geom_point(size = 3) +
  labs(title = "Đồ thị 6: Phân tích Hiệu quả (ROA vs ROE)",
       x = "Năm",
       y = "Tỷ lệ (%)",
       color = "Chỉ số") +
  scale_color_manual(values = c("ROA" = "darkcyan", "ROE" = "darkorange")) +
  theme_minimal()
print(p6)

# Đồ thị 7: Tăng trưởng Lợi nhuận (YoY)
# Loại bỏ NA của năm 2015 để vẽ
p7 <- ggplot(df_clean %>% filter(!is.na(LN_Growth_YoY)), aes(x = as.factor(Nam), y = LN_Growth_YoY)) +
  geom_col(aes(fill = LN_Growth_YoY > 0)) + # Tô màu khác nhau cho Âm/Dương
  geom_hline(yintercept = 0, color = "black") +
  labs(title = "Đồ thị 7: Tăng trưởng Lợi nhuận (So với năm trước)",
       x = "Năm",
       y = "Tăng trưởng (%)") +
  scale_fill_manual(values = c("TRUE" = "seagreen", "FALSE" = "tomato"),
                    guide = "none") + # Ẩn chú thích
  theme_light()
print(p7)

# --- Nhóm 4: Phân tích Mối quan hệ (Relationship Plots) ---

# Đồ thị 8: Tương quan Tài sản và Lợi nhuận (Scatter Plot)
p8 <- ggplot(df_clean, aes(x = Tong_tai_san, y = Loi_nhuan_ST)) +
  geom_point(color = "blue", size = 4, alpha = 0.7) +
  geom_smooth(method = "lm", color = "red", se = FALSE) + # Thêm đường hồi quy (lm)
  labs(title = "Đồ thị 8: Mối quan hệ Tổng Tài sản và Lợi nhuận",
       x = "Tổng Tài sản (VND)",
       y = "Lợi nhuận sau thuế (VND)") +
  scale_x_continuous(labels = scales::comma) +
  scale_y_continuous(labels = scales::comma) +
  theme_minimal()
print(p8)

# Đồ thị 9: Ma trận tương quan (Heatmap)
# (Yêu cầu thư viện ggcorrplot)
p9 <- ggcorrplot(cor_matrix,
                 method = "circle", # Hiển thị bằng hình tròn
                 lab = TRUE, # Hiển thị hệ số
                 lab_size = 3,
                 colors = c("red", "white", "blue")) + # Màu sắc
  labs(title = "Đồ thị 9: Ma trận Tương quan các Biến số chính")
print(p9)

# Đồ thị 10: Tương quan Vốn CSH và Lợi nhuận
p10 <- ggplot(df_clean, aes(x = Von_CSH, y = Loi_nhuan_ST)) +
  geom_point(aes(size = ROA), color = "purple") + # Kích thước điểm là ROA
  geom_smooth(method = "lm", color = "black", linetype = "dashed") +
  labs(title = "Đồ thị 10: Mối quan hệ Vốn CSH và Lợi nhuận",
       subtitle = "Kích thước điểm thể hiện ROA",
       x = "Vốn Chủ sở hữu (VND)",
       y = "Lợi nhuận sau thuế (VND)",
       size = "ROA (%)") +
  scale_x_continuous(labels = scales::comma) +
  scale_y_continuous(labels = scales::comma) +
  theme_bw()
print(p10)

# --- Nhóm 5: Phân phối (Distribution Plots) ---

# Đồ thị 11: Phân phối của ROA (Histogram)
p11 <- ggplot(df_clean, aes(x = ROA)) +
  geom_histogram(binwidth = 0.2, fill = "cyan", color = "black", alpha = 0.8) +
  geom_vline(aes(xintercept = mean(ROA)), color = "red", linetype = "dashed", size = 1) +
  annotate("text", x = mean(df_clean$ROA) * 1.1, y = 3,
           label = paste("Mean =", round(mean(df_clean$ROA), 2)), color = "red") +
  labs(title = "Đồ thị 11: Phân phối của chỉ số ROA (2015-2024)",
       x = "ROA (%)",
       y = "Số lượng (Số năm)") +
  theme_classic()
print(p11)

# Đồ thị 12: Phân phối của ROE (Density Plot)
p12 <- ggplot(df_clean, aes(x = ROE)) +
  geom_density(fill = "orange", alpha = 0.7) +
  geom_vline(aes(xintercept = median(ROE)), color = "blue", size = 1) +
  labs(title = "Đồ thị 12: Phân phối (Mật độ) của chỉ số ROE",
       x = "ROE (%)",
       y = "Mật độ") +
  theme_minimal()
print(p12)

# Đồ thị 13: Boxplot (Biểu đồ Hộp) cho ROA theo Phân loại
p13 <- ggplot(df_clean, aes(x = ROA_Category, y = ROA, fill = ROA_Category)) +
  geom_boxplot() +
  geom_jitter(width = 0.1, alpha = 0.5) + # Thêm các điểm dữ liệu
  labs(title = "Đồ thị 13: Phân phối ROA theo Nhóm",
       x = "Phân loại ROA",
       y = "ROA (%)",
       fill = "Phân loại") +
  theme_light()
print(p13)

# Đồ thị 14: Boxplot cho LDR
p14 <- ggplot(df_clean, aes(y = LDR)) +
  geom_boxplot(fill = "lightblue") +
  labs(title = "Đồ thị 14: Phân phối Tỷ lệ LDR (2015-2024)",
       y = "LDR (%)") +
  coord_flip() + # Xoay ngang biểu đồ
  theme_bw()
print(p14)

# --- Nhóm 6: Biểu đồ kết hợp & khác ---

# Đồ thị 15: Thu nhập lãi thuần (Bar plot)
p15 <- ggplot(df_clean, aes(x = Nam, y = Thu_nhap_lai_thuan)) +
  geom_bar(stat = "identity", fill = "brown") +
  labs(title = "Đồ thị 15: Thu nhập Lãi thuần (NIM)",
       x = "Năm",
       y = "Thu nhập Lãi thuần (VND)") +
  scale_y_continuous(labels = scales::comma) +
  scale_x_continuous(breaks = df_clean$Nam) + # Đảm bảo hiện đủ các năm
  theme_minimal()
print(p15)

# Đồ thị 16: Biểu đồ "Kẹo mút" (Lollipop) cho ROE
p16 <- ggplot(df_clean, aes(x = as.factor(Nam), y = ROE)) +
  geom_segment(aes(x = as.factor(Nam), xend = as.factor(Nam), y = 0, yend = ROE), color = "grey") +
  geom_point(color = "darkgreen", size = 4) +
  labs(title = "Đồ thị 16: Hiệu quả Vốn CSH (ROE) qua các năm",
       x = "Năm",
       y = "ROE (%)") +
  theme_light() +
  coord_flip() # Xoay ngang
print(p16)

# Đồ thị 17: Biểu đồ Diện tích (Area Chart) - Vốn CSH
p17 <- ggplot(df_clean, aes(x = Date, y = Von_CSH)) +
  geom_area(fill = "cadetblue", alpha = 0.8) +
  geom_line(color = "black") +
  labs(title = "Đồ thị 17: Tăng trưởng Vốn CSH (Biểu đồ Diện tích)",
       x = "Năm",
       y = "Vốn CSH (VND)") +
  scale_y_continuous(labels = scales::comma) +
  theme_minimal()
print(p17)

# Đồ thị 18: Biểu đồ tròn (Pie Chart) - (Giả định) Tỷ trọng 3 năm gần nhất
# Biểu đồ tròn không tốt cho chuỗi thời gian, nhưng dùng để minh họa
df_pie <- df_clean %>%
  filter(Nam %in% c(2022, 2023, 2024)) %>%
  mutate(Ty_trong = Loi_nhuan_ST / sum(Loi_nhuan_ST))

p18 <- ggplot(df_pie, aes(x = "", y = Ty_trong, fill = as.factor(Nam))) +
  geom_bar(stat = "identity", width = 1) +
  coord_polar("y", start = 0) + # Chuyển thành tọa độ cực
  geom_text(aes(label = scales::percent(Ty_trong)),
            position = position_stack(vjust = 0.5)) +
  labs(title = "Đồ thị 18: Tỷ trọng Lợi nhuận (3 năm gần nhất)",
       fill = "Năm", x = NULL, y = NULL) +
  theme_void() # Xóa toàn bộ trục và nền
print(p18)

# Đồ thị 19: Scatter plot Lợi nhuận vs Cho vay
p19 <- ggplot(df_clean, aes(x = Cho_vay_KH, y = Loi_nhuan_ST)) +
  geom_point(aes(color = as.factor(Nam)), size = 3) + # Tô màu theo năm
  geom_smooth(method = "lm", se = FALSE, color = "black") +
  labs(title = "Đồ thị 19: Lợi nhuận vs. Hoạt động Cho vay",
       x = "Cho vay Khách hàng",
       y = "Lợi nhuận sau thuế",
       color = "Năm") +
  scale_x_continuous(labels = scales::comma) +
  scale_y_continuous(labels = scales::comma) +
  theme_minimal()
print(p19)

# Đồ thị 20: Biểu đồ kết hợp Line + Bar (Dual-axis)
# Trục 1: Tổng tài sản (Cột)
# Trục 2: ROA (Đường)
# Cần điều chỉnh tỷ lệ 2 trục
coeff <- max(df_clean$Tong_tai_san) / max(df_clean$ROA)

p20 <- ggplot(df_clean, aes(x = Date)) +
  geom_col(aes(y = Tong_tai_san), fill = "lightblue", alpha = 0.7) +
  geom_line(aes(y = ROA * coeff), color = "red", size = 1.5) +
  labs(title = "Đồ thị 20: Quy mô (Tài sản) vs Hiệu quả (ROA)",
       x = "Năm",
       y = "Tổng Tài sản (Trục trái)") +
  scale_y_continuous(
    labels = scales::comma,
    # Trục thứ 2
    sec.axis = sec_axis(~ . / coeff, name = "ROA (%) (Trục phải)")
  ) +
  theme_bw() +
  theme(axis.title.y.right = element_text(color = "red"),
        axis.text.y.right = element_text(color = "red"))
print(p20)

Nhóm 1: Xu hướng

  • Đồ thị 1 (Line Plot - Tổng tài sản):

  • Kỹ thuật: geom_line + geom_point + geom_text (hiển thị số liệu).

  • Ý nghĩa: Trực quan hóa tốc độ tăng trưởng quy mô của VPBank. Cho thấy sự tăng trưởng ổn định và mạnh mẽ qua 10 năm.

  • Đồ thị 2 (Line Plot - Lợi nhuận):

  • Kỹ thuật: Tương tự Đồ thị 1, nhưng đổi màu và dùng theme_classic.

  • Ý nghĩa: Trực quan hóa sự tăng trưởng về lợi nhuận. Có thể thấy những năm tăng trưởng nóng hoặc chững lại.

  • Đồ thị 3 (Bar Plot - Vốn CSH):

  • Kỹ thuật: geom_col (biểu đồ cột) thể hiện giá trị tuyệt đối.

  • Ý nghĩa: Cho thấy sự dày lên của “bộ đệm” vốn chủ sở hữu, thể hiện sức khỏe tài chính và khả năng hấp thụ rủi ro.

Nhóm 2: So sánh

  • Đồ thị 4 (Grouped Bar - Cho vay với Tiền gửi):

  • Kỹ thuật: Yêu cầu pivot_longer để đưa dữ liệu về dạng dài. Dùng geom_bar(position = “dodge”) để đặt các cột cạnh nhau.

  • Ý nghĩa: So sánh trực tiếp 2 hoạt động cốt lõi. Ta có thể thấy VPBank thường cho vay ra nhiều hơn (cột đỏ cao hơn) hay huy động được nhiều hơn (cột xanh cao hơn).

  • Đồ thị 5 (Line Plot - LDR):

  • Kỹ thuật: geom_line + geom_hline (vẽ đường tham chiếu 80%) + annotate (thêm chữ).

  • Ý nghĩa: Phân tích rủi ro thanh khoản. Những năm nào LDR vượt ngưỡng (nếu có) là những năm đáng báo động.

Nhóm 3: Chỉ số Hiệu quả

  • Đồ thị 6 (Multi-line Plot - ROA vs ROE):

  • Kỹ thuật: Dùng pivot_longer và aes(group = Chi_so, color = Chi_so) để vẽ 2 đường trên cùng 1 biểu đồ.

  • Ý nghĩa: So sánh hiệu quả sử dụng tài sản (ROA) và vốn CSH (ROE). Khoảng cách giữa ROE và ROA thể hiện đòn bẩy tài chính.

  • Đồ thị 7 (Bar Plot - Tăng trưởng LN):

  • Kỹ thuật: geom_col với aes(fill = LN_Growth_YoY > 0) để tự động tô màu âm/dương.

  • Ý nghĩa: Hiển thị rõ những năm tăng trưởng bùng nổ (cột xanh lá) và những năm sụt giảm (cột đỏ).

Nhóm 4: Mối quan hệ

  • Đồ thị 8 (Scatter Plot - Tài sản vs LN):

  • Kỹ thuật: geom_point + geom_smooth(method = “lm”) (vẽ đường hồi quy).

  • Ý nghĩa: Xác nhận kết quả của Phân tích Hồi quy (Mục 3). Các điểm bám sát đường thẳng cho thấy mối quan hệ tuyến tính rất chặt chẽ (R^2 cao).

  • Đồ thị 9 (Heatmap - Tương quan):

  • Kỹ thuật: Dùng gói ggcorrplot để vẽ ma trận tương quan đã tính ở Bước 3.

  • Ý nghĩa: Cho cái nhìn tổng quan về tất cả các mối quan hệ. Màu xanh (đồng biến), màu đỏ (nghịch biến). Kích thước vòng tròn/số thể hiện độ mạnh.

  • Đồ thị 10 (Bubble Plot - Vốn CSH vs LN):

  • Kỹ thuật: geom_point(aes(size = ROA)) tạo ra biểu đồ bong bóng.

  • Ý nghĩa: Biểu đồ 3 chiều. Trục X (Vốn CSH), Trục Y (Lợi nhuận), Kích thước bong bóng (ROA). Cho thấy liệu việc tăng vốn CSH có đi kèm tăng lợi nhuận và tăng hiệu quả (bong bóng to) không.

Nhóm 5: Phân phối

  • Đồ thị 11 (Histogram - Phân phối ROA):

  • Kỹ thuật: geom_histogram (đếm tần suất) + geom_vline (vẽ đường trung bình).

  • Ý nghĩa: Cho thấy ROA của VPBank thường rơi vào khoảng nào nhất. Dữ liệu có phân phối chuẩn không?

  • Đồ thị 12 (Density Plot - Phân phối ROE):

  • Kỹ thuật: geom_density (phiên bản mượt hơn của histogram).

  • Ý nghĩa: Tương tự histogram, cho thấy hình dạng phân phối của ROE.

  • Đồ thị 13 (Box Plot - ROA theo Nhóm):

  • Kỹ thuật: geom_boxplot (vẽ biểu đồ hộp) + geom_jitter (hiển thị các điểm dữ liệu thực tế).

  • Ý nghĩa: Thể hiện 5 giá trị (Min, Q1, Median, Q3, Max) cho từng nhóm (“Cao”, “Thap”, “Trung binh”).

  • Đồ thị 14 (Box Plot - LDR):

  • Kỹ thuật: geom_boxplot + coord_flip (xoay ngang).

  • Ý nghĩa: Tóm tắt toàn bộ 10 năm LDR vào 1 hình. Cho thấy trung vị, khoảng tứ phân vị và các giá trị ngoại lai (nếu có).

Nhóm 6: Biểu đồ kết hợp & khác

  • Đồ thị 15 (Bar Plot - Thu nhập lãi thuần):

  • Kỹ thuật: geom_bar(stat=“identity”) (giống geom_col).

  • Ý nghĩa: Trực quan hóa nguồn thu chính của ngân hàng (chênh lệch giữa lãi cho vay và lãi tiền gửi).

  • Đồ thị 16 (Lollipop Plot - ROE):

  • Kỹ thuật: geom_segment + geom_point.

  • Ý nghĩa: Một giải pháp thay thế đẹp mắt cho biểu đồ cột, giúp so sánh ROE các năm.

  • Đồ thị 17 (Area Chart - Vốn CSH):

  • Kỹ thuật: geom_area (tô màu khu vực dưới đường line).

  • Ý nghĩa: Nhấn mạnh sự “tích lũy” và “tăng trưởng” về quy mô Vốn CSH qua thời gian.

  • Đồ thị 18 (Pie Chart - Tỷ trọng LN):

  • Kỹ thuật: geom_bar + coord_polar(“y”) (biến biểu đồ cột chồng thành biểu đồ tròn).

  • Ý nghĩa: (Chỉ mang tính minh họa) Cho thấy tỷ trọng lợi nhuận của 3 năm 2022, 2023, 2024 trong tổng lợi nhuận 3 năm đó.

  • Đồ thị 19 (Scatter Plot - LN vs Cho vay):

  • Kỹ thuật: geom_point(aes(color = as.factor(Nam))).

  • Ý nghĩa: Cho thấy mối quan hệ giữa hoạt động cho vay và lợi nhuận. Việc tô màu theo năm giúp thấy “sự tiến hóa” (ví dụ: các năm gần đây nằm ở góc trên bên phải).

  • Đồ thị 20 (Dual-Axis Plot - Tài sản vs ROA):

  • Kỹ thuật: Kỹ thuật phức tạp, dùng sec_axis (trục thứ 2) và coeff (hệ số điều chỉnh).

  • Ý nghĩa: Trả lời câu hỏi: “Quy mô tăng (cột xanh, trục trái) có đi kèm với hiệu quả tăng (đường đỏ, trục phải) không?”.