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.
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.
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.
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ê
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ý.
# 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.
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ố.
# --- 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.
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.
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.
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.
BK %>%
count(Bike_Model, sort = TRUE) %>%
kable(caption = "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.
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.
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"
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.
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.
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.
Đâ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
)
)
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)
| 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 |
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.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.
# --- 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.
# 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
}
| 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 |
| 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 |
| 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 |
| 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.
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
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
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
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
# --- 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"))
| 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.
# --- 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"))
| 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.
# --- 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"))
| 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).
# --- 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ệ"))
| 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.
# --- 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"))
| Đị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.
# --- 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"))
| Đị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.
# --- 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"))
| Đị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 |
# --- 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"))
| 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 |
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
# --- 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ệ" ))
| 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.
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"))
| 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.
# --- 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"))
| 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.
# --- 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")
| 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.
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"))
| Đị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.
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"))
| 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?
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"))
| Năm | Tổng doanh thu |
|---|---|
| 2020 | 164224491 |
| 2021 | 163535245 |
| 2022 | 165560749 |
| 2023 | 164497574 |
| 2024 | 120616177 |
Nhận xét:
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.
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ẽ.
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"))
| 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.
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"))
| 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.
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ệ"))
| 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.
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"))
| Đị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.
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.
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.
# --- 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.
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.
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.
# 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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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ể.
# 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.
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.
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ả.
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.
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.
# 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.
# 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.
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.
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.
Để 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.
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
HAG <- read_csv("C:/Users/DELL/Downloads/HAG (1).csv")
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")
| 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 |
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>
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"
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.
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
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>
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
bao_cao_kqkd_processed <- bao_cao_kqkd_subset %>%
mutate(across(where(is.numeric),
~ ifelse(is.na(.), median(., na.rm = TRUE), .)))
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.
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.
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)
# 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")
| 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.
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.
# 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)
| 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 |
# 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")
| 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.
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)
| 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).
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)
| 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.
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.
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)
| 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.
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)
| 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.
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)
| 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.
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
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.
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”
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.
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.
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.
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.
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).
# 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ể.
# 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.
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.
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.
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.
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.
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:
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.
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.
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.
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.
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.
# 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.
# --- 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.
# 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.
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.