CHƯƠNG 1: PHÂN TÍCH HOẠT ĐỘNG KINH DOANH CỦA MỘT CÔNG TY BÁN LẺ XE ĐẠP

Giới thiệu

Trong bối cảnh thị trường cạnh tranh ngày càng gay gắt, việc phân tích dữ liệu kinh doanh đóng vai trò then chốt giúp doanh nghiệp thấu hiểu khách hàng, tối ưu hóa hoạt động và đưa ra các quyết định chiến lược đúng đắn. Bài tiểu luận này sẽ thực hiện một quy trình phân tích toàn diện trên bộ dữ liệu giả định về hoạt động bán xe đạp của một chuỗi cửa hàng trong giai đoạn từ 2022 đến 2024. Cấu trúc bài tiểu luận bao gồm 4 phần chính:

1. Giới thiệu bộ dữ liệu: Khám phá cấu trúc và các đặc điểm ban đầu của dữ liệu.

2. Xử lý và làm sạch dữ liệu: Chuẩn bị dữ liệu cho quá trình phân tích, bao gồm việc tạo các biến mới, xử lý các vấn đề tiềm ẩn và mã hóa dữ liệu.

3. Thống kê cơ bản: Thực hiện các phép tính thống kê mô tả để trả lời các câu hỏi kinh doanh cụ thể.

4. Trực quan hóa dữ liệu: Sử dụng các biểu đồ đa dạng để minh họa các kết quả phân tích một cách sinh động và dễ hiểu.

Toàn bộ quá trình phân tích sẽ được thực hiện bằng ngôn ngữ lập trình R, một công cụ mạnh mẽ trong lĩnh vực khoa học dữ liệu.

1. Tổng quan dữ liệu

Bước đầu tiên trong mọi dự án phân tích là làm quen với bộ dữ liệu. Chúng ta cần hiểu rõ về cấu trúc, ý nghĩa của từng cột và các đặc điểm cơ bản của dữ liệu.

1.1 Giới thiệu dữ liệu

Bộ dữ liệu “Bike Sales 100K” được nhóm tác giả thu thập từ nền tảng Kaggle. Đây là bộ dữ liệu mô phỏng hoạt động kinh doanh trong lĩnh vực bán lẻ xe đạp, được thiết kế nhằm phục vụ cho mục đích học tập, nghiên cứu và thực hành phân tích dữ liệu.

Dữ liệu bao gồm khoảng 100.000 quan sát và 11 biến, mỗi quan sát tương ứng với một giao dịch mua xe đạp của khách hàng. Các biến có thể được phân loại thành biến định tính và biến định lượng nhằm phục vụ cho các phân tích thống kê và mô hình hóa.

1.2 Nạp các gói thư viện cần thiết

library(readr)
library(dplyr)
library(tidyr)
library(zoo)
library(lubridate)
library(knitr)
library(kableExtra)
library(ggplot2)
library(scales)
library(ggridges)
library(treemapify)
library(ggalluvial)
library(fmsb)
library(corrplot)
library(ggrepel)
library(e1071)
library(moments)

Nhóm 1: Xử lý và Thao tác Dữ liệu

  • readr: Cung cấp các hàm để đọc và ghi dữ liệu dạng văn bản (như file .csv, .tsv) một cách nhanh chóng và hiệu quả, tối ưu hơn so với các hàm cơ bản của R.

  • dplyr: Là thư viện nền tảng cho việc thao tác dữ liệu theo triết lý “ngữ pháp của thao tác dữ liệu”. Nó cung cấp một bộ các hàm (động từ) nhất quán và hiệu suất cao như mutate(), select(), filter(), summarise(), và group_by() để thực hiện các tác vụ biến đổi và tóm tắt dữ liệu một cách logic.

  • tidyr: Chuyên về việc “dọn dẹp” và tái cấu trúc bố cục dữ liệu. Các hàm chính như pivot_longer() và pivot_wider() giúp chuyển đổi linh hoạt giữa định dạng dữ liệu dạng rộng (wide) và dạng dài (long), một bước tiền xử lý quan trọng cho nhiều loại phân tích và trực quan hóa.

  • lubridate: Giúp việc xử lý các đối tượng ngày tháng và thời gian (date/time) trở nên đơn giản và nhất quán. Thư viện này cho phép dễ dàng trích xuất các thành phần như năm, tháng, ngày, thứ, hoặc thực hiện các phép tính khoảng thời gian.

  • zoo: Là một thư viện mạnh mẽ cho việc làm việc với dữ liệu chuỗi thời gian (time series). Trong bài tiểu luận, thư viện này được sử dụng cho hàm rollmean() để tính trung bình động (moving average), một kỹ thuật hữu ích để làm mượt và nhận diện xu hướng dài hạn của dữ liệu.

Nhóm 2: Trình bày Báo cáo và Bảng biểu

  • knitr: Là công cụ cốt lõi để tạo ra các báo cáo động từ R Markdown. Nó cho phép kết hợp mã R, kết quả thực thi (văn bản, bảng biểu, biểu đồ) và văn bản tường thuật vào một tài liệu duy nhất, sau đó biên dịch (knit) thành các định dạng đầu ra như PDF hoặc HTML.

  • kableExtra: Mở rộng khả năng của hàm knitr::kable(), cung cấp các công cụ để tạo ra các bảng biểu có tính thẩm mỹ cao và chuyên nghiệp. Nó cho phép tùy chỉnh định dạng nâng cao như tạo sọc, nhóm hàng/cột, định dạng có điều kiện và thêm thanh cuộn cho bảng lớn.

Nhóm 3: Trực quan hóa Dữ liệu (Vẽ biểu đồ)

  • ggplot2: Là thư viện trực quan hóa dữ liệu mạnh mẽ và phổ biến nhất trong R, được xây dựng dựa trên triết lý “Ngữ pháp của Đồ thị” (Grammar of Graphics). Nó cho phép người dùng xây dựng các biểu đồ phức tạp từng lớp một cách linh hoạt.

  • scales: Cung cấp các công cụ để kiểm soát việc ánh xạ dữ liệu sang các thuộc tính thẩm mỹ. Thường được dùng cùng ggplot2 để định dạng lại các nhãn trên trục và chú giải (ví dụ: định dạng tiền tệ $, phần trăm %, hay ngày tháng).

  • corrplot: Chuyên dùng để trực quan hóa ma trận tương quan (correlogram). Nó cung cấp nhiều phương pháp hiển thị hệ số tương quan (dưới dạng số, màu sắc, hình tròn,…) giúp dễ dàng nhận diện mối quan hệ giữa các biến số.

  • treemapify: Vẽ biểu đồ dạng Treemap, giúp hiển thị dữ liệu có cấu trúc phân cấp dưới dạng các hình chữ nhật lồng nhau.

  • ggridges: Vẽ biểu đồ mật độ dạng “dãy núi” (Ridgeline plots), rất hữu ích để so sánh sự phân bố của dữ liệu giữa nhiều nhóm khác nhau.

  • ggalluvial: Vẽ biểu đồ Alluvial và Sankey, dùng để minh họa “dòng chảy” của dữ liệu từ nhóm này sang nhóm khác.

  • fmsb: Dùng để vẽ các loại biểu đồ ít phổ biến hơn như biểu đồ radar (biểu đồ mạng nhện).

  • ggrepel: Là một phần mở rộng của ggplot2, cung cấp các hàm geom_text_repel() và geom_label_repel() để tự động điều chỉnh vị trí của các nhãn văn bản trên biểu đồ, tránh cho chúng bị chồng chéo lên nhau.

Nhóm 4: Thống kê

  • moments/e1071: Cả hai thư viện đều cung cấp các hàm để tính toán các chỉ số thống kê mô tả nâng cao, đặc biệt là các moments của một phân phối, như độ xiên (Skewness) và độ nhọn (Kurtosis), giúp đánh giá hình dạng phân phối của dữ liệu.

1.3 Nạp dữ liệu vào R

BK <- read_csv("C:/Users/DELL/Downloads/bike_sales_100k.csv")

Sau khi cài đặt và kích hoạt các gói. Dữ liệu sẽ được đọc vào được lưu dưới tên BK để tiện thao tác trong quá trình xử lý.

1.4 Hiển thị 10 dòng đầu tiên

# Hiển thị 10 dòng đầu tiên
head(BK, 10) %>%
  kable("latex", booktabs = TRUE, caption = "10 dòng đầu tiên của bộ dữ liệu") %>%
  kable_styling(
    latex_options = c("hold_position", "striped", "scale_down"),
    position = "center",
    font_size = 9
  )

Giải thích code:

  • head(BK, 10): Lệnh này có nghĩa là “Lấy ra 10 dòng đầu tiên của bộ dữ liệu có tên là BK”.

  • %>%: Dấu này được gọi là “pipe” (đường ống). Nó có tác dụng lấy kết quả của lệnh bên trái (tức là 10 dòng dữ liệu) và “đẩy” nó sang cho lệnh bên phải xử lý tiếp.

  • kable(…): Lệnh này nhận 10 dòng dữ liệu từ bước 1 và biến nó thành một cái bảng. Đây là bước “tạo khung sản phẩm”.

    • “latex”: Chỉ định rằng bảng này sẽ được tạo ra để hiển thị trong file PDF (LaTeX là công nghệ nền tảng để tạo file PDF trong R Markdown).

    • booktabs = TRUE: Làm cho các đường kẻ ngang của bảng trông đẹp và chuyên nghiệp hơn, theo một phong cách thường thấy trong sách và báo cáo học thuật.

    • caption = “…”: Thêm một tiêu đề (chú thích) cho bảng, ở đây là “10 dòng đầu tiên của bộ dữ liệu”.

    • %>%: Lại là “đường ống”, nó lấy cái bảng vừa được tạo khung và đẩy sang bước cuối cùng để trang trí.

  • kable_styling(…): Lệnh này nhận cái bảng từ bước 2 và áp dụng các tùy chỉnh định dạng để nó trông đẹp hơn. Đây là bước “trang trí hoàn thiện”.

    • latex_options = c(…): Đây là một nhóm các tùy chọn dành riêng cho file PDF.

    • “hold_position”: Cố gắng giữ bảng ở đúng vị trí bạn đặt nó trong code, không để nó tự động “trôi” đi chỗ khác.

    • “striped”: Tạo hiệu ứng sọc (tô màu xen kẽ các dòng) để người đọc dễ theo dõi dữ liệu hơn.

    • “scale_down”: Nếu bảng quá rộng so với trang giấy, nó sẽ tự động thu nhỏ lại cho vừa.

    • position = “center”: Căn chỉnh cho cả cái bảng nằm ở giữa trang.

    • font_size = 9: Thiết lập cỡ chữ bên trong bảng là 9pt.

1.5 Khám phá dữ liệu

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

cat("Số biến trong bộ dữ liệu là:", ncol(BK))
## Số biến trong bộ dữ liệu là: 11
cat("Số quan sát trong bộ dữ liệu là:", nrow(BK))
## Số quan sát trong bộ dữ liệu là: 100000

Giải thích code:

  • Dùng cat() để hiển thị một câu thông báo kết hợp cả chữ và số trong báo cáo của mình một cách tự nhiên và sạch sẽ nhất.

  • ncol(BK): Lệnh này có một nhiệm vụ duy nhất: Đếm xem có bao nhiêu cột trong bảng dữ liệu BK và trả về một con số.

  • nrow(BK): Lệnh này có nhiệm vụ là đếm xem có bao nhiêu hàng (dòng) trong bảng dữ liệu BK và trả về một con số.

1.5.2 Cấu trúc và kiểu dữ liệu của các biến

# --- BƯỚC 1: TẠO BẢNG DỮ LIỆU TÓM TẮT ---
# Tạo một data frame (bảng) mới tên là 'data_summary_auto' để chứa thông tin.
data_summary_auto <- data.frame(
  
  # Cột 1: Lấy tên của tất cả các cột từ dữ liệu gốc BK.
  Ten_Cot = names(BK), 
  
  # Cột 2: Lấy kiểu dữ liệu (vd: numeric, character) của từng cột.
  Loai_Du_lieu = unname(sapply(BK, class)), 
  
  # Cột 3: Tự định nghĩa một danh sách các giải thích tương ứng cho mỗi cột.
  Giai_thich = c("Mã số bán hàng.", 
                 "Ngày bán hàng.",
                 "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.")
)

# --- BƯỚC 2: TẠO BẢNG ĐẸP VÀ IN RA ---
# Dùng kable() để chuyển data frame thành một bảng có định dạng cho file PDF.
kable(data_summary_auto, 
      caption = "Bảng Tóm Tắt Tên Cột và Kiểu Dữ liệu", # Đặt tiêu đề cho bảng.
      col.names = c("Tên Biến", "Loại Dữ liệu trong R", "Ý nghĩa"), # Đặt lại tên cho các cột tiêu đề.
      format = "latex", 
      booktabs = TRUE
) %>%
  
# Dùng kable_styling() để "trang điểm" thêm cho bảng.
kable_styling(
  latex_options = "striped", # "striped": Tạo các dòng có màu xen kẽ (sọc).
  full_width = F,            # Bảng chỉ rộng vừa đủ nội dung, không kéo hết trang.
  position = "center"        # Căn chỉnh bảng ra giữa trang.
)
data_summary_auto
# Đếm số lượng biến định lượng từ bảng tóm tắt đã tạo.
so_bien_dinh_luong <- data_summary_auto %>%      # Bắt đầu với bảng 'data_summary_auto'.
  filter(Loai_Du_lieu == "numeric") %>%          # Dùng filter() để chỉ giữ lại các dòng có Loai_Du_lieu là "numeric".
  nrow()                                         # Dùng nrow() để đếm số dòng còn lại.
  # Kết quả (một con số) được lưu vào biến 'so_bien_dinh_luong'.

# Dùng cat() để in ra màn hình một câu thông báo hoàn chỉnh.
cat("Số biến định lượng:", so_bien_dinh_luong, "\n")
## Số biến định lượng: 6

Các biến định lượng thể hiện các thông số số học, đo lường giá trị và khối lượng giao dịch, bao gồm: Sale_ID, Customer_ID, Salesperson_ID, Price, Quantity, và Customer_Age. Biến Date mặc dù được lưu dưới dạng ngày tháng, cũng có thể được chuyển đổi thành dạng định lượng để phân tích theo thời gian. Những biến định lượng này hỗ trợ các phân tích thống kê mô tả, tính toán doanh thu, lợi nhuận và mô hình dự báo.

# Đếm số lượng biến định tính (dữ liệu dạng chữ).
so_bien_dinh_tinh <- data_summary_auto %>% 
  
  # Dùng filter() để chỉ giữ lại các dòng có Loai_Du_lieu là "character".
  filter(Loai_Du_lieu == "character") %>% 
  
  # Dùng nrow() để đếm số dòng còn lại sau khi lọc.
  nrow()
  # Kết quả (một con số) được lưu vào biến 'so_bien_dinh_tinh'.

# Dùng cat() để in ra màn hình một câu thông báo.
cat("Số biến định tính:", so_bien_dinh_tinh, "\n")
## Số biến định tính: 5

Các biến định tính mô tả các đặc điểm phân loại và chất lượng của khách hàng, sản phẩm và giao dịch, bao gồm: Bike_Model, Store_Location, Payment_Method, Customer_Gender, và Date. Những biến này cho phép phân tích phân phối, nhóm khách hàng, đánh giá hiệu suất nhân viên và các đặc trưng sản phẩm.

1.5.3 Kiểm tra chất lượng dữ liệu

cat(paste("Tổng số giá trị bị thiếu (NA):", sum(is.na(BK)), "\n"))
## Tổng số giá trị bị thiếu (NA): 0
cat(paste("Tổng số dòng bị trùng lặp hoàn toàn:", sum(duplicated(BK))))
## Tổng số dòng bị trùng lặp hoàn toàn: 0

Giải thích code:

  • Hàm is.na(): sẽ quét qua từng ô trong toàn bộ dataframe BK. Nó sẽ trả về một dataframe mới có cùng kích thước, nhưng thay vì chứa dữ liệu gốc, nó sẽ chứa các giá trị TRUE (nếu ô gốc bị thiếu, tức là NA) hoặc FALSE (nếu ô gốc có dữ liệu).

  • Hàm duplicated(): sẽ quét qua từng dòng (row) của dataframe BK. Nó so sánh mỗi dòng với tất cả các dòng đã xuất hiện trước nó. Nếu một dòng giống hệt (tất cả các giá trị trong các cột đều giống nhau) với một dòng nào đó ở phía trên, nó sẽ trả về TRUE cho dòng đó. Ngược lại, nó trả về FALSE.

  • Hàm sum(…): cho một tập hợp các giá trị TRUE/FALSE, R sẽ tự động coi TRUE = 1 và FALSE = 0.Kết quả cuối cùng chính là tổng số dữ liệu cần tính.

Nhận xét: Dữ liệu rất sạch, không có giá trị bị thiếu (NA) và không có dòng nào bị trùng lặp hoàn toàn.

1.6 Kiểm tra các giá trị Zero (0) bất thường

price_zero_count <- sum(BK$Price == 0, na.rm = TRUE)
quantity_zero_count <- sum(BK$Quantity == 0, na.rm = TRUE)

cat(sprintf("Số lượng giao dịch có Giá bán (Price) bằng 0 là: %d\n", price_zero_count))
## Số lượng giao dịch có Giá bán (Price) bằng 0 là: 0
cat(sprintf("Số lượng giao dịch có Số lượng (Quantity) bằng 0 là: %d\n", quantity_zero_count))
## Số lượng giao dịch có Số lượng (Quantity) bằng 0 là: 0
# sprintf(): Giúp tạo ra một câu văn có định dạng, bằng cách chèn giá trị của biến vào vị trí có placeholder (%d).

Nhận xét:

Kết quả kiểm tra cho thấy không có bất kỳ giao dịch nào trong bộ dữ liệu có giá bán (Price) hoặc số lượng (Quantity) bằng 0. Đây là một dấu hiệu rất tích cực về chất lượng dữ liệu.

  • Về mặt logic kinh doanh: Mỗi giao dịch được ghi nhận đều là một giao dịch hợp lệ, có giá trị và có ít nhất một sản phẩm được bán ra.

  • Về mặt kỹ thuật: Dữ liệu sạch ở điểm này, giúp đảm bảo rằng các phép tính tài chính sau này, đặc biệt là tính toán Doanh thu (Revenue = Price * Quantity), sẽ chính xác và không bị sai lệch bởi các giá trị zero bất thường.

1.7 Thống kê tóm tắt sơ bộ

1.7.1 Tóm tắt nhanh các biến định lượng

summary(BK %>% select(where(is.numeric)))
##     Sale_ID        Customer_ID       Price         Quantity     Salesperson_ID 
##  Min.   :     1   Min.   :1000   Min.   : 200   Min.   :1.000   Min.   :100.0  
##  1st Qu.: 25001   1st Qu.:3249   1st Qu.:1400   1st Qu.:2.000   1st Qu.:324.0  
##  Median : 50001   Median :5491   Median :2599   Median :3.000   Median :550.0  
##  Mean   : 50001   Mean   :5495   Mean   :2598   Mean   :2.997   Mean   :549.9  
##  3rd Qu.: 75000   3rd Qu.:7738   3rd Qu.:3796   3rd Qu.:4.000   3rd Qu.:775.0  
##  Max.   :100000   Max.   :9999   Max.   :5000   Max.   :5.000   Max.   :999.0  
##   Customer_Age  
##  Min.   :18.00  
##  1st Qu.:31.00  
##  Median :44.00  
##  Mean   :44.04  
##  3rd Qu.:57.00  
##  Max.   :70.00

Giải thích code:

  • Hàm summary(): tính toán các thống kê mô tả (như trung bình, trung vị, min, max,…) cho từng cột số đó và hiển thị kết quả.

  • Hàm select(where(is.numeric)): lọc và chỉ giữ lại những cột có kiểu dữ liệu là số từ BK.

  • Toán tử %>% lấy BK và chuyển nó đến hàm select().

Ý nghĩa:

  • Đối với các biến mang tính chất định danh (ID), các chỉ số như Trung bình (Mean) hay Trung vị (Median) không mang ý nghĩa về mặt phân tích kinh doanh. Tuy nhiên, giá trị Nhỏ nhất (Min) và Lớn nhất (Max) lại rất hữu ích. Ví dụ, Sale_ID chạy từ 1 đến 100,000 cho thấy dữ liệu có vẻ đầy đủ. Tương tự, Customer_ID và Salesperson_ID cho chúng ta thấy khoảng mã định danh hợp lệ của khách hàng và nhân viên.

  • Price (Giá bán): Giá xe dao động từ 200 USD (Min) đến 5,000 USD (Max), cho thấy danh mục sản phẩm của cửa hàng khá đa dạng, từ các dòng xe phổ thông đến cao cấp. Giá trị Trung bình (Mean = 2598) và Trung vị (Median = 2599) rất gần nhau. Đây là một dấu hiệu quan trọng cho thấy sự phân bổ của giá bán là tương đối đối xứng, không bị lệch nhiều bởi các sản phẩm có giá quá cao hoặc quá thấp.

  • Quantity (Số lượng): Khách hàng mua từ 1 (Min) đến 5 (Max) sản phẩm trong một lần giao dịch. Khoảng tứ phân vị (giữa 1st Qu. = 2 và 3rd Qu. = 4) cho thấy 50% số giao dịch của cửa hàng có số lượng bán ra từ 2 đến 4 chiếc. Giá trị trung bình cũng xấp xỉ 3, khẳng định đây là quy mô giao dịch phổ biến nhất.

  • Customer_Age (Tuổi khách hàng): Độ tuổi khách hàng rất rộng, từ 18 (Min) đến 70 (Max), cho thấy sản phẩm phù hợp với nhiều thế hệ. Đây là thông tin giá trị nhất. Khoảng tứ phân vị cho thấy 50% khách hàng cốt lõi của cửa hàng nằm trong độ tuổi từ 31 đến 57 tuổi. Cả giá trị trung bình và trung vị đều là 44, một lần nữa khẳng định nhóm khách hàng chính là những người ở độ tuổi trung niên.

Kết luận sơ bộ: Qua bước tóm tắt nhanh, có thể thấy dữ liệu định lượng hoàn toàn hợp lý, không có giá trị bất thường. Các biến kinh doanh chính có sự phân bổ khá cân đối và đã cung cấp những gợi ý ban đầu rất quan trọng về dải sản phẩm và nhóm khách hàng mục tiêu của chuỗi cửa hàng.

1.7.2 Đếm tần suất sơ bộ một biến định tính

BK %>% 
  count(Bike_Model, sort = TRUE) %>%
  kable(caption = "Số lượng giao dịch tại mỗi cửa hàng")
Số lượng giao dịch tại mỗi cửa hàng
Bike_Model n
BMX 14377
Road Bike 14363
Cruiser 14332
Folding Bike 14329
Hybrid Bike 14319
Electric Bike 14169
Mountain Bike 14111

Giải thích code:

  • Hàm count(): Đây là một hàm tiện lợi từ gói dplyr, chuyên dùng để đếm số lần xuất hiện của mỗi giá trị duy nhất trong một hoặc nhiều cột.

  • Tham số sort = TRUE: Tùy chọn này tự động sắp xếp kết quả theo thứ tự giảm dần của tần suất (cột n), giúp chúng ta ngay lập tức thấy được danh mục nào là phổ biến nhất.

Kết quả: Mẫu xe “BMX” có số lượng giao dịch cao nhất với 14377 lượt, theo sau sát sao là “Road Bike” với 14363 lượt. Trong khi đó, “Mountain Bike” là mẫu xe có số lượng giao dịch thấp nhất, với 14111 lượt. Khoảng cách giữa mẫu xe bán chạy nhất và mẫu xe bán ít nhất không đáng kể. Điều này cho thấy danh mục sản phẩm của cửa hàng rất cân bằng, không có mẫu xe nào chiếm ưu thế vượt trội hay bị bỏ lại phía sau. Tất cả các dòng xe đều có sức hút tương đối đồng đều đối với khách hàng.

2. Xử lý dữ liệu và mã hóa

Trong mục này, chúng ta sẽ thực hiện các bước quan trọng để làm sạch, chuẩn hóa và làm giàu bộ dữ liệu. Mục tiêu là chuyển đổi dữ liệu thô thành một dạng có cấu trúc, đầy đủ thông tin và sẵn sàng cho các bước phân tích sâu hơn.

2.1. Chuẩn Hóa Kiểu Dữ Liệu

Bước đầu tiên là đảm bảo các biến được lưu trữ dưới đúng định dạng mà R có thể hiểu và thao tác.

Biến Date đang ở dạng chữ (character). Chúng ta cần chuyển nó sang định dạng Date để có thể thực hiện các phân tích theo thời gian.

BK$Date <- as.Date(BK$Date, format = "%d-%m-%Y")
head(BK$Date)
## [1] "2022-07-11" "2024-05-03" "2022-09-01" "2022-09-28" "2021-01-05"
## [6] "2021-09-06"
# Kiểm tra lại kiểu dữ liệu của cột Date
class(BK$Date)
## [1] "Date"

2.2. Xử Lý Các Vấn Đề Dữ Liệu (Minh Họa)

Một bộ dữ liệu thực tế thường chứa các giá trị bị thiếu (NA) hoặc giá trị ngoại lai (outliers). Mặc dù bộ dữ liệu hiện tại của chúng ta khá sạch, chúng ta sẽ minh họa cách xử lý các vấn đề này.

2.2.1. Xử lý giá trị thiếu (Missing Values)

Tình huống giả định: Giả sử có 800 quan sát bị thiếu thông tin về tuổi khách hàng . Giải pháp: Một cách tiếp cận phổ biến là thay thế các giá trị thiếu bằng giá trị trung bình của toàn bộ cột.

# Tạo một bản sao để minh họa
BK_dirty <- BK 
set.seed(500) # -> set.seed() đảm bảo rằng mỗi lần bạn chạy code, bạn sẽ luôn nhận được CÙNG MỘT KẾT QUẢ "ngẫu nhiên"

na_indices <- sample(1:nrow(BK_dirty), 800)
BK_dirty$Customer_Age[na_indices] <- NA

# Tính tuổi trung bình (loại bỏ các giá trị NA khi tính)
mean_age <- mean(BK_dirty$Customer_Age, na.rm = TRUE)

# Điền các giá trị NA bằng tuổi trung bình đã làm tròn
BK_dirty$Customer_Age[is.na(BK_dirty$Customer_Age)] <- round(mean_age)

# Kiểm tra lại số lượng giá trị thiếu
sum(is.na(BK_dirty$Customer_Age))
## [1] 0

Giải thích code:

  • BK_dirty$Customer_Age[na_indices] <- NA: tạo ra 800 giá trị bị thiếu (NA) trong cột Customer_Age để minh họa việc xử lý dữ liệu.

  • mean_age <- mean(BK_dirty$Customer_Age, na.rm = TRUE): tính tuổi trung bình của cột Customer_Age. Tham số na.rm = TRUE là quan trọng nhất, nó yêu cầu hàm mean phải bỏ qua tất cả các ô bị thiếu (NA) khi tính toán.

  • BK_dirty\(Customer_Age[is.na(BK_dirty\)Customer_Age)] <- round(mean_age): đây là bước xử lý chính. Code này tìm tất cả các ô đang là NA trong cột Customer_Age và thay thế chúng bằng giá trị tuổi trung bình đã tính ở bước trên (đã được làm tròn).

  • Ghi chú: Cho các phân tích tiếp theo, chúng ta sẽ tiếp tục sử dụng bộ dữ liệu BK gốc không có giá trị thiếu.

2.2.2. Xử lý giá trị ngoại lai (Outliers)

Tình huống giả định: Giả sử do lỗi nhập liệu, một vài giao dịch có giá trị Price bất thường (ví dụ: bằng 0 hoặc quá cao).

Giải pháp: Thay thế các giá trị ngoại lai này bằng một giá trị hợp lý hơn, ở đây là giá trị trung vị (median) của từng loại xe.

# Tạo bản sao để minh họa
BK_outliers <- BK
BK_outliers$Price[sample(1:nrow(BK_outliers), 10)] <- c(0, 120000, 10, 50000, 20, 70, 40, 80000, 5, 150000)

# Xử lý ngoại lai
BK_cleaned <- BK_outliers %>%
  group_by(Bike_Model) %>%
  mutate(Median_Price = median(Price)) %>%
  ungroup() %>%
  mutate(Price = ifelse(Price < 100 | Price > 10000, Median_Price, Price)) %>%
  select(-Median_Price)

# Hiển thị tóm tắt giá sau khi làm sạch để so sánh
summary(BK_outliers$Price)
##    Min. 1st Qu.  Median    Mean 3rd Qu.    Max. 
##       0    1400    2599    2602    3796  150000
summary(BK_cleaned$Price)
##    Min. 1st Qu.  Median    Mean 3rd Qu.    Max. 
##     200    1400    2598    2598    3796    5000

Giải thích code:

  • sample(1:nrow(BK_outliers), 10): Lệnh này chọn ra 10 vị trí (chỉ số hàng) ngẫu nhiên trong data frame.

  • mutate(): Là hàm dùng để tạo ra một cột mới hoặc chỉnh sửa một cột hiện có.

  • ifelse(điều_kiện, giá_trị_nếu_đúng, giá_trị_nếu_sai): Đây là một hàm điều kiện. Nếu giá là một ngoại lai (thỏa mãn điều kiện), nó sẽ được thay thế bằng giá trị Median_Price (trung vị của loại xe đó) mà chúng ta đã tính ở bước trên và ngược lại.

  • Ghi chú: Chúng ta sẽ tiếp tục sử dụng bộ dữ liệu BK gốc cho các phân tích sau.

2.3. Kỹ thuật tạo cơ bản

Đây là bước quan trọng nhất để làm giàu thông tin. Chúng ta sẽ tạo một bản sao BK1 từ BK gốc và thực hiện tất cả các thao tác trên một chuỗi duy nhất.

# Bước tiền xử lý: Đếm số lần mua hàng của mỗi khách hàng trước
customer_frequency <- BK %>%
  group_by(Customer_ID) %>%
  summarise(Purchase_Count = n(), .groups = 'drop')

# Bắt đầu chuỗi xử lý để tạo ra dataframe BK1 hoàn chỉnh
BK1 <- BK %>%
  # Nối thông tin tần suất mua hàng vào bảng chính
  left_join(customer_frequency, by = "Customer_ID") %>%
  
  # Bắt đầu tạo và biến đổi các cột mới
  mutate(
    # 1. Tạo biến Doanh thu
    Revenue = Price * Quantity,
    
    # 2. Trích xuất thông tin Năm, Tháng, Thứ từ cột Date
    Year = year(Date),
    Month = month(Date, label = TRUE, abbr = FALSE),
    Weekday = wday(Date, label = TRUE, abbr = FALSE),
    
    # 3. Tạo biến Mùa (Season)
    Season = case_when(
      month(Date) %in% c(3, 4, 5)   ~ "Xuân",
      month(Date) %in% c(6, 7, 8)   ~ "Hạ",
      month(Date) %in% c(9, 10, 11) ~ "Thu",
      TRUE                         ~ "Đông"
    ),
    
    # 4. Phân tổ theo nhóm tuổi
    Age_Group = case_when(
      Customer_Age <= 30 ~ "Trẻ (18-30)",
      Customer_Age <= 55 ~ "Trung niên (31-55)",
      TRUE               ~ "Lớn tuổi (56+)"
    ),
    
    # 5. Phân tổ theo mức giá
    Price_Level = case_when(
      Price <= 2600      ~ "Phổ thông",
      Price < 4000       ~ "Cao cấp",
      TRUE               ~ "Hạng sang"
    ),
    
    # 6. Tạo biến Hạng khách hàng thân thiết (dựa vào Purchase_Count đã join ở trên)
    Loyalty_Status = case_when(
      Purchase_Count >= 15 ~ "VIP",
      Purchase_Count >= 10  ~ "Thân thiết",
      TRUE                 ~ "Khách hàng mới"
    ),
    
    # 7. Mã hóa Dữ liệu (Encoding) Giới tính
    Gender_Encoded = case_when(
      Customer_Gender == "Male"   ~ 0,
      Customer_Gender == "Female" ~ 1
    )
  )

2.4 Tổng kết và xem lại dữ liệu sau xử lý

Sau khi thực hiện tất cả các bước trên, bộ dữ liệu của chúng ta đã được mở rộng và làm giàu đáng kể.

# Hiển thị 10 dòng đầu của bộ dữ liệu đã được xử lý hoàn chỉnh
kable(head(BK1, 10), 
      caption = "Dữ liệu sau khi được xử lý và làm giàu.",
      booktabs = TRUE) %>%
  kable_styling(latex_options = c("striped", "hold_position",  "scale_down"), 
                font_size = 5)
Dữ liệu sau khi được xử lý và làm giàu.
Sale_ID Date Customer_ID Bike_Model Price Quantity Store_Location Salesperson_ID Payment_Method Customer_Age Customer_Gender Purchase_Count Revenue Year Month Weekday Season Age_Group Price_Level Loyalty_Status Gender_Encoded
1 2022-07-11 9390 Cruiser 318.32 1 Philadelphia 589 Apple Pay 70 Female 15 318.32 2022 Tháng Bảy |Thứ Ha |Hạ |Lớn tuổi (56+) |Phổ thông |VIP
  • Kết quả: Bộ dữ liệu BK1 giờ đây đã có thêm nhiều cột mới (Revenue, Year, Month, Weekday, Season, Age_Group, Price_Level, Loyalty_Status, Gender_Encoded), sẵn sàng cho các phân tích sâu sắc ở các chương tiếp theo.

3. Thống kê và Phân tích Mô tả

Sau khi đã xử lý và làm giàu dữ liệu, chương này sẽ tập trung vào việc thực hiện các phép tính thống kê cơ bản để trả lời các câu hỏi kinh doanh cụ thể, từ đó rút ra những insight ban đầu về hoạt động của doanh nghiệp.

3.1 Phân tích thống kê mô tả chi tiết

3.1.1 Thống kê Mô tả biến Định lượng

# --- BƯỚC 1: CHUẨN BỊ DỮ LIỆU ---

# Bắt đầu với bộ dữ liệu BK, chỉ chọn các cột số, sau đó loại bỏ các cột ID.
numeric_vars <- BK %>% 
  select(where(is.numeric)) %>% # Giữ lại các cột là số.
  select(-ends_with("_ID"))    # Loại bỏ các cột có tên kết thúc bằng "_ID".

# --- BƯỚC 2: TÍNH TOÁN VÀ TÁI CẤU TRÚC BẢNG ---

# Bắt đầu chuỗi xử lý trên dữ liệu 'numeric_vars'.
descriptive_table_adv <- numeric_vars %>%
  
  # Dùng summarise(across(...)) để áp dụng một loạt hàm thống kê cho TẤT CẢ các cột.
  summarise(across(
    everything(), # Áp dụng cho mọi cột.
    
    # Danh sách các hàm cần tính: Mean, Median, SD (Độ lệch chuẩn), Var (Phương sai),...
    list(
      Mean     = ~mean(., na.rm = TRUE),
      Median   = ~median(., na.rm = TRUE),
      SD       = ~sd(., na.rm = TRUE),
      Var      = ~var(., na.rm = TRUE),
      Min      = ~min(., na.rm = TRUE),
      Max      = ~max(., na.rm = TRUE),
      Skewness = ~skewness(., na.rm = TRUE),
      Kurtosis = ~kurtosis(., na.rm = TRUE)
    ),
    
    # Đặt tên cho các cột kết quả theo mẫu: TenCot__TenHam (ví dụ: Price__Mean).
    .names = "{.col}__{.fn}"
  )) %>%
  
  # Dùng pivot_longer() để "xoay" bảng từ dạng RỘNG sang DÀI.
  # -> Mỗi hàng sẽ là một cặp (Tên biến, Tên thống kê).
  tidyr::pivot_longer(
    cols = everything(),
    names_to = c("Variable", "Statistic"), # Tách tên cột thành 2 cột mới.
    names_sep = "__"                       # Dùng dấu "__" làm điểm để tách.
  ) %>%
  
  # Dùng pivot_wider() để "xoay" bảng từ DÀI về lại RỘNG theo đúng định dạng mong muốn.
  # -> Mỗi hàng là một biến, mỗi cột là một chỉ số thống kê.
  tidyr::pivot_wider(
    names_from = Statistic, # Lấy các giá trị trong cột "Statistic" làm tên cột mới.
    values_from = value     # Điền giá trị từ cột "value" vào các ô tương ứng.
  ) %>%
  
  # Làm tròn tất cả các cột số trong bảng kết quả đến 2 chữ số thập phân.
  mutate(across(where(is.numeric), ~round(., 2)))

# --- BƯỚC 3: HIỂN THỊ BẢNG ĐẸP ---

# Dùng kable() và kable_styling() để tạo bảng có định dạng chuyên nghiệp cho file PDF.
kable(descriptive_table_adv, 
      caption = "Thống kê mô tả chi tiết các biến định lượng", 
      digits = 2,
      booktabs = TRUE,
      format = "latex") %>%
  kable_styling(
    latex_options = c("striped", "hold_position"), 
    full_width = FALSE, 
    position = "center"
  )

Ý nghĩa:

1. Biến Price (Giá cả):

  • Mean (2598.18) & Median (2598.57): Giá trị trung bình và trung vị gần như bằng nhau. Điều này là một dấu hiệu rất tốt, cho thấy sự phân phối của giá cả rất đối xứng. Không có nhiều sản phẩm giá quá cao hoặc quá thấp kéo lệch giá trị trung bình.

  • SD (1384.94) & Var (1918067.48): Độ lệch chuẩn (SD) khá lớn. Điều này cho thấy giá cả của các sản phẩm có sự biến động và chênh lệch cao. Dữ liệu không tập trung quanh một mức giá duy nhất mà trải rộng ra.

  • Min (200.01) & Max (4999.81): Khoảng giá của sản phẩm là từ khoảng 200 đến 5000. Điều này xác nhận lại độ phân tán cao của dữ liệu giá.

  • Skewness (0): Độ xiên bằng 0. Đây là sự khẳng định về mặt toán học rằng phân phối giá cả là hoàn toàn đối xứng. Đồ thị phân phối có hình dạng giống quả chuông cân đối.

  • Kurtosis (1.8): Độ nhọn là 1.8. Giá trị này nhỏ hơn 3 (độ nhọn của phân phối chuẩn). Điều này có nghĩa là phân phối ít nhọn hơn (bẹt hơn) so với phân phối chuẩn. Nó có ít các giá trị ngoại lai (outliers) ở hai phía đuôi.

2. Biến Quantity (Số lượng):

  • Mean (3.00) & Median (3.00): Trung bình và trung vị bằng nhau tuyệt đối. Số lượng sản phẩm được mua trung bình là 3.

  • SD (1.41) & Var (2.00): Độ lệch chuẩn nhỏ, cho thấy số lượng mua ít biến động. Hầu hết các giao dịch đều có số lượng xoay quanh mức 3.

  • Min (1.00) & Max (5.00): Số lượng mua ít nhất là 1 và nhiều nhất là 5. Đây là một khoảng giá trị rất hẹp, củng cố cho việc độ biến động thấp.

  • Skewness (0): Tương tự như giá, phân phối của số lượng cũng hoàn toàn đối xứng.

  • Kurtosis (1.7): Phân phối cũng bẹt hơn phân phối chuẩn, cho thấy các giá trị tập trung đều hơn và ít giá trị ngoại lai.

3. Biến Customer_Age (Tuổi khách hàng):

  • Mean (44.04) & Median (44.00): Độ tuổi trung bình và trung vị của khách hàng là khoảng 44 tuổi. Hai giá trị này rất gần nhau, cho thấy phân phối tuổi cũng rất cân đối.

  • SD (15.31): Độ lệch chuẩn khá lớn, cho thấy độ tuổi của các khách hàng rất đa dạng, không tập trung ở một nhóm tuổi cụ thể nào.

  • Min (18.00) & Max (70.00): Nhóm khách hàng trải dài từ 18 đến 70 tuổi.

  • Skewness (0): Phân phối tuổi hoàn toàn đối xứng. Lượng khách hàng trẻ tuổi và lớn tuổi được phân bổ đều quanh độ tuổi trung bình.

  • Kurtosis (1.8): Phân phối tuổi cũng bẹt hơn phân phối chuẩn.

Kết luận chung: Price là biến có độ biến động lớn nhất, tiếp theo là Customer_Age, và cuối cùng Quantity là biến ổn định và ít thay đổi nhất.Tất cả các biến đều có phân phối “bẹt hơn” (Platykurtic) so với phân phối chuẩn, nghĩa là dữ liệu ít tập trung vào đỉnh và có ít giá trị cực đoan ở hai bên. Cả ba biến đều có độ xiên (Skewness) bằng 0 nó cho thấy dữ liệu của bạn cực kỳ cân bằng và đối xứng.

3.1.2 Thống kê Mô tả Biến Định tính

# Lấy các cột là character hoặc factor
qual_data <- BK %>% select(where(is.character) | where(is.factor))

# Dùng vòng lặp để tạo và in ra từng bảng
for (col_name in names(qual_data)) {
  
  # Sửa lại chuỗi lệnh cho logic và chính xác
  freq_table <- qual_data %>%
    count(!!sym(col_name), sort = TRUE) %>%
    # Bước 1: Tạo cột tỷ lệ với tên đơn giản là 'Ty_le'
    mutate(Ty_le = n / sum(n) * 100) %>%
    # Bước 2: Làm tròn ngay trên cột 'Ty_le' đó
    mutate(Ty_le = round(Ty_le, 2)) %>%
    # Bước 3: Đổi tên tất cả các cột ở bước cuối cùng, khi đã tính toán xong
    rename(
      Gia_tri = 1, 
      Tan_so = n, 
      "Ty_le (\\%)" = Ty_le # Đây là nơi duy nhất dùng tên phức tạp
    )

  # Tạo và in bảng kable cho PDF (phần này của bạn đã đúng)
  table_for_pdf <- kable(freq_table, 
                         caption = paste("Bảng tần suất cho biến:", gsub("_", "\\\\_", col_name)),
                         booktabs = TRUE) %>%
    kable_styling(latex_options = c("striped", "hold_position"),  full_width = FALSE, position = "center")
  
  print(table_for_pdf)
  cat("\n\n") # Thêm khoảng trắng giữa các bảng
}
Bảng tần suất cho biến: Bike_Model
Gia_tri Tan_so Ty_le (%)
BMX 14377 14.38
Road Bike 14363 14.36
Cruiser 14332 14.33
Folding Bike 14329 14.33
Hybrid Bike 14319 14.32
Electric Bike 14169 14.17
Mountain Bike 14111 14.11
Bảng tần suất cho biến: Store_Location
Gia_tri Tan_so Ty_le (%)
New York 14515 14.52
Phoenix 14385 14.38
Philadelphia 14330 14.33
San Antonio 14300 14.30
Chicago 14207 14.21
Houston 14149 14.15
Los Angeles 14114 14.11
Bảng tần suất cho biến: Payment_Method
Gia_tri Tan_so Ty_le (%)
Apple Pay 16751 16.75
Debit Card 16738 16.74
Cash 16692 16.69
Credit Card 16653 16.65
Google Pay 16613 16.61
PayPal 16553 16.55
Bảng tần suất cho biến: Customer_Gender
Gia_tri Tan_so Ty_le (%)
Female 50227 50.23
Male 49773 49.77

Giải thích code:

  • names(qual_data): Lệnh này lấy ra một danh sách (vector) chứa tên của tất cả các cột trong qual_data.

  • for (col_name in …): Lệnh này tạo ra một vòng lặp.

Ý nghĩa:

1. Bảng tần suất cho biến Bike_Model (Loại xe đạp)

  • Nội dung: Bảng này liệt kê 7 loại xe đạp khác nhau (BMX, Road Bike, v.v.) và số lượng của mỗi loại.

  • Ý nghĩa quan trọng: Tần suất và tỷ lệ phần trăm của tất cả các loại xe đạp là gần như bằng nhau (tất cả đều xoay quanh 14.1% - 14.4%). Điều này cho thấy dữ liệu được phân bổ rất đều cho mỗi loại xe. Không có loại xe nào chiếm ưu thế vượt trội.

2. Bảng tần suất cho biến Store_Location (Vị trí cửa hàng)

  • Nội dung: Liệt kê số lượng bản ghi (có thể là giao dịch) tại 7 thành phố khác nhau.

  • Ý nghĩa quan trọng: Tương tự như loại xe, số lượng giao dịch tại mỗi thành phố cũng cực kỳ cân bằng (đều trong khoảng 14.1% - 14.5%). Mặc dù New York có nhiều hơn một chút, sự khác biệt là không đáng kể. Điều này cho thấy hoạt động kinh doanh hoặc việc thu thập dữ liệu diễn ra đồng đều trên tất cả các địa điểm.

3. Bảng tần suất cho biến Payment_Method (Phương thức thanh toán)

  • Nội dung: Thống kê 6 phương thức thanh toán khác nhau mà khách hàng đã sử dụng.

  • Ý nghĩa quan trọng: Một lần nữa, chúng ta lại thấy một sự cân bằng gần như hoàn hảo. Tất cả các phương thức thanh toán đều được sử dụng với tần suất rất giống nhau (khoảng 16.6% - 16.7%). Điều này có nghĩa là không có phương thức thanh toán nào được ưa chuộng hơn hẳn các phương thức còn lại trong tập dữ liệu này.

4. Bảng tần suất cho biến Customer_Gender (Giới tính khách hàng)

  • Nội dung: Thống kê số lượng khách hàng nam và nữ.

  • Ý nghĩa quan trọng: Tỷ lệ giữa khách hàng nữ (Female) và nam (Male) gần như là 50/50 (50.23% so với 49.77%). Đây là một sự cân bằng giới tính hoàn hảo.

3.2 Phân tích Tổng quan về Giao dịch

3.2.1 Tổng doanh thu:

total_revenue <- sum(BK1$Revenue) 
# sum(BK1$Revenue): Cộng tất cả các giá trị trong cột 'Revenue' của bộ dữ liệu BK1.
# <- : Lưu kết quả tính tổng vào một biến mới tên là 'total_revenue'.
cat("Tổng doanh thu:", dollar(total_revenue, prefix = "", suffix = " USD"))
## Tổng doanh thu: 778,434,235 USD

3.2.2 Doanh thu trung bình trên mỗi giao dịch:

avg_revenue_per_sale <- mean(BK1$Revenue)
# mean(BK1$Revenue): Tính giá trị trung bình của cột 'Revenue'.
# <- : Lưu kết quả tính trung bình vào biến 'avg_revenue_per_sale'.
cat("Doanh thu trung bình mỗi giao dịch:", dollar(avg_revenue_per_sale, prefix = "", suffix = " USD"))
## Doanh thu trung bình mỗi giao dịch: 7,784.34 USD

3.2.3 Tổng số giao dịch đã thực hiện:

total_transactions <- nrow(BK1)
# nrow(BK1): Đếm tổng số hàng trong bộ dữ liệu BK1. Vì mỗi hàng là một giao dịch, đây chính là tổng số giao dịch.
# <- : Lưu kết quả đếm được vào biến 'total_transactions'.
cat("Tổng số giao dịch:", comma(total_transactions))
## Tổng số giao dịch: 100,000

3.2.4 Số lượng sản phẩm trung bình mỗi giao dịch:

avg_quantity_per_sale <- mean(BK1$Quantity)
cat("Số lượng xe trung bình mỗi giao dịch:", round(avg_quantity_per_sale, 2))
## Số lượng xe trung bình mỗi giao dịch: 3
  • Nhận xét: Các chỉ số tổng quan cho thấy quy mô kinh doanh, giá trị trung bình mỗi đơn hàng và thói quen mua sắm (số lượng) của khách hàng.

3.3 Phân tích theo Sản phẩm

3.3.1 Tổng số lượng bán theo từng mẫu xe:

# --- TÍNH TOÁN VÀ TÓM TẮT DỮ LIỆU ---
quantity_summary <- BK1 %>%
  
  # group_by(): Gom nhóm dữ liệu theo từng mẫu xe (Bike_Model).
  group_by(Bike_Model) %>%
  
  # summarise(): Với mỗi nhóm, tính tổng số lượng (sum(Quantity)) và lưu vào cột mới 'Total_Quantity'.
  summarise(Total_Quantity = sum(Quantity)) %>%
  
  # arrange(): Sắp xếp bảng kết quả theo thứ tự giảm dần (desc) của cột 'Total_Quantity'.
  arrange(desc(Total_Quantity))
  # -> Kết quả cuối cùng được lưu vào biến 'quantity_summary'.


# --- TRÌNH BÀY BẢNG KẾT QUẢ ---
kable(quantity_summary, # Dữ liệu đầu vào là bảng 'quantity_summary'.
      caption = "Số lượng bán theo mẫu xe", # Đặt tiêu đề cho bảng.
      
      # col.names: Đổi tên các cột tiêu đề sang tiếng Việt cho dễ đọc.
      col.names = c("Mẫu xe", "Tổng số lượng bán"))
Số lượng bán theo mẫu xe
Mẫu xe Tổng số lượng bán
Cruiser 43120
Hybrid Bike 43089
BMX 43080
Road Bike 43022
Folding Bike 42872
Mountain Bike 42279
Electric Bike 42249

Nhận xét: Về mặt số lượng, Cruiser mới là mẫu xe bán chạy nhất với 43,120 chiếc, theo sau rất sát là Hybrid Bike và BMX. Sự khác biệt về số lượng bán ra giữa các mẫu xe là rất nhỏ. Điều này chứng tỏ nhu cầu của khách hàng được trải đều trên các dòng sản phẩm, cho thấy công ty đã thành công trong việc đa dạng hóa sản phẩm để tiếp cận nhiều phân khúc thị trường.

3.3.2 Tổng doanh thu theo từng mẫu xe:

# --- TÍNH TỔNG DOANH THU THEO MẪU XE ---
revenue_by_model <- BK1 %>%
  
  # Gom nhóm dữ liệu theo từng mẫu xe (Bike_Model).
  group_by(Bike_Model) %>%
  
  # Với mỗi nhóm, tính tổng doanh thu (sum(Revenue)) và lưu vào cột mới 'Total_Revenue'.
  summarise(Total_Revenue = sum(Revenue)) %>%
  
  # Sắp xếp bảng kết quả theo thứ tự giảm dần (desc) của tổng doanh thu.
  arrange(desc(Total_Revenue))
  # -> Kết quả cuối cùng được lưu vào biến 'revenue_by_model'.


# --- TRÌNH BÀY BẢNG KẾT QUẢ ---
kable(revenue_by_model, # Dữ liệu đầu vào là bảng 'revenue_by_model'.
      caption = "Doanh thu theo mẫu xe", # Đặt tiêu đề cho bảng.
      
      # col.names: Đổi tên các cột tiêu đề sang tiếng Việt.
      col.names = c("Mẫu xe", "Tổng Doanh thu"))
Doanh thu theo mẫu xe
Mẫu xe Tổng Doanh thu
Hybrid Bike 112505511
BMX 112146114
Cruiser 111849092
Road Bike 111579574
Folding Bike 110966818
Electric Bike 109750159
Mountain Bike 109636967

Nhận xét: Hybrid Bike là mẫu xe mang lại doanh thu cao nhất (khoảng 112.5 triệu USD), nhưng chỉ nhỉnh hơn một chút so với các mẫu xe khác. Sự chênh lệch giữa mẫu xe có doanh thu cao nhất (Hybrid Bike) và thấp nhất (Mountain Bike) là không đáng kể. Điều này cho thấy không có một sản phẩm “ngôi sao” nào đang phải “gánh” doanh thu cho toàn bộ công ty. Thay vào đó, sự thành công được phân bổ đều.

3.3.3 Giá bán trung bình của từng mẫu xe:

# --- TÍNH GIÁ BÁN TRUNG BÌNH THEO MẪU XE ---
avg_price_by_model <- BK1 %>%
  
  # Gom nhóm dữ liệu theo từng mẫu xe (Bike_Model).
  group_by(Bike_Model) %>%
  
  # Với mỗi nhóm, tính giá trung bình (mean(Price)) và lưu vào cột mới 'Average_Price'.
  summarise(Average_Price = mean(Price)) %>%
  
  # Sắp xếp bảng kết quả theo thứ tự giảm dần (desc) của giá trung bình.
  arrange(desc(Average_Price))
  # -> Kết quả cuối cùng được lưu vào biến 'avg_price_by_model'.


# --- TRÌNH BÀY BẢNG KẾT QUẢ ---
kable(avg_price_by_model, # Dữ liệu đầu vào là bảng 'avg_price_by_model'.
      caption = "Giá bán trung bình theo mẫu xe", # Đặt tiêu đề cho bảng.
      
      # col.names: Đổi tên các cột tiêu đề sang tiếng Việt.
      col.names = c("Mẫu xe", "Giá bán trung bình"))
Giá bán trung bình theo mẫu xe
Mẫu xe Giá bán trung bình
BMX 2608.601
Hybrid Bike 2601.903
Road Bike 2600.954
Electric Bike 2598.047
Cruiser 2596.131
Mountain Bike 2591.299
Folding Bike 2590.196

Nhận xét: Mức giá dao động trong một khoảng cực kỳ hẹp, chỉ chênh lệch khoảng 18 USD giữa mẫu xe có giá trung bình cao nhất là BMX (2608.6 USD) và mẫu xe có giá thấp nhất là Folding Bike (2590.2 USD).

3.3.4 Phân bổ sản phẩm theo các mức giá đã phân tổ:

# --- THỐNG KÊ PHÂN BỐ SẢN PHẨM THEO PHÂN KHÚC GIÁ ---
price_level_dist <- BK1 %>%
  
  # count(): Đếm số lượng giao dịch cho mỗi giá trị trong cột 'Price_Level'.
  # sort = TRUE: Tự động sắp xếp kết quả theo thứ tự giảm dần.
  # -> Kết quả là một bảng có 2 cột: 'Price_Level' và 'n' (số lượng).
  count(Price_Level, sort = TRUE) %>%
  
  # mutate(): Tạo một cột mới tên là 'Percentage'.
  # Công thức: (số lượng của nhóm / tổng số lượng) * 100.
  mutate(Percentage = n / sum(n) * 100)
  # -> Bảng kết quả cuối cùng được lưu vào biến 'price_level_dist'.


# --- TRÌNH BÀY BẢNG KẾT QUẢ ---
kable(price_level_dist, # Dữ liệu đầu vào.
      caption = "Tỷ lệ sản phẩm theo mức giá", # Tiêu đề bảng.
      col.names = c("Mức giá", "Số lượng sản phẩm", "Tỷ lệ"))
Tỷ lệ sản phẩm theo mức giá
Mức giá Số lượng sản phẩm Tỷ lệ
Phổ thông 50030 50.030
Cao cấp 29341 29.341
Hạng sang 20629 20.629

Nhận xét:

  • Phân khúc “Phổ thông” chiếm ưu thế tuyệt đối: Với 50,030 giao dịch, chiếm đúng 50% tổng số sản phẩm bán ra, đây rõ ràng là phân khúc chủ lực của công ty. Điều này cho thấy phần lớn khách hàng của công ty ưa chuộng các sản phẩm có mức giá phải chăng và dễ tiếp cận.

  • Các phân khúc còn lại: Phân khúc “Cao cấp” chiếm khoảng 29.3%, và phân khúc “Hạng sang” chiếm 20.6% thị phần.

  • Kết luận chung: Phân tích theo sản phẩm giúp xác định đâu là dòng xe “chủ lực” (best-seller), đâu là dòng xe cao cấp (premium), và phân khúc giá nào đang chiếm ưu thế trên thị trường.

3.4. Phân tích theo Địa điểm và Nhân viên

3.4.1 Mẫu xe mang lại doanh thu cao nhất tại mỗi cửa hàng:

# --- TÌM MẪU XE CÓ DOANH THU CAO NHẤT TẠI MỖI CỬA HÀNG ---
top_model_by_store <- BK1 %>%
  
  # Bước 1: Gom nhóm theo Cả Cửa hàng VÀ Mẫu xe.
  group_by(Store_Location, Bike_Model) %>%
  
  # Bước 2: Tính tổng doanh thu cho mỗi cặp (Cửa hàng, Mẫu xe) đó.
  # .groups = 'drop' là để xóa cấu trúc gom nhóm cũ, chuẩn bị cho bước tiếp theo.
  summarise(Total_Revenue = sum(Revenue), .groups = 'drop') %>%
  
  # Bước 3: Gom nhóm lại lần nữa, nhưng LẦN NÀY CHỈ THEO Cửa hàng.
  group_by(Store_Location) %>%
  
  # Bước 4: Với mỗi nhóm cửa hàng, dùng top_n() để lọc ra chỉ 1 hàng
  #         có Total_Revenue cao nhất.
  top_n(1, Total_Revenue)
  # -> Kết quả cuối cùng được lưu vào biến 'top_model_by_store'.


# --- TRÌNH BÀY BẢNG KẾT QUẢ ---
kable(top_model_by_store, 
      caption = "Mẫu xe có doanh thu cao nhất tại mỗi cửa hàng",
      col.names = c("Địa điểm","Mẫu xe", "Tổng Doanh thu"))
Mẫu xe có doanh thu cao nhất tại mỗi cửa hàng
Địa điểm Mẫu xe Tổng Doanh thu
Chicago Electric Bike 16355493
Houston Hybrid Bike 16536842
Los Angeles BMX 16241146
New York Hybrid Bike 16663923
Philadelphia Road Bike 16538470
Phoenix Cruiser 16558341
San Antonio Folding Bike 16155920

Nhận xét:

  • Tại Chicago, Electric Bike là mẫu xe chủ lực, trong khi ở Los Angeles thì BMX lại được ưa chuộng nhất.

  • Hybrid Bike tỏ ra là một sản phẩm mạnh khi dẫn đầu ở cả hai thành phố lớn là Houston và New York.

  • Các thị trường còn lại như Philadelphia, Phoenix và San Antonio đều có những mẫu xe bán chạy nhất riêng biệt là Road Bike, Cruiser và Folding Bike.

3.4.2 Cửa hàng có số lượng xe bán trung bình mỗi giao dịch cao nhất:

# --- TÍNH SỐ LƯỢNG XE TRUNG BÌNH MỖI GIAO DỊCH THEO CỬA HÀNG ---
avg_quantity_by_store <- BK1 %>%
  
  # Gom nhóm dữ liệu theo từng cửa hàng.
  group_by(Store_Location) %>%
  
  # Với mỗi cửa hàng, tính SỐ LƯỢNG TRUNG BÌNH (mean(Quantity)) cho mỗi giao dịch.
  summarise(Average_Quantity_Per_Sale = mean(Quantity)) %>%
  
  # Sắp xếp kết quả giảm dần.
  arrange(desc(Average_Quantity_Per_Sale))
  # -> Bảng kết quả được lưu vào biến 'avg_quantity_by_store'.


# --- TRÌNH BÀY BẢNG KẾT QUẢ ---
kable(avg_quantity_by_store, 
      caption = "Số lượng xe trung bình mỗi giao dịch theo cửa hàng",
      # Đổi tên cột tiêu đề sang tiếng Việt.
      col.names = c("Địa điểm", "Số lượng giao dịch trung bình"))
Số lượng xe trung bình mỗi giao dịch theo cửa hàng
Địa điểm Số lượng giao dịch trung bình
Houston 3.011308
Los Angeles 3.010628
New York 3.009852
Chicago 2.999507
San Antonio 2.986783
Phoenix 2.982343
Philadelphia 2.979623

Nhận xét: Số lượng xe trung bình bán ra trong một giao dịch ở tất cả các cửa hàng đều dao động rất sít sao quanh mốc 3.0. Sự chênh lệch giữa cửa hàng cao nhất (Houston) và thấp nhất (Philadelphia) là không đáng kể về mặt thống kê và kinh doanh.

Kết luận: Thói quen mua sắm của khách hàng (quy mô đơn hàng) là như nhau ở mọi địa điểm. Điều này cho thấy công ty có thể áp dụng một mô hình vận hành và chiến lược bán hàng chung cho toàn bộ hệ thống mà không cần tùy chỉnh riêng cho từng nơi.

3.4.3 Phân khúc giá trị giao dịch tại mỗi cửa hàng:

# --- PHÂN TÍCH CƠ CẤU GIÁ TRỊ GIAO DỊCH TẠI MỖI CỬA HÀNG ---
transaction_value_by_store <- BK1 %>%
  
  # Bước 1: Dùng mutate() và case_when() để tạo một cột mới phân loại giá trị giao dịch.
  mutate(Transaction_Value_Tier = case_when(
    Revenue < 5000  ~ "Dưới $5,000",       # Giao dịch giá trị thấp
    Revenue < 15000 ~ "$5,000 - $15,000",  # Giao dịch giá trị trung bình
    TRUE            ~ "Trên $15,000"       # Giao dịch giá trị cao (trường hợp còn lại)
  )) %>%
  
  # Bước 2: Dùng count() để đếm số lượng giao dịch cho mỗi cặp (Cửa hàng, Phân loại giá trị).
  count(Store_Location, Transaction_Value_Tier) %>%
  
  # Bước 3: Sắp xếp kết quả: theo tên cửa hàng, rồi theo số lượng giảm dần.
  arrange(Store_Location, desc(n)) 
  # -> Bảng kết quả được lưu vào biến 'transaction_value_by_store'.


# --- TRÌNH BÀY BẢNG KẾT QUẢ ---
kable(transaction_value_by_store, 
      caption = "Số lượng giao dịch theo từng phân khúc giá trị tại mỗi cửa hàng",
      # Đổi tên các cột tiêu đề sang tiếng Việt.
      col.names = c("Địa điểm", "Giá trị giao dịch", "Số lượng"))
Số lượng giao dịch theo từng phân khúc giá trị tại mỗi cửa hàng
Địa điểm Giá trị giao dịch Số lượng
Chicago $5,000 - $15,000 6211
Chicago Dưới $5,000 6131
Chicago Trên $15,000 1865
Houston Dưới $5,000 6126
Houston $5,000 - $15,000 6125
Houston Trên $15,000 1898
Los Angeles Dưới $5,000 6106
Los Angeles $5,000 - $15,000 6095
Los Angeles Trên $15,000 1913
New York Dưới $5,000 6265
New York $5,000 - $15,000 6234
New York Trên $15,000 2016
Philadelphia Dưới $5,000 6261
Philadelphia $5,000 - $15,000 6125
Philadelphia Trên $15,000 1944
Phoenix Dưới $5,000 6283
Phoenix $5,000 - $15,000 6160
Phoenix Trên $15,000 1942
San Antonio Dưới $5,000 6295
San Antonio $5,000 - $15,000 6166
San Antonio Trên $15,000 1839

3.4.4 Top 10 nhân viên bán được nhiều xe nhất:

# --- TẠO BẢNG XẾP HẠNG TOP 10 NHÂN VIÊN BÁN NHIỀU XE NHẤT ---
top_salesperson_quantity <- BK1 %>%
  
  # Gom nhóm dữ liệu theo ID của mỗi nhân viên.
  group_by(Salesperson_ID) %>%
  
  # Với mỗi nhân viên, tính tổng số lượng xe đã bán.
  summarise(Total_Quantity_Sold = sum(Quantity)) %>%
  
  # Sắp xếp toàn bộ danh sách nhân viên theo thứ tự giảm dần.
  arrange(desc(Total_Quantity_Sold)) %>%
  
  # top_n(): Lọc và chỉ giữ lại 10 hàng đầu tiên trong bảng đã sắp xếp.
  top_n(10, Total_Quantity_Sold)
  # -> Bảng kết quả Top 10 được lưu vào biến 'top_salesperson_quantity'.


# --- TRÌNH BÀY BẢNG KẾT QUẢ ---
kable(top_salesperson_quantity, 
      caption = "Top 10 nhân viên bán nhiều xe nhất",
      col.names = c("ID nhân viên", "Tổng số lượng bán"))
Top 10 nhân viên bán nhiều xe nhất
ID nhân viên Tổng số lượng bán
794 441
693 435
422 419
653 418
869 417
291 415
557 415
830 415
894 414
541 413
  • Nhận xét: Các thống kê này giúp đánh giá hiệu quả hoạt động của từng chi nhánh và hiệu suất làm việc của cá nhân, từ đó có chính sách khen thưởng hoặc cải thiện phù hợp.

3.5 Phân tích theo Khách hàng

3.5.1 Tổng số khách hàng duy nhất:

total_unique_customers <- n_distinct(BK1$Customer_ID)
# n_distinct(): Hàm từ 'dplyr' để đếm số lượng giá trị duy nhất (không lặp lại).
# BK1$Customer_ID: Áp dụng hàm đếm trên cột ID khách hàng.
cat("Tổng số khách hàng duy nhất:", comma(total_unique_customers))
## Tổng số khách hàng duy nhất: 9,000

3.5.2 Đặc điểm nhân khẩu học của khách hàng:

# --- PHẦN 1: TÍNH TUỔI TRUNG BÌNH ---

# Tính giá trị trung bình của cột tuổi khách hàng.
mean_customer_age <- mean(BK1$Customer_Age)

# In kết quả đã làm tròn đến 1 chữ số thập phân ra màn hình.
cat("Độ tuổi trung bình của khách hàng:", round(mean_customer_age, 1), "tuổi\n")
## Độ tuổi trung bình của khách hàng: 44 tuổi
# --- PHẦN 2: THỐNG KÊ PHÂN BỔ GIỚI TÍNH ---

# Đếm số lượng, tính tỷ lệ phần trăm cho mỗi giới tính, và lưu kết quả.
gender_distribution <- BK1 %>%
  count(Customer_Gender, sort = TRUE) %>%
  mutate(Percentage = n / sum(n) * 100)

# Trình bày kết quả dưới dạng bảng.
kable(gender_distribution, caption = "Phân bổ khách hàng theo giới tính",col.names = c("Giới tính", "Số lượng KH","Tỷ lệ" ))
Phân bổ khách hàng theo giới tính
Giới tính Số lượng KH Tỷ lệ
Female 50227 50.227
Male 49773 49.773

Nhận xét:

  • Về Độ tuổi: Độ tuổi trung bình của khách hàng là khoảng 44 tuổi (dựa trên kết quả tính toán ở trên). Điều này cho thấy nhóm khách hàng cốt lõi của công ty là những người ở độ tuổi trung niên, có sự ổn định về tài chính và nhận thức về sức khỏe.

  • Về Giới tính: Điểm nổi bật nhất là sự cân bằng gần như hoàn hảo về giới tính trong tệp khách hàng. Tỷ lệ khách hàng Nữ (50.23%) và Nam (49.77%) gần như là 50/50. Sự chênh lệch là không đáng kể, cho thấy các sản phẩm xe đạp của công ty có sức hấp dẫn rộng rãi, không hề thiên vị một giới tính cụ thể nào.

3.5.3 Phân tích doanh thu theo các nhóm tuổi đã phân tổ:

revenue_by_age_group <- BK1 %>%
  group_by(Age_Group) %>%
  summarise(
    Total_Revenue = sum(Revenue),
    Average_Purchase_Value = mean(Revenue)
    ) %>%
  arrange(desc(Total_Revenue))
kable(revenue_by_age_group, caption = "Doanh thu theo nhóm tuổi", col.names = c("Nhóm tuổi", "Tổng Doanh thu", "GT mua TB"))
Doanh thu theo nhóm tuổi
Nhóm tuổi Tổng Doanh thu GT mua TB
Trung niên (31-55) 367911187 7820.244
Lớn tuổi (56+) 220315371 7741.501
Trẻ (18-30) 190207676 7765.163

Nhận xét:

  • Tập trung duy trì: Các chiến dịch marketing và chương trình khách hàng thân thiết nên tập trung vào nhóm “Trung niên (31-55)” để duy trì và phát huy “mỏ vàng” này.

  • Cơ hội phát triển: Vì các nhóm “Trẻ” và “Lớn tuổi” vẫn có sức mua tương đương, đây là những thị trường tiềm năng. Công ty có thể nghiên cứu các chiến lược để tăng số lượng khách hàng hoặc khuyến khích tần suất mua sắm ở hai nhóm này để khai thác thêm doanh thu.

  • Nhận xét chung: Giúp phác họa chân dung khách hàng mục tiêu và xác định nhóm tuổi nào đang là nguồn doanh thu chính.

3.6 Phân tích Lòng trung thành của Khách hàng

3.6.1 Đóng góp Doanh thu của từng Hạng khách hàng vào các Phân khúc giá:

# --- PHÂN TÍCH DOANH THU THEO HẠNG KHÁCH HÀNG VÀ PHÂN KHÚC GIÁ ---
revenue_by_loyalty_price <- BK1 %>%
  
  # Gom nhóm dữ liệu theo cả Hạng khách hàng VÀ Phân khúc giá.
  group_by(Loyalty_Status, Price_Level) %>%
  
  # Tính tổng doanh thu cho mỗi cặp nhóm.
  summarise(Total_Revenue = sum(Revenue), .groups = 'drop') %>%
  
  # Sắp xếp kết quả: theo Hạng khách hàng trước, sau đó theo Doanh thu giảm dần.
  arrange(Loyalty_Status, desc(Total_Revenue))
  # -> Bảng kết quả được lưu vào biến 'revenue_by_loyalty_price'.


# --- TRÌNH BÀY BẢNG KẾT QUẢ ---
kable(revenue_by_loyalty_price,
      caption = "Tổng doanh thu theo Hạng khách hàng và Phân khúc giá",
      # Đổi tên các cột tiêu đề sang tiếng Việt.
      col.names = c("Hạng Khách hàng", "Phân khúc Giá", "Tổng Doanh thu"))
Tổng doanh thu theo Hạng khách hàng và Phân khúc giá
Hạng Khách hàng Phân khúc Giá Tổng Doanh thu
Khách hàng mới Cao cấp 65660789
Khách hàng mới Hạng sang 62633342
Khách hàng mới Phổ thông 47142927
Thân thiết Cao cấp 158421038
Thân thiết Hạng sang 151258194
Thân thiết Phổ thông 115380053
VIP Cao cấp 66330031
VIP Hạng sang 64053325
VIP Phổ thông 47554537

Nhận xét:

  • Sản phẩm chủ lực là phân khúc giá cao: Công ty nên tập trung các nỗ lực marketing, phát triển sản phẩm và quản lý tồn kho cho hai phân khúc “Cao cấp” và “Hạng sang” vì đây là “cỗ máy kiếm tiền” chính, thu hút được tất cả các nhóm khách hàng.

  • Hành trình khách hàng hiệu quả: Mô hình kinh doanh đang hoạt động tốt: Thu hút khách hàng mới bằng sản phẩm chất lượng -> Nuôi dưỡng họ thành khách hàng thân thiết, chi tiêu nhiều hơn -> Chuyển đổi họ thành khách hàng VIP trung thành.

  • Vai trò của phân khúc “Phổ thông”: Mặc dù có doanh thu thấp nhất, phân khúc “Phổ thông” vẫn có thể đóng vai trò quan trọng trong việc tạo ra một danh mục sản phẩm hoàn chỉnh hoặc là điểm bắt đầu cho một số ít khách hàng nhạy cảm về giá. Tuy nhiên, rõ ràng đây không phải là động lực tăng trưởng chính của công ty.

3.6.2 Cửa hàng được khách hàng “VIP” ghé thăm nhiều nhất:

# --- TÌM CỬA HÀNG ĐƯỢC KHÁCH HÀNG VIP GHÉ THĂM NHIỀU NHẤT ---
platinum_store_preference <- BK1 %>%
  
  # Bước 1: Lọc ra chỉ những giao dịch của khách hàng hạng "VIP".
  filter(Loyalty_Status == "VIP") %>%
  
  # Bước 2: Đếm số lượng giao dịch này theo từng cửa hàng và sắp xếp giảm dần.
  count(Store_Location, sort = TRUE) %>%
  
  # Bước 3: Chỉ giữ lại 1 cửa hàng đứng đầu trong danh sách.
  top_n(1)
  # -> Kết quả (một bảng chỉ có 1 dòng) được lưu vào biến 'platinum_store_preference'.


# --- TRÌNH BÀY BẢNG KẾT QUẢ ---
kable(platinum_store_preference, caption = "Cửa hàng ưa thích của khách hàng VIP")
Cửa hàng ưa thích của khách hàng VIP
Store_Location n
San Antonio 3319

Nhận xét: San Antonio là điểm đến ưa thích nhất của nhóm khách hàng VIP, với số lượng giao dịch vượt trội là 3,319. Điều này cho thấy cửa hàng tại San Antonio đã rất thành công trong việc xây dựng và duy trì mối quan hệ với những khách hàng giá trị nhất. Đây là một mô hình thành công cần được nghiên cứu và nhân rộng ra các chi nhánh khác.

3.6.3 Phân bổ Hạng khách hàng theo từng Cửa hàng:

loyalty_by_store <- BK1 %>%
  group_by(Store_Location, Loyalty_Status) %>%
  # Đếm số lượng khách hàng duy nhất, không phải số giao dịch
  summarise(Unique_Customer_Count = n_distinct(Customer_ID), .groups = 'drop') %>%
  arrange(Store_Location, desc(Unique_Customer_Count))

kable(loyalty_by_store, 
      caption = "Số lượng khách hàng duy nhất theo Hạng và Địa điểm cửa hàng",
      col.names = c("Địa điểm", "Hạng Khách hàng", "Số lượng KH"))
Số lượng khách hàng duy nhất theo Hạng và Địa điểm cửa hàng
Địa điểm Hạng Khách hàng Số lượng KH
Chicago Thân thiết 3851
Chicago Khách hàng mới 2036
Chicago VIP 1262
Houston Thân thiết 3821
Houston Khách hàng mới 2044
Houston VIP 1260
Los Angeles Thân thiết 3860
Los Angeles Khách hàng mới 1974
Los Angeles VIP 1281
New York Thân thiết 3851
New York Khách hàng mới 2068
New York VIP 1278
Philadelphia Thân thiết 3872
Philadelphia Khách hàng mới 1992
Philadelphia VIP 1262
Phoenix Thân thiết 3848
Phoenix Khách hàng mới 2003
Phoenix VIP 1281
San Antonio Thân thiết 3839
San Antonio Khách hàng mới 2026
San Antonio VIP 1264

Nhận xét: Tại mọi cửa hàng, từ Chicago đến San Antonio, mô hình phân bổ khách hàng đều tuân theo một quy luật chung rất rõ ràng:

  • Nhóm “Thân thiết” luôn là nhóm khách hàng đông đảo nhất, chiếm số lượng lớn nhất.

  • Nhóm “Khách hàng mới” đứng ở vị trí thứ hai.

  • Nhóm “VIP” là nhóm có số lượng ít nhất, thể hiện tính chọn lọc và độc quyền.

Không có cửa hàng nào có cấu trúc khách hàng khác biệt một cách đáng kể. Số lượng khách hàng ở mỗi hạng tại các thành phố khác nhau là rất tương đồng. Ví dụ, số lượng khách hàng “Thân thiết” ở mọi nơi đều dao động quanh mốc 3,800 người.

3.6.4 Sự phát triển Doanh thu theo từng hạng khách hàng qua các năm:

revenue_by_loyalty_over_time <- BK1 %>%
  group_by(Year, Loyalty_Status) %>%
  summarise(Total_Revenue = sum(Revenue), .groups = 'drop') %>%
  # Sắp xếp để bảng kết quả dễ đọc hơn
  arrange(Year, Loyalty_Status)

kable(revenue_by_loyalty_over_time,
      caption = "Tổng doanh thu theo từng Hạng khách hàng qua các năm",
      col.names = c("Năm", "Hạng Khách hàng", "Tổng Doanh thu"))
Tổng doanh thu theo từng Hạng khách hàng qua các năm
Năm Hạng Khách hàng Tổng Doanh thu
2020 Khách hàng mới 37618231
2020 Thân thiết 90277093
2020 VIP 36329167
2021 Khách hàng mới 36714800
2021 Thân thiết 89142641
2021 VIP 37677803
2022 Khách hàng mới 37442841
2022 Thân thiết 89922738
2022 VIP 38195171
2023 Khách hàng mới 37084619
2023 Thân thiết 89494397
2023 VIP 37918558
2024 Khách hàng mới 26576568
2024 Thân thiết 66222416
2024 VIP 27817193

Nhận xét:

  • “Khách hàng Thân thiết” là động lực chính: Ở tất cả các năm, nhóm khách hàng “Thân thiết” luôn là nguồn mang lại doanh thu vượt trội và áp đảo so với hai nhóm còn lại.

  • Sự ổn định qua thời gian: Doanh thu từ mỗi hạng khách hàng duy trì ở mức tương đối ổn định từ năm 2020 đến 2023, trước khi có dấu hiệu suy giảm nhẹ ở tất cả các nhóm vào năm 2024.

  • Cấu trúc không đổi: Tỷ lệ đóng góp giữa các nhóm gần như không thay đổi qua các năm: Khách hàng “Thân thiết” > Khách hàng “Mới” ≈ Khách hàng “VIP”.

  • Nhận xét chung: Đánh giá sức khỏe của chương trình khách hàng thân thiết. Liệu khách hàng hạng cao có thực sự chi tiêu nhiều hơn không? Phần lớn doanh thu đến từ nhóm khách hàng nào?

3.7 Phân tích theo Thời gian

3.7.1 Doanh thu theo từng năm:

revenue_by_year <- BK1 %>%
  group_by(Year) %>%
  summarise(Total_Revenue = sum(Revenue))
kable(revenue_by_year, caption = "Doanh thu theo năm", 
      col.names = c ("Năm", "Tổng doanh thu"))
Doanh thu theo năm
Năm Tổng doanh thu
2020 164224491
2021 163535245
2022 165560749
2023 164497574
2024 120616177

Nhận xét:

  • Giai đoạn 2020-2023: Hiệu suất ổn định và mạnh mẽ

Doanh thu của công ty duy trì ở mức rất cao và ổn định, dao động quanh mốc 164 triệu USD mỗi năm. Điều này cho thấy hoạt động kinh doanh rất vững chắc và có thể dự báo được trong giai đoạn này.

  • Năm 2024: Tín hiệu tăng trưởng tích cực

Số liệu doanh thu của năm 2024 (120.6 triệu USD) mới chỉ phản ánh kết quả kinh doanh của hai quý đầu năm.

So sánh với mức trung bình hàng năm (~164 triệu USD), việc đạt được gần 74% mục tiêu cả năm chỉ trong nửa đầu năm là một tín hiệu cực kỳ tích cực.

Nếu duy trì được đà kinh doanh này, doanh thu cả năm 2024 được dự báo sẽ vượt xa so với các năm trước, cho thấy một sự tăng trưởng mạnh mẽ.

3.7.2 Doanh thu theo từng mùa:

revenue_by_season <- BK1 %>%
  group_by(Season) %>%
  summarise(Total_Revenue = sum(Revenue)) %>%
  arrange(desc(Total_Revenue))
kable(revenue_by_season, caption = "Doanh thu theo mùa", col.names=c("Mùa", "Tổng doanh thu"))
Doanh thu theo mùa
Mùa Tổng doanh thu
Hạ 207337508
Xuân 207312828
Đông 188748226
Thu 175035674

Nhận xét:

  • Mùa cao điểm: Mùa Hè và Mùa Xuân là hai mùa kinh doanh sôi động nhất, mang lại doanh thu cao và gần như tương đương nhau. Đây là giai đoạn “vàng” của công ty.

  • Mùa thấp điểm: Ngược lại, Mùa Thu là mùa có doanh thu thấp nhất, cho thấy nhu cầu mua sắm giảm đáng kể trong giai đoạn này, theo sau là Mùa Đông.

3.7.3 Doanh thu theo từng ngày trong tuần:

revenue_by_weekday <- BK1 %>%
  group_by(Weekday) %>%
  summarise(Total_Revenue = sum(Revenue)) %>%
  arrange(desc(Total_Revenue))
kable(revenue_by_weekday, caption = "Doanh thu theo ngày trong tuần", col.names=c("Ngày", "Tổng doanh thu"))
Doanh thu theo ngày trong tuần
Ngày Tổng doanh thu
Thứ Năm 113678630
Thứ Sáu 111803200
Thứ Tư 111762837
Thứ Bảy 111409344
Thứ Hai 110441224
Chủ Nhật 110304080
Thứ Ba 109034920

Nhận xét: Hành vi mua sắm của khách hàng không bị phụ thuộc nhiều vào các ngày nghỉ. Điều này cho thấy khách hàng có thể là những người có nhu cầu ổn định, mua sắm thường xuyên trong suốt cả tuần. Sự ổn định này giúp việc lên kế hoạch nhân sự và quản lý hàng tồn kho trở nên dễ dàng và hiệu quả hơn.

  • Nhận xét chung: Giúp phát hiện các xu hướng mùa vụ, xác định các thời điểm kinh doanh cao điểm để lên kế hoạch marketing, nhân sự và tồn kho hiệu quả.

3.8 Phân tích Hành vi và Tương quan

3.8.1 Mức độ ưa chuộng theo phân khúc giá:

price_level_popularity <- BK1 %>%
  count(Price_Level, sort = TRUE) %>% 
  mutate(Percentage = round(n / sum(n) * 100, 2))

# In bảng kết quả
kable(price_level_popularity, 
      caption = "Mức độ phổ biến của các phân khúc giá",
      col.names = c("Phân khúc giá", "Số lượng giao dịch", "Tỷ lệ"))
Mức độ phổ biến của các phân khúc giá
Phân khúc giá Số lượng giao dịch Tỷ lệ
Phổ thông 50030 50.03
Cao cấp 29341 29.34
Hạng sang 20629 20.63

Nhận xét: Cấu trúc sản phẩm của công ty có dạng hình kim tự tháp rõ rệt. Đáy của kim tự tháp là dòng sản phẩm “Phổ thông”, phục vụ cho số đông và là nguồn doanh số chính. Các phân khúc “Cao cấp” và “Hạng sang” tuy chiếm tỷ trọng nhỏ hơn nhưng vẫn đóng vai trò quan trọng trong việc đa dạng hóa danh mục, nâng cao hình ảnh thương hiệu và phục vụ các nhóm khách hàng có khả năng chi trả cao hơn.

3.8.2 Mẫu xe được ưa chuộng nhất theo giới tính:

model_preference_by_location <- BK1 %>%
  group_by(Store_Location, Bike_Model) %>%
  summarise(Total_Quantity = sum(Quantity), .groups = 'drop') %>%
  group_by(Store_Location) %>%
  top_n(1, Total_Quantity)
kable(model_preference_by_location, caption = "Mẫu xe được ưa chuộng nhất theo địa điểm",
      col.names = c("Địa điểm","Mẫu xe", "Tổng số lượng bán"))
Mẫu xe được ưa chuộng nhất theo địa điểm
Địa điểm Mẫu xe Tổng số lượng bán
Chicago Hybrid Bike 6318
Houston Road Bike 6243
Los Angeles Folding Bike 6251
New York Hybrid Bike 6422
Philadelphia BMX 6253
Phoenix Cruiser 6442
San Antonio Folding Bike 6248

Nhận xét: Phân tích cho thấy thị hiếu của khách hàng có sự khác biệt rõ rệt theo từng địa điểm. Không có mẫu xe nào thống trị toàn bộ hệ thống; mỗi thành phố lại có một mẫu xe bán chạy nhất riêng, ví dụ như Cruiser tại Phoenix hay BMX tại Philadelphia.

Kết luận: Công ty nên áp dụng chiến lược marketing và quản lý tồn kho riêng cho từng khu vực để tối ưu hiệu quả kinh doanh.

3.8.3 Tương quan giữa Doanh thu và Giá xe:

correlation_re_price <- cor(BK1$Revenue, BK1$Price)
print(paste("Hệ số tương quan giữa Doanh thu và Giá xe:", round(correlation_re_price, 4)))
## [1] "Hệ số tương quan giữa Doanh thu và Giá xe: 0.7055"

Giải thích code: Hàm cor() trong R để tính toán hệ số tương quan Pearson giữa hai biến.

Ý nghĩa: Kết quả 0.7055, một con số dương và khá gần với 1. Điều này cho thấy có một mối quan hệ tương quan dương mạnh giữa Giá xe (Price) và Doanh thu (Revenue) của một giao dịch. Nói một cách đơn giản: Khi giá của chiếc xe trong một giao dịch tăng lên, thì doanh thu của giao dịch đó cũng có xu hướng tăng theo. Mối quan hệ này là hợp lý và đúng với mong đợi trong kinh doanh.

4. Trực Quan Hóa Dữ Liệu

Trong chương này, chúng ta sẽ sử dụng thư viện ggplot2 và các phần mở rộng của nó để trực quan hóa các insight đã tìm thấy, giúp truyền tải thông tin một cách sinh động và dễ hiểu.

4.1 Phân tích Doanh thu và Sản phẩm

4.1.1 Biểu đồ cột: Doanh thu theo từng mẫu xe theo địa điểm cửa hàng

# --- BƯỚC 1: CHUẨN BỊ DỮ LIỆU TÓM TẮT ---
# Tạo bảng tóm tắt doanh thu theo từng cặp (Mẫu xe, Cửa hàng).
revenue_by_model_store <- BK1 %>%
  group_by(Bike_Model, Store_Location) %>%
  summarise(Total_Revenue = sum(Revenue), .groups = "drop")

# --- BƯỚC 2: VẼ BIỂU ĐỒ CỘT NHÓM ---
ggplot(revenue_by_model_store, 
       # aes(): Ánh xạ dữ liệu vào các yếu tố hình ảnh.
       aes(x = reorder(Bike_Model, -Total_Revenue), # Trục X: Mẫu xe, sắp xếp giảm dần theo Doanh thu.
           y = Total_Revenue,                      # Trục Y: Tổng doanh thu (chiều cao cột).
           fill = Store_Location)) +               # Fill: Màu sắc của cột thể hiện Cửa hàng.
  
  # geom_bar(): Vẽ các cột.
  #   - stat = "identity": Sử dụng giá trị y đã cung cấp làm chiều cao.
  #   - position = "dodge": Đặt các cột cạnh nhau thay vì chồng lên nhau.
  geom_bar(stat = "identity", position = "dodge") +
  
  # labs(): Đặt tiêu đề và tên cho các trục, chú giải.
  labs(title = "So sánh Doanh Thu của Từng Mẫu Xe Theo Địa Điểm Cửa Hàng",
       subtitle = "Giúp xác định mẫu xe nào là sản phẩm chủ lực tại từng địa điểm",
       x = "Mẫu Xe",
       y = "Tổng Doanh Thu",
       fill = "Địa điểm cửa hàng") +
       
  # scale_y_continuous(): Định dạng lại trục Y.
  scale_y_continuous(labels = scales::dollar) + # Hiển thị dạng tiền tệ ($).
  
  # theme(): Tùy chỉnh giao diện.
  # Xoay nhãn trục X 45 độ để tránh chồng chéo.
  theme(axis.text.x = element_text(angle = 45, hjust = 1))

Ý nghĩa: - So sánh hiệu suất sản phẩm: Có thể dễ dàng thấy mẫu xe nào đang tạo ra doanh thu cao nhất hoặc thấp nhất tại một địa điểm cụ thể. Ví dụ, tại New York (cột màu xanh mòng két), “Road Bike” và “Hybrid Bike” có vẻ là những mẫu xe có doanh thu cao nhất.

  • So sánh hiệu suất cửa hàng: Đối với một mẫu xe nhất định, ta có thể so sánh xem cửa hàng ở thành phố nào bán chạy nhất. Ví dụ, với “Mountain Bike”, cửa hàng ở Los Angeles (cột màu xanh lá) có doanh thu cao hơn hẳn so với các cửa hàng khác.

  • Xác định sản phẩm chủ lực: Đúng như phụ đề của biểu đồ, mục đích chính là “Giúp xác định mẫu xe nào là sản phẩm chủ lực tại từng địa điểm”. Dựa vào chiều cao các cột, nhà quản lý có thể biết được ở Chicago nên tập trung vào sản phẩm nào, ở Houston nên tập trung vào sản phẩm nào, từ đó đưa ra các chiến lược kinh doanh và marketing phù hợp cho từng khu vực.

4.1.2 Biểu đồ cột phân nhóm: Doanh thu theo Mẫu xe và Hạng Khách hàng

revenue_model_loyalty <- BK1 %>%
  group_by(Bike_Model, Loyalty_Status) %>%
  summarise(Total_Revenue = sum(Revenue), .groups = 'drop')

ggplot(revenue_model_loyalty, aes(x = Bike_Model, y = Total_Revenue, fill = Loyalty_Status)) +
  geom_bar(stat = "identity", position = "dodge") +
  labs(title = "Doanh Thu Theo Mẫu Xe và Hạng Khách Hàng",
       subtitle = "So sánh sự đóng góp doanh thu của từng nhóm khách hàng cho mỗi mẫu xe",
       x = "Mẫu Xe",
       y = "Tổng Doanh Thu",
       fill = "Hạng Khách Hàng") +
  scale_y_continuous(labels = scales::dollar) +
  scale_fill_brewer(palette = "Set1") +
  theme_minimal() +
  theme(axis.text.x = element_text(angle = 45, hjust = 1))

Ý nghĩa:

  • “Khách hàng Thân thiết” (xanh dương) là nguồn doanh thu chính, chiếm phần lớn nhất một cách áp đảo.

  • Hai nhóm “Khách hàng mới” (đỏ) và “VIP” (xanh lá) có mức đóng góp tương đương nhau và thấp hơn đáng kể.

Kết luận: Sức mạnh tài chính của công ty đến từ tệp khách hàng thân thiết. Việc giữ chân và phát triển nhóm này là yếu tố quan trọng nhất để tăng doanh thu cho mọi dòng sản phẩm.

4.1.3 Biểu đồ tròn: Tỷ lệ Doanh thu theo Địa điểm Cửa hàng

revenue_by_store <- BK1 %>%
  group_by(Store_Location) %>%
  summarise(Total_Revenue = sum(Revenue))

ggplot(revenue_by_store, aes(x = "", y = Total_Revenue, fill = Store_Location)) +
  geom_bar(stat = "identity", width = 1) +
  coord_polar("y", start = 0) +
  geom_text(aes(label = scales::percent(Total_Revenue / sum(Total_Revenue), accuracy = 0.1)),
            position = position_stack(vjust = 0.5), color = "white", size = 5) +
  labs(title = "Tỷ Lệ Phân Bổ Doanh Thu Theo Địa Điểm Cửa Hàng",
       fill = "Địa Điểm Cửa Hàng", x = NULL, y = NULL) +
  theme_void() +
  theme(legend.title = element_text(face = "bold"))

Giải thích code:

  • ggplot(revenue_by_store, aes(x = ““, y = Total_Revenue, fill = Store_Location)): Khởi tạo biểu đồ. Thay vì vẽ các cột riêng biệt, x =”” làm cho tất cả các giá trị được xếp chồng lên nhau tại một vị trí duy nhất, đây là bước đầu tiên để tạo biểu đồ tròn từ biểu đồ cột.

  • geom_bar(stat = “identity”, width = 1): Vẽ một biểu đồ cột chồng duy nhất.

  • coord_polar(“y”, start = 0): Đây là lệnh quan trọng nhất. Nó biến đổi hệ tọa độ của biểu đồ cột chồng thành hệ tọa độ cực, uốn cong thanh cột đó thành một hình tròn, tạo ra biểu đồ tròn.

Ý nghĩa: Sự chênh lệch giữa cửa hàng hoạt động tốt nhất (New York) và thấp nhất (San Antonio) chỉ là 0.5%. Điều này cho thấy hiệu suất kinh doanh của các chi nhánh đang ở mức tương đối cân bằng.

4.1.4 Biểu đồ Barplot (cột chồng): Cơ cấu Số lượng Sản phẩm Bán ra theo Mức giá tại mỗi Cửa hàng

# Tính toán tổng số lượng theo từng Cửa hàng và Mức giá
quantity_by_store_price <- BK1 %>%
  group_by(Store_Location, Price_Level) %>%
  summarise(Total_Quantity = sum(Quantity), .groups = "drop")

# Tính tổng số lượng của mỗi cửa hàng để sắp xếp các cột
store_order <- BK1 %>%
  group_by(Store_Location) %>%
  summarise(Grand_Total_Quantity = sum(Quantity)) %>%
  arrange(desc(Grand_Total_Quantity))

# Áp dụng thứ tự cho bảng dữ liệu sẽ vẽ
quantity_by_store_price$Store_Location <- factor(quantity_by_store_price$Store_Location, levels = store_order$Store_Location)

ggplot(quantity_by_store_price, 
       aes(x = Store_Location, y = Total_Quantity, fill = Price_Level)) +
  geom_col() + # Sử dụng geom_col cho biểu đồ cột chồng
  geom_text(aes(label = scales::comma(Total_Quantity)), 
            position = position_stack(vjust = 0.5), # Đặt nhãn vào giữa mỗi đoạn
            color = "black", size = 3.5) +
  labs(title = "Cơ Cấu Số Lượng Sản Phẩm Bán Ra Theo Mức Giá Tại Mỗi Cửa Hàng",
       x = "Địa Điểm Cửa Hàng",
       y = "Tổng Số Lượng Xe Bán Ra",
       fill = "Mức Giá") +
  scale_y_continuous(labels = scales::comma) +
  scale_fill_brewer(palette = "viridis") + # Sử dụng một bảng màu khác
  theme_minimal() +
  theme(axis.text.x = element_text(angle = 30, hjust = 1))

Ý nghĩa:

  • Hiệu suất đồng đều: Tổng số lượng xe bán ra ở tất cả các cửa hàng là gần như bằng nhau.

  • Cơ cấu nhất quán: Tỷ lệ giữa các phân khúc giá (“Phổ thông”, “Cao cấp”, “Hạng sang”) là gần giống hệt nhau ở mọi địa điểm.

Kết luận: Toàn bộ hệ thống kinh doanh hoạt động rất ổn định và đồng nhất, cho phép công ty áp dụng một chiến lược chung cho tất cả các chi nhánh.

4.1.5 Biểu đồ Treemap: Tỷ lệ doanh thu theo mẫu xe

ggplot(revenue_by_model, aes(area = Total_Revenue, fill = Bike_Model, label = Bike_Model)) +
  geom_treemap() +
  geom_treemap_text(colour = "white", place = "centre", size = 14, grow = TRUE) +
  labs(title = "Tỷ Trọng Doanh Thu Theo Mẫu Xe",
       fill = "Mẫu xe")

Ý nghĩa: Không có bất kỳ mẫu xe nào có diện tích vượt trội, cho thấy không có một sản phẩm “ngôi sao” nào đang thống trị hay “gánh” doanh thu cho toàn bộ công ty.

Kết luận:

  • Giảm thiểu rủi ro: Công ty không bị phụ thuộc vào sự thành công của bất kỳ một sản phẩm riêng lẻ nào. Nếu một mẫu xe gặp vấn đề, các mẫu xe khác vẫn có thể duy trì hoạt động kinh doanh ổn định.

  • Tiếp cận thị trường rộng: Sự thành công đồng đều cho thấy công ty đã đáp ứng tốt nhu cầu của nhiều phân khúc khách hàng khác nhau.

4.1.6 Biểu đồ đường: Xu hướng Giá bán Trung bình Hàng tháng

monthly_avg_price <- BK1 %>%
  mutate(YearMonth = floor_date(Date, "month")) %>%
  group_by(YearMonth) %>%
  summarise(Avg_Price = mean(Price), .groups = "drop")
ggplot(data = monthly_avg_price, aes(x = YearMonth, y = Avg_Price)) +
  geom_line(color = "darkgreen", size = 1) + # Layer hình học (Đường)
  geom_point(color = "orange", size = 3) +   # Layer hình học (Điểm)
  labs(
    title = "Xu Hướng Giá Bán Trung Bình Hàng Tháng",
    subtitle = "Giai đoạn 2022 - 2024",
    x = "Thời Gian",
    y = "Giá Bán Trung Bình"
  ) +
  scale_y_continuous(labels = dollar_format()) +
  scale_x_date(date_breaks = "3 months", date_labels = "%b %Y") +
  theme_minimal() +
  theme(axis.text.x = element_text(angle = 45, hjust = 1))

Ý nghĩa: Biểu đồ cho thấy giá bán trung bình hàng tháng biến động rất mạnh và không có một xu hướng tăng hay giảm dài hạn rõ rệt. Thay vì một đường đi lên hoặc xuống ổn định, giá cả liên tục dao động thất thường qua từng tháng. Điều này cho thấy chiến lược giá có thể bị ảnh hưởng bởi các yếu tố ngắn hạn như các đợt khuyến mãi hoặc sự thay đổi trong cơ cấu sản phẩm bán ra mỗi tháng.

4.1.7 Biểu đồ đường: Xu hướng doanh thu qua các tháng có thêm đường trung bình động 3 tháng

revenue_over_time <- BK1 %>%
  mutate(YearMonth = floor_date(Date, "month")) %>%
  group_by(YearMonth) %>%
  summarise(Monthly_Revenue = sum(Revenue), .groups = "drop") %>%
  mutate(MA3 = rollmean(Monthly_Revenue, k = 3, fill = NA, align = "right"))

ggplot(revenue_over_time, aes(x = YearMonth)) +
  geom_line(aes(y = Monthly_Revenue), color = "steelblue", size = 1) +
  geom_point(aes(y = Monthly_Revenue), color = "darkred", size = 2, shape = 21, fill = "yellow") +
  
  # Đường trung bình động 3 tháng
  geom_line(aes(y = MA3), color = "orange", size = 1.2, linetype = "solid") +
  
  labs(title = "Xu Hướng Doanh Thu Hàng Tháng",subtitle = "Có thêm đường Trung Bình Động 3 Tháng (MA3) để làm mượt xu hướng",
       x = "Thời Gian", 
       y = "Doanh Thu Tháng") +
  scale_y_continuous(labels = scales::dollar) +
  scale_x_date(date_breaks = "3 months", date_labels = "%b %Y") +
  theme_light() +
  theme(axis.text.x = element_text(angle = 45, hjust = 1))

Ý nghĩa: Đường MA3 cho thấy trong suốt giai đoạn từ 2020 đến giữa 2024, xu hướng doanh thu dài hạn là tương đối ổn định, dao động quanh mốc 13.5 đến 14 triệu đô la. Biểu đồ này cung cấp một cái nhìn sâu sắc và đáng tin cậy hơn về hiệu suất kinh doanh. Nó không chỉ cho thấy những gì đã xảy ra hàng tháng mà còn giúp lọc ra các biến động ngắn hạn để tập trung vào xu hướng cốt lõi, giúp các nhà quản lý đưa ra quyết định chiến lược tốt hơn.

4.1.8 Biểu đồ hộp (Boxplot): Phân bổ Độ tuổi Khách hàng theo Từng mẫu xe

ggplot(BK1, aes(x = reorder(Bike_Model, Customer_Age, FUN = median), y = Customer_Age, fill = Bike_Model)) +
  geom_boxplot(show.legend = FALSE) +
  stat_summary(fun = mean, geom = "point", shape = 23, size = 3, fill = "white") + # Thêm điểm trung bình
  labs(title = "Phân Bổ Độ Tuổi Khách Hàng Theo Từng Mẫu Xe",
       subtitle = "Mỗi mẫu xe thu hút một phân khúc độ tuổi khác nhau",
       x = "Mẫu Xe", y = "Tuổi Khách Hàng") +
  theme_bw() +
  theme(axis.text.x = element_text(angle = 45, hjust = 1))

Ý nghĩa: Biểu đồ hộp cho thấy “Electric Bolt” không chỉ có giá trung bình cao nhất mà còn có khoảng giá rất rộng. Ngược lại, “Kids Explorer” có giá thấp và ít biến động.

4.1.9 Biểu đồ cột Facet: Số lượng xe bán ra theo từng mẫu xe và từng địa điểm cửa hàng

quantity_by_model_store <- BK1 %>%
  group_by(Store_Location, Bike_Model) %>%
  summarise(Total_Quantity = sum(Quantity), .groups = "drop")

ggplot(quantity_by_model_store, aes(x = Bike_Model, y = Total_Quantity)) +
  geom_col(position = "dodge", fill = "yellow") +
  facet_wrap(~ Store_Location) +
  geom_text(aes(label = Total_Quantity), vjust = -0.1, size = 2.5) +
  labs(title = "Số lượng xe bán ra theo từng mẫu xe tại mỗ địa điểm cửa hàng",
       subtitle = "So sánh mức độ tiêu thụ sản phẩm giữa các địa điểm",
       x = "Mẫu Xe",
       y = "Số Lượng Bán Ra") +
  theme_minimal() +
  theme(axis.text.x = element_text(angle = 45, hjust = 1))

Ý nghĩa: Độ tuổi trung vị (đường kẻ ngang) và khoảng phân vị (chiều cao hộp màu) gần như không có sự khác biệt.

Kết luận: Tất cả các mẫu xe đều có sức hấp dẫn tương đương đối với cùng một nhóm khách hàng có độ tuổi trung bình khoảng 44. Không có mẫu xe nào đặc biệt thu hút người trẻ hay người lớn tuổi hơn.

4.1.10. Biểu đồ mật độ: Phân bố Doanh thu mỗi Giao dịch

ggplot(BK1, aes(x = Revenue)) +
  geom_density(fill = "lightgreen", alpha = 0.7, color = "darkgreen", size = 1) +
  labs(
    title = "Phân Bố Giá Trị Mỗi Giao Dịch (Doanh Thu)",
    x = "Doanh thu (Revenue)",
    y = "Mật độ"
  ) +
  scale_x_continuous(labels = dollar_format()) +
  theme_minimal()

Ý nghĩa:

  • Phần lớn các giao dịch có giá trị thấp: Mật độ giao dịch tập trung đông nhất và cao nhất ở khoảng giá trị dưới 5,000 USD.

  • Giao dịch giá trị cao ít phổ biến hơn: Khi giá trị đơn hàng (doanh thu) tăng lên, số lượng giao dịch tương ứng giảm dần.

  • Có nhiều “cụm” giá trị: Sự xuất hiện của nhiều đỉnh/gợn sóng cho thấy có nhiều mức giá trị giao dịch phổ biến khác nhau, có thể do việc mua các sản phẩm hoặc số lượng khác nhau.

4.1.11 Biểu đồ mật độ: Biểu đồ mật độ phân bố giá theo từng mẫu xe

BK1Density <- BK1
BK1Density %>% 
  ggplot(aes(x = Price)) +
  geom_density(fill = "purple", alpha = 0.7) +
  facet_wrap(~ Bike_Model) +
  labs(
    title = "Phân bố giá theo từng mẫu xe",
    x = "Giá bán (Price)",
    y = "Mật độ"
  ) +
  theme_minimal()

Ý nghĩa: Giá bán của các mẫu xe nhìn chung phân bố khá đồng đều trong khoảng 500 – 5000 USD, không có sự chênh lệch quá lớn giữa các dòng xe. Tuy nhiên, một số dòng như BMX và Cruiser có xu hướng tập trung giá ở mức thấp hơn, trong khi Electric Bike và Hybrid Bike có phân bố giá rộng hơn, phản ánh các dòng xe này có thể có nhiều phiên bản hoặc phân khúc khác nhau. Điều này cho thấy thị trường sản phẩm có cấu trúc giá đa dạng nhưng vẫn cân đối giữa các nhóm xe.

4.2. Phân tích Khách hàng

4.2.1 Biểu đồ tần suất (Histogram): Phân bổ Giá trị mỗi Giao dịch (Doanh thu)

mean_revenue <- mean(BK1$Revenue)
median_revenue <- median(BK1$Revenue)

ggplot(BK1, aes(x = Revenue)) +
  geom_histogram(binwidth = 500, fill = "skyblue", color = "black", alpha = 0.7) +
  # Thêm một ĐƯỜNG THẲNG ĐỨNG (Vertical Line) vào biểu đồ.
# xintercept: Vị trí của đường thẳng trên trục X.
  geom_vline(aes(xintercept = mean_revenue), color = "red", linetype = "dashed", size = 1) +
  geom_vline(aes(xintercept = median_revenue), color = "green", linetype = "dashed", size = 1) +
  # Thêm một chú thích VĂN BẢN (Text) tĩnh lên biểu đồ.
# x, y: Tọa độ để đặt văn bản.
# label: Nội dung của văn bản cần hiển thị.
  annotate("text", x = mean_revenue + 3000, y = 3500, label = paste("Mean:", scales::dollar(mean_revenue)), color = "red") +
  annotate("text", x = median_revenue + 3000, y = 3000, label = paste("Median:", scales::dollar(median_revenue)), color = "green") +
  labs(title = "Phân Bổ Giá Trị Mỗi Giao Dịch",
       x = "Doanh thu mỗi giao dịch", y = "Số Lượng Giao Dịch") +
  scale_x_continuous(labels = scales::dollar) +
  theme_classic()

Ý nghĩa:

  • Tập trung ở giá trị thấp: Phần lớn các giao dịch có giá trị tập trung ở khoảng dưới 5,000 USD, thể hiện qua các cột cao nhất ở bên trái.

  • Phân phối lệch phải: Giá trị Trung bình (Mean) lớn hơn giá trị Trung vị (Median). Điều này cho thấy sự phân bổ bị “kéo” về phía bên phải bởi một số lượng ít hơn các giao dịch có giá trị cao.

Kết luận: Hầu hết khách hàng thực hiện các giao dịch nhỏ, nhưng doanh thu tổng vẫn bị ảnh hưởng đáng kể bởi một nhóm nhỏ khách hàng chi tiêu mạnh tay hơn.

4.2.2 Biểu đồ cột chồng: Doanh thu theo nhóm tuổi và giới tính

revenue_age_gender <- BK1 %>%
  group_by(Age_Group, Customer_Gender) %>%
  summarise(Total_Revenue = sum(Revenue), .groups = 'drop')

ggplot(revenue_age_gender, aes(x = Age_Group, y = Total_Revenue, fill = Customer_Gender)) +
  geom_bar(stat = "identity", position = "stack") +
  facet_wrap(~Customer_Gender) + # Chia thành các biểu đồ nhỏ theo giới tính
  labs(title = "Doanh Thu Theo Nhóm Tuổi và Giới Tính",
       x = "Nhóm Tuổi", y = "Tổng Doanh Thu", fill = "Giới Tính") +
  scale_y_continuous(labels = scales::dollar) +
  scale_fill_brewer(palette = "Set2") +
  theme_minimal()

Ý nghĩa: Nhóm tuổi “Trung niên” (31-55) đóng góp nhiều doanh thu nhất. Trong hầu hết các nhóm tuổi, tỷ lệ doanh thu từ nam và nữ khá tương đồng.

4.2.3 Biểu đồ phân tán (Scatter Plot): Mối quan hệ giữa tần suất mua hàng và giá trị đơn hàng

ggplot(BK1 %>% sample_n(5000), aes(x = Purchase_Count, y = Revenue)) + # Lấy mẫu 5000 điểm để vẽ cho nhẹ
  geom_point(alpha = 0.3, aes(color = Loyalty_Status)) +
  geom_smooth(method = "lm", color = "red", se = FALSE, linetype = "dashed") +
  labs(title = "Mối Quan Hệ Giữa Tần Suất Mua Hàng và Giá Trị Mỗi Đơn Hàng",
       subtitle = "Mỗi điểm là một giao dịch",
       x = "Tổng Số Lần Mua Hàng Của Khách Hàng", y = "Doanh Thu Mỗi Giao Dịch", color = "Hạng Khách Hàng") +
  scale_y_continuous(labels = scales::dollar) +
  scale_x_continuous(breaks = scales::pretty_breaks()) +
  theme_gray()

Ý nghĩa:

  • Không có mối tương quan rõ ràng: Đường xu hướng màu đỏ gần như nằm ngang cho thấy không có mối quan hệ giữa việc một khách hàng đã mua hàng bao nhiêu lần (trục X) và giá trị của một đơn hàng cụ thể của họ (trục Y). Khách hàng “lão làng” không hề chi tiêu nhiều hơn (hoặc ít hơn) cho một đơn hàng so với khách hàng mới.

  • Sự phân hóa theo Hạng khách hàng:

    • Khách hàng mới (màu đỏ) có tần suất mua hàng thấp (dưới 10 lần).

    • Khách hàng Thân thiết (màu xanh lá) có tần suất mua hàng ở mức trung bình (từ 10 đến 14 lần).

    • Khách hàng VIP (màu xanh dương) có tần suất mua hàng cao nhất (từ 15 lần trở lên).

Kết luận: Chương trình khách hàng thân thiết hoạt động đúng như thiết kế: khách hàng càng mua nhiều lần, hạng của họ càng cao. Tuy nhiên, lòng trung thành (hạng khách hàng) không phải là yếu tố quyết định giá trị của một đơn hàng cụ thể.

4.3. Phân tích Đa chiều và Chuyên sâu

4.3.1 Heatmap: Doanh thu theo Mẫu xe và Cửa hàng

# Bước 1: Chuẩn bị dữ liệu
store_model_heatmap_data <- BK1 %>%
  group_by(Store_Location, Bike_Model) %>%
  summarise(Total_Revenue = sum(Revenue), .groups = 'drop')

# Bước 2: Vẽ biểu đồ 
ggplot(store_model_heatmap_data, aes(x = Store_Location, y = Bike_Model, fill = Total_Revenue)) +
  geom_tile(color = "white", size = 0.5) +
  geom_text(aes(label = dollar(Total_Revenue, scale = 1/1e6, accuracy = 0.1, suffix = "M")),
            size = 3.5, color = "black") +
  scale_fill_viridis_c(
    # Tự chỉ định các điểm ngắt để chú thích trông đẹp nhất
    breaks = c(15000000, 16000000, 16700000),
    # Định dạng lại nhãn tương ứng
    labels = function(x) dollar(x, scale = 1/1e6, accuracy = 0.1, suffix = "M")
  ) +
  labs(
    title = "Heatmap Doanh Thu Theo Mẫu Xe và Cửa Hàng",
    subtitle = "Đơn vị: Triệu Đô la (M)",
    x = "Địa Điểm Cửa Hàng",
    y = "Mẫu Xe",
    fill = "Tổng Doanh Thu"
  ) +
  # Sửa lại hàm theme() cho đúng cú pháp
  theme(
    axis.text.x = element_text(angle = 45, hjust = 1),
    legend.key.width = unit(1.5, "cm") # Đưa vào bên trong theme()
  )

Ý nghĩa:

  • Sự đồng đều: Toàn bộ heatmap có một dải màu xanh lá cây và vàng tương đối đồng nhất. Điều này cho thấy doanh thu rất cân bằng và không có sự chênh lệch quá lớn giữa các mẫu xe hay các cửa hàng.

  • Điểm nóng (Hotspot): Ô màu vàng sáng nhất là Hybrid Bike tại New York ($16.7M), cho thấy đây là sự kết hợp mang lại doanh thu cao nhất.

  • Điểm lạnh (Coldspot): Ô màu tím đậm nhất là Mountain Bike tại Houston ($14.7M), là sự kết hợp có doanh thu thấp nhất.

Kết luận: Mặc dù có một vài “điểm nóng” và “điểm lạnh” nhỏ, nhưng nhìn chung, hiệu suất kinh doanh rất ổn định trên toàn bộ hệ thống. Không có một sản phẩm hay cửa hàng nào quá vượt trội hay quá yếu kém so với phần còn lại.

4.3.2 Biểu đồ Cột Chia nhỏ: Số lượng xe bán theo mùa và địa điểm cửa hàng

quantity_season_store <- BK1 %>%
  group_by(Season, Store_Location) %>%
  summarise(Total_Quantity = sum(Quantity), .groups = 'drop')
ggplot(quantity_season_store, aes(x = Season, y = Total_Quantity, fill = Season)) + 
  geom_col(show.legend = FALSE) + # Dùng geom_col và ẩn chú thích màu

  # Tách biểu đồ thành các ô nhỏ dựa trên địa điểm cửa hàng
  facet_wrap(~ Store_Location, nrow = 2) + # Hiển thị trên 2 hàng cho gọn

  geom_text(aes(label = comma(Total_Quantity)), vjust = 1, size = 3) + # Thêm nhãn

  labs(title = "So Sánh Xu Hướng Bán Hàng Theo Mùa Tại Từng Cửa Hàng",
       x = "Mùa", y = "Tổng Số Lượng Xe") +
  scale_y_continuous(labels = comma) +
  theme_light()

Ý nghĩa:

  • Mùa cao điểm: Tại mọi địa điểm, Mùa Hè (màu xanh lá) và Mùa Xuân (màu tím) luôn là hai mùa có số lượng xe bán ra cao nhất.

  • Mùa thấp điểm: Ngược lại, Mùa Thu (màu xanh dương) luôn là mùa bán chậm nhất ở tất cả các chi nhánh.

Kết luận: Tính mùa vụ trong kinh doanh là một quy luật chung, ảnh hưởng đồng đều lên toàn bộ hệ thống. Công ty có thể áp dụng một chiến lược kinh doanh chung theo mùa (ví dụ: tăng cường quảng cáo vào mùa Xuân-Hè và khuyến mãi vào mùa Thu) cho tất cả các cửa hàng.

4.3.3 Biểu đồ đường: Xu hướng số lượng xe bán theo quý và địa điểm cửa hàng

quantity_quarter_store <- BK1 %>%
  mutate(Quarter = paste0("Q", quarter(Date), "-", year(Date))) %>%   
  # Tạo biến Quý (VD: Q1-2023)
  group_by(Quarter, Store_Location) %>%
  summarise(Total_Quantity = sum(Quantity), .groups = "drop") %>%
  arrange(Quarter)

ggplot(quantity_quarter_store, aes(x = Quarter, y = Total_Quantity, color = Store_Location, group = Store_Location)) +
  geom_line(size = 1.2) +
  geom_point(size = 2) +
  labs(title = "Xu Hướng Số Lượng Xe Bán Theo Quý và Địa điểm cửa Hàng",
       x = "Quý",
       y = "Tổng Số Lượng Xe",
       color = "Địa điểm cửa Hàng") +
  theme_minimal() +
  theme(axis.text.x = element_text(angle = 45, hjust = 1))

Ý nghĩa:Số lượng xe bán ra dao động theo từng quý, thể hiện sự biến động nhu cầu của thị trường theo thời gian. Các cửa hàng như New York, Chicago và Los Angeles thường có mức bán ra cao và ổn định hơn so với các cửa hàng còn lại. Một số quý xuất hiện mức giảm mạnh (điểm đáy), cho thấy khả năng chịu ảnh hưởng từ yếu tố mùa vụ hoặc điều kiện kinh tế. Xu hướng tổng thể cho thấy không có chênh lệch quá lớn giữa các cửa hàng, nhưng một số cửa hàng duy trì hiệu suất tốt hơn liên tục, phản ánh ưu thế vị trí, thị hiếu hoặc chiến lược bán hàng hiệu quả.

4.3.4 Biểu đồ thanh ngang: Top 5 nhân viên bán được nhiều xe nhất.

top5_salesperson_quantity <- BK1 %>%
  group_by(Salesperson_ID) %>%
  summarise(Total_Quantity_Sold = sum(Quantity), .groups = 'drop') %>%
  arrange(desc(Total_Quantity_Sold)) %>% # Sắp xếp theo tổng số lượng giảm dần
  slice_head(n = 5)                      # Lấy 5 nhân viên hàng đầu
ggplot(top5_salesperson_quantity,
       # Cập nhật các biến trong aes()
       aes(x = reorder(as.factor(Salesperson_ID), Total_Quantity_Sold),
           y = Total_Quantity_Sold,
           fill = as.factor(Salesperson_ID))) +
  geom_bar(stat = "identity", show.legend = FALSE, width = 0.7) +
  coord_flip() + # Lật biểu đồ thành dạng ngang

  # Cập nhật nhãn để hiển thị đúng tổng số lượng xe
  geom_text(aes(label = Total_Quantity_Sold), hjust = -0.2, size = 4) +

  # Cập nhật lại tiêu đề và các nhãn trục cho phù hợp
  labs(title = "Top 5 Nhân Viên Bán Được Nhiều Xe Nhất",
       subtitle = "Dựa trên tổng số lượng xe đã bán",
       x = "Mã Nhân Viên",
       y = "Tổng Số Lượng Xe Bán Ra") +
  theme_minimal()

Ý nghĩa: Nhân viên có mã số 794 dẫn đầu với 441 chiếc xe bán ra, nhưng chỉ hơn người đứng thứ năm (mã số 869, bán được 417 chiếc) một khoảng cách không quá lớn. Sự chênh lệch nhỏ này cho thấy công ty đang sở hữu một đội ngũ bán hàng mạnh và đồng đều ở top đầu, chứ không phụ thuộc vào một vài “siêu sao” cá biệt.

Kết luận: Công ty có một nền tảng nhân sự bán hàng vững chắc. Chính sách khen thưởng và đào tạo nên tập trung vào việc duy trì sự xuất sắc của nhóm này và nhân rộng kinh nghiệm của họ cho các nhân viên khác.

4.3.5 Biểu đồ bong bóng: Tổng quan các mẫu xe

bubble_data_stores <- BK1 %>%
  group_by(Store_Location) %>%
  summarise(
    Total_Revenue = sum(Revenue),
    Total_Quantity = sum(Quantity),
    Avg_Price = mean(Price),
    .groups = 'drop'
  )
ggplot(bubble_data_stores, aes(x = Total_Quantity, y = Avg_Price, size = Total_Revenue, color = Store_Location)) +
  geom_point(alpha = 0.7) +

  geom_text_repel(
    aes(label = Store_Location),
    size = 4, 
    fontface = "bold",
    box.padding = 0.5, # Thêm khoảng trống quanh nhãn
    max.overlaps = Inf # Đảm bảo tất cả các nhãn đều được hiển thị
  ) +
  scale_size(
    name = "Tổng Doanh Thu",
    range = c(8, 20),
    labels = label_dollar(scale = 1e-6, suffix = "M", accuracy = 1) # Hiển thị dạng $110M, $111M,...
  ) +
  guides(color = "none") +

  labs(
    title = "Phân Tích Tổng Quan Hiệu Suất Các Cửa Hàng",
    x = "Tổng Số Lượng Bán Ra",
    y = "Giá Bán Trung Bình (USD)"
  ) +
  scale_y_continuous(labels = dollar) +
  scale_x_continuous(labels = comma) +
  theme_minimal(base_size = 12) 

Ý nghĩa: Biểu đồ cho thấy New York có tổng số lượng bán ra và doanh thu cao nhất, trong khi Philadelphia có giá bán trung bình cao nhất. Các thành phố khác như San Antonio, Houston, Los Angeles có hiệu suất thấp hơn cả về số lượng và doanh thu.

4.3.6 Biểu đồ Treemap: Tỷ trọng doanh thu theo mẫu xe và địa điểm cửa hàng

# Nhóm theo Nhóm tuổi và Mức giá để tính tổng doanh thu
treemap_data_age_price <- BK1 %>%
  group_by(Age_Group, Price_Level) %>%
  summarise(Total_Revenue = sum(Revenue), .groups = 'drop')
ggplot(treemap_data_age_price,
       aes(area = Total_Revenue,
           fill = Price_Level, # Màu sắc thể hiện Mức giá
           label = paste(Price_Level, scales::dollar(Total_Revenue, scale = 1/1e6, accuracy = 1, suffix = "M"), sep = "\n"),
           subgroup = Age_Group)) + # Nhóm lớn là Nhóm tuổi
  geom_treemap() +
  geom_treemap_subgroup_border(colour = "white", size = 5) +
  geom_treemap_subgroup_text(
    place = "centre", grow = TRUE, alpha = 0.5, colour = "black",
    fontface = "italic", min.size = 0
  ) +
  geom_treemap_text(colour = "white", place = "topleft", reflow = TRUE, size=14) +
  labs(title = "Tỷ Trọng Doanh Thu Theo Nhóm Tuổi và Phân Khúc Giá",
       subtitle = "(Đơn vị: triệu USD)", fill = "Mức giá")

Ý nghĩa: Khách hàng trung niên là nhóm mang lại doanh thu cao nhất, chủ yếu chi tiêu cho sản phẩm cao cấp và hạng sang, trong khi nhóm trẻ thiên về sản phẩm phổ thông.

Kết luận: Doanh nghiệp nên tập trung duy trì khách hàng trung niên – nhóm chi tiêu mạnh nhất, đồng thời mở rộng chiến lược tiếp cận nhóm trẻ để tăng trưởng dài hạn. Việc đa dạng hóa sản phẩm phù hợp từng độ tuổi sẽ giúp doanh thu ổn định và bền vững hơn.

4.3.7 Biểu đồ Sankey: Luồng khách hàng từ giới tính đến mẫu xe

# Nhóm theo Nhóm tuổi và Mức giá, sau đó đếm số lượng
sankey_data_age_price <- BK1 %>%
  group_by(Age_Group, Price_Level) %>%
  summarise(Count = n(), .groups = 'drop')
ggplot(as.data.frame(sankey_data_age_price),
       # Cập nhật các trục trong aes()
       aes(y = Count, axis1 = Age_Group, axis2 = Price_Level)) +
  # Luồng sẽ có màu sắc dựa trên Mức giá
  geom_alluvium(aes(fill = Price_Level), width = 1/4, alpha = 0.8) +
  geom_stratum(width = 1/3, fill = "grey80", color = "white") +
  geom_label(stat = "stratum", aes(label = after_stat(stratum))) +
  scale_x_discrete(limits = c("Nhóm Tuổi", "Mức Giá"), expand = c(.05, .05)) 

  labs(title = "Luồng Lựa Chọn Mức Giá Theo Nhóm Tuổi",
       subtitle = "Độ rộng của dải màu thể hiện số lượng khách hàng") +
  theme_void() +
  theme(legend.position = "bottom")
## NULL

Ý nghĩa: Biểu đồ thể hiện mối liên hệ giữa nhóm tuổi khách hàng và mức giá sản phẩm. Nhìn chung, nhóm lớn tuổi (56+) và trung niên (31–55) có xu hướng chọn sản phẩm cao cấp và hạng sang nhiều hơn, trong khi nhóm trẻ (18–30) lại nghiêng về phân khúc phổ thông. Tuy nhiên, sự phân bổ giữa các nhóm không quá chênh lệch, cho thấy công ty đang tiếp cận đa dạng các phân khúc khách hàng.

Kết luận: Doanh nghiệp sở hữu cơ cấu khách hàng cân bằng, với tiềm năng mở rộng ở nhóm trẻ và khả năng duy trì lợi nhuận ổn định từ nhóm trung niên – lớn tuổi. Chính sách marketing nên phân hóa thông điệp theo từng độ tuổi, vừa giữ chân khách hàng truyền thống, vừa thu hút thế hệ trẻ bằng các dòng sản phẩm phù hợp hơn.

4.3.8 Biểu đồ tương quan (Correlogram)

numeric_vars_for_corr <- BK1 %>%
  dplyr::select(where(is.numeric))
numeric_vars_for_corr <- numeric_vars_for_corr %>%
  dplyr::select(
    -Sale_ID,
    -Customer_ID,
    -Salesperson_ID,
    -Year,
    -Gender_Encoded,
    -Purchase_Count
  )
cor_matrix <- cor(numeric_vars_for_corr, use = "complete.obs")
corrplot(
  cor_matrix,
  method = "color",
  type = "upper",
  addCoef.col = "black",
  tl.col = "black",
  tl.srt = 45,
  title = "Ma Trận Tương Quan Giữa Các Biến Số Kinh Doanh",
  mar = c(0, 0, 1.5, 0)
)

Ý nghĩa:

  • Biểu đồ cho thấy Price (Giá) có tương quan dương mạnh nhất với Revenue (Doanh thu), với hệ số là 0.71. Điều này có nghĩa là khi giá sản phẩm tăng thì doanh thu có xu hướng tăng theo.

  • Tương tự, Quantity (Số lượng) cũng có tương quan dương đáng kể với Revenue (0.62), điều này là hợp lý vì bán được nhiều hàng hơn sẽ tạo ra nhiều doanh thu hơn.

  • Một điểm đáng chú ý khác là hầu như không có mối tương quan nào giữa Customer_Age (Tuổi khách hàng) và Revenue, cho thấy tuổi tác không phải là yếu tố ảnh hưởng đến doanh thu trong bộ dữ liệu này.

CHƯƠNG 2: PHÂN TÍCH KẾT QUẢ HOẠT ĐỘNG KINH DOANH CỦA CÔNG TY CỔ PHẦN HOÀNG ANH GIA LAI (HAG)

Giới thiệu

Công ty Cổ phần Hoàng Anh Gia Lai (HAG) là một trong những doanh nghiệp có lịch sử hoạt động đầy biến động và thu hút sự quan tâm lớn trên thị trường chứng khoán Việt Nam. Giai đoạn 2015-2024 đánh dấu một thập kỷ mang tính bước ngoặt, khi HAG thực hiện quá trình tái cấu trúc sâu sắc, chuyển đổi mô hình kinh doanh từ bất động sản và cao su sang tập trung vào nông nghiệp công nghệ cao, với các sản phẩm chủ lực là cây ăn trái (chuối) và chăn nuôi (heo).

Quá trình chuyển đổi này đặt ra một câu hỏi nghiên cứu cốt lõi: Liệu chiến lược tái cấu trúc và tập trung vào nông nghiệp có thực sự mang lại hiệu quả tài chính bền vững cho HAG hay không?

Để trả lời câu hỏi này, chương này sẽ thực hiện một phân tích định lượng chi tiết dựa trên dữ liệu tài chính của công ty. Trọng tâm của phân tích sẽ là Báo cáo Kết quả Hoạt động Kinh doanh (KQKD), vì đây là báo cáo phản ánh rõ nét nhất khả năng tạo ra doanh thu, quản lý chi phí và hiệu quả sinh lời từ hoạt động cốt lõi của doanh nghiệp. Thông qua việc phân tích sâu các chỉ tiêu trên Báo cáo KQKD trong suốt 10 năm, nghiên cứu này sẽ làm rõ các xu hướng, xác định các động lực tăng trưởng và đánh giá những thách thức mà HAG đã và đang đối mặt.

1. Tổng quan dữ liệu

1.1 Giới thiệu dữ liệu

Để thực hiện phân tích, chúng tôi sử dụng bộ dữ liệu tài chính của HAG được tổng hợp cho giai đoạn 10 năm, từ 2015 đến 2024.

Nguồn gốc và Phạm vi: Dữ liệu được thu thập từ các báo cáo tài chính chính thức của CTCP Hoàng Anh Gia Lai, bao gồm số liệu hàng năm trong khoảng thời gian đã nêu.

Cấu trúc dữ liệu gốc: Dữ liệu ban đầu được tổ chức dưới dạng bảng (dạng rộng - wide format). Trong đó, mỗi hàng đại diện cho một năm tài chính và mỗi cột là một chỉ tiêu tài chính cụ thể. Tệp dữ liệu gốc (HAG.csv) là một bộ dữ liệu lớn, tích hợp các chỉ tiêu từ ba báo cáo tài chính chính:

  • Bảng Cân đối Kế toán

  • Báo cáo Kết quả Hoạt động Kinh doanh

  • Báo cáo Lưu chuyển Tiền tệ

Trọng tâm phân tích: Để đáp ứng mục tiêu nghiên cứu đã đề ra trong phần giới thiệu, bài phân tích này sẽ thực hiện thao tác rút trích dữ liệu (data extraction). Cụ thể, chúng tôi sẽ tạo ra một tập con (subset) chỉ chứa các biến thuộc Báo cáo Kết quả Kinh doanh để tiến hành phân tích chuyên sâu.

1.2 Nạp thư viện cần thiết

library(dplyr)
library(readr)
library(knitr)
library(kableExtra)
library(e1071)
library(ggplot2)
library(scales) 
library(tidyr) 
library(ggrepel)
library(reshape2) # Giúp tái cấu trúc dữ liệu linh hoạt, phục vụ cho việc trực quan hóa

1.3 Nạp dữ liệu vào R

HAG <- read_csv("C:/Users/DELL/Downloads/HAG (1).csv")

1.4 Hiển thị 10 dòng đầu tiên của bộ dữ biệu BCTC

HAG %>%
  head(10) %>%
  kable(caption = "10 dòng đầu tiên của bộ dữ liệu BCTC HAG") %>%
  kable_styling(latex_options = "scale_down")
10 dòng đầu tiên của bộ dữ liệu BCTC HAG
Nam Tai_san_ngan_han tien…3 tien…4 cac_khoan_phai_thu_ngan_han phai_thu_ngan_han_cua_khach_hang tra_truoc_cho_nguoi_ban_ngan_han phai_thu_ve_cho_vay_ngan_han phai_thu_ngan_han_khac du_phong_phai_thu_ngan_han_kho_doi hang_ton_kho…11 hang_ton_kho…12 du_phong_giam_gia_hang_ton_kho tai_san_ngan_han_khac…14 chi_phi_tra_truoc_ngan_han thue_gtgt_duoc_khau_tru thue_va_cac_khoan_khac_phai_thu_nha_nuoc tai_san_ngan_han_khac…18 tai_san_dai_han cac_khoan_phai_thu_dai_han phai_thu_ve_cho_vay_dai_han phai_thu_dai_han_khac du_phong_phai_thu_dai_han_kho_doi phai_thu_cho_nguoi_ban_dai_han tai_san_co_dinh tai_san_co_dinh_huu_hinh tai_san_co_dinh_vo_hinh bat_dong_san_dau_tu tai_san_do_dang_dai_han chi_phi_xay_dung_co_ban_do_dang dau_tu_tai_chinh_dai_han dau_tu_vao_cac_cong_ty_lien_ket dau_tu_gop_von_vao_cac_don_vi_khac du_phong_dau_tu_tai_chinh_dai_han tai_san_dai_han_khac chi_phi_tra_truoc_dai_han tai_san_thue_thu_nhap_hoan_lai loi_the_thuong_mai tong_cong_tai_san nguon_von no_phai_tra no_ngan_han phai_tra_nguoi_ban_ngan_han nguoi_mua_tra_tien_truoc_ngan_han thue_va_cac_khoan_phai_nop_nha_nuoc phai_tra_nguoi_lao_dong chi_phi_phai_tra_ngan_han doanh_thu_chua_thuc_hien_ngan_han phai_tra_ngan_han_khac vay_ngan_han quy_khen_thuong_phuc_loi no_dai_han chi_phi_phai_tra_dai_han phai_tra_dai_han_khac vay_dai_han thue_thu_nhap_hoan_lai_phai_tra du_phong_phai_tra_dai_han von_chu_so_huu…58 von_chu_so_huu…59 von_co_phan thang_du_von_co_phan co_phieu_quy chenh_lech_ty_gia_hoi_doai quy_dau_tu_phat_trien lo_luy_ke loi_nhuan_sau_thue_chua_phan_phoi loi_ich_co_dong_khong_kiem_soat tong_cong_nguon_von Doanh_thu_ban_hang_va_cung_cap_dich_vu cac_khoan_giam_tru_doanh_thu doanh_thu_thuan_ve_ban_hang_va_cung_cap_dich_vu gia_von_hang_ban_va_dich_vu_cung_cap loi_nhuan_gop_ve_ban_hang_va_cung_cap_dich_vu doanh_thu_hoat_dong_tai_chinh chi_phi_tai_chinh trong_do_chi_phi_lai_vay phan_lai_trong_cong_ty_lien_ket chi_phi_ban_hang chi_phi_quan_ly_doanh_nghiep lo_thuan_tu_hoat_dong_kinh_doanh thu_nhap_khac chi_phi_khac lo_khac lo_ke_toan_truoc_thue…84 chi_phi_thue_tndn_hien_hanh chi_phi_thu_nhap_thue_tndn_hoan_lai lo_sau_thue_tndn loloi_nhuan_sau_thue_cua_cong_ty_me lo_sau_thue_cua_co_dong_khong_kiem_soat lo_lai_co_ban_tren_co_phieu_vnd lo_lai_suy_giam_tren_co_phieu_vnd Luu_chuyen_tien_tu_hoat_dong_kinh_doanh lo_ke_toan_truoc_thue…93 khau_hao_va_hao_mon du_phong lai_lo_chenh_lech_ty_gia_hoi_doai lai_tu_hoat_dong_dau_tu chi_phi_lai_vay cac_dieu_chinh_khac loi_nhuan_cua_hoat_dong_kinh_doanh_truoc_thay_doi_von_luu_dong tang_giam_cac_khoan_phai_thu tang_hang_ton_kho tanggiam_cac_khoan_phai_tra tanggiam_chi_phi_tra_truoc tien_lai_vay_da_tra thue_thu_nhap_doanh_nghiep_da_nop tien_chi_khac_cho_hoat_dong_kinh_doanh luu_chuyen_tien_thuan_su_dung_vao_hoat_dong_kinh_doanh luu_chuyen_tien_tu_hoat_dong_dau_tu tien_chi_de_mua_sam_xay_dung_tscd_va_tai_san_dai_han_khac tien_thu_do_thanh_ly_nhuong_ban_tscd_va_tai_san_dai_han_khac tien_chi_cho_cac_don_vi_khac_vay tien_thu_hoi_cho_vay tien_chi_de_dau_tu_gop_von_vao_don_vi_khac tien_thu_hoi_dau_tu_gop_von_vao_don_vi_khac tien_thu_lai_cho_vay_tien_gui_co_tuc_va_loi_nhuan_duoc_chia luu_chuyen_tien_thuan_su_dung_vaotu_hoat_dong_dau_tu luu_chuyen_tien_tu_hoat_dong_tai_chinh co_dong_thieu_so_gop_von tien_tra_lai_von_gop_cho_co_dong_khong_kiem_soat tien_thu_tu_di_vay tien_tra_no_goc_vay luu_chuyen_tien_thuan_tusu_dung_vao_hoat_dong_tai_chinh luu_chuyen_tien_thuan_trong_nam tien_dau_nam tien_cuoi_nam
2015 13215916673 967966695 967966695 8469868136 1607110089 1661082955 3699988122 1511776819 -10089849 3646452010 3651634817 -5182807 131629832 13427321 33767746 2238777 82195988 36012472005 6141903570 6062008291 79895279 NA NA 6287742157 6176778419 110963738 81725494 21458876315 21458876315 328257789 252299640 75938149 20000 1713966680 1156515098 82941387 474510195 49228388678 NA 32962668396 13212975900 1123648086 1438433801 275400876 46519890 809388331 NA 1217547588 8297755147 4282181 19749692496 NA 546724865 18801459914 395127749 6379968 16265720282 16265720282 7899679470 3539078784 -686640 555077253 279895303 NA 2023903249 1968772863 49228388678 6252482061 -35528 6252446533 -4398020571 1854425962 1053656518 -1203667607 -1078711240 -1898163 -111239060 -350371742 1240905908 180631718 -615325413 -434693695 806212213 -153548976 -50302292 602360945 502343207 100017738 613 613 NA 806212213 372592068 9745286 -115305562 -628376312 1078711240 NA 1523578933 1169669226 -1916001996 1699906910 121084629 -932571773 -109599492 -26760841 1529305596 NA -7946189324 791534557 -6581690554 4476003816 -2350933815 866639814 411747874 -10332887632 NA 159000000 -2.20e+06 15978713459 -7342378545 8793134914 -10447122 978413817 967966695
2016 9394220363 791208293 791208293 6768206227 1772653862 1316838516 2034357256 1672681113 -28324520 1789466577 1822154682 -32688105 45339266 7961305 26318790 11059171 NA 43369249238 6350659266 5717370743 633288523 NA NA 10017094697 8664993197 1352101500 3510539222 17983864412 17983864412 877887933 865766030 12101903 20000 4629203708 1497175881 91119227 3040908600 52763469601 NA 36113695179 12726074032 1319409776 3546000509 195748396 74235298 846456575 6760210 1535617649 5197619996 4225623 23387621147 4222541 1374575760 21444223544 287204877 277394425 16649774422 16649774422 7899679470 3539078784 -686640 650139359 279895303 NA 1391155127 2890513019 52763469601 6441028981 -1249713 6439779268 -5430638742 1009140526 947916097 -1674519826 -1579381993 11710281 -169154415 -501564190 -376471527 176199117 -1206015281 -1029816164 -1406287691 -10311463 -86187524 -1502786678 -1136650486 -366136192 -1439 -1439 NA -1406287691 774966464 45528933 33309004 -767018139 1579381993 NA 259880564 1119197170 1293921678 1067210872 -120577118 -1417691509 -25424754 -56558 2176460345 NA -3895058904 1711964916 -3351481274 4404445889 -4604707935 2018359523 354720632 -3361757153 NA 2792000000 -3.13e+08 4868173006 -6433696706 913476300 -271820508 967966695 791208293
2017 8815052625 141473491 141473491 7481808506 2189131465 611144225 3969777546 707027281 -21272009 1118852515 1126498195 -7645680 72918113 35147018 35050293 6014158 NA 44247075031 8887895570 7951978808 935439558 NA 477204 8921066066 8890006818 1330981494 3210064249 17750120892 17750120892 857860477 847332517 10507903 20000 3620067844 976304493 1090388994 2538638296 53062127656 NA 35274154978 12370346571 970327536 3595954762 83448891 1251096533 2528893658 13984482 1234592114 5717296133 4225623 22895808707 987071192 1269645155 20296208849 336941517 5940694 17787972678 17787972678 9274679470 3263858784 -686640 453812960 279895303 NA 702809115 3813603686 53062127656 4841225074 NA 4841225074 -3109682997 1731542077 1685918448 -1697932438 -1585315746 -18433513 -143923122 -707548329 829621123 267202683 -666678513 -399475830 430145293 -24802221 -33735757 371607315 69588012 302019303 80 80 NA 430145293 1054629884 28441450 60032858 -1737590490 1585315746 NA 1421004923 515236384 -211051050 775769299 -70137982 -714364510 -4591515 -316303 1014522675 NA -1454631442 475590760 -7208840920 2938905796 NA 1517118217 1119834929 -2561827694 NA 2450000 NA 4119461254 -3055353071 1066558183 -480746836 794326175 141473492
2018 6567906781 337736719 337736719 4747120864 2976376936 427114472 724888836 656027274 -37286654 1397223406 1409194346 -11970940 85825792 42012128 33782839 10030825 41543534835 6531099389 NA 342673458 10732352612 NA 6188425931 10671588242 12582296997 115343472 42073202 16910792900 2788206391 2771892520 16313871 NA 4543978740 1224232772 98599120 3221146848 48111441616 31300554930 NA 13136735456 473908598 2411088952 57716523 67209973 2045910162 228667 228667 1130795710 6949803327 73544 18163819474 2029868704 980019908 14803739630 344457866 5733366 16810886686 16810886686 9274679470 3263858784 -686640 485237344 280644763 NA -36434976 3543587941 48111441616 NA NA 5388200400 -3013495226 2374705174 1404799179 -1721684164 -1532928450 64840488 -192446215 -989336089 940878373 21546363 -914727898 -893181535 47696838 -2998375 -38454058 6244405 117506769 -111262364 127 127 NA 47696838 1137274221 19682377 44675852 -1435670677 1532928450 NA 1346587061 1511655755 -695030279 -3837314700 -215749814 -971481036 -54584465 -1758964 -2917676442 NA -2597907012 531497895 -3041376766 3903352004 -7783830 74975161 783659345 -353583203 NA NA NA 7594866696 -4127343823 3467522873 196263228 141473491 337736719
2019 7073675026 254431616 254431616 4569330218 1551364334 374650728 2267368418 467023910 -91077172 2201556690 2223128790 -21572100 48356502 5242656 38898934 4214912 NA 31558812063 8261530824 7513945466 747838961 -253603 NA 10280435755 10247239903 33195852 67867999 11229762864 11229762864 284237784 273113133 11124651 NA 1434976837 381576859 74528409 978871569 38632487089 NA 21823683301 8089793475 1014993762 239268824 32597878 109501022 2020469752 60667 920339356 3752458704 103510 13733889826 1990123829 570972657 10945607569 221472405 5713366 16808803788 16808803788 9274679470 3263858784 -686640 -424458674 281668774 NA 290839236 4122902838 38632487089 2091833174 -16389150 2075444024 -1847659651 227784373 2137143442 -1963934151 -1263369664 12562347 -308856859 -672601510 -567902358 42577126 -1380140330 -1337563204 -1905465562 -2253490 98914750 -1808804302 216517715 -2025322017 233 233 NA -1905465562 1207452901 63625281 58008292 -165792637 1263369664 NA 521197939 77839787 -878775630 -1233712837 120173500 -1128584792 -12947293 -2767027 -2537576353 NA -4679597082 1492108659 -4183656108 1327282202 -708435715 12446724361 537820566 6232246883 NA NA NA 4568150621 -8346126254 -3777975633 -83305103 337736719 254431616
2020 8930375455 97151198 97151198 6410638635 4075221471 109143346 4186477204 563738589 -2523941975 2347965565 2423112551 -75146986 74620057 11353928 60705339 2560790 NA 28335444096 2295094417 1782648474 514915299 -2469356 NA 12626270334 12104977632 521292702 65237146 12006780151 12006780151 277318516 266193865 11124651 NA 1064743532 353396829 85724272 625622431 37265819551 NA 27238024092 15428980447 1474036885 633729744 32844475 175795782 2864427371 409091 1475782291 8771851298 103510 11809043645 1173684620 454179120 9330999170 844467369 5713366 10027795459 10027795459 9274679470 3263858784 -686640 -1440136262 282410699 -6301662837 NA 4949332245 37265819551 3189964886 -13318930 3176645956 -2970915613 205730343 1287363665 -1318161483 -1253570666 8767467 -354584206 -1851240106 -2022124320 98148465 -427484407 -329335942 -2351460262 -3440989 -28438599 -2383339850 -1255661344 -1127678506 -1354 -1354 NA -2351460262 963189845 1614455830 -72723455 -1053097065 1253570666 16172109 370107668 -821286302 -430250325 270122076 -21743758 -1130267163 -818203 NA -1764136007 NA -2335313765 2653633 -820994359 352437170 -421331381 1314904350 440002574 -1467641778 NA NA NA 7805577396 -4731080029 3074497367 -157280418 254431616 97151198
2021 7051853577 78298037 78298037 6535652693 553790175 147090473 6516258180 785572698 -1467058833 410031564 413734969 -3703405 27871283 7124641 17611524 3135118 NA 11387831414 2958712989 2452838426 649545621 -143671058 NA 2809669569 2686778608 122890961 62606294 3495149075 3495149075 1778826680 NA 1781156721 -2330041 282866807 271900161 10966646 NA 18439684991 NA 13766451651 6754505795 359479015 528938858 7155321 98870565 3088705929 81818 161601224 2509569555 103510 7011945856 653649038 65398026 5776845065 510611231 5442496 4673233340 4673233340 9274679470 NA -686640 -602619336 282410699 -4467100553 NA 186549700 18439684991 2187415636 -89997270 2097418366 -1590448139 506970227 735078612 -1090293038 -971878185 -5819760 -129287166 174279229 190928104 79670972 -401205709 -321534737 -130606633 -885768 259098512 127606111 203030161 -75424050 219 219 NA -130606633 870230953 -885411353 -104788770 -455074138 971878185 1759669 267987913 -605054037 -264123046 82660109 -54040134 -65501069 -2205764 NA -640276028 NA -1215681721 227716258 -2910721238 1889196184 -108511316 3332388023 74291023 1288677213 NA 55000 NA 1458994671 -2126304017 -667254346 -18853161 97151198 78298037
2022 8038560913 72372525 72372525 6765361545 906404137 766151359 4017224678 1155995000 -80413629 1148037609 1150379184 -2341575 52789234 17274977 32372352 3141905 NA 11759826640 2430132241 1745420930 702237574 -17526263 NA 3821150484 3559467131 261683353 59975442 4620301248 4620301248 441689596 NA 1049961081 -608271485 386577629 370108968 16468661 NA 19798387553 NA 14603644212 9218063487 535119892 629603992 8789821 80012780 3857898088 NA 106050215 4000485189 103510 5385580725 490236779 308838184 4165134234 416006694 5364834 5194743341 5194743341 9274679470 NA -686640 -1221066442 282410699 -3341007157 NA 200413411 19798387553 5197982826 -87200939 5110781887 -3937380869 1173401018 486143713 -1649147246 -793176972 NA -251938809 1349894514 1108353190 35975907 -116111269 -80135362 1028217828 -3649540 100106552 1124674840 1128745396 -4070556 1217 1217 NA 1028217828 337569217 -908288047 222844063 -438812767 793176972 NA 1034707266 22964621 -595021928 -251359212 -107385162 -63237554 -3332591 NA 37335440 NA -544321349 17965272 -2165452268 2330063239 -232446836 791244823 53169424 250222305 NA 22594000 NA 1802441405 -2118518662 -293483257 -5925512 78298037 72372525
2023 8768525586 41812548 41812548 7780210370 1492430980 1795878037 2248319624 2283803636 -40221907 928718695 931060270 -2341575 17783973 4379912 10268943 3135118 NA 12134729704 495190422 274178939 221011483 NA NA 5997879680 5743738807 254140873 36187721 4824942853 4824942853 492019500 NA 1049961081 -557941581 288509528 288509528 NA NA 20903255290 NA 14225785185 9710404280 1123332723 329422144 52221065 95022833 3382113745 NA 199619170 4528569090 103510 4515380905 331211708 381772904 3340420808 456610651 5364834 6677470105 6677470105 9274679470 NA -686640 -1525752918 279895303 -1669170708 NA 318505598 20903255290 6492569736 -50172537 6442397199 -5148941719 1293455480 602752483 215432853 270599417 -11069302 -255058076 -155100623 1690412815 281127775 -178663887 102463888 1792876703 -30945417 19754499 1781685785 1663970953 117714832 1794 1794 NA 1792876703 579014760 -117903371 73118511 -713557518 -270599417 NA 1342949668 -50492765 424194523 -1299962404 124742131 -436458129 -2323226 -1536000 101113798 NA -614181316 204906906 -125380935 609108000 -34223686 2557440 7027004 49813413 NA NA NA 5416358111 -5597845299 -181487188 -30559977 72372525 41812548
2024 8435357672 149708825 149708825 7536948369 1383718468 1022089432 2684222732 2504387857 -57470120 694457742 696799317 -2341575 54242736 28514802 22588435 3139499 NA 13845458167 1293470367 46813199 1246657168 NA NA 6567006867 6319160472 247846395 34296263 5022320011 5022320011 557387037 NA 917550007 -360162970 370977622 370977622 NA NA 22280815839 NA 12955187719 11122837652 987308074 196242091 4375602 67888786 4004971339 NA 113629996 5748318254 103510 1832350067 169506186 21938626 1217151938 418388483 5364834 9325628120 9325628120 10574679470 NA -686640 -1407086490 279895303 -422660071 NA 581381851 22280815839 5894531814 -111481812 5783050002 -3611137012 2171912990 280428437 -688075391 -716094685 NA -396487002 -165284639 1202494395 35942854 -215615117 -179672263 1022822132 -922479 38222168 1060121821 1013433083 46688738 997 997 NA 1022822132 487722491 -110676324 29702204 -197191877 716094685 NA 1948473311 -1139245871 234260953 -1093852988 -406356942 -294260645 -28881207 -2917360 -782780749 NA -793841012 31217343 -457005980 1192724315 434414952 76598065 484107683 NA NA 1300000000 NA 7926952950 -8820383607 406569343 107896277 41812548 149708825

1.5 Chọn phân tích Bảng Kết quả Kinh doanh

Trong bối cảnh HAG trải qua quá trình tái cấu trúc và chuyển đổi mô hình kinh doanh (từ bất động sản/cao su sang nông nghiệp), việc đánh giá hiệu suất hoạt động cốt lõi là tối quan trọng. Bảng KQKD là báo cáo duy nhất cung cấp bức tranh chi tiết về các nguồn thu nhập và chi phí phát sinh, cho phép nhà nghiên cứu:

Phân tích Chiều sâu Lợi nhuận: Theo dõi lợi nhuận từ các hoạt động chính (nông nghiệp) qua các tầng (Lợi nhuận gộp, Lợi nhuận từ hoạt động kinh doanh).

Đánh giá Sức khỏe Tài chính (Cơ bản): Đánh giá khả năng tạo ra dòng tiền từ hoạt động kinh doanh (trước khi xem xét các hoạt động đầu tư/tài chính).

Xác định Xu hướng (Trend Analysis): So sánh các yếu tố doanh thu và chi phí qua các năm để làm rõ tính ổn định và động lực tăng trưởng mới của HAG.

Trong KQKD, có nhiều chỉ tiêu phản ánh chi tiết hoạt động doanh nghiệp. Tuy nhiên, để tập trung vào phân tích hiệu suất cốt lõi và xu hướng sinh lời, nhóm nghiên cứu chọn ra 10 biến có ý nghĩa kinh tế – tài chính cao nhất. Các biến được chọn bao phủ toàn bộ chuỗi tạo lợi nhuận – từ doanh thu, chi phí, lợi nhuận gộp, đến hiệu quả tài chính, chi phí vận hành và lợi nhuận sau thuế. Nhờ đó, nhà phân tích có thể đánh giá được sức khỏe tài chính, khả năng sinh lời và xu hướng tăng trưởng thực chất của doanh nghiệp qua các năm.

ten_bien_kqkd <- c(
  "doanh_thu_thuan_ve_ban_hang_va_cung_cap_dich_vu",
  "gia_von_hang_ban_va_dich_vu_cung_cap",
  "loi_nhuan_gop_ve_ban_hang_va_cung_cap_dich_vu",
  "doanh_thu_hoat_dong_tai_chinh",
  "chi_phi_tai_chinh",
  "chi_phi_ban_hang",
  "chi_phi_quan_ly_doanh_nghiep",
  "lo_thuan_tu_hoat_dong_kinh_doanh",
  "thu_nhap_khac",
  "loloi_nhuan_sau_thue_cua_cong_ty_me"
)

# Tạo tập con (subset)
bao_cao_kqkd_subset <- HAG %>%
  select(
    Nam,                   # Giữ lại cột Năm
    any_of(ten_bien_kqkd)  # Chỉ chọn các cột TỒN TẠI trong danh sách mới
  )

# In ra vài dòng đầu của tập con để kiểm tra kết quả
print(head(bao_cao_kqkd_subset))
## # A tibble: 6 × 11
##     Nam doanh_thu_thuan_ve_ban_h…¹ gia_von_hang_ban_va_…² loi_nhuan_gop_ve_ban…³
##   <dbl>                      <dbl>                  <dbl>                  <dbl>
## 1  2015                 6252446533            -4398020571             1854425962
## 2  2016                 6439779268            -5430638742             1009140526
## 3  2017                 4841225074            -3109682997             1731542077
## 4  2018                 5388200400            -3013495226             2374705174
## 5  2019                 2075444024            -1847659651              227784373
## 6  2020                 3176645956            -2970915613              205730343
## # ℹ abbreviated names: ¹​doanh_thu_thuan_ve_ban_hang_va_cung_cap_dich_vu,
## #   ²​gia_von_hang_ban_va_dich_vu_cung_cap,
## #   ³​loi_nhuan_gop_ve_ban_hang_va_cung_cap_dich_vu
## # ℹ 7 more variables: doanh_thu_hoat_dong_tai_chinh <dbl>,
## #   chi_phi_tai_chinh <dbl>, chi_phi_ban_hang <dbl>,
## #   chi_phi_quan_ly_doanh_nghiep <dbl>, lo_thuan_tu_hoat_dong_kinh_doanh <dbl>,
## #   thu_nhap_khac <dbl>, loloi_nhuan_sau_thue_cua_cong_ty_me <dbl>

1.6 Khám phá dữ liệu mới

1.6.1 Hiển thị tên các biến

cat("\n--- Tên các biến trong tập dữ liệu KQKD ---\n")
## 
## --- Tên các biến trong tập dữ liệu KQKD ---
colnames(bao_cao_kqkd_subset)
##  [1] "Nam"                                            
##  [2] "doanh_thu_thuan_ve_ban_hang_va_cung_cap_dich_vu"
##  [3] "gia_von_hang_ban_va_dich_vu_cung_cap"           
##  [4] "loi_nhuan_gop_ve_ban_hang_va_cung_cap_dich_vu"  
##  [5] "doanh_thu_hoat_dong_tai_chinh"                  
##  [6] "chi_phi_tai_chinh"                              
##  [7] "chi_phi_ban_hang"                               
##  [8] "chi_phi_quan_ly_doanh_nghiep"                   
##  [9] "lo_thuan_tu_hoat_dong_kinh_doanh"               
## [10] "thu_nhap_khac"                                  
## [11] "loloi_nhuan_sau_thue_cua_cong_ty_me"

1.6.2 Kiểm tra cấu trúc dữ liệu của tập con

cat("\n--- Cấu trúc dữ liệu của tập con ---\n")
## 
## --- Cấu trúc dữ liệu của tập con ---
str(bao_cao_kqkd_subset)
## tibble [10 × 11] (S3: tbl_df/tbl/data.frame)
##  $ Nam                                            : num [1:10] 2015 2016 2017 2018 2019 ...
##  $ doanh_thu_thuan_ve_ban_hang_va_cung_cap_dich_vu: num [1:10] 6.25e+09 6.44e+09 4.84e+09 5.39e+09 2.08e+09 ...
##  $ gia_von_hang_ban_va_dich_vu_cung_cap           : num [1:10] -4.40e+09 -5.43e+09 -3.11e+09 -3.01e+09 -1.85e+09 ...
##  $ loi_nhuan_gop_ve_ban_hang_va_cung_cap_dich_vu  : num [1:10] 1.85e+09 1.01e+09 1.73e+09 2.37e+09 2.28e+08 ...
##  $ doanh_thu_hoat_dong_tai_chinh                  : num [1:10] 1.05e+09 9.48e+08 1.69e+09 1.40e+09 2.14e+09 ...
##  $ chi_phi_tai_chinh                              : num [1:10] -1.20e+09 -1.67e+09 -1.70e+09 -1.72e+09 -1.96e+09 ...
##  $ chi_phi_ban_hang                               : num [1:10] -1.11e+08 -1.69e+08 -1.44e+08 -1.92e+08 -3.09e+08 ...
##  $ chi_phi_quan_ly_doanh_nghiep                   : num [1:10] -3.50e+08 -5.02e+08 -7.08e+08 -9.89e+08 -6.73e+08 ...
##  $ lo_thuan_tu_hoat_dong_kinh_doanh               : num [1:10] 1.24e+09 -3.76e+08 8.30e+08 9.41e+08 -5.68e+08 ...
##  $ thu_nhap_khac                                  : num [1:10] 1.81e+08 1.76e+08 2.67e+08 2.15e+07 4.26e+07 ...
##  $ loloi_nhuan_sau_thue_cua_cong_ty_me            : num [1:10] 5.02e+08 -1.14e+09 6.96e+07 1.18e+08 2.17e+08 ...

Nhận xét:

  • Tập dữ liệu gồm 10 chỉ tiêu tài chính trọng yếu của HAG trong giai đoạn 2015–2024, phản ánh toàn bộ quá trình hình thành lợi nhuận — từ doanh thu, chi phí đến lợi nhuận sau thuế.

  • Các cột dữ liệu theo năm tài chính giúp thuận tiện cho việc phân tích xu hướng (time-series), đánh giá mức độ cải thiện hoạt động kinh doanh sau quá trình tái cấu trúc.

  • Dữ liệu ở dạng số (numeric) cho thấy đây là bảng đã được xử lý định lượng, sẵn sàng cho các thao tác thống kê hoặc trực quan hóa (như biểu đồ đường, heatmap,…).

  • Một vài giá trị bị thiếu (NA, như năm 2019 trong doanh thu) cho thấy chuỗi dữ liệu chưa hoàn toàn đầy đủ, cần được kiểm tra hoặc xử lý trước khi mô hình hóa.

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

cat(paste("\nSố quan sát:", nrow(bao_cao_kqkd_subset), "- Số biến:", ncol(bao_cao_kqkd_subset), "\n"))
## 
## Số quan sát: 10 - Số biến: 11

1.6.4 Xem 5 dòng cuối cùng của dữ liệu

cat("\n--- 5 dòng cuối cùng ---\n")
## 
## --- 5 dòng cuối cùng ---
print(head(bao_cao_kqkd_subset, 5))
## # A tibble: 5 × 11
##     Nam doanh_thu_thuan_ve_ban_h…¹ gia_von_hang_ban_va_…² loi_nhuan_gop_ve_ban…³
##   <dbl>                      <dbl>                  <dbl>                  <dbl>
## 1  2015                 6252446533            -4398020571             1854425962
## 2  2016                 6439779268            -5430638742             1009140526
## 3  2017                 4841225074            -3109682997             1731542077
## 4  2018                 5388200400            -3013495226             2374705174
## 5  2019                 2075444024            -1847659651              227784373
## # ℹ abbreviated names: ¹​doanh_thu_thuan_ve_ban_hang_va_cung_cap_dich_vu,
## #   ²​gia_von_hang_ban_va_dich_vu_cung_cap,
## #   ³​loi_nhuan_gop_ve_ban_hang_va_cung_cap_dich_vu
## # ℹ 7 more variables: doanh_thu_hoat_dong_tai_chinh <dbl>,
## #   chi_phi_tai_chinh <dbl>, chi_phi_ban_hang <dbl>,
## #   chi_phi_quan_ly_doanh_nghiep <dbl>, lo_thuan_tu_hoat_dong_kinh_doanh <dbl>,
## #   thu_nhap_khac <dbl>, loloi_nhuan_sau_thue_cua_cong_ty_me <dbl>

2. Xử lý dữ liệu thô và mã hoá dữ liệu

2.1 Kiểm tra chất lượng dữ liệu

2.1.1 Kiểm tra giá trị bị thiếu

cat("Tổng số giá trị bị thiếu (NA):", sum(is.na(bao_cao_kqkd_subset)))
## Tổng số giá trị bị thiếu (NA): 0

2.1.2 Xử lý giá trị bị thiếu

  • Tính giá trị trung vị (median) vào các giá trị bị thiếu.
bao_cao_kqkd_processed <- bao_cao_kqkd_subset %>%
  mutate(across(where(is.numeric),
                ~ ifelse(is.na(.), median(., na.rm = TRUE), .)))

2.1.3 Kiểm tra lại để đảm bảo không còn giá trị NA

cat("Tổng số giá trị bị thiếu (NA) sau khi xử lý:", sum(is.na(bao_cao_kqkd_processed)), "\n")
## Tổng số giá trị bị thiếu (NA) sau khi xử lý: 0

Nhận xét: Sau khi xử lý giá trị bị thiếu ta kiểm tra lại và thấy dữ liệu đã sạch.

2.2 Kiểm tra số dòng bị trùng lặp hoàn toàn

cat("Số dòng bị trùng lặp hoàn toàn:", sum(duplicated(bao_cao_kqkd_processed)), "\n")
## Số dòng bị trùng lặp hoàn toàn: 0

Nhận xét: Dữ liệu không có dòng (quan sát) nào bị trùng lặp hoàn toàn.

2.3 Mã hoá dữ liệu

2.3.1 Đổi tên các biến

hag_data_final <- bao_cao_kqkd_processed %>%
  rename(
    Doanh_thu_thuan = doanh_thu_thuan_ve_ban_hang_va_cung_cap_dich_vu,
    Gia_von = gia_von_hang_ban_va_dich_vu_cung_cap,
    Loi_nhuan_gop = loi_nhuan_gop_ve_ban_hang_va_cung_cap_dich_vu,
    Doanh_thu_TC = doanh_thu_hoat_dong_tai_chinh,
    Chi_phi_TC = chi_phi_tai_chinh,
    Chi_phi_BH = chi_phi_ban_hang,
    Chi_phi_QLDN = chi_phi_quan_ly_doanh_nghiep,
    LN_thuan_HD_KD = lo_thuan_tu_hoat_dong_kinh_doanh,
    Thu_nhap_khac = thu_nhap_khac,
    LNST_Cong_ty_me = loloi_nhuan_sau_thue_cua_cong_ty_me
  )
head(hag_data_final)

2.3.2 Mã hóa

    # Mã hóa Giai đoạn kinh doanh: Trước và sau cột mốc phục hồi 2020
hag_data_final <- hag_data_final %>%
  mutate(Giai_doan = ifelse(Nam <= 2019, "2015-2019 (Tái cấu trúc)", "2020-2024 (Phục hồi)"))
    # Mã hóa Tình trạng kinh doanh dựa trên lợi nhuận
hag_data_final <- hag_data_final %>%
  mutate(Tinh_trang_KD = ifelse(LNST_Cong_ty_me > 0, "Có lãi", "Lỗ"))
# Chuyển các biến vừa mã hóa thành dạng Factor để tối ưu cho việc vẽ biểu đồ
hag_data_final <- hag_data_final %>%
  mutate(
    Giai_doan = as.factor(Giai_doan),
    Tinh_trang_KD = as.factor(Tinh_trang_KD)
  )
# Hiển thị kết quả mã hóa
hag_data_final %>% 
  select(Nam, Giai_doan, Tinh_trang_KD) %>%
  kable(caption = "Kết quả mã hóa dữ liệu")
Kết quả mã hóa dữ liệu
Nam Giai_doan Tinh_trang_KD
2015 2015-2019 (Tái cấu trúc) Có lãi
2016 2015-2019 (Tái cấu trúc) Lỗ
2017 2015-2019 (Tái cấu trúc) Có lãi
2018 2015-2019 (Tái cấu trúc) Có lãi
2019 2015-2019 (Tái cấu trúc) Có lãi
2020 2020-2024 (Phục hồi) Lỗ
2021 2020-2024 (Phục hồi) Có lãi
2022 2020-2024 (Phục hồi) Có lãi
2023 2020-2024 (Phục hồi) Có lãi
2024 2020-2024 (Phục hồi) Có lãi

Nhận xét:

  • Trong giai đoạn tái cấu trúc (2015–2019): phần lớn các năm đã có lãi, ngoại trừ 2016 là năm lỗ — có thể do chi phí tái cơ cấu và xử lý tài sản cao.

  • Sang giai đoạn phục hồi (2020–2024): HAG chỉ lỗ duy nhất năm 2020, sau đó liên tục có lãi → cho thấy hiệu quả tái cấu trúc đã phát huy, doanh nghiệp bước vào chu kỳ tăng trưởng bền vững hơn.

2.4 Tạo thêm biến

hag_data_final <- hag_data_final %>%
  mutate(
    # Tỷ suất lợi nhuận gộp (Gross Profit Margin)
    Ty_suat_LNG = (Loi_nhuan_gop / Doanh_thu_thuan) * 100,
    
    # Tỷ suất lợi nhuận ròng (Net Profit Margin)
    Ty_suat_LNST = (LNST_Cong_ty_me / Doanh_thu_thuan) * 100,
    
    # Tổng chi phí hoạt động
    Tong_CPHD = Chi_phi_BH + Chi_phi_QLDN,
    # Tạo Tỷ suất Lợi nhuận từ HĐKD (%)
LNHĐKD = (LN_thuan_HD_KD / Doanh_thu_thuan) * 100,
    # Tạo Tỷ trọng Thu nhập khác trên Lợi nhuận trước thuế
Ty_trong_TNK = (Thu_nhap_khac / (LN_thuan_HD_KD + Thu_nhap_khac)) * 100
  )

# Kiểm tra xem các cột mới đã được tạo thành công chưa
print(head(hag_data_final %>% select(Nam, Ty_suat_LNG, Ty_suat_LNST, Tong_CPHD, LNHĐKD, Ty_trong_TNK)))
## # A tibble: 6 × 6
##     Nam Ty_suat_LNG Ty_suat_LNST   Tong_CPHD LNHĐKD Ty_trong_TNK
##   <dbl>       <dbl>        <dbl>       <dbl>  <dbl>        <dbl>
## 1  2015       29.7          8.03  -461610802  19.8         12.7 
## 2  2016       15.7        -17.7   -670718605  -5.85       -88.0 
## 3  2017       35.8          1.44  -851471451  17.1         24.4 
## 4  2018       44.1          2.18 -1181782304  17.5          2.24
## 5  2019       11.0         10.4   -981458369 -27.4         -8.10
## 6  2020        6.48       -39.5  -2205824312 -63.7         -5.10

Nhận xét: Bộ dữ liệu hag_data_final giờ đây đã được bổ sung thêm nhiều cột mới (Ty_suat_LNG, Ty_suat_LNST, Tong_CPHD, LNHĐKD, Ty_trong_TNK), giúp phản ánh rõ hơn hiệu quả hoạt động kinh doanh của doanh nghiệp. Các biến này sẵn sàng phục vụ cho các phân tích tài chính chuyên sâu ở các bước tiếp theo, chẳng hạn như so sánh tỷ suất lợi nhuận qua các năm, đánh giá cơ cấu chi phí, hoặc xác định mức độ phụ thuộc của lợi nhuận vào thu nhập khác.

3. Thông kê cơ bản

3.1 Thống kê mô tả từng biến

# Hàm thống kê mô tả với định dạng số gọn gàng
thong_ke_mo_ta <- function(data, var_name){
  x <- data[[var_name]]
  data.frame(
    Bien = var_name,
    Min = mean(x, na.rm = TRUE) %>% number(big.mark = ",", accuracy = 1),
    Q1 = quantile(x, 0.25, na.rm = TRUE) %>% number(big.mark = ",", accuracy = 1),
    Median = median(x, na.rm = TRUE) %>% number(big.mark = ",", accuracy = 1),
    Mean = mean(x, na.rm = TRUE) %>% number(big.mark = ",", accuracy = 1),
    Q3 = quantile(x, 0.75, na.rm = TRUE) %>% number(big.mark = ",", accuracy = 1),
    Max = max(x, na.rm = TRUE) %>% number(big.mark = ",", accuracy = 1),
    Sd = sd(x, na.rm = TRUE) %>% number(accuracy = 1),
    Skewness = skewness(x, na.rm = TRUE) %>% round(2),
    Kurtosis = kurtosis(x, na.rm = TRUE) %>% round(2)
  )
}

# Lấy danh sách biến numeric cần thống kê
cac_bien_numeric <- setdiff(names(hag_data_final), c("Nam", "Giai_doan", "Tinh_trang_KD"))

# Tạo bảng thống kê
bang_thong_ke_day_du <- do.call(rbind, lapply(cac_bien_numeric, function(v) thong_ke_mo_ta(hag_data_final, v)))
rownames(bang_thong_ke_day_du) <- NULL

# In bảng đẹp, dễ nhìn
bang_thong_ke_day_du %>%
  kable(caption = "Bảng Thống Kê Mô Tả Các Biến KQKD của HAG", align = "c") %>%
  kable_styling(bootstrap_options = c("striped", "hover", "condensed", "responsive"), 
                full_width = FALSE, font_size = 7)
Bảng Thống Kê Mô Tả Các Biến KQKD của HAG
Bien Min Q1 Median Mean Q3 Max Sd Skewness Kurtosis
Doanh_thu_thuan 4,760,738,871 3,592,790,736 5,249,491,144 4,760,738,871 6,135,097,400 6,442,397,199 1 707 942 693 -0.66 1.90
Gia_von -3,505,832,054 -4,282,860,646 -3,360,410,004 -3,505,832,054 -2,981,560,516 -1,590,448,139 1 269 370 382 -0.03 2.04
Loi_nhuan_gop 1,254,906,817 632,512,802 1,233,428,249 1,254,906,817 1,823,704,991 2,374,705,174 779 254 933 -0.04 1.71
Doanh_thu_TC 1,062,120,059 635,834,015 1,000,786,308 1,062,120,059 1,375,440,300 2,137,143,442 576 082 822 0.45 2.29
Chi_phi_TC -1,279,198,249 -1,692,079,285 -1,483,654,364 -1,279,198,249 -1,118,636,680 215,432,853 646 305 167 1.28 3.85
Chi_phi_BH -231,297,493 -295,407,163 -222,192,512 -231,297,493 -150,230,945 -111,239,060 98 499 222 -0.38 1.84
Chi_phi_QLDN -386,887,348 -698,811,624 -425,967,966 -386,887,348 -157,646,627 1,349,894,514 825 992 044 0.42 3.70
LN_thuan_HD_KD 423,709,570 -234,621,619 885,249,748 423,709,570 1,178,959,094 1,690,412,815 1 127 420 460 -1.03 3.12
Thu_nhap_khac 121,902,298 37,626,212 88,909,718 121,902,298 179,523,568 281,127,775 97 949 046 0.57 1.83
LNST_Cong_ty_me 252,282,347 81,567,701 209,773,938 252,282,347 885,660,614 1,663,970,953 922 629 589 -0.32 2.35
Ty_suat_LNG 25 17 24 25 34 44 12 0.08 1.95
Ty_suat_LNST 4 2 9 4 16 26 20 -1.15 3.51
Tong_CPHD -618,184,842 -948,961,640 -616,245,123 -618,184,842 -423,021,725 1,097,955,705 848 744 564 0.21 3.65
LNHĐKD 4 -2 17 4 21 26 29 -1.50 4.03
Ty_trong_TNK -1 -3 3 -1 14 29 33 -2.00 6.22

3.2 Phân tích mối quan hệ tương quan

# Chọn các biến số chính để tính tương quan
cor_data <- hag_data_final %>% 
  select(Doanh_thu_thuan, Gia_von, Loi_nhuan_gop, Chi_phi_TC, LNST_Cong_ty_me)

# Tính ma trận tương quan
correlation_matrix <- cor(cor_data)

# Hiển thị ma trận
kable(correlation_matrix, caption = "Ma trận tương quan giữa các chỉ tiêu chính")
Ma trận tương quan giữa các chỉ tiêu chính
Doanh_thu_thuan Gia_von Loi_nhuan_gop Chi_phi_TC LNST_Cong_ty_me
Doanh_thu_thuan 1.0000000 -0.9043150 0.7186763 0.3546328 0.2832087
Gia_von -0.9043150 1.0000000 -0.3530908 -0.3850516 -0.1353471
Loi_nhuan_gop 0.7186763 -0.3530908 1.0000000 0.1500400 0.4002524
Chi_phi_TC 0.3546328 -0.3850516 0.1500400 1.0000000 0.5615514
LNST_Cong_ty_me 0.2832087 -0.1353471 0.4002524 0.5615514 1.0000000

Nhận xét:

  • Doanh_thu_thuan và Gia_von (-0.9043150): Mối tương quan nghịch biến rất mạnh. Giá trị này gần với -1, cho thấy khi doanh thu thuần tăng lên, giá vốn có xu hướng giảm đi đáng kể, và ngược lại. Điều này có thể phản ánh hiệu quả kinh tế theo quy mô, nơi việc sản xuất hoặc mua hàng với số lượng lớn hơn giúp giảm chi phí đơn vị, từ đó giảm tổng giá vốn tương ứng với mức tăng doanh thu. Ngược lại, khi doanh thu giảm, giá vốn có thể không giảm tương ứng hoặc thậm chí tăng theo tỷ lệ doanh thu, cho thấy kém hiệu quả.

  • Doanh_thu_thuan và Loi_nhuan_gop (0.7186763): Mối tương quan đồng biến mạnh. Giá trị này gần với 1, cho thấy khi doanh thu thuần tăng, lợi nhuận gộp cũng có xu hướng tăng mạnh một cách đáng kể. Điều này là hoàn toàn hợp lý và mong muốn trong kinh doanh: doanh thu bán hàng cao hơn (giả định giá vốn không tăng với tốc độ nhanh hơn nhiều) sẽ trực tiếp dẫn đến lợi nhuận gộp lớn hơn. Điều này khẳng định rằng hoạt động bán hàng đang tạo ra giá trị hiệu quả cho lợi nhuận cốt lõi của công ty.

  • Loi_nhuan_gop và LNST_Cong_ty_me (0.4002524): Mối tương quan đồng biến vừa phải. Lợi nhuận gộp là cơ sở để tính lợi nhuận sau thuế của công ty mẹ, nhưng còn nhiều yếu tố khác (chi phí hoạt động, thuế, lợi ích của cổ đông thiểu số) ảnh hưởng đến LNST.

  • Chi_phi_TC và LNST_Cong_ty_me (0.5615514): Mối tương quan đồng biến vừa phải. Điều này khá thú vị. Thông thường, chi phí tài chính cao sẽ làm giảm lợi nhuận. Tuy nhiên, nếu chi phí tài chính này được sử dụng để tài trợ cho các hoạt động đầu tư mang lại lợi nhuận cao, thì cả chi phí tài chính và LNST đều có thể tăng. Hoặc có thể có một biến ẩn khác ảnh hưởng đến cả hai.

3.3 Phân tích Kết quả Kinh doanh của HAG

3.3.1 Tốc độ tăng trưởng Doanh thu, Giá vốn và Lợi nhuận gộp

bang_tang_truong_tong_hop <- hag_data_final %>%
  mutate(
    Tang_truong_DT = (Doanh_thu_thuan / lag(Doanh_thu_thuan) - 1) * 100,
    Tang_truong_GVHB = (Gia_von / lag(Gia_von) - 1) * 100,
    Tang_truong_LNG = (Loi_nhuan_gop / lag(Loi_nhuan_gop) - 1) * 100
  ) %>%
  select(Nam, Doanh_thu_thuan, Tang_truong_DT, Gia_von, Tang_truong_GVHB, Loi_nhuan_gop, Tang_truong_LNG)

# Trình bày bảng
bang_tang_truong_tong_hop %>%
  kable(caption = "Tốc độ tăng trưởng các chỉ tiêu cốt lõi qua các năm (\\%)", 
        digits = 2,
        col.names = c("Năm", "DT thuần", "Tăng trưởng DT (\\%)", "Giá vốn", "Tăng trưởng GVHB (\\%)", "LN gộp", "Tăng trưởng LNG (\\%)")) %>%
  kable_styling(latex_options = c("striped", "scale_down"), full_width = F, font_size = 7)
Tốc độ tăng trưởng các chỉ tiêu cốt lõi qua các năm (%)
Năm DT thuần Tăng trưởng DT (%) Giá vốn Tăng trưởng GVHB (%) LN gộp Tăng trưởng LNG (%)
2015 6252446533 NA -4398020571 NA 1854425962 NA
2016 6439779268 3.00 -5430638742 23.48 1009140526 -45.58
2017 4841225074 -24.82 -3109682997 -42.74 1731542077 71.59
2018 5388200400 11.30 -3013495226 -3.09 2374705174 37.14
2019 2075444024 -61.48 -1847659651 -38.69 227784373 -90.41
2020 3176645956 53.06 -2970915613 60.79 205730343 -9.68
2021 2097418366 -33.97 -1590448139 -46.47 506970227 146.42
2022 5110781887 143.67 -3937380869 147.56 1173401018 131.45
2023 6442397199 26.06 -5148941719 30.77 1293455480 10.23
2024 5783050002 -10.23 -3611137012 -29.87 2171912990 67.92

Nhận xét:

1. Tăng trưởng Doanh thu thuần (Tăng trưởng DT):

  • Biến động mạnh: Tăng trưởng doanh thu thuần của công ty tiếp tục cho thấy sự biến động rất mạnh qua các năm. Các mức tăng trưởng cao bao gồm 53.06% (2020) và 143.67% (2022), trong khi các năm giảm sâu nhất là -61.48% (2019) và -33.97% (2021).

  • Các năm giảm mạnh: Các năm 2017 (-24.82%), 2019 (-61.48%), 2021 (-33.97%) và 2024 (dự kiến -10.23%) cho thấy sự sụt giảm đáng kể trong doanh thu thuần. Đặc biệt là năm 2019 với mức giảm hơn 61%, đây là một cú sốc rất lớn đối với doanh thu của công ty.

  • Các năm tăng trưởng đột biến: Năm 2022 nổi bật với mức tăng trưởng Doanh thu thuần lên tới 143.67%, cao nhất trong giai đoạn này, cho thấy có thể đã có một sự kiện hoặc chính sách đặc biệt nào đó thúc đẩy doanh thu mạnh mẽ. Năm 2020 cũng có mức tăng trưởng khá cao 53.06%.

  • Xu hướng gần đây: Sau mức tăng trưởng rất cao năm 2022 và tiếp tục tăng trưởng 26.06% năm 2023, doanh thu dự kiến giảm -10.23% vào năm 2024. Điều này cho thấy công ty có thể đang đối mặt với một số thách thức hoặc sự điều chỉnh/ổn định lại sau giai đoạn tăng trưởng nóng vừa qua.

2. Tăng trưởng Giá vốn hàng bán (Tăng trưởng GVHB):

  • Biến động cùng chiều DT nhưng cường độ khác nhau: Nhìn chung, tăng trưởng giá vốn cũng biến động rất mạnh, thường (nhưng không phải luôn luôn) đi cùng chiều với tăng trưởng doanh thu.

    Ví dụ: Năm 2019 DT giảm -59.76% thì GVHB cũng giảm -38.69%. Năm 2022 DT tăng 137.63% thì GVHB tăng 147.56%.

  • Giá vốn tăng nhanh hơn DT (hoặc giảm chậm hơn DT): Có những năm giá vốn tăng/giảm với tốc độ lớn hơn doanh thu, điều này có thể ảnh hưởng đến lợi nhuận gộp.

    Ví dụ năm 2022: DT tăng 137.63% nhưng GVHB tăng 147.56%. Điều này cho thấy chi phí để tạo ra doanh thu đang tăng nhanh hơn chính doanh thu, có thể gây áp lực lên biên lợi nhuận gộp.

    Năm 2020: DT tăng 52.50% và GVHB tăng 60.79%.

  • Giá vốn giảm chậm hơn DT (hoặc tăng chậm hơn DT):

    Năm 2019: DT giảm -59.76% nhưng GVHB giảm -38.69%. Mức giảm của GVHB chậm hơn DT, cũng gây áp lực lên biên lợi nhuận.

3. Tăng trưởng Lợi nhuận gộp (Tăng trưởng LNG):

  • Phản ánh hiệu quả hoạt động cốt lõi: Tăng trưởng lợi nhuận gộp là chỉ số quan trọng phản ánh hiệu quả hoạt động sản xuất kinh doanh cốt lõi của doanh nghiệp sau khi trừ đi giá vốn.

  • Biến động cực kỳ lớn: Mức biến động của tăng trưởng lợi nhuận gộp còn lớn hơn cả doanh thu và giá vốn, từ giảm sâu kỷ lục -90.41% (2019) đến tăng trưởng phi mã 146.42% (2021) và 131.45% (2022).

  • Năm 2019 (-90.41%): Doanh thu giảm gần 60%, giá vốn cũng giảm nhưng chậm hơn, dẫn đến lợi nhuận gộp gần như biến mất. Đây là một năm hoạt động kinh doanh cực kỳ tồi tệ.

  • Năm 2021 (146.42%): Mặc dù doanh thu thuần giảm mạnh (-31.43%), nhưng giá vốn hàng bán lại giảm mạnh hơn nhiều (-46.47%). Điều này đã giúp lợi nhuận gộp tăng trưởng đột biến, cho thấy doanh nghiệp có thể đã kiểm soát chi phí rất tốt hoặc có sự thay đổi lớn trong cấu trúc sản phẩm/giá. Đây là một điểm đáng chú ý cần phân tích sâu hơn.

  • Năm 2022 (131.45%): Doanh thu tăng trưởng mạnh 137.63%, giá vốn cũng tăng nhưng tỷ lệ tăng giá vốn cao hơn tỷ lệ tăng doanh thu (147.56%). Tuy nhiên, nhờ mức tăng trưởng doanh thu tuyệt đối rất lớn, lợi nhuận gộp vẫn tăng trưởng mạnh 131.45%.

  • Dự kiến 2024 (67.92%): Mặc dù doanh thu dự kiến giảm -9.21%, nhưng giá vốn cũng dự kiến giảm -29.87%. Mức giảm của giá vốn nhanh hơn doanh thu, giúp lợi nhuận gộp vẫn có mức tăng trưởng dương đáng kể 67.92%. Đây là dấu hiệu của việc kiểm soát chi phí hiệu quả trong bối cảnh doanh thu giảm.

Nhận xét chung: HAG cho thấy một mô hình tăng trưởng và hiệu quả hoạt động kinh doanh rất biến động qua các năm. Mặc dù có những năm khó khăn với doanh thu và lợi nhuận gộp sụt giảm nghiêm trọng, nhưng cũng có những năm phục hồi và tăng trưởng mạnh mẽ, đôi khi là do kiểm soát chi phí hiệu quả (như 2021) hoặc do doanh thu tăng vọt (như 2022).

3.3.2 Phân tích Biên lợi nhuận gộp

bang_bien_loi_nhuan_gop <- hag_data_final %>%
    # Sử dụng cột đã tạo sẵn ở mục 2.4
    select(Nam, Doanh_thu_thuan, Loi_nhuan_gop, Ty_suat_LNG)

kable(bang_bien_loi_nhuan_gop, 
      caption = "Biên lợi nhuận gộp qua các năm",
      col.names = c("Năm", "Doanh thu thuần", "Lợi nhuận gộp", "Biên LN gộp (\\%)"),
      digits = 2)
Biên lợi nhuận gộp qua các năm
Năm Doanh thu thuần Lợi nhuận gộp Biên LN gộp (%)
2015 6252446533 1854425962 29.66
2016 6439779268 1009140526 15.67
2017 4841225074 1731542077 35.77
2018 5388200400 2374705174 44.07
2019 2075444024 227784373 10.98
2020 3176645956 205730343 6.48
2021 2097418366 506970227 24.17
2022 5110781887 1173401018 22.96
2023 6442397199 1293455480 20.08
2024 5783050002 2171912990 37.56

Nhận xét:

  • Biến động lớn: Biên lợi nhuận gộp của công ty cho thấy sự biến động rất lớn qua các năm. Mức thấp nhất là 6.48% (2020) và mức cao nhất đã đạt được là 44.07% (2018), với mức dự kiến cao vào năm 2024 (37.56%). Sự biến động này cho thấy tính ổn định trong hoạt động quản lý giá vốn và doanh thu chưa cao.

  • Giai đoạn khó khăn 2019-2020: Đây là giai đoạn công ty gặp khó khăn nghiêm trọng về hiệu quả hoạt động. Biên lợi nhuận gộp giảm xuống mức rất thấp (10.98% năm 2019 và 6.48% năm 2020). Điều này cho thấy chi phí sản xuất/giá vốn hàng bán đang chiếm tỷ trọng rất lớn trong doanh thu, hoặc công ty phải đối mặt với áp lực giảm giá bán mạnh, làm bào mòn lợi nhuận cốt lõi.

  • Phục hồi và cải thiện: Từ năm 2021 trở đi, công ty đã có sự phục hồi đáng kể. Biên lợi nhuận gộp tăng vọt lên 24.17% năm 2021 và duy trì ổn định quanh mức 20% vào năm 2022 (22.96%) và 2023 (20.08%). Điều này cho thấy công ty đã kiểm soát chi phí tốt hơn sau giai đoạn khó khăn.

  • Triển vọng 2024: Dự kiến biên lợi nhuận gộp sẽ đạt 37.56% vào năm 2024. Đây là một con số rất ấn tượng và nếu đạt được, sẽ là mức cao đáng kể, chỉ thấp hơn một chút so với đỉnh 44.07% của năm 2018. Điều này báo hiệu một sự cải thiện mạnh mẽ về hiệu quả quản lý chi phí hoặc khả năng định giá sản phẩm trong tương lai.

3.3.3 Lợi nhuận sau thuế trung bình của các năm kinh doanh “Có lãi”

hag_data_final %>% 
  filter(Tinh_trang_KD == "Có lãi") %>% 
  summarise(LNST_TB_CoLai = mean(LNST_Cong_ty_me))

Nhận xét: Lợi nhuận sau thuế trung bình 614 triệu trong các năm có lãi là một con số khả quan, cho thấy tiềm năng sinh lời của công ty khi hoạt động hiệu quả. Điều này củng cố niềm tin vào khả năng tạo ra giá trị của doanh nghiệp, mặc dù cần thêm phân tích về sự ổn định và bối cảnh để có cái nhìn toàn diện nhất.

3.3.4 So sánh hiệu quả trung bình giữa 2 giai đoạn

hag_data_final %>%
  group_by(Giai_doan) %>%
  summarise(
    Doanh_thu_TB = mean(Doanh_thu_thuan),
    LNG_TB = mean(Loi_nhuan_gop),
    LNST_TB = mean(LNST_Cong_ty_me),
    Ty_suat_LNG_TB = mean(Ty_suat_LNG),
    Ty_suat_LNST_TB = mean(Ty_suat_LNST),
    CPTC_TB = mean(Chi_phi_TC)
  ) %>%
  kable(caption = "So sánh hiệu quả trung bình giữa 2 giai đoạn", digits = 2) %>%
  kable_styling(latex_options = "striped", full_width = F, font_size = 7)
So sánh hiệu quả trung bình giữa 2 giai đoạn
Giai_doan Doanh_thu_TB LNG_TB LNST_TB Ty_suat_LNG_TB Ty_suat_LNST_TB CPTC_TB
2015-2019 (Tái cấu trúc) 4999419060 1439519622 -46138957 27.23 0.89 -1652347637
2020-2024 (Phục hồi) 4522058682 1070294012 550703650 22.25 7.12 -906048861

Nhận xét:

  • Bảng so sánh này cung cấp bằng chứng rõ ràng về sự cải thiện hiệu quả tài chính đáng kể của công ty trong giai đoạn 2020-2024 (Phục hồi) so với giai đoạn 2015-2019 (Tái cấu trúc).

  • Mặc dù doanh thu và lợi nhuận gộp tuyệt đối có xu hướng giảm (có thể do thu hẹp quy mô hoặc thay đổi mô hình kinh doanh), nhưng điều quan trọng nhất là công ty đã chuyển từ lỗ sau thuế trung bình sang lãi sau thuế trung bình cao. Yếu tố then chốt đóng góp vào sự chuyển biến tích cực này là việc giảm mạnh chi phí tài chính và quản lý hiệu quả hơn các chi phí khác, giúp tăng tỷ suất lợi nhuận sau thuế một cách ấn tượng. Điều này cho thấy quá trình tái cấu trúc và tập trung vào ngành nông nghiệp (nếu đây là HAG) đang đi đúng hướng và mang lại thành quả về mặt lợi nhuận ròng.

3.3.5 Phân tích các tỷ suất sinh lời

hag_data_final %>%
  select(Nam, Ty_suat_LNG, Ty_suat_LNST) %>%
  kable(caption = "Tỷ suất lợi nhuận gộp và lợi nhuận ròng qua các năm (\\%)", digits = 2) %>%
  kable_styling(latex_options = "striped", full_width = F)
Tỷ suất lợi nhuận gộp và lợi nhuận ròng qua các năm (%)
Nam Ty_suat_LNG Ty_suat_LNST
2015 29.66 8.03
2016 15.67 -17.65
2017 35.77 1.44
2018 44.07 2.18
2019 10.98 10.43
2020 6.48 -39.53
2021 24.17 9.68
2022 22.96 22.09
2023 20.08 25.83
2024 37.56 17.52

Nhận xét:

  • Năm 2019 (Bất thường): Ty_suat_LNG (10.89%) chỉ cao hơn Ty_suat_LNST (10.35%) một chút. Điều này ám chỉ rằng chi phí hoạt động và chi phí tài chính gần như bằng 0 hoặc thậm chí là âm (có thể có thu nhập tài chính đáng kể) trong năm đó, hoặc có sai sót trong dữ liệu. Đây là một điểm cực kỳ cần được làm rõ nếu muốn phân tích sâu.

  • Giai đoạn 2021-2023: Mặc dù Ty_suat_LNG tương đối ổn định khoảng 20-23%, Ty_suat_LNST lại tăng vọt từ 9.28% lên 25.63%. Điều này cho thấy công ty đã quản lý chi phí hoạt động và chi phí tài chính rất hiệu quả, hoặc có những khoản thu nhập khác làm tăng lợi nhuận ròng.

  • Dự kiến 2024: Ty_suat_LNG dự kiến tăng mạnh (36.85%), nhưng Ty_suat_LNST (17.19%) lại thấp hơn mức cao điểm của 2022 và 2023. Điều này có thể gợi ý rằng mặc dù hiệu quả sản xuất kinh doanh cốt lõi (biên gộp) cải thiện, nhưng các chi phí khác hoặc thuế suất dự kiến sẽ tăng lên.

Kết luận: Bảng này cung cấp cái nhìn chi tiết về hiệu suất sinh lời của công ty qua từng năm. Sự biến động mạnh của cả hai tỷ suất cho thấy công ty đã trải qua nhiều thăng trầm trong hoạt động kinh doanh. Giai đoạn 2019-2020 là cực kỳ khó khăn với tỷ suất lợi nhuận ròng âm sâu. Tuy nhiên, giai đoạn 2021-2023 cho thấy sự phục hồi ấn tượng về lợi nhuận ròng, cho thấy công ty đã cải thiện đáng kể khả năng quản lý chi phí tổng thể, biến doanh thu thành lợi nhuận cuối cùng một cách hiệu quả hơn. Điểm bất thường của năm 2019 cần được kiểm tra kỹ lưỡng.

3.3.6 Chi phí tài chính chiếm bao nhiêu phần trăm trong tổng doanh thu qua các năm?

hag_data_final %>%
  mutate(Ty_le_CPTC_tren_DT = abs(Chi_phi_TC) / Doanh_thu_thuan * 100) %>%
  select(Nam, Ty_le_CPTC_tren_DT) %>%
  kable(caption = "Tỷ lệ Chi phí tài chính trên Doanh thu", digits = 2)
Tỷ lệ Chi phí tài chính trên Doanh thu
Nam Ty_le_CPTC_tren_DT
2015 19.25
2016 26.00
2017 35.07
2018 31.95
2019 94.63
2020 41.50
2021 51.98
2022 32.27
2023 3.34
2024 11.90

Nhận xét: Bảng này nhấn mạnh rằng chi phí tài chính là một trong những yếu tố biến động và ảnh hưởng mạnh mẽ nhất đến lợi nhuận của công ty. Giai đoạn trước năm 2022, đặc biệt là năm 2019, công ty đã phải đối mặt với gánh nặng tài chính khổng lồ, làm bào mòn gần hết hoặc vượt quá doanh thu. Tuy nhiên, việc giảm mạnh tỷ lệ này vào năm 2023 là một thành tựu đáng kể, cho thấy công ty đã quản lý và tái cấu trúc tài chính thành công, tạo ra một nền tảng vững chắc hơn cho khả năng sinh lời trong tương lai. Sự phục hồi của công ty rất phụ thuộc vào việc kiểm soát tốt chi phí tài chính.

3.3.7 Tìm năm kinh doanh hiệu quả nhất và kém nhất dựa trên LNST

hieu_qua_nhat <- hag_data_final %>% filter(LNST_Cong_ty_me == max(LNST_Cong_ty_me))
kem_hieu_qua_nhat <- hag_data_final %>% filter(LNST_Cong_ty_me == min(LNST_Cong_ty_me))

cat("--- Năm kinh doanh hiệu quả nhất (dựa trên LNST) ---\n")
## --- Năm kinh doanh hiệu quả nhất (dựa trên LNST) ---
print(hieu_qua_nhat %>% select(Nam, Doanh_thu_thuan, Loi_nhuan_gop, LNST_Cong_ty_me))
## # A tibble: 1 × 4
##     Nam Doanh_thu_thuan Loi_nhuan_gop LNST_Cong_ty_me
##   <dbl>           <dbl>         <dbl>           <dbl>
## 1  2023      6442397199    1293455480      1663970953
cat("\n--- Năm kinh doanh kém hiệu quả nhất (dựa trên LNST) ---\n")
## 
## --- Năm kinh doanh kém hiệu quả nhất (dựa trên LNST) ---
print(kem_hieu_qua_nhat %>% select(Nam, Doanh_thu_thuan, Loi_nhuan_gop, LNST_Cong_ty_me))
## # A tibble: 1 × 4
##     Nam Doanh_thu_thuan Loi_nhuan_gop LNST_Cong_ty_me
##   <dbl>           <dbl>         <dbl>           <dbl>
## 1  2020      3176645956     205730343     -1255661344

4. Trực quan hoá dữ liệu

4.1 Biểu đồ xu hướng Doanh thu và Lợi nhuận

4.1.1 Biểu đồ Đường: Xu hướng Doanh thu thuần qua các năm

plot1 <- ggplot(hag_data_final, aes(x = Nam, y = Doanh_thu_thuan)) +
  geom_line(color = "steelblue", size = 1.2) +
  geom_point(color = "steelblue", size = 3) +
  geom_text_repel(aes(label = comma(Doanh_thu_thuan, accuracy = 1)), size = 3.5) +
  scale_y_continuous(labels = scales::comma) +
  scale_x_continuous(breaks = hag_data_final$Nam) +
  labs(title = "Xu hướng Doanh thu thuần của HAG (2015-2024)",
       subtitle = "Sự phục hồi mạnh mẽ từ năm 2022 sau giai đoạn tái cấu trúc",
       x = "Năm", y = "Doanh thu thuần (tỷ VND)",
       caption = "Nguồn: BCTC Hợp nhất HAG")
print(plot1)

Ý nghĩa:

  • Giai đoạn đầu (2015-2016): Doanh thu ở mức cao, đạt đỉnh vào năm 2016 với khoảng 6.439 tỷ VND.

  • Suy giảm mạnh (2017-2019): Doanh thu bắt đầu giảm mạnh từ năm 2017 và chạm đáy vào năm 2019 với khoảng 2.075 tỷ VND. Giai đoạn này có thể phản ánh những khó khăn hoặc tái cấu trúc của công ty.

  • Hồi phục nhẹ (2020): Có sự hồi phục nhẹ vào năm 2020 lên khoảng 3.176 tỷ VND, nhưng sau đó lại giảm xuống vào năm 2021.

  • Tái cấu trúc và Phục hồi mạnh mẽ (2022-2024): Biểu đồ ghi chú “Sự phục hồi mạnh mẽ từ năm 2022 sau giai đoạn tái cấu trúc”. Doanh thu tăng vọt từ 2.097 tỷ VND năm 2021 lên 5.110 tỷ VND năm 2022 và tiếp tục tăng lên 6.442 tỷ VND vào năm 2023. Doanh thu dự kiến năm 2024 là 5.783 tỷ VND, cho thấy sự ổn định ở mức cao sau giai đoạn tái cấu trúc.

4.1.2 Biến động Lợi nhuận sau thuế qua các năm

plot2 <- ggplot(hag_data_final, aes(x = as.factor(Nam), y = LNST_Cong_ty_me, fill = Tinh_trang_KD)) +
  geom_col(width = 0.7) +
  geom_hline(yintercept = 0, linetype = "dashed", color = "black") +
  geom_text(aes(label = comma(LNST_Cong_ty_me, accuracy = 1)), vjust = ifelse(hag_data_final$LNST_Cong_ty_me > 0, -0.5, 1.5), size = 3.5) +
  scale_fill_manual(values = c("Có lãi" = "seagreen3", "Lỗ" = "tomato2")) +
  scale_y_continuous(labels = scales::comma) +
  labs(title = "Lợi nhuận sau thuế của Công ty mẹ (2015-2024)",
       subtitle = "Chuyển từ thua lỗ sang có lãi bền vững từ năm 2021",
       x = "Năm", y = "Lợi nhuận sau thuế (tỷ VND)", fill = "Tình trạng",
       caption = "Nguồn: BCTC Hợp nhất HAG")
print(plot2)

Nhận xét: Biểu đồ này cho thấy một hành trình đầy thử thách của Công ty mẹ HAG, với những biến động lớn về lợi nhuận trong giai đoạn 2015-2020, xen kẽ giữa lãi và lỗ lớn. Tuy nhiên, từ năm 2021, công ty đã có sự chuyển mình ngoạn mục, đạt được lợi nhuận dương và duy trì sự tăng trưởng mạnh mẽ, bền vững cho đến năm 2024 (dự kiến). Điều này phù hợp với chú thích về việc “Chuyển từ thua lỗ sang có lãi bền vững từ năm 2021”

4.1.3 So sánh Doanh thu thuần và Lợi nhuận gộp

plot3 <- ggplot(hag_data_final, aes(x = Nam)) +
  geom_line(aes(y = Doanh_thu_thuan, color = "Doanh thu thuần"), size = 1.2) +
  geom_line(aes(y = Loi_nhuan_gop, color = "Lợi nhuận gộp"), size = 1.2, linetype = "dashed") +
  geom_point(aes(y = Doanh_thu_thuan), color = "steelblue", size = 3) +
  geom_point(aes(y = Loi_nhuan_gop), color = "orange", size = 3) +
  scale_y_continuous(labels = scales::comma) +
  scale_x_continuous(breaks = hag_data_final$Nam) +
  scale_color_manual(name = "Chỉ tiêu", values = c("Doanh thu thuần" = "steelblue", "Lợi nhuận gộp" = "orange")) +
  theme(legend.position = "top") +
  labs(title = "Xu hướng Doanh thu thuần và Lợi nhuận gộp",
       x = "Năm", y = "Giá trị (tỷ VND)",
       caption = "Nguồn: BCTC Hợp nhất HAG")
print(plot3)

Nhận xét: - Doanh thu thuần (đường màu xanh):

Giai đoạn biến động lớn (2015-2021): Doanh thu thuần có xu hướng tăng giảm thất thường, đạt đỉnh vào năm 2016 và 2023, và chạm đáy vào năm 2019 và 2021.

Phục hồi mạnh mẽ (2022-2023): Doanh thu có sự tăng trưởng ấn tượng từ năm 2021 đến năm 2023, gần chạm mức đỉnh của năm 2016. Ổn định (2024): Dự kiến năm 2024 có sự giảm nhẹ nhưng vẫn duy trì ở mức cao.

  • Lợi nhuận gộp (đường màu cam - nét đứt):

Tương quan với Doanh thu thuần: Nhìn chung, lợi nhuận gộp có xu hướng biến động cùng chiều với doanh thu thuần, nhưng với biên độ thấp hơn.

Giai đoạn 2015-2018: Lợi nhuận gộp duy trì ở mức khá cao, đạt đỉnh vào năm 2018.

Sụt giảm mạnh (2019-2020): Lợi nhuận gộp giảm rất mạnh, xuống mức thấp nhất vào năm 2019 và 2020. Điều này có thể cho thấy chi phí giá vốn hàng bán tăng cao hoặc doanh thu giảm, ảnh hưởng lớn đến lợi nhuận gộp.

Phục hồi (2021-2024): Lợi nhuận gộp có xu hướng phục hồi liên tục từ năm 2021 đến năm 2024 (dự kiến), cho thấy hiệu quả hoạt động sản xuất kinh doanh đã được cải thiện.

Kết luận: Biểu đồ này cung cấp cái nhìn tổng quan về hiệu quả hoạt động cốt lõi của HAG. Doanh thu thuần và lợi nhuận gộp đều trải qua giai đoạn biến động mạnh, đặc biệt là giai đoạn suy giảm vào cuối thập kỷ 2010. Tuy nhiên, từ năm 2021, cả hai chỉ số đều cho thấy sự phục hồi ấn tượng và bền vững, phản ánh nỗ lực tái cấu trúc và cải thiện hoạt động kinh doanh của tập đoàn.

4.2 Biểu đồ về Hiệu suất sinh lời

4.2.1 Tỷ suất Lợi nhuận gộp qua các năm

plot4 <- ggplot(hag_data_final, aes(x = Nam, y = Ty_suat_LNG)) +
  geom_line(color = "darkgreen", size = 1.2) +
  geom_point(aes(color = Giai_doan), size = 4) +
  geom_text_repel(aes(label = paste0(round(Ty_suat_LNG, 1), "%")), size = 4) +
  scale_x_continuous(breaks = hag_data_final$Nam) +
  scale_y_continuous(labels = function(x) paste0(x, "%")) +
  labs(title = "Tỷ suất Lợi nhuận gộp (2015-2024)",
       subtitle = "Hiệu quả hoạt động cốt lõi cải thiện rõ rệt trong giai đoạn Phục hồi",
       x = "Năm", y = "Tỷ suất Lợi nhuận gộp (%)", color = "Giai đoạn")
print(plot4)

Nhận xét:

  • Biểu đồ này xác nhận một cách rõ ràng rằng HAG đã trải qua một quá trình tái cấu trúc đầy khó khăn, thể hiện qua sự biến động và sụt giảm nghiêm trọng của tỷ suất lợi nhuận gộp.

  • Tuy nhiên, từ năm 2021, công ty đã thực sự bước vào giai đoạn phục hồi hiệu quả hoạt động cốt lõi. Sự tăng trưởng trở lại của tỷ suất lợi nhuận gộp, đặc biệt là mức dự kiến năm 2024, cho thấy khả năng kiểm soát chi phí tốt hơn, cải thiện biên lợi nhuận từ các sản phẩm chính, hoặc tối ưu hóa quy trình sản xuất kinh doanh sau quá trình tái cấu trúc. Điều này rất quan trọng vì nó phản ánh khả năng tạo ra lợi nhuận từ hoạt động kinh doanh chính của doanh nghiệp.

4.2.2 So sánh Tỷ suất LNG và Tỷ suất LNST

data_long_margin <- hag_data_final %>%
  select(Nam, Ty_suat_LNG, Ty_suat_LNST) %>%
  pivot_longer(cols = -Nam, names_to = "Loai_ty_suat", values_to = "Gia_tri")

plot5 <- ggplot(data_long_margin, aes(x = Nam, y = Gia_tri, color = Loai_ty_suat)) +
  geom_line(size = 1.2) +
  geom_point(size = 3) +
  geom_hline(yintercept = 0, linetype = "dotted") +
  facet_wrap(~Loai_ty_suat, ncol = 1, scales = "free_y") +
  scale_x_continuous(breaks = hag_data_final$Nam) +
  theme(legend.position = "none") +
  labs(title = "So sánh các Tỷ suất sinh lời",
       x = "Năm", y = "Tỷ lệ (%)")
print (plot5)

Nhận xét:

  • Khoảng cách giữa hai tỷ suất: Khoảng cách giữa tỷ suất LNG và tỷ suất LNST phản ánh mức độ ảnh hưởng của các chi phí hoạt động, chi phí tài chính và thuế. Khi khoảng cách này lớn (ví dụ: năm 2020, LNG dương nhưng LNST âm sâu), điều đó cho thấy công ty đang phải đối mặt với gánh nặng chi phí khác rất lớn.

  • Tương quan phục hồi: Cả hai tỷ suất đều cho thấy xu hướng phục hồi mạnh mẽ từ năm 2021, cho thấy sự cải thiện đồng bộ từ hoạt động sản xuất kinh doanh cốt lõi đến hiệu quả tài chính tổng thể của công ty.

  • Điểm khác biệt: Tỷ suất LNG có thể duy trì ở mức dương ngay cả khi tỷ suất LNST âm (như năm 2020), điều này nhấn mạnh vai trò của các chi phí gián tiếp trong việc xác định lợi nhuận ròng cuối cùng.

4.2.3 Phân phối của Tỷ suất Lợi nhuận gộp theo Giai đoạn

plot6 <- ggplot(hag_data_final, aes(x = Giai_doan, y = Ty_suat_LNG, fill = Giai_doan)) +
  geom_boxplot(alpha = 0.7) +
  geom_jitter(width = 0.1, alpha = 0.5) +
  scale_fill_manual(values = c("2015-2019 (Tái cấu trúc)" = "coral", "2020-2024 (Phục hồi)" = "turquoise3")) +
  theme(legend.position = "none") +
  labs(title = "So sánh Tỷ suất LNG giữa 2 Giai đoạn",
       x = "Giai đoạn", y = "Tỷ suất Lợi nhuận gộp (%)")
print (plot6)

Nhận xét:

1. Giai đoạn 2015-2019 (Tái cấu trúc - Hộp màu cam):

  • Phạm vi rộng: Tỷ suất LNG biến động rất lớn trong giai đoạn này, từ mức thấp nhất (khoảng 11% hoặc 6.5% - có thể là điểm ngoại lệ thấp nhất) đến mức rất cao (khoảng 44% - điểm ngoại lệ cao nhất). Trung vị cao: Giá trị trung vị (đường đen đậm) nằm khoảng 29-30%. Điều này cho thấy trong phần lớn thời gian của giai đoạn này, tỷ suất LNG ở mức khá tốt.

  • Phân bố lệch: Hộp dài, cho thấy sự phân tán dữ liệu rộng. Có vẻ như có một số năm rất tốt (như 2018 với 44.1%) và một số năm rất tệ (như 2019 với 11% và 2020 với 6.5% - nếu 2020 được tính vào giai đoạn này như một điểm dữ liệu của quá trình tái cấu trúc). Dữ liệu thực tế cho thấy điểm 44.1% là outlier trên và 11%, 6.5% là các điểm thấp hơn.

2. Giai đoạn 2020-2024 (Phục hồi - Hộp màu xanh lam):

  • Phạm vi hẹp hơn và ổn định hơn: Hộp nhỏ hơn đáng kể so với giai đoạn trước, cho thấy tỷ suất LNG có sự ổn định hơn và ít biến động hơn.

  • Trung vị thấp hơn: Giá trị trung vị nằm khoảng 23-24%.

  • Tỷ suất ổn định ở mức trung bình: Phần lớn các năm trong giai đoạn này (2021, 2022, 2023) có tỷ suất LNG khá gần nhau (khoảng 20-24%).

  • Điểm ngoại lệ: Có một điểm dữ liệu thấp (khoảng 6.5%, năm 2020) và một điểm dữ liệu cao (khoảng 37.6%, năm 2024 dự kiến) nằm ngoài râu. Điều này cho thấy giai đoạn phục hồi bắt đầu từ mức thấp và dự kiến kết thúc ở mức cao hơn đáng kể.

Kết luận so sánh:

  • Tính ổn định: Giai đoạn phục hồi (2020-2024) cho thấy sự ổn định hơn nhiều về tỷ suất lợi nhuận gộp so với giai đoạn tái cấu trúc (2015-2019), mặc dù trung vị có phần thấp hơn một chút.

  • Khả năng tạo lợi nhuận cốt lõi: Mặc dù trung vị của giai đoạn phục hồi thấp hơn, điều quan trọng là giai đoạn này không có sự sụt giảm nghiêm trọng như những năm cuối của giai đoạn tái cấu trúc. Điểm thấp nhất của giai đoạn phục hồi (năm 2020, là điểm khởi đầu) cho thấy mức độ khó khăn, nhưng sau đó, các năm còn lại của giai đoạn này đều duy trì tỷ suất LNG ở mức ổn định và có xu hướng tăng trưởng (như dự kiến năm 2024 đạt mức cao).

  • Hiệu quả hoạt động: Giai đoạn tái cấu trúc có những năm hiệu quả rất cao (44.1% năm 2018) nhưng cũng có những năm hiệu quả cực kỳ thấp. Ngược lại, giai đoạn phục hồi cho thấy một mức hiệu quả “an toàn” hơn, ít biến động tiêu cực hơn và có xu hướng cải thiện dần lên (dự kiến 2024 là điểm sáng).

4.2.4 So sánh Tỷ suất Lợi nhuận gộp (GPM) và Lợi nhuận ròng (NPM)

# Chuyển dữ liệu sang định dạng dài để vẽ
data_ty_suat <- hag_data_final %>%
 select(Nam, Ty_suat_LNG, Ty_suat_LNST) %>%
 pivot_longer(-Nam, names_to = "Ty_suat", values_to = "Gia_tri")

plot7 <- ggplot(data_ty_suat, aes(x = Nam, y = Gia_tri, color = Ty_suat)) +
 geom_line(size = 1.2) +
 geom_point(size = 3) +
 geom_hline(yintercept = 0, linetype = "dashed", color = "black") +
 geom_text_repel(aes(label = paste0(round(Gia_tri, 1), "%")), size = 3.5) +
 labs(title = "So sánh Hiệu quả Sinh lời Gộp và Ròng",
      subtitle = "Khoảng cách giữa hai đường thể hiện mức độ ảnh hưởng của chi phí hoạt động và tài chính",
      x = "Năm", y = "Tỷ lệ (%)", color = "Loại tỷ suất") +
 scale_y_continuous(labels = scales::percent_format(scale = 1)) + 
 scale_x_continuous(breaks = hag_data_final$Nam) +
 scale_color_manual(values = c("Ty_suat_LNG" = "seagreen", "Ty_suat_LNST" = "firebrick"),
                    labels = c("Ty_suat_LNG" = "Tỷ suất Lợi nhuận gộp (GPM)", "Ty_suat_LNST" = "Tỷ suất Lợi nhuận ròng (NPM)")) +
 theme(legend.position = "bottom")
print (plot7)

Nhận xét:

Giai đoạn 2015-2018: Hiệu suất gộp cao, lợi nhuận ròng biến động:

  • GPM duy trì ở mức cao và tăng trưởng ấn tượng, đạt đỉnh 44.1% vào năm 2018.

  • NPM lại biến động mạnh: dương 8% năm 2015, âm 17.7% năm 2016, sau đó dương nhẹ trở lại 1.4% (2017) và 2.2% (2018).

  • Khoảng cách lớn: Khoảng cách giữa GPM và NPM trong giai đoạn này là rất lớn, đặc biệt là năm 2016 và 2018. Điều này cho thấy mặc dù hoạt động kinh doanh cốt lõi (GPM) tạo ra nhiều lợi nhuận, nhưng các chi phí khác (chi phí hoạt động, chi phí tài chính, thuế) đã bào mòn phần lớn, thậm chí làm âm lợi nhuận ròng. Đây là dấu hiệu của gánh nặng chi phí ngoài sản xuất trực tiếp.

Giai đoạn 2019-2020: Suy thoái nghiêm trọng:

  • GPM giảm mạnh: GPM giảm từ 44.1% (2018) xuống 11% (2019) và 6.5% (2020). Hiệu quả hoạt động cốt lõi suy giảm đáng kể.

  • NPM xuống đáy: NPM cũng giảm theo, từ 10.4% (2019) xuống mức thấp kỷ lục -39.5% (2020).

  • Khoảng cách duy trì lớn: Mặc dù cả hai đều giảm, khoảng cách vẫn còn đáng kể, đặc biệt năm 2020, GPM vẫn dương 6.5% nhưng NPM lại âm gần 40%. Điều này tái khẳng định rằng chi phí hoạt động và tài chính đã gây áp lực cực lớn lên khả năng sinh lời ròng của công ty.

Giai đoạn 2021-2024: Phục hồi mạnh mẽ và thu hẹp khoảng các:

  • Phục hồi đồng bộ: Cả GPM và NPM đều có sự phục hồi mạnh mẽ và đồng bộ.

  • GPM tăng từ 6.5% (2020) lên 24.2% (2021), duy trì khoảng 20-25% và dự kiến bật lên 37.6% (2024).

  • NPM tăng từ -39.5% (2020) lên 9.7% (2021), sau đó tăng ổn định trên 20% (25.8% năm 2022, 22.1% năm 2023) và dự kiến là 17.5% (2024).

  • Khoảng cách thu hẹp: Đây là điểm rất quan trọng. Khoảng cách giữa GPM và NPM đã thu hẹp đáng kể trong giai đoạn này, đặc biệt từ năm 2021 trở đi. Điều này cho thấy HAG đã kiểm soát tốt hơn các chi phí hoạt động và chi phí tài chính, giúp chuyển phần lớn lợi nhuận gộp thành lợi nhuận ròng. Việc NPM duy trì trên mức 20% trong giai đoạn này là một dấu hiệu tích cực về khả năng quản lý chi phí.

  • Năm 2024: GPM dự kiến tăng cao trở lại (37.6%), trong khi NPM dự kiến giảm nhẹ so với 2023 (17.5%). Khoảng cách có vẻ giãn ra một chút so với 2022-2023, có thể do một số chi phí tăng lên hoặc do dự phóng thận trọng.

Kết luận chung:

  • Biểu đồ này là bức tranh toàn diện về hiệu quả tài chính của HAG. Nó không chỉ cho thấy khả năng tạo ra lợi nhuận từ hoạt động kinh doanh cốt lõi (GPM) mà còn cả khả năng chuyển hóa lợi nhuận đó thành lợi nhuận ròng cho cổ đông (NPM) sau khi tính đến tất cả các chi phí khác.

  • Giai đoạn tái cấu trúc (đặc biệt 2016 và 2020) cho thấy GPM có thể cao nhưng NPM lại âm sâu, chỉ ra vấn đề lớn về quản lý chi phí ngoài sản xuất. Giai đoạn phục hồi từ năm 2021 cho thấy sự cải thiện đồng bộ và quan trọng hơn là khả năng kiểm soát chi phí hiệu quả, giúp công ty đạt được lợi nhuận ròng bền vững. Sự thu hẹp khoảng cách giữa hai đường là dấu hiệu tích cực nhất cho thấy sức khỏe tài chính tổng thể của HAG đã được cải thiện đáng kể.

4.3 Biểu đồ về Cơ cấu và Gánh nặng Chi phí

4.3.1 Biểu đồ các loại chi phí chính (Cơ cấu chi phí)

# 1. Chuẩn bị dữ liệu
data_chi_phi <- hag_data_final %>%
  # Chọn các cột chi phí cần phân tích
  select(Nam, Chi_phi_TC, Chi_phi_BH, Chi_phi_QLDN) %>%
  # Chuyển từ dạng rộng sang dạng dài
  pivot_longer(
    cols = -Nam, 
    names_to = "Loai_chi_phi", 
    values_to = "So_tien"
  ) %>%
  # Xử lý tên và giá trị
  mutate(
    # Chi phí trong BCTC thường là số âm, lấy giá trị tuyệt đối để vẽ
    So_tien = abs(So_tien), 
    # Đổi tên biến thành nhãn đẹp hơn để hiển thị
    Loai_chi_phi = factor(case_when(
      Loai_chi_phi == "Chi_phi_TC"   ~ "1. Chi phí Tài chính",
      Loai_chi_phi == "Chi_phi_QLDN" ~ "2. Chi phí Quản lý DN",
      Loai_chi_phi == "Chi_phi_BH"   ~ "3. Chi phí Bán hàng"
    ))
  )

# 2. Vẽ biểu đồ vùng xếp chồng
plot8 <- ggplot(data_chi_phi, aes(x = Nam, y = So_tien, fill = Loai_chi_phi)) +
  # Layer 1: Vẽ vùng xếp chồng
  geom_area(position = "stack", alpha = 0.8, color = "white", size = 0.5) +
  
  # Layer 2: Thêm các đường line để phân tách rõ hơn
  geom_line(position = "stack", size = 0.5, color="gray20") +

  # Layer 3: Định dạng các trục và tiêu đề
  labs(
    title = "Cơ cấu Chi phí thay đổi theo quá trình Tái cấu trúc",
    x = "Năm", 
    y = "Tổng Chi phí (tỷ VND)", 
    fill = "Loại chi phí:"
  ) +
  
  # Layer 4: Tùy chỉnh thang đo và màu sắc
  scale_y_continuous(labels = scales::comma) +
  scale_x_continuous(breaks = hag_data_final$Nam) +
  scale_fill_manual(values = c(
    "1. Chi phí Tài chính" = "firebrick", 
    "2. Chi phí Quản lý DN" = "darkorange", 
    "3. Chi phí Bán hàng" = "steelblue"
  )) +
  
  # Layer 5: Áp dụng theme và tùy chỉnh
  theme_minimal(base_size = 14) +
  theme(
    plot.title = element_text(hjust = 0.5, face = "bold"),
    plot.subtitle = element_text(hjust = 0.5, size = 11),
    legend.position = "top"
  )
print (plot8)

Nhận xét:

Giai đoạn 2015-2020: Chi phí Tài chính là gánh nặng lớn nhất:

  • Tổng chi phí tăng cao: Tổng chi phí có xu hướng tăng từ 2015 và đạt đỉnh vào khoảng năm 2020 (hơn 3.500 tỷ VND).

  • Chi phí Tài chính chiếm tỷ trọng cực lớn: Trong suốt giai đoạn này, chi phí tài chính là thành phần lớn nhất và tăng trưởng mạnh mẽ, chiếm phần lớn tổng chi phí. Đặc biệt, nó tăng vọt vào năm 2020. Điều này giải thích lý do tại sao tỷ suất lợi nhuận ròng (NPM) lại âm sâu trong giai đoạn này, mặc dù tỷ suất lợi nhuận gộp (GPM) vẫn dương. Gánh nặng nợ vay và chi phí tài chính khác là nguyên nhân chính.

  • Chi phí Quản lý DN và Bán hàng tương đối ổn định/tăng nhẹ: Hai loại chi phí này có xu hướng tăng dần nhưng không đáng kể so với chi phí tài chính.

Giai đoạn 2021-2024: Thay đổi cơ cấu chi phí và giảm gánh nặng tài chính:

  • Giảm tổng chi phí: Từ đỉnh năm 2020, tổng chi phí giảm mạnh vào năm 2021 và 2023. Mặc dù có sự tăng trở lại vào năm 2022, nhưng xu hướng chung cho thấy sự kiểm soát chi phí hiệu quả hơn.

  • Chi phí Tài chính giảm đột biến: Đây là thay đổi quan trọng nhất. Chi phí tài chính giảm mạnh từ năm 2021, đặc biệt là vào năm 2023 và 2024 (dự kiến) khi nó chỉ còn chiếm một phần rất nhỏ trong tổng chi phí. Điều này phù hợp với quá trình tái cấu trúc tài chính, giảm nợ và giảm gánh nặng lãi vay của HAG.

  • Chi phí Quản lý DN và Bán hàng trở nên nổi bật hơn: Khi chi phí tài chính giảm, tỷ trọng của chi phí Quản lý DN và chi phí Bán hàng trở nên rõ ràng hơn trong cơ cấu tổng chi phí.

  • Chi phí Quản lý DN: Có vẻ như duy trì ở mức tương đối ổn định hoặc có xu hướng tăng nhẹ theo hoạt động kinh doanh (năm 2022 tăng, 2023 giảm).

  • Chi phí Bán hàng: Cũng có xu hướng tương tự, tăng vào các năm hoạt động kinh doanh tốt (như 2022 và dự kiến 2024).

Kết luận chung:

  • Biểu đồ này xác nhận rằng Chi phí Tài chính là “thủ phạm” chính gây ra các khoản lỗ ròng lớn cho HAG trong giai đoạn trước tái cấu trúc. Quá trình tái cấu trúc, đặc biệt từ năm 2021 trở đi, đã thành công trong việc giải quyết gánh nặng này.

  • 9Sự thay đổi rõ rệt trong cơ cấu chi phí, với chi phí tài chính giảm mạnh, đã giúp HAG cải thiện đáng kể lợi nhuận ròng và đạt được sự phục hồi bền vững. Điều này cho thấy công ty đã quản lý tốt hơn cấu trúc vốn và các khoản nợ của mình, chuyển trọng tâm từ việc đối phó với chi phí tài chính sang việc tối ưu hóa chi phí hoạt động và bán hàng để nâng cao hiệu quả kinh doanh.

4.3.2 Xu hướng Chi phí tài chính qua các năm

plot9 <- ggplot(hag_data_final, aes(x = Nam, y = Chi_phi_TC)) +
  geom_col(fill = "firebrick", width=0.6) +
  geom_text(aes(label = comma(Chi_phi_TC, 1)), vjust = -0.5, size=3.5) +
  scale_x_continuous(breaks = hag_data_final$Nam) +
  scale_y_continuous(labels = scales::comma) +
  labs(title = "Gánh nặng Chi phí tài chính qua các năm",
       subtitle = "Chi phí tài chính giảm dần từ năm 2022",
       x = "Năm", y = "Chi phí tài chính (tỷ VND)")
print (plot9)

Nhận xét:

Giai đoạn 2015-2022: Gánh nặng chi phí tài chính rất lớn:

  • Mức độ tiêu cực: Trong phần lớn giai đoạn này, chi phí tài chính đều ở mức âm rất lớn, cho thấy đây là một gánh nặng tài chính đáng kể đối với HAG.

  • Đỉnh điểm: Gánh nặng này đạt đỉnh vào năm 2019 (-1.913 tỷ VND) và 2022 (-1.649 tỷ VND). Mức chi phí tài chính này là một trong những nguyên nhân chính khiến công ty gặp khó khăn về lợi nhuận ròng như đã phân tích ở các biểu đồ trước.

  • Tăng giảm thất thường: Mặc dù có những năm chi phí tài chính thấp hơn (ví dụ như 2017, 2018), nhưng xu hướng chung cho thấy nó thường xuyên ở mức trên 1.000 tỷ VND.

Giai đoạn 2023-2024: Thay đổi đột phá - Chi phí tài chính giảm dần từ năm 2022:

  • Năm 2023 - Lợi nhuận tài chính: Đây là điểm rất đáng chú ý và khác biệt hoàn toàn. Năm 2023, chi phí tài chính chuyển thành giá trị dương (215 triệu VND). Điều này có nghĩa là HAG đã có lợi nhuận từ hoạt động tài chính thay vì chịu chi phí. Điều này có thể đến từ việc:

    Thanh toán phần lớn các khoản nợ vay, giảm đáng kể chi phí lãi vay.

    Tái cấu trúc thành công các khoản nợ.

    Có các khoản thu nhập tài chính bất thường hoặc đáng kể (ví dụ: lãi từ đầu tư, hoàn nhập dự phòng tài chính…).

  • Năm 2024 - Giảm đáng kể: Chi phí tài chính dự kiến năm 2024 là -688 triệu VND, tuy vẫn là một khoản chi phí nhưng đã giảm đi đáng kể so với các năm trước 2023 và thấp hơn rất nhiều so với mức trung bình của giai đoạn 2015-2022. Đây là một dấu hiệu cực kỳ tích cực cho thấy sự kiểm soát và giảm thiểu gánh nặng tài chính của công ty.

Kết luận chung:

  • Biểu đồ này minh họa rõ ràng thành công của HAG trong việc giải quyết bài toán chi phí tài chính, vốn là một trong những rào cản lớn nhất đối với lợi nhuận của công ty trong quá khứ.

  • Việc chuyển từ gánh nặng chi phí tài chính hàng ngàn tỷ đồng sang có lợi nhuận tài chính vào năm 2023 và giảm mạnh vào năm 2024 là kết quả trực tiếp của quá trình tái cấu trúc tài chính sâu rộng. Điều này giúp cải thiện đáng kể lợi nhuận ròng của HAG, giải phóng nguồn lực cho các hoạt động kinh doanh cốt lõi và đặt nền tảng cho sự phát triển bền vững hơn trong tương lai.

4.3.3 Tỷ trọng Chi phí tài chính trên Doanh thu

plot10_data <- hag_data_final %>%
    mutate(Ty_trong_CPTC = abs(Chi_phi_TC) / Doanh_thu_thuan * 100)
plot10 <- ggplot(plot10_data, aes(x = Nam, y = Ty_trong_CPTC)) +
  geom_line(color = "purple", size = 1.2) +
  geom_area(fill = "purple", alpha = 0.2) +
  geom_point(color = "purple", size = 3) +
  geom_text_repel(aes(label = paste0(round(Ty_trong_CPTC, 1), "%"))) +
  scale_x_continuous(breaks = hag_data_final$Nam) +
  scale_y_continuous(labels = function(x) paste0(x, "%")) +
  labs(title = "Tỷ trọng Chi phí tài chính trên Doanh thu thuần",
       subtitle = "Gánh nặng lãi vay đã giảm đáng kể trong những năm gần đây",
       x = "Năm", y = "Tỷ trọng (%)") 
print(plot10)

Nhận xét:

Giai đoạn 2015-2018: Tỷ trọng tương đối cao:

  • Trong giai đoạn này, tỷ trọng chi phí tài chính trên doanh thu thuần dao động từ 19.3% (2015) đến 35.1% (2017). Đây là mức khá cao, cho thấy một phần đáng kể doanh thu bị chi phối bởi chi phí tài chính.

  • Năm 2019: Đỉnh điểm của gánh nặng tài chính: Tỷ trọng này tăng vọt lên 94.6% vào năm 2019. Đây là con số cực kỳ đáng báo động, có nghĩa là gần như toàn bộ doanh thu thuần của công ty đã bị “nuốt chửng” bởi chi phí tài chính. Điều này có thể xảy ra khi doanh thu giảm mạnh (như đã thấy ở biểu đồ doanh thu thuần) trong khi chi phí tài chính vẫn ở mức cao tuyệt đối. Tỷ lệ này giải thích rõ ràng mức độ khó khăn tài chính mà HAG phải đối mặt trong năm này.

Giai đoạn 2020-2022: Gánh nặng vẫn còn lớn: Sau đỉnh điểm năm 2019, tỷ trọng này có giảm xuống 41.5% (2020) nhưng sau đó lại tăng lên 52% (2021) và 32.3% (2022). Mặc dù đã thấp hơn mức cực đoan của năm 2019, nhưng mức 30-50% vẫn là rất cao. Điều này cho thấy chi phí tài chính vẫn chiếm một phần đáng kể trong doanh thu thuần, tiếp tục là một yếu tố hạn chế khả năng sinh lời ròng của công ty.

Giai đoạn 2023-2024: Giảm đáng kể gánh nặng:

  • Năm 2023: Giảm đột phá: Tỷ trọng này giảm mạnh mẽ xuống chỉ còn 3.3%. Đây là một sự thay đổi ngoạn mục, cho thấy gánh nặng chi phí tài chính trên doanh thu thuần gần như đã được loại bỏ hoàn toàn. Điều này phù hợp với việc công ty đã có lợi nhuận tài chính trong năm này (như biểu đồ “Gánh nặng Chi phí tài chính qua các năm” đã chỉ ra).

  • Năm 2024: Duy trì ở mức thấp: Tỷ trọng dự kiến là 11.9%. Mặc dù cao hơn năm 2023, nhưng đây vẫn là một mức rất thấp so với lịch sử của công ty (ngoại trừ 2023). Điều này xác nhận rằng HAG đã thành công trong việc giảm thiểu ảnh hưởng của chi phí tài chính lên doanh thu.

4.4 Biểu đồ về Mối quan hệ giữa các biến

4.4.1 Mối quan hệ giữa Doanh thu và Lợi nhuận gộp

plot11 <- ggplot(hag_data_final, aes(x = Doanh_thu_thuan, y = Loi_nhuan_gop)) +
  geom_point(aes(color = Giai_doan, size = LNST_Cong_ty_me)) +
  geom_smooth(method = "lm", se = FALSE, color = "black", linetype = "dashed") +
  geom_text_repel(aes(label = Nam), size = 3.5) +
  scale_x_continuous(labels = scales::comma) +
  scale_y_continuous(labels = scales::comma) +
  scale_color_manual(values = c("2015-2019 (Tái cấu trúc)" = "coral", "2020-2024 (Phục hồi)" = "turquoise3")) +
  labs(title = "Mối quan hệ Doanh thu và Lợi nhuận gộp",
       x = "Doanh thu thuần (tỷ VND)", y = "Lợi nhuận gộp (tỷ VND)", color = "Giai đoạn", size = "LNST")
print (plot11)

Nhận xét:

1. Mối quan hệ chung: Nhìn chung, có một mối quan hệ tương đối tuyến tính và dương giữa Doanh thu thuần và Lợi nhuận gộp, như được chỉ ra bởi đường xu hướng nét đứt dốc lên. Điều này có nghĩa là, theo kỳ vọng, khi doanh thu tăng lên, lợi nhuận gộp cũng có xu hướng tăng theo.

2. Giai đoạn 2015-2019 (Tái cấu trúc - điểm màu cam):

  • Năm 2015: Doanh thu cao, lợi nhuận gộp khá, LNST cũng tốt (điểm lớn).

  • Năm 2016: Doanh thu cao nhưng lợi nhuận gộp thấp hơn đáng kể so với 2015, và LNST rất thấp/âm (điểm rất nhỏ). Đây là một năm kém hiệu quả.

  • Năm 2017: Doanh thu và lợi nhuận gộp thấp hơn 2015/2016, nhưng LNST dương (điểm kích thước trung bình).

  • Năm 2018: Đây là một năm nổi bật với lợi nhuận gộp cao nhất trong giai đoạn này (khoảng 2.400 tỷ VND) với doanh thu khá cao, tuy nhiên LNST lại nhỏ (điểm nhỏ), cho thấy các chi phí khác đã ăn mòn lợi nhuận.

  • Năm 2019: Doanh thu và lợi nhuận gộp đều rất thấp, và LNST cũng rất thấp/âm (điểm rất nhỏ). Đây là năm hoạt động kém hiệu quả nhất.

3. Giai đoạn 2020-2024 (Phục hồi - điểm màu xanh lam):

  • Năm 2020: Doanh thu và lợi nhuận gộp vẫn rất thấp (tương tự 2019), và LNST cũng rất thấp/âm (điểm nhỏ). Đây là khởi đầu của giai đoạn phục hồi.

  • Năm 2021: Doanh thu tăng nhẹ so với 2019/2020, lợi nhuận gộp cũng tăng theo, và LNST đã chuyển sang dương (điểm lớn hơn).

  • Năm 2022: Doanh thu và lợi nhuận gộp tăng đáng kể, và LNST cũng tăng theo (điểm lớn).

  • Năm 2023: Doanh thu đạt mức cao (tương đương 2015/2016), lợi nhuận gộp cũng tốt, và LNST đạt mức rất cao (điểm lớn nhất).

  • Năm 2024: Doanh thu dự kiến giảm nhẹ nhưng vẫn ở mức cao, lợi nhuận gộp vẫn rất tốt, và LNST cũng ở mức cao (điểm lớn).

Kết luận chung:

  • Hiệu quả theo thời gian: Biểu đồ cho thấy sự cải thiện rõ rệt về hiệu quả hoạt động theo thời gian. Các điểm của giai đoạn phục hồi (xanh lam) có xu hướng nằm gần hoặc trên đường xu hướng hơn, và kích thước điểm (LNST) lớn hơn đáng kể so với các năm kém hiệu quả trong giai đoạn tái cấu trúc (như 2016, 2019, 2020).

  • Điểm ngoại lệ: Các điểm nằm xa đường xu hướng (ví dụ 2018 với lợi nhuận gộp cao nhưng doanh thu không tương xứng, hoặc 2016 với doanh thu cao nhưng lợi nhuận gộp thấp) cho thấy những năm mà hiệu suất biên lợi nhuận gộp (GPM) có sự khác biệt lớn so với xu hướng chung.

  • Phục hồi chất lượng: Giai đoạn phục hồi (từ 2021) không chỉ thể hiện sự tăng trưởng về doanh thu và lợi nhuận gộp mà còn thể hiện sự cải thiện về lợi nhuận sau thuế, cho thấy công ty đang tạo ra giá trị thực sự cho cổ đông. Sự dịch chuyển của các điểm dữ liệu lên phía trên và sang phải (doanh thu và lợi nhuận gộp cao hơn) và kích thước điểm lớn hơn (LNST cao hơn) cho thấy HAG đang hoạt động hiệu quả hơn rất nhiều.

4.4.2 Mối quan hệ giữa Lợi nhuận gộp và Lợi nhuận sau thuế

plot12 <- ggplot(hag_data_final, aes(x = Loi_nhuan_gop, y = LNST_Cong_ty_me)) +
  geom_point(aes(color = Giai_doan), size = 4, alpha = 0.8) +
  geom_vline(xintercept = 0, linetype = "dotted") +
  geom_hline(yintercept = 0, linetype = "dotted") +
  geom_text_repel(aes(label = Nam), size = 3.5) +
  scale_x_continuous(labels = scales::comma) +
  scale_y_continuous(labels = scales::comma) +
  labs(title = "Lợi nhuận gộp ảnh hưởng đến Lợi nhuận sau thuế",
       subtitle = "Các năm thuộc giai đoạn phục hồi nằm ở góc phần tư thứ nhất (cùng có lãi)",
       x = "Lợi nhuận gộp (tỷ VND)", y = "Lợi nhuận sau thuế (tỷ VND)", color = "Giai đoạn")
print (plot12)

Nhận xét:

1. Giai đoạn 2015-2019 (Tái cấu trúc - điểm màu cam):

  • Năm 2015: Lợi nhuận gộp khá cao (khoảng 1.900 tỷ VND), Lợi nhuận sau thuế cũng dương (khoảng 500 tỷ VND). Đây là một năm hiệu quả.

  • Năm 2016: Lợi nhuận gộp dương (khoảng 1.100 tỷ VND) nhưng Lợi nhuận sau thuế lại âm sâu (khoảng -1.100 tỷ VND). Điểm này nằm ở góc phần tư thứ tư (lợi nhuận gộp dương, lợi nhuận sau thuế âm), cho thấy các chi phí khác đã ăn mòn toàn bộ lợi nhuận gộp và gây lỗ ròng.

  • Năm 2017: Lợi nhuận gộp dương (khoảng 1.600 tỷ VND), Lợi nhuận sau thuế dương nhẹ (khoảng 69 tỷ VND). Hiệu quả khá thấp so với lợi nhuận gộp.

  • Năm 2018: Lợi nhuận gộp rất cao (khoảng 2.400 tỷ VND), nhưng Lợi nhuận sau thuế lại rất thấp và gần như hòa vốn (khoảng 117 tỷ VND). Tương tự năm 2017, hiệu quả chuyển đổi từ lợi nhuận gộp sang lợi nhuận sau thuế rất kém.

  • Năm 2019: Lợi nhuận gộp rất thấp (khoảng 216 tỷ VND), nhưng Lợi nhuận sau thuế dương (khoảng 216 tỷ VND). Điểm này khá gần với đường y=x, cho thấy chi phí khác không quá lớn trong năm này so với lợi nhuận gộp.

2. Giai đoạn 2020-2024 (Phục hồi - điểm màu xanh lam):

  • Năm 2020: Lợi nhuận gộp thấp (khoảng 317 tỷ VND) nhưng Lợi nhuận sau thuế lại âm rất sâu (khoảng -1.255 tỷ VND). Điểm này nằm ở góc phần tư thứ tư, cho thấy gánh nặng chi phí khác cực lớn đã gây lỗ ròng nghiêm trọng. Đây là năm khó khăn nhất.

  • Năm 2021: Lợi nhuận gộp tăng lên (khoảng 511 tỷ VND), và quan trọng hơn, Lợi nhuận sau thuế đã chuyển sang dương (khoảng 203 tỷ VND). Điểm này nằm ở góc phần tư thứ nhất.

  • Năm 2022: Lợi nhuận gộp và Lợi nhuận sau thuế đều tăng trưởng mạnh mẽ và dương (khoảng 1.100 tỷ VND lợi nhuận gộp và 1.100 tỷ VND lợi nhuận sau thuế). Điểm này nằm ở góc phần tư thứ nhất, gần đường y=x, cho thấy hiệu quả chuyển đổi rất tốt.

  • Năm 2023: Lợi nhuận gộp và Lợi nhuận sau thuế đạt mức cao nhất (khoảng 1.300 tỷ VND lợi nhuận gộp và 1.600 tỷ VND lợi nhuận sau thuế). Điểm này nằm rất rõ ràng ở góc phần tư thứ nhất và thậm chí Lợi nhuận sau thuế còn cao hơn Lợi nhuận gộp (có thể do thu nhập tài chính dương như đã phân tích).

  • Năm 2024: Lợi nhuận gộp và Lợi nhuận sau thuế dự kiến duy trì ở mức cao và dương (khoảng 2.100 tỷ VND lợi nhuận gộp và 1.000 tỷ VND lợi nhuận sau thuế). Điểm này cũng nằm ở góc phần tư thứ nhất.

Kết luận: Biểu đồ này xác nhận mạnh mẽ nhận định về sự cải thiện hiệu quả tài chính của HAG:

  • Trước phục hồi: Trong giai đoạn tái cấu trúc và đầu giai đoạn phục hồi (2016, 2017, 2018, 2020), mặc dù lợi nhuận gộp có thể dương và thậm chí cao, nhưng lợi nhuận sau thuế thường thấp hoặc âm. Điều này cho thấy gánh nặng chi phí hoạt động, chi phí tài chính và thuế đã bào mòn đáng kể lợi nhuận từ hoạt động kinh doanh cốt lõi.

  • Sau phục hồi: Từ năm 2021 trở đi, các điểm dữ liệu đều nằm ở góc phần tư thứ nhất, cho thấy cả lợi nhuận gộp và lợi nhuận sau thuế đều dương và tăng trưởng mạnh mẽ. Điều này là minh chứng cho việc HAG đã giải quyết thành công các vấn đề về chi phí khác, đặc biệt là chi phí tài chính, giúp chuyển hóa hiệu quả lợi nhuận gộp thành lợi nhuận ròng. Các năm 2022, 2023, 2024 thể hiện sự ổn định và tăng trưởng bền vững về lợi nhuận.

4.4.3 Mối quan hệ giữa Lợi nhuận gộp và Chi phí tài chính

plot13 <- ggplot(hag_data_final, aes(x = Nam)) +
  # Vẽ Chi phí tài chính dạng cột
  geom_col(aes(y = abs(Chi_phi_TC), fill = "Chi phí Tài chính"), width = 0.6, alpha = 0.8) +
  # Vẽ Lợi nhuận gộp dạng đường và điểm
  geom_line(aes(y = Loi_nhuan_gop, color = "Lợi nhuận gộp"), size = 1.2) +
  geom_point(aes(y = Loi_nhuan_gop, color = "Lợi nhuận gộp"), size = 3) +
  geom_hline(yintercept = 0) +
  
  labs(title = "Lợi nhuận gộp có đủ 'gánh' Chi phí tài chính?",
       subtitle = "Sự đảo chiều từ năm 2021 khi Lợi nhuận gộp vượt xa Chi phí tài chính",
       x = "Năm", y = "Số tiền (tỷ VND)") +
  
  scale_y_continuous(labels = scales::comma) +
  scale_x_continuous(breaks = hag_data_final$Nam) +
  scale_fill_manual(name = "", values = c("Chi phí Tài chính" = "firebrick")) +
  scale_color_manual(name = "", values = c("Lợi nhuận gộp" = "steelblue")) +
  theme(legend.position = "top")

print(plot13)

Nhận xét:

  1. Giai đoạn 2015-2020: Chi phí Tài chính là gánh nặng lớn và cạnh tranh với Lợi nhuận gộp:
  • Năm 2015: Lợi nhuận gộp cao hơn chi phí tài chính.

  • Năm 2016-2017: Chi phí tài chính (cột đỏ) gần bằng hoặc thậm chí vượt qua lợi nhuận gộp (đường xanh) trong một số năm. Điều này có nghĩa là phần lớn, hoặc toàn bộ, lợi nhuận từ hoạt động sản xuất kinh doanh cốt lõi đã bị chi phí tài chính “nuốt chửng”.

  • Năm 2018: Lợi nhuận gộp đạt đỉnh (khoảng 2.400 tỷ VND) và cao hơn đáng kể so với chi phí tài chính. Đây là một năm tốt về mặt hoạt động cốt lõi.

  • Năm 2019-2020: Lợi nhuận gộp giảm sâu, trong khi chi phí tài chính vẫn ở mức cao (đặc biệt năm 2019). Năm 2020, lợi nhuận gộp (khoảng 200-300 tỷ VND) thấp hơn rất nhiều so với chi phí tài chính (gần 2.000 tỷ VND). Đây là những năm mà chi phí tài chính là gánh nặng không thể chịu đựng được, gây ra lỗ ròng lớn.

2. Giai đoạn 2021-2024: Sự đảo chiều rõ rệt - Lợi nhuận gộp vượt xa Chi phí Tài chính:

  • Năm 2021: Lợi nhuận gộp (khoảng 500 tỷ VND) bắt đầu tăng nhẹ, trong khi chi phí tài chính (khoảng 1.100 tỷ VND) vẫn cao hơn. Tuy nhiên, mức chênh lệch đã giảm.

  • Năm 2022: Lợi nhuận gộp tăng đáng kể (khoảng 1.200 tỷ VND), nhưng chi phí tài chính cũng vẫn còn cao (khoảng 1.600 tỷ VND), vẫn tạo ra áp lực.

  • Năm 2023: Điểm đảo chiều mạnh mẽ: Lợi nhuận gộp tiếp tục tăng (khoảng 1.300 tỷ VND), nhưng quan trọng nhất, chi phí tài chính đã giảm đột biến xuống mức rất thấp (khoảng 200 tỷ VND, thậm chí là lợi nhuận tài chính như đã thấy ở biểu đồ trước). Lợi nhuận gộp đã vượt xa chi phí tài chính một cách rõ rệt.

  • Năm 2024: Lợi nhuận gộp dự kiến tiếp tục tăng mạnh (hơn 2.000 tỷ VND), trong khi chi phí tài chính dự kiến duy trì ở mức thấp (khoảng 700 tỷ VND). Khoảng cách giữa lợi nhuận gộp và chi phí tài chính là rất lớn và tích cực.

Kết luận: Biểu đồ này minh họa trực quan và mạnh mẽ vấn đề cốt lõi mà HAG phải đối mặt trong quá khứ và thành công trong việc giải quyết nó:

  • Trước năm 2021: Chi phí tài chính là một “gánh nặng” khổng lồ, thường xuyên “nuốt chửng” phần lớn hoặc toàn bộ lợi nhuận gộp, khiến công ty khó có lãi ròng.

  • Từ năm 2021 trở đi: Nhờ quá trình tái cấu trúc, đặc biệt là giảm nợ và tối ưu hóa chi phí tài chính, gánh nặng này đã được giảm thiểu đáng kể. Từ năm 2023, lợi nhuận gộp đã vượt xa chi phí tài chính một cách rõ rệt, cho phép công ty chuyển hóa lợi nhuận từ hoạt động cốt lõi thành lợi nhuận ròng một cách hiệu quả.

Sự đảo chiều này là một tín hiệu cực kỳ tích cực cho sức khỏe tài chính và khả năng sinh lời bền vững của HAG trong tương lai.

4.4.4 Tỷ suất Lợi nhuận gộp và Lợi nhuận ròng (%)

data_ty_suat_viz <- hag_data_final %>%
 select(Nam, Ty_suat_LNG, Ty_suat_LNST) %>%
 pivot_longer(-Nam, names_to = "Ty_suat", values_to = "Gia_tri")

plot14 <- ggplot(data_ty_suat_viz, aes(x = Nam, y = Gia_tri, color = Ty_suat)) +
 geom_line(size = 1) +
 geom_point(size = 2.5) +
 geom_hline(yintercept = 0, linetype = "dotted") +
    geom_text_repel(aes(label = label_percent(scale = 1, accuracy = 0.1)(Gia_tri)), 
                    size = 3.5, max.overlaps = Inf) +
 labs(title = "Tỷ suất Lợi nhuận gộp (GPM) và Lợi nhuận ròng (NPM) (%)",
x = "Năm", y = "Tỷ lệ (%)", color = "Loại tỷ suất") +
 theme_minimal() +
 scale_y_continuous(labels = label_percent(scale = 1)) + 
 scale_x_continuous(breaks = hag_data_final$Nam) +
 scale_color_manual(values = c("Ty_suat_LNG" = "forestgreen", "Ty_suat_LNST" = "darkred"),
labels = c("Ty_suat_LNG" = "Tỷ suất Lợi nhuận gộp (GPM)",
 "Ty_suat_LNST" = "Tỷ suất Lợi nhuận ròng (NPM)")) +
 theme(plot.title = element_text(hjust = 0.5, face = "bold"),
 legend.position = "bottom")
print(plot14)

Nhận xét:

1. Giai đoạn trước phục hồi (2015-2020):

  • GPM biến động mạnh, có những năm rất cao (44.1% năm 2018) nhưng cũng có những năm rất thấp (6.5% năm 2020).

  • NPM rất kém, thường xuyên âm sâu (đặc biệt -17.7% năm 2016 và -39.5% năm 2020), cho thấy công ty không tạo ra đủ lợi nhuận để bù đắp các chi phí ngoài giá vốn.

  • Khoảng cách lớn: Khoảng cách lớn giữa GPM và NPM trong giai đoạn này chỉ ra rằng các chi phí hoạt động, chi phí tài chính và thuế đã bào mòn lợi nhuận gộp một cách nghiêm trọng, đẩy công ty vào tình trạng thua lỗ ròng.

2. Giai đoạn phục hồi (2021-2024):

  • Phục hồi đồng bộ: Cả GPM và NPM đều có sự phục hồi mạnh mẽ và bền vững.

    • GPM tăng từ 6.5% (2020) lên 24.2% (2021) và dự kiến đạt 37.6% vào năm 2024.

    • NPM chuyển từ âm sâu (-39.5% năm 2020) sang dương và tăng trưởng ổn định (9.7% năm 2021, 25.8% năm 2022, 22.1% năm 2023) và dự kiến 17.5% vào năm 2024.

  • Khoảng cách thu hẹp: Đây là điểm nhấn quan trọng. Khoảng cách giữa GPM và NPM đã thu hẹp đáng kể trong giai đoạn này. Điều này cho thấy HAG đã kiểm soát hiệu quả hơn các chi phí hoạt động và tài chính, giúp chuyển phần lớn lợi nhuận gộp thành lợi nhuận ròng. Việc NPM duy trì mức dương và tăng trưởng là minh chứng cho sự cải thiện đáng kể về sức khỏe tài chính.

Kết luận chung: Biểu đồ này cung cấp một cái nhìn tổng quan mạnh mẽ về quá trình chuyển đổi của HAG từ một giai đoạn đầy thách thức về khả năng sinh lời ròng sang một giai đoạn phục hồi ổn định và bền vững, nhờ vào việc cải thiện hiệu quả hoạt động cốt lõi và kiểm soát chặt chẽ hơn các chi phí khác, đặc biệt là chi phí tài chính.

4.5 Biểu đồ phân tích chuyên sâu

4.5.1 Tương quan giữa Doanh thu và LNST

plot15 <- ggplot(hag_data_final, aes(x = Doanh_thu_thuan, y = LNST_Cong_ty_me)) +
 geom_point(aes(color = Giai_doan, size = abs(Chi_phi_TC)), alpha = 0.8) +
 geom_smooth(method = "lm", se = FALSE, color = "black", linetype="dashed", fullrange=TRUE) +
 geom_text_repel(aes(label = Nam), size = 4) + 
 geom_hline(yintercept = 0, linetype="dotted") +
 labs(title = "Mối quan hệ giữa Doanh thu và Lợi nhuận sau thuế",
      subtitle = "Doanh thu cao hơn không phải lúc nào cũng đảm bảo lợi nhuận dương trong giai đoạn tái cấu trúc",
      x = "Doanh thu thuần (tỷ VND)", y = "Lợi nhuận sau thuế (tỷ VND)",
      color = "Giai đoạn", size = "Quy mô Chi phí TC") +
 scale_y_continuous(labels = scales::comma) +
 scale_x_continuous(labels = scales::comma) +
 scale_color_manual(values = c("2015-2019 (Tái cấu trúc)" = "coral", "2020-2024 (Phục hồi)" = "turquoise3"))
print(plot15)

Nhận xét:

1. Mối quan hệ chung: Có một mối quan hệ dương, nhưng không hoàn hảo, giữa Doanh thu thuần và Lợi nhuận sau thuế. Khi doanh thu tăng, Lợi nhuận sau thuế có xu hướng tăng, nhưng có nhiều yếu tố khác ảnh hưởng.

2. Giai đoạn 2015-2019 (Tái cấu trúc - điểm màu cam):

  • Năm 2015: Doanh thu cao (khoảng 6.200 tỷ VND), Lợi nhuận sau thuế dương (khoảng 500 tỷ VND). Kích thước điểm cho thấy chi phí tài chính không quá lớn.

  • Năm 2016: Doanh thu cao nhất trong giai đoạn này (khoảng 6.400 tỷ VND) nhưng Lợi nhuận sau thuế lại âm sâu (khoảng -1.100 tỷ VND). Đây là minh chứng rõ ràng cho chú thích của biểu đồ: doanh thu cao nhưng vẫn lỗ nặng. Kích thước điểm lớn cho thấy chi phí tài chính cao đã góp phần gây ra khoản lỗ này.

  • Năm 2017 & 2018: Doanh thu thấp hơn, Lợi nhuận sau thuế dương nhưng rất thấp (chỉ vài chục đến hơn trăm tỷ VND). Kích thước điểm cho thấy chi phí tài chính ở mức trung bình.

  • Năm 2019: Doanh thu rất thấp (khoảng 2.000 tỷ VND), Lợi nhuận sau thuế dương nhẹ (khoảng 200 tỷ VND). Đáng chú ý, kích thước điểm của 2019 rất lớn, cho thấy chi phí tài chính là gánh nặng khổng lồ so với doanh thu thấp.

3. Giai đoạn 2020-2024 (Phục hồi - điểm màu xanh lam):

  • Năm 2020: Doanh thu thấp (khoảng 3.000 tỷ VND), Lợi nhuận sau thuế âm sâu nhất (khoảng -1.200 tỷ VND). Kích thước điểm rất lớn, chứng tỏ chi phí tài chính là nguyên nhân chính gây ra khoản lỗ này. Năm 2020 đánh dấu đáy của sự suy thoái.

  • Năm 2021: Doanh thu thấp hơn 2020, nhưng Lợi nhuận sau thuế đã chuyển sang dương (khoảng 200 tỷ VND). Kích thước điểm nhỏ hơn đáng kể, cho thấy chi phí tài chính đã giảm.

  • Năm 2022: Doanh thu tăng mạnh, Lợi nhuận sau thuế cũng tăng đáng kể (khoảng 1.100 tỷ VND). Kích thước điểm cho thấy chi phí tài chính vẫn còn cao nhưng đã quản lý được.

  • Năm 2023: Doanh thu tăng trở lại mức cao (khoảng 6.400 tỷ VND), Lợi nhuận sau thuế đạt đỉnh cao nhất (khoảng 1.600 tỷ VND). Quan trọng nhất, kích thước điểm của 2023 rất nhỏ, cho thấy chi phí tài chính đã giảm thiểu đến mức thấp nhất.

  • Năm 2024: Doanh thu dự kiến giảm nhẹ nhưng vẫn cao, Lợi nhuận sau thuế duy trì ở mức cao (khoảng 1.000 tỷ VND). Kích thước điểm vẫn nhỏ, cho thấy chi phí tài chính được kiểm soát tốt.

Kết luận:

  • Biểu đồ này minh họa rõ ràng ảnh hưởng của Chi phí Tài chính đến khả năng sinh lời ròng của HAG:

  • Doanh thu không đảm bảo lợi nhuận: Trong giai đoạn tái cấu trúc, đặc biệt là năm 2016, doanh thu cao không đảm bảo lợi nhuận dương do gánh nặng chi phí tài chính quá lớn (thể hiện qua kích thước điểm).

  • Chi phí tài chính là rào cản chính: Chi phí tài chính cao (kích thước điểm lớn) thường đi kèm với lợi nhuận sau thuế thấp hoặc âm (như 2016, 2019, 2020), bất kể mức doanh thu.

  • Thành công của tái cấu trúc: Từ năm 2021 trở đi, các năm trong giai đoạn phục hồi (màu xanh lam) có xu hướng dịch chuyển lên phía trên (lợi nhuận sau thuế dương và cao hơn) và các điểm có kích thước nhỏ dần (chi phí tài chính giảm). Đặc biệt năm 2023 và 2024 cho thấy doanh thu cao kết hợp với chi phí tài chính thấp đã dẫn đến lợi nhuận sau thuế rất cao, minh chứng cho thành công của quá trình tái cấu trúc tài chính của HAG.

4.5.2 Phân phối Lợi nhuận sau thuế theo Giai đoạn

plot16 <- ggplot(hag_data_final, aes(x = Giai_doan, y = LNST_Cong_ty_me, fill = Giai_doan)) +
  geom_boxplot(alpha = 0.7, outlier.shape = NA) +
  geom_jitter(width = 0.15, aes(color = Tinh_trang_KD), size = 4, alpha = 0.8) +
  labs(title = "Phân phối Lợi nhuận sau thuế giữa 2 Giai đoạn",
       subtitle = "Giai đoạn Phục hồi có mức lợi nhuận trung vị cao hơn và ít thua lỗ hơn",
       x = "Giai đoạn", y = "Lợi nhuận sau thuế (tỷ VND)") +
  scale_y_continuous(labels = scales::comma) +
  scale_fill_manual(values = c("2015-2019 (Tái cấu trúc)" = "coral", "2020-2024 (Phục hồi)" = "turquoise3"), name = "Giai đoạn") +
  scale_color_manual(values = c("Có lãi" = "darkgreen", "Lỗ" = "darkred"), name = "Tình trạng KD") +
  theme(legend.position = "right")
print (plot16)

Nhận xét:

1. Giai đoạn 2015-2019 (Tái cấu trúc):

  • Lợi nhuận khiêm tốn: Biểu đồ hộp (boxplot) màu cam cho giai đoạn này khá hẹp và nằm gần mức 0. Điều này cho thấy lợi nhuận sau thuế trong thời kỳ này không cao và có độ biến động thấp. Đường trung vị (vạch ngang giữa hộp) chỉ nhỉnh hơn 0 một chút, phản ánh mức lợi nhuận trung bình khá thấp.

  • Tình hình kinh doanh: Giai đoạn này có cả những lần kinh doanh có lãi (các chấm xanh) và một lần thua lỗ đáng kể (chấm đỏ). Các mức lãi không quá đột biến. Điều này phù hợp với tính chất của một giai đoạn “tái cấu trúc”, khi doanh nghiệp thường tập trung vào việc ổn định lại hoạt động và chưa tạo ra sự đột phá về doanh thu, lợi nhuận.

2. Giai đoạn 2020-2024 (Phục hồi):

  • Lợi nhuận tăng trưởng vượt bậc: Biểu đồ hộp màu xanh dương cho thấy một sự thay đổi rõ rệt. Toàn bộ hộp được đẩy lên cao hơn nhiều so với giai đoạn trước, với mức lợi nhuận trung vị cao hơn đáng kể. Điều này khẳng định nhận định trong tiêu đề phụ của biểu đồ: “Giai đoạn Phục hồi có mức lợi nhuận trung vị cao hơn”.

  • Biên độ lợi nhuận lớn hơn: Hộp màu xanh rộng hơn, cho thấy lợi nhuận trong giai đoạn này có sự biến động lớn hơn. Có những thời điểm doanh nghiệp đạt được mức lợi nhuận rất cao (chấm xanh ở trên cùng), nhưng cũng có một trường hợp thua lỗ sâu (chấm đỏ ở dưới cùng).

  • Hiệu quả kinh doanh cải thiện: Mặc dù vẫn còn một trường hợp lỗ, nhưng số lần có lãi nhiều hơn và các mức lãi đạt được cũng cao hơn hẳn so với giai đoạn trước. Điều này cho thấy các biện pháp tái cấu trúc đã phát huy hiệu quả, giúp doanh nghiệp kinh doanh tốt hơn và tạo ra lợi nhuận cao hơn.

Kết luận: Biểu đồ đã minh họa một câu chuyện thành công về quá trình chuyển đổi của doanh nghiệp. Sau giai đoạn tái cấu trúc với lợi nhuận khiêm tốn, doanh nghiệp đã bước vào giai đoạn phục hồi và tăng trưởng mạnh mẽ, với mức lợi nhuận trung bình cao hơn và khả năng tạo ra lợi nhuận đột phá tốt hơn. Đây là một dấu hiệu rất tích cực, cho thấy doanh nghiệp đang phát triển đúng hướng và hiệu quả hơn.

4.5.3 Mối quan hệ giữa Chi phí tài chính và LNST

plot17 <- ggplot(hag_data_final, aes(x = abs(Chi_phi_TC), y = LNST_Cong_ty_me)) +
  geom_point(aes(color = Giai_doan, size = Doanh_thu_thuan), alpha = 0.8) +
  geom_text_repel(aes(label = Nam)) +
  geom_smooth(method = "lm", se = FALSE, color = "gray40", linetype = "dashed") +
  geom_hline(yintercept = 0, linetype = "dotted") +
  labs(title = "Chi phí tài chính - Yếu tố quyết định Lợi nhuận",
       subtitle = "Tương quan nghịch rõ rệt: Chi phí tài chính càng cao, lợi nhuận càng thấp",
       x = "Chi phí Tài chính (tỷ VND)", y = "Lợi nhuận sau thuế (tỷ VND)",
       color = "Giai đoạn", size = "Doanh thu thuần") +
  scale_x_continuous(labels = scales::comma) +
  scale_y_continuous(labels = scales::comma) +
  scale_color_manual(values = c("2015-2019 (Tái cấu trúc)" = "coral", "2020-2024 (Phục hồi)" = "turquoise3"))
print (plot17)

Nhận xét:

1. Mối tương quan nghịch giữa Chi phí tài chính và Lợi nhuận:

  • Đường xu hướng dốc xuống thể hiện rất rõ ràng rằng khi chỉ số trên trục hoành (Chi phí tài chính) tăng, chỉ số trên trục tung (Lợi nhuận sau thuế) có xu hướng giảm.

  • Điều này cho thấy chi phí tài chính (chủ yếu là chi phí lãi vay) là một gánh nặng đáng kể, bào mòn trực tiếp vào lợi nhuận của doanh nghiệp. Những năm có chi phí tài chính cao như 2016, 2018, 2019 đều ghi nhận mức lợi nhuận rất thấp hoặc thậm chí là lỗ. Ngược lại, những năm kiểm soát tốt chi phí tài chính như 2023 lại đạt được lợi nhuận cao kỷ lục.

2. Sự chuyển biến tích cực qua hai giai đoạn:

  • Giai đoạn 2015-2019 (Tái cấu trúc - chấm màu cam):

    • Các điểm dữ liệu của giai đoạn này chủ yếu tập trung ở phía bên phải của biểu đồ, cho thấy một mức chi phí tài chính rất cao.

    • Hầu hết các điểm này đều nằm gần hoặc dưới trục 0, tương ứng với lợi nhuận thấp hoặc thua lỗ. Đặc biệt, năm 2016 là năm có chi phí tài chính cực lớn và mức lỗ sâu nhất.

    • Điều này phản ánh đúng tính chất của giai đoạn tái cấu trúc, khi doanh nghiệp có thể phải vay nợ nhiều để đầu tư, xử lý các vấn đề tồn đọng, dẫn đến chi phí lãi vay tăng vọt.

  • Giai đoạn 2020-2024 (Phục hồi - chấm màu xanh):

    • Có một sự dịch chuyển rõ rệt của các điểm dữ liệu về phía bên trái và lên trên. Điều này có nghĩa là doanh nghiệp đã thành công trong việc giảm đáng kể chi phí tài chính.

    • Kết quả là lợi nhuận đã được cải thiện vượt bậc. Các năm 2022, 2023 đều có lợi nhuận rất cao nhờ kiểm soát tốt chi phí tài chính. Sự thay đổi này cho thấy các chiến lược trong giai đoạn tái cấu trúc (ví dụ: trả bớt nợ vay, tái cơ cấu nguồn vốn) đã phát huy hiệu quả trong giai đoạn sau.

3. Vai trò của Doanh thu thuần (Kích thước điểm):

  • Kích thước của các điểm cho thấy một câu chuyện sâu sắc hơn. Năm 2016, dù doanh thu thuần (điểm to) không hề thấp, nhưng vì gánh nặng chi phí tài chính quá lớn đã khiến doanh nghiệp lỗ nặng.

  • Ngược lại, năm 2022 và 2023 không chỉ thành công trong việc giảm chi phí tài chính mà còn đạt được doanh thu thuần cao (điểm to), tạo ra hiệu ứng “cộng hưởng” giúp lợi nhuận tăng vọt.

  • Điều này nhấn mạnh rằng: chỉ tăng doanh thu là chưa đủ, việc quản lý và tối ưu hóa chi phí, đặc biệt là chi phí tài chính, là chìa khóa để tối đa hóa lợi nhuận.

Kết luận: Biểu đồ đã trình bày một cách trực quan và thuyết phục câu chuyện về sự “hồi sinh” của một doanh nghiệp. Bằng việc kiểm soát và cắt giảm thành công gánh nặng chi phí tài chính, doanh nghiệp đã chuyển mình từ giai đoạn tái cấu trúc khó khăn với lợi nhuận bấp bênh sang giai đoạn phục hồi và tăng trưởng mạnh mẽ, cho thấy hiệu quả rõ rệt của chiến lược tái cấu trúc tài chính.

4.5.4 Ma trận Tương quan Trực quan

# Lấy lại ma trận tương quan đã tính
cor_matrix <- cor(hag_data_final %>% select(Doanh_thu_thuan, Gia_von, Loi_nhuan_gop, Chi_phi_TC, LNST_Cong_ty_me), use = "complete.obs")
# Chuyển sang dạng dài
melted_cor_matrix <- melt(cor_matrix)

plot18 <- ggplot(data = melted_cor_matrix, aes(x=Var1, y=Var2, fill=value)) +
  geom_tile(color = "white") +
  geom_text(aes(label = round(value, 2)), color = "black", size = 4) +
  scale_fill_gradient2(low = "firebrick", high = "seagreen", mid = "white", 
                       midpoint = 0, limit = c(-1,1), space = "Lab", 
                       name="Hệ số\ntương quan") +
  theme_minimal(base_size = 12) +
  theme(axis.text.x = element_text(angle = 45, vjust = 1, hjust = 1),
        axis.title = element_blank(),
        plot.title = element_text(hjust = 0.5, face="bold")) +
  labs(title = "Ma trận Tương quan giữa các Chỉ tiêu Chính")

print(plot18)

Nhận xét:

1. Mối quan hệ “kỳ lạ” giữa Doanh thu và Giá vốn (-0.9)

  • Phát hiện: Ma trận cho thấy một mối tương quan nghịch rất mạnh (-0.9) giữa Doanh thu thuần và Giá vốn.

  • Nhận xét: Đây là một kết quả cực kỳ bất thường và trái với logic kinh doanh thông thường. Thông thường, khi doanh thu tăng lên (bán được nhiều hàng hơn), giá vốn hàng bán cũng phải tăng theo (tương quan thuận mạnh).

  • Các giả thuyết có thể xảy ra:

    • Lỗi dữ liệu: Có thể có sai sót trong quá trình nhập liệu hoặc tính toán.

    • Sự thay đổi đột biến trong cơ cấu sản phẩm: Doanh nghiệp có thể đã chuyển từ bán các sản phẩm có giá vốn cao sang các sản phẩm có giá vốn cực thấp (ví dụ: chuyển từ bán hàng hóa vật chất sang cung cấp dịch vụ số).

    • Cách hạch toán đặc biệt: Có một phương pháp kế toán nào đó không theo chuẩn mực thông thường.

  • Kết luận: Mối quan hệ này cần được xem xét và kiểm tra lại dữ liệu gốc vì nó không phản ánh đúng thực tế vận hành của hầu hết các doanh nghiệp.

2. Mối quan hệ logic giữa Doanh thu và Lợi nhuận gộp (0.72)

  • Phát hiện: Doanh thu thuần và Lợi nhuận gộp có tương quan thuận mạnh (0.72).

  • Nhận xét: Điều này hoàn toàn hợp lý. Khi doanh thu tăng, nếu quản lý tốt biên lợi nhuận, lợi nhuận gộp sẽ tăng theo. Đây là dấu hiệu của một hoạt động kinh doanh cốt lõi lành mạnh.

3. Mối quan hệ giữa Chi phí và Lợi nhuận

  • Giá vốn vs. Lợi nhuận gộp (-0.35): Tương quan nghịch vừa phải. Điều này đúng, vì Lợi nhuận gộp = Doanh thu - Giá vốn. Khi giá vốn tăng (với doanh thu không đổi), lợi nhuận gộp sẽ giảm.

  • Chi phí tài chính (Chi_phi_TC) vs. Lợi nhuận sau thuế (LNST_Cong_ty_me) (0.56):

    • Phát hiện: Ma trận cho thấy mối tương quan thuận khá mạnh (0.56).

    • Nhận xét: Đây cũng là một điểm khá bất thường. Về lý thuyết, chi phí tài chính càng cao thì lợi nhuận sau thuế phải càng thấp (tương quan nghịch).

    • Giải thích khả dĩ: Có thể có một yếu tố thứ ba ảnh hưởng đến cả hai chỉ số này. Ví dụ: Trong những năm doanh nghiệp mở rộng quy mô, họ phải vay nợ nhiều hơn (làm tăng Chi phí TC), nhưng các dự án đầu tư đó lại mang lại lợi nhuận rất lớn, đủ sức bù đắp chi phí và làm LNST tăng cao. Do đó, cả hai chỉ số cùng tăng trong những năm mở rộng và cùng giảm trong những năm hoạt động bình thường.

Kết luận chung: Ma trận này cung cấp một cái nhìn tổng quan nhanh về các mối quan hệ tài chính nội tại của doanh nghiệp. Nó đã làm nổi bật được các mối quan hệ hợp lý như Doanh thu -> Lợi nhuận gộp, đồng thời cũng chỉ ra những điểm bất thường và cần phân tích sâu hơn như mối quan hệ nghịch giữa Doanh thu và Giá vốn, và mối quan hệ thuận giữa Chi phí tài chính và Lợi nhuận sau thuế. Những điểm bất thường này là gợi ý quan trọng để các nhà phân tích kiểm tra lại dữ liệu hoặc tìm hiểu sâu hơn về chiến lược kinh doanh đặc thù của doanh nghiệp trong giai đoạn phân tích.

4.5.5 Phân bổ Doanh thu năm 2023

# --- BƯỚC 1: CHUẨN BỊ DỮ LIỆU ---
# Lấy dữ liệu năm 2023 và tạo dataframe để vẽ
pie_data <- hag_data_final %>%
  filter(Nam == 2023) %>%
  summarise(
    `Giá vốn` = abs(Gia_von),
    `Chi phí TC` = abs(Chi_phi_TC),
    `Chi phí HĐ` = abs(Chi_phi_BH + Chi_phi_QLDN),
    `Lợi nhuận ròng` = LNST_Cong_ty_me
  ) %>%
  pivot_longer(everything(), names_to = "Thanh_phan", values_to = "Gia_tri")

# --- BƯỚC 2: VẼ BIỂU ĐỒ TRÒN ---
plot19 <- ggplot(pie_data, aes(x = "", y = Gia_tri, fill = Thanh_phan)) +
  geom_col(width = 1, color = "white") + # Tạo 1 cột chồng duy nhất
  coord_polar("y", start = 0) +          # Biến cột thành biểu đồ tròn
  
  # Thêm nhãn phần trăm vào các miếng bánh
  geom_text(aes(label = scales::percent(Gia_tri / sum(Gia_tri), accuracy = 0.1)),
            position = position_stack(vjust = 0.5)) +
            
  theme_void() + # Xóa toàn bộ nền và trục không cần thiết
  labs(
    title = "Cơ cấu Phân bổ Doanh thu của HAG năm 2023",
    fill = "Thành phần:"
  ) +
  scale_fill_brewer(palette = "Pastel1") # Dùng một bảng màu đẹp

print(plot19)

Nhận xét:

1. Gánh nặng Giá vốn chiếm tỷ trọng lớn nhất (69.2%)

  • Nhận xét: Gần 70% doanh thu của HAG được dùng để chi trả cho giá vốn hàng bán. Đây là khoản mục chiếm tỷ trọng lớn nhất một cách áp đảo.

  • Ý nghĩa: Điều này cho thấy biên lợi nhuận gộp của HAG tương đối mỏng (khoảng 30.8%). Doanh nghiệp phải chi ra một số tiền lớn cho các yếu tố đầu vào trực tiếp như nguyên vật liệu, nhân công sản xuất… Tỷ lệ này là đặc trưng của các ngành thâm dụng vốn và có chi phí sản xuất cao như nông nghiệp, sản xuất.

2. Lợi nhuận ròng ở mức khá tốt (22.4%)

  • Nhận xét: Sau khi trang trải mọi chi phí, HAG giữ lại được 22.4% doanh thu làm lợi nhuận ròng.

  • Ý nghĩa: Tỷ suất lợi nhuận ròng (Net Profit Margin) ở mức 22.4% là một con số rất tích cực và được xem là cao trong nhiều ngành nghề. Điều này cho thấy, mặc dù biên lợi nhuận gộp không quá dày, công ty đã quản lý các chi phí hoạt động và chi phí tài chính một cách hiệu quả để tối ưu hóa lợi nhuận cuối cùng.

3. Các chi phí khác được kiểm soát tốt

  • Chi phí Hoạt động (5.5%): Khoản chi phí này ở mức khá hợp lý, cho thấy công ty không chi tiêu quá đà cho việc bán hàng và quản lý.

  • Chi phí Tài chính (2.9%): Tỷ trọng chi phí tài chính chỉ chiếm 2.9% doanh thu là một điểm sáng rất lớn, đặc biệt khi nhìn vào lịch sử tài chính của HAG với các khoản nợ vay lớn. Con số này cho thấy công ty đã kiểm soát rất tốt gánh nặng lãi vay trong năm 2023, có thể do đã trả bớt nợ hoặc tái cấu trúc các khoản vay thành công.

Kết luận: Biểu đồ cho thấy một bức tranh tài chính khá lành mạnh của HAG trong năm 2023. Mặc dù hoạt động kinh doanh cốt lõi có chi phí giá vốn cao, công ty đã chứng tỏ năng lực quản trị chi phí xuất sắc ở các khâu vận hành và tài chính. Kết quả là HAG đã tạo ra một tỷ suất lợi nhuận ròng ấn tượng, biến 100 đồng doanh thu thành hơn 22 đồng lợi nhuận thực. Đây là một dấu hiệu quan trọng cho thấy sự hiệu quả trong hoạt động và sự phục hồi vững chắc của doanh nghiệp.

4.5.6 Hiệu quả Chi phí Hoạt động trên Doanh thu

# Chuẩn bị dữ liệu tỷ lệ chi phí
data_cp_hieuqua <- hag_data_final %>%
  mutate(
    Ty_le_CPBH = (abs(Chi_phi_BH) / Doanh_thu_thuan) * 100,
    Ty_le_QLDN = (abs(Chi_phi_QLDN) / Doanh_thu_thuan) * 100
  ) %>%
  select(Nam, Ty_le_CPBH, Ty_le_QLDN) %>%
  pivot_longer(-Nam, names_to = "Loai_CP", values_to = "Ty_le")

# Vẽ biểu đồ
plot20 <- ggplot(data_cp_hieuqua, aes(x = Nam, y = Ty_le, group = Loai_CP, color = Loai_CP)) +
  geom_line(size = 1.2) +
  geom_point(size = 3) +
  geom_text_repel(aes(label = paste0(round(Ty_le, 1), "%")), size = 3.5) +
  labs(title = "Hiệu quả Chi phí Hoạt động trên Doanh thu",
       subtitle = "Tỷ lệ Chi phí Bán hàng tăng, cho thấy sự đầu tư vào đầu ra sản phẩm",
       x = "Năm", y = "Tỷ lệ trên Doanh thu (%)") +
  scale_y_continuous(labels = scales::percent_format(scale = 1)) +
  scale_x_continuous(breaks = hag_data_final$Nam) +
  scale_color_manual(values = c("Ty_le_CPBH" = "steelblue", "Ty_le_QLDN" = "darkorange"),
                     labels = c("Tỷ lệ Chi phí Bán hàng", "Tỷ lệ Chi phí Quản lý DN"))

print(plot20)

Nhận xét:

1. Chi phí Quản lý Doanh nghiệp (Đường màu cam) - Biến động dữ dội, cho thấy sự tái cấu trúc mạnh mẽ

  • Giai đoạn 2015-2020: Chi phí leo thang mất kiểm soát. Tỷ lệ này tăng liên tục từ 5.6% (2015) lên đến đỉnh điểm cực kỳ cao là 58.9% vào năm 2020. Điều này có nghĩa là trong năm 2020, cứ 100 đồng doanh thu tạo ra, doanh nghiệp đã phải chi gần 59 đồng chỉ cho việc quản lý. Đây là một con số báo động, cho thấy bộ máy quản lý cồng kềnh, chi phí vận hành quá lớn hoặc có thể đã hạch toán các khoản chi phí bất thường (ví dụ: chi phí tái cấu trúc, dự phòng…).

  • Giai đoạn 2021-2023: Tái cấu trúc và tối ưu hóa thành công. Ngay sau đỉnh điểm năm 2020, tỷ lệ này đã giảm mạnh một cách ngoạn mục xuống chỉ còn 6.3% vào năm 2021 và xuống mức rất thấp là 2.4% vào năm 2023. Sự sụt giảm đột ngột này cho thấy một nỗ lực tái cấu trúc và cắt giảm chi phí quyết liệt đã thành công rực rỡ. Doanh nghiệp đã tạo ra một bộ máy vận hành tinh gọn và hiệu quả hơn rất nhiều.

2. Chi phí Bán hàng (Đường màu xanh) - Thể hiện sự đầu tư có chiến lược

  • Giai đoạn 2015-2019: Giai đoạn đầu tư. Đúng như tiêu đề phụ của biểu đồ (“Tỷ lệ Chi phí Bán hàng tăng, cho thấy sự đầu tư vào đầu ra sản phẩm”), tỷ lệ này đã tăng dần từ 1.8% (2015) lên đỉnh 14.9% (2019). Điều này cho thấy doanh nghiệp đã chủ động đẩy mạnh đầu tư vào các kênh phân phối, marketing và bán hàng để mở rộng thị trường và tăng độ phủ cho sản phẩm.

  • Giai đoạn 2020-2023: Giai đoạn tối ưu hóa hiệu quả. Sau khi đạt đỉnh, tỷ lệ này bắt đầu giảm dần, cho thấy các khoản đầu tư vào hệ thống bán hàng trước đó đã bắt đầu phát huy hiệu quả. Doanh nghiệp không cần chi quá nhiều tiền nhưng vẫn duy trì hoặc tăng được doanh thu. Việc tỷ lệ này giảm xuống còn 4% vào năm 2023 là một dấu hiệu rất tốt.

Kết luận chung: Biểu đồ kể một câu chuyện rất rõ ràng về quá trình chuyển đổi của doanh nghiệp:

  • Trải qua một giai đoạn khó khăn với chi phí quản lý phình to đến mức báo động (đỉnh điểm 2020).

  • Đồng thời, có chiến lược đầu tư bài bản vào việc phát triển hệ thống bán hàng trong giai đoạn đầu.

  • Sau đó, doanh nghiệp đã thực hiện một cuộc “đại phẫu” thành công, cắt giảm triệt để các chi phí không hiệu quả (đặc biệt là chi phí quản lý) và tối ưu hóa chi phí bán hàng.

Kết quả là đến năm 2023, doanh nghiệp đã có một cơ cấu chi phí hoạt động cực kỳ tinh gọn và hiệu quả, tạo ra nền tảng vững chắc để tối đa hóa lợi nhuận từ doanh thu tạo ra.

KẾT LUẬN CHUNG

Bài tiểu luận đã trình bày một cách toàn diện về năng lực và tính ứng dụng của ngôn ngữ lập trình R trong lĩnh vực phân tích dữ liệu kinh doanh thông qua hai nghiên cứu tình huống điển hình.

1. Tổng kết các kết quả chính:

  • Đối với bài toán bán lẻ xe đạp (Chương 1), phân tích đã chỉ ra rằng công ty sở hữu một mô hình kinh doanh cực kỳ ổn định và cân bằng. Doanh thu và hiệu suất hoạt động được phân bổ đều trên các dòng sản phẩm, địa điểm kinh doanh và nhóm khách hàng. Điều này cho thấy một nền tảng vững chắc nhưng cũng mở ra cơ hội để tạo ra các chiến lược đột phá nhằm tối ưu hóa cho từng phân khúc cụ thể.

  • Đối với bài toán tài chính của CTCP Hoàng Anh Gia Lai (Chương 2), phân tích báo cáo kết quả kinh doanh giai đoạn 2015-2024 đã vẽ nên một bức tranh sống động về quá trình “hồi sinh” của doanh nghiệp. Kết quả khẳng định rằng chiến lược tái cấu trúc đã thành công rực rỡ, đặc biệt là trong việc kiểm soát và cắt giảm gánh nặng chi phí tài chính, từ đó giúp HAG chuyển từ thua lỗ sang giai đoạn tăng trưởng lợi nhuận bền vững.

2. Khẳng định vai trò của Ngôn ngữ R:

Qua hai ví dụ trên, có thể thấy R không chỉ là một công cụ tính toán mà còn là một hệ sinh thái mạnh mẽ cho phép thực hiện toàn bộ quy trình khoa học dữ liệu. Từ việc làm sạch, biến đổi dữ liệu (dplyr, tidyr) đến việc phân tích thống kê và trực quan hóa các insight phức tạp một cách sinh động (ggplot2), R đã chứng tỏ là một công cụ không thể thiếu cho các nhà phân tích kinh doanh hiện đại.

3. Hạn chế của bài tiểu luận:

Mặc dù đã đạt được các mục tiêu đề ra, bài tiểu luận vẫn còn một số hạn chế. Thứ nhất, bộ dữ liệu bán lẻ xe đạp là dữ liệu giả định, có thể không phản ánh hết sự phức tạp của thị trường thực tế. Thứ hai, phân tích tài chính HAG chỉ tập trung vào báo cáo kết quả kinh doanh và chưa kết hợp các yếu tố vĩ mô hay các báo cáo tài chính khác để có cái nhìn đa chiều hơn. Cuối cùng, các phân tích chủ yếu dừng lại ở mức độ mô tả mà chưa đi sâu vào các mô hình dự báo hay phân tích nhân quả.

4. Hướng phát triển trong tương lai:

Dựa trên nền tảng của bài tiểu luận này, các nghiên cứu tiếp theo có thể được phát triển theo hướng:

  • Xây dựng mô hình học máy để dự báo doanh số bán xe đạp hoặc phân khúc khách hàng tiềm năng.

  • Thực hiện một phân tích tài chính toàn diện hơn cho HAG, kết hợp mô hình định giá cổ phiếu hoặc phân tích các chỉ số từ bảng cân đối kế toán và báo cáo lưu chuyển tiền tệ.

Tóm lại, bài tiểu luận đã hoàn thành mục tiêu ứng dụng R để khai phá những câu chuyện kinh doanh ẩn sau các con số, qua đó khẳng định giá trị to lớn của phân tích dữ liệu trong việc ra quyết định chiến lược.