Khối code đầu tiên sẽ tải dữ liệu từ file fpt.csv. Ngay
sau đó, chúng ta sẽ thực hiện hai thao tác kiểm tra kỹ thuật cơ bản:
dim(fpt): Để xem chính xác bộ dữ
liệu có bao nhiêu hàng (quan sát) và bao nhiêu cột (biến).
sum(is.na(fpt)): Để đếm tổng số giá
trị bị thiếu (NA) trong toàn bộ data frame
# 1. Tải dữ liệu
fpt <- read.csv("D:/rstudio/cuoikyrstudio/fpt.csv") # Sửa lại đường dẫn cho chuẩn R
# 2. Lấy kết quả kiểm tra
dims <- dim(fpt)
total_na <- sum(is.na(fpt))
# 3. Tạo một data frame tóm tắt
bang_kiem_tra <- data.frame(
  ThongTin = c("Số hàng (Quan sát)", 
               "Số cột (Biến)", 
               "Tổng giá trị thiếu (NA)"),
  KetQua = c(dims[1], 
             dims[2], 
             total_na)
)
# 4. Tải thư viện kableExtra và "vẽ" bảng đẹp
# (Đảm bảo bạn đã gọi 'library(kableExtra)' trong khối 'setup' nhé)
kbl(
  bang_kiem_tra,
  caption = "Kết quả Kiểm tra Kỹ thuật Bộ dữ liệu",
  col.names = c("Thông tin Kiểm tra", "Kết quả"),
  row.names = FALSE, # Ẩn cột số thứ tự 1,2,3
  booktabs = TRUE    # Thêm đường kẻ ngang cho đẹp
) %>%
  kable_styling(
    position = "center",            # <--- Căn giữa bảng
    latex_options = "hold_position" # <--- Giữ bảng đứng yên tại vị trí
  )| Thông tin Kiểm tra | Kết quả | 
|---|---|
| Số hàng (Quan sát) | 10 | 
| Số cột (Biến) | 11 | 
| Tổng giá trị thiếu (NA) | 0 | 
Bộ dữ liệu gồm 10 quan sát và 11
biến, cho thấy quy mô nhỏ, phù hợp cho các bài phân tích mô
phỏng hoặc thực hành.
Việc không có giá trị thiếu (NA = 0) là tín hiệu tích
cực, đảm bảo tính đầy đủ và độ tin cậy của dữ
liệu.
Tuy nhiên, do số lượng quan sát ít, cần thận trọng khi suy luận
hoặc khái quát các kết quả kinh tế, vì dữ liệu có thể chưa đại
diện cho toàn bộ thị trường hoặc giai đoạn phân tích.
Bộ dữ liệu được sử dụng trong bài phân tích này được trích xuất và tổng hợp từ Báo cáo tài chính (BCTC) đã công bố của doanh nghiệp Tập đoàn FPT. Dữ liệu bao gồm các chỉ tiêu tài chính trọng yếu trong 10 năm liên tiếp, từ năm 2015 đến 2024.
Mục tiêu của việc thu thập bộ dữ liệu này là để làm nền tảng cho việc phân tích toàn diện về sức khỏe tài chính và hiệu quả hoạt động của công ty, bao gồm:
# (Đảm bảo library(kableExtra) đã được gọi ở khối 'setup')
kbl(
  head(fpt),
  caption = "6 Dòng dữ liệu đầu tiên (Dữ liệu gốc)",
  booktabs = TRUE # Thêm dòng này để bảng đẹp hơn (có kẻ ngang)
) %>%
  kable_styling(
    position = "center",            # <--- Căn giữa bảng
    
    # Gộp "scale_down" (tự co) và "hold_position" (đứng yên)
    latex_options = c("scale_down", "hold_position") 
  )| Nam | DoanhThuThuan | GiaVon | ChiPhiBanHang | ChiPhiQLDN | LoiNhuanSauThue | ChiPhiTaiChinh | LuuChuyenTienHDKD | TaiSanNganHan | TaiSanDaiHan | NoPhaiTra | 
|---|---|---|---|---|---|---|---|---|---|---|
| 2015 | 3.795970e+13 | 3.046588e+13 | 2.226871e+12 | 2.331789e+12 | 2.438085e+12 | 620411567508 | 1.155885e+12 | 1.895901e+13 | 7.086579e+12 | 1.586330e+13 | 
| 2016 | 3.953147e+13 | 3.109333e+13 | 2.638455e+12 | 2.751158e+12 | 2.575691e+12 | 694213959980 | 4.311658e+12 | 2.190866e+13 | 7.924599e+12 | 1.838519e+13 | 
| 2017 | 4.265861e+13 | 3.297621e+13 | 3.074637e+12 | 3.441129e+12 | 3.528114e+12 | 600871831217 | 1.988184e+12 | 1.605994e+13 | 8.939739e+12 | 1.176130e+13 | 
| 2018 | 2.321354e+13 | 1.449066e+13 | 2.047834e+12 | 3.553288e+12 | 3.233997e+12 | 361046565710 | 3.588320e+12 | 1.840609e+13 | 1.135098e+13 | 1.498210e+13 | 
| 2019 | 2.771696e+13 | 1.700491e+13 | 2.345958e+12 | 4.219255e+12 | 3.911712e+12 | 592386050061 | 3.898750e+12 | 1.897918e+13 | 1.441499e+13 | 1.659487e+13 | 
| 2020 | 2.983040e+13 | 1.801674e+13 | 2.713561e+12 | 4.495366e+12 | 4.423745e+12 | 548165211617 | 6.339679e+12 | 2.561249e+13 | 1.612183e+13 | 2.312866e+13 | 
Giai đoạn 2015–2020 cho thấy doanh nghiệp có xu hướng tăng trưởng ổn định, dù có một số biến động theo từng năm.
Nhìn chung, giai đoạn này phản ánh doanh nghiệp duy trì được tốc độ tăng trưởng tốt, quản lý chi phí hiệu quả, và đang hướng đến mở rộng quy mô đầu tư một cách bền vững.
kbl(
  tail(fpt, 3), 
  caption = "3 Dòng dữ liệu cuối cùng",
  booktabs = TRUE # Thêm đường kẻ ngang cho đẹp
) %>%
  kable_styling(
    position = "center",            # <--- Căn giữa bảng
    
    # Gộp "scale_down" (tự co) và "hold_position" (đứng yên)
    # Bảng này cũng rộng như bảng 'head()' nên RẤT CẦN "scale_down"
    latex_options = c("scale_down", "hold_position") 
  )| Nam | DoanhThuThuan | GiaVon | ChiPhiBanHang | ChiPhiQLDN | LoiNhuanSauThue | ChiPhiTaiChinh | LuuChuyenTienHDKD | TaiSanNganHan | TaiSanDaiHan | NoPhaiTra | |
|---|---|---|---|---|---|---|---|---|---|---|---|
| 8 | 2022 | 4.400953e+13 | 2.684225e+13 | 4.526441e+12 | 5.846281e+12 | 6.491343e+12 | 1.687370e+12 | 5.053832e+12 | 3.093771e+13 | 2.071269e+13 | 2.629428e+13 | 
| 9 | 2023 | 5.261790e+13 | 3.229835e+13 | 5.242552e+12 | 6.625374e+12 | 7.788050e+12 | 1.718298e+12 | 9.517096e+12 | 3.670575e+13 | 2.357708e+13 | 3.034982e+13 | 
| 10 | 2024 | 6.284879e+13 | 3.915045e+13 | 6.115962e+12 | 7.074039e+12 | 9.427423e+12 | 1.811547e+12 | 1.170378e+13 | 4.553594e+13 | 2.646405e+13 | 3.627246e+13 | 
# Tạo bảng tóm tắt cấu trúc
bang_cau_truc <- data.frame(
  TenBien = names(fpt),
  KieuDuLieu = sapply(fpt, class)
)
# In bảng đẹp (Đã sửa)
kbl(
  bang_cau_truc, 
  row.names = FALSE,
  booktabs = TRUE # Thêm đường kẻ ngang cho đẹp
) %>%
  kable_styling(
    position = "center",            # <--- Căn giữa bảng
    latex_options = "hold_position" # <--- Giữ bảng đứng yên
  )| TenBien | KieuDuLieu | 
|---|---|
| Nam | integer | 
| DoanhThuThuan | numeric | 
| GiaVon | numeric | 
| ChiPhiBanHang | numeric | 
| ChiPhiQLDN | numeric | 
| LoiNhuanSauThue | numeric | 
| ChiPhiTaiChinh | numeric | 
| LuuChuyenTienHDKD | numeric | 
| TaiSanNganHan | numeric | 
| TaiSanDaiHan | numeric | 
| NoPhaiTra | numeric | 
Kết quả kiểm tra xác nhận rằng bộ dữ liệu gồm 11
biến, trong đó kiểu dữ liệu chủ yếu là dbl (số
thực), hoàn toàn phù hợp cho phân tích định lượng trong
lĩnh vực tài chính.
Nam: Đại diện cho mốc thời gian quan
sát, có kiểu dữ liệu số (numeric).DoanhThuThuan: Doanh thu thuần về bán hàng và cung cấp
dịch vụ.GiaVon: Giá vốn hàng bán.ChiPhiBanHang: Chi phí liên quan đến hoạt động bán
hàng.ChiPhiQLDN: Chi phí quản lý chung của doanh
nghiệp.ChiPhiTaiChinh: Chi phí liên quan đến hoạt động vốn
(chủ yếu là lãi vay).LoiNhuanSauThue: Kết quả kinh doanh cuối cùng sau
thuế.TaiSanNganHan: Tổng tài sản ngắn hạn.TaiSanDaiHan: Tổng tài sản dài hạn.NoPhaiTra: Tổng nợ phải trả (ngắn hạn và dài hạn).LuuChuyenTienHDKD: Dòng tiền thuần từ hoạt động kinh
doanh cốt lõi.Nhìn chung, bộ dữ liệu có cấu trúc hợp lý, rõ ràng và đầy đủ, phản ánh toàn diện tình hình tài chính – kinh doanh – dòng tiền của doanh nghiệp, tạo nền tảng vững chắc cho các phân tích rủi ro tín dụng và hiệu quả hoạt động ở các phần sau.
Kết quả từ phân MÔ TẢ CÁC BIẾN ở trên cho thấy các biến tài chính
đang được biểu thị bằng những con số rất lớn (ví dụ:
3.796e+13), khiến cho việc đọc và diễn giải trở nên khó
khăn.
Để giải quyết vấn đề này, trong khối code tiếp theo, chúng ta sẽ thực hiện hai thao tác quan trọng:
fpt_ty_dong) bằng cách chia tất cả các cột tài chính
(mọi cột trừ Nam) cho 1 tỷ (\(1,000,000,000\)). Thao tác này giúp chuẩn
hóa dữ liệu về đơn vị “Tỷ đồng”, giúp các con số trở
nên dễ đọc và dễ so sánh hơn.skim() từ thư viện skimr. Hàm này cung cấp một
bảng thống kê mô tả “dễ nhìn” và giàu thông tin hơn nhiều so với hàm
summary() mặc định, bao gồm cả một biểu đồ histogram nhỏ
cho từng biến.# (Các thư viện dplyr, skimr, kableExtra đã được gọi ở 'setup')
# 1. Biến đổi sang đơn vị Tỷ đồng
fpt_ty_dong <- fpt %>%
  mutate(across(.cols = -Nam, .fns = ~ . / 1000000000))
# 2. In 3 dòng đầu tiên (dùng kable đẹp)
fpt_ty_dong %>%
  head(3) %>%
  kbl(
    caption = "3 Dòng đầu của Dữ liệu (Đã đổi sang Tỷ đồng)",
    digits = 2,
    align = "c",
    booktabs = TRUE
  ) %>%
  kable_styling(
    position = "center",            # <--- Căn giữa bảng
    full_width = FALSE,
    font_size = 10,
    
    # Gộp "scale_down" (tự co) và "hold_position" (đứng yên)
    latex_options = c("hold_position", "scale_down") 
  )| Nam | DoanhThuThuan | GiaVon | ChiPhiBanHang | ChiPhiQLDN | LoiNhuanSauThue | ChiPhiTaiChinh | LuuChuyenTienHDKD | TaiSanNganHan | TaiSanDaiHan | NoPhaiTra | 
|---|---|---|---|---|---|---|---|---|---|---|
| 2015 | 37959.70 | 30465.88 | 2226.87 | 2331.79 | 2438.08 | 620.41 | 1155.89 | 18959.01 | 7086.58 | 15863.30 | 
| 2016 | 39531.47 | 31093.33 | 2638.45 | 2751.16 | 2575.69 | 694.21 | 4311.66 | 21908.66 | 7924.60 | 18385.19 | 
| 2017 | 42658.61 | 32976.21 | 3074.64 | 3441.13 | 3528.11 | 600.87 | 1988.18 | 16059.94 | 8939.74 | 11761.30 | 
# 1. Tạo thống kê mô tả chi tiết bằng skimr
thong_ke_skim <- skim(fpt_ty_dong)
# 2. Chỉ giữ lại các biến numeric (ĐÃ SỬA, BỎ HẾT DẤU TIẾNG VIỆT)
thong_ke_skim_df <- thong_ke_skim %>%
  filter(skim_type == "numeric") %>%
  select(
    Bien = skim_variable,        # <--- Đã bỏ dấu
    Thieu = n_missing,          # <--- Đã bỏ dấu
    Ty_le_day_du = complete_rate, # <--- Đã bỏ dấu
    Trung_binh = numeric.mean,  # <--- Đã bỏ dấu
    Do_lech_chuan = numeric.sd, # <--- Đã bỏ dấu
    Min = numeric.p0,
    Q1 = numeric.p25,
    Median = numeric.p50,
    Q3 = numeric.p75,
    Max = numeric.p100
  )
# 3. Hiển thị bảng đẹp cho cả HTML và PDF
thong_ke_skim_df %>%
  kbl(
    # Phần caption (chú thích) có dấu thì KHÔNG SAO
    caption = "Bảng Thống kê Mô tả Chi tiết (Đơn vị: Tỷ đồng)",
    digits = 2,
    align = "c",
    booktabs = TRUE,
    linesep = ""
  ) %>%
  kable_styling(
    position = "center",
    full_width = FALSE,
    font_size = 9,
    latex_options = c("hold_position", "scale_down")
  )| Bien | Thieu | Ty_le_day_du | Trung_binh | Do_lech_chuan | Min | Q1 | Median | Q3 | Max | 
|---|---|---|---|---|---|---|---|---|---|
| Nam | 0 | 1 | 2019.50 | 3.03 | 2015.00 | 2017.25 | 2019.50 | 2021.75 | 2024.00 | 
| DoanhThuThuan | 0 | 1 | 39604.42 | 11842.39 | 23213.54 | 31287.12 | 38745.58 | 43671.80 | 62848.79 | 
| GiaVon | 0 | 1 | 26436.41 | 8157.27 | 14490.66 | 19018.88 | 28654.06 | 31997.09 | 39150.45 | 
| ChiPhiBanHang | 0 | 1 | 3453.69 | 1395.47 | 2047.83 | 2419.08 | 2894.10 | 4295.98 | 6115.96 | 
| ChiPhiQLDN | 0 | 1 | 4495.00 | 1592.47 | 2331.79 | 3469.17 | 4357.31 | 5537.79 | 7074.04 | 
| LoiNhuanSauThue | 0 | 1 | 4916.75 | 2330.82 | 2438.08 | 3307.53 | 4167.73 | 6205.83 | 9427.42 | 
| ChiPhiTaiChinh | 0 | 1 | 977.85 | 561.58 | 361.05 | 594.51 | 657.31 | 1551.57 | 1811.55 | 
| LuuChuyenTienHDKD | 0 | 1 | 5339.69 | 3235.59 | 1155.89 | 3665.93 | 4682.75 | 6214.68 | 11703.78 | 
| TaiSanNganHan | 0 | 1 | 26822.31 | 9827.73 | 16059.94 | 18964.05 | 23760.58 | 34073.21 | 45535.94 | 
| TaiSanDaiHan | 0 | 1 | 15517.21 | 6766.67 | 7086.58 | 9542.55 | 15268.41 | 20179.41 | 26464.05 | 
| NoPhaiTra | 0 | 1 | 22591.19 | 8362.23 | 11761.30 | 16046.20 | 20756.92 | 29335.93 | 36272.46 | 
# --- 1. Xoay dữ liệu sang dạng dài ---
fpt_long <- fpt_ty_dong %>%
  pivot_longer(
    cols = -Nam,
    names_to = "ChiTieu",
    values_to = "GiaTri"
  )
# --- 2. Tính giá trị nhỏ nhất và lớn nhất ---
bang_min_max <- fpt_long %>%
  group_by(ChiTieu) %>%
  summarise(
    GiaTri_Min = min(GiaTri, na.rm = TRUE),
    Nam_Min = Nam[which.min(GiaTri)],
    GiaTri_Max = max(GiaTri, na.rm = TRUE),
    Nam_Max = Nam[which.max(GiaTri)]
  ) %>%
  arrange(ChiTieu)
# --- 3. Hiển thị bảng đẹp ) ---
bang_min_max %>%
  kbl(
    caption = "Giá trị Nhỏ nhất / Lớn nhất (và Năm tương ứng) cho từng Chỉ Tiêu (Đơn vị: Tỷ đồng)",
    digits = 2,
    
    # ---  (BỎ HẾT DẤU) ---
    col.names = c("Chi Tieu", "Gia tri Min", "Nam (Min)", "Gia tri Max", "Nam (Max)"),
    
    align = "c",
    booktabs = TRUE
  ) %>%
  kable_styling(
    position = "center",
    full_width = FALSE,
    font_size = 10,
    bootstrap_options = c("striped", "hover", "condensed", "responsive"),
    latex_options = c("hold_position", "scale_down")
  )| Chi Tieu | Gia tri Min | Nam (Min) | Gia tri Max | Nam (Max) | 
|---|---|---|---|---|
| ChiPhiBanHang | 2047.83 | 2018 | 6115.96 | 2024 | 
| ChiPhiQLDN | 2331.79 | 2015 | 7074.04 | 2024 | 
| ChiPhiTaiChinh | 361.05 | 2018 | 1811.55 | 2024 | 
| DoanhThuThuan | 23213.54 | 2018 | 62848.79 | 2024 | 
| GiaVon | 14490.66 | 2018 | 39150.45 | 2024 | 
| LoiNhuanSauThue | 2438.08 | 2015 | 9427.42 | 2024 | 
| LuuChuyenTienHDKD | 1155.89 | 2015 | 11703.78 | 2024 | 
| NoPhaiTra | 11761.30 | 2017 | 36272.46 | 2024 | 
| TaiSanDaiHan | 7086.58 | 2015 | 26464.05 | 2024 | 
| TaiSanNganHan | 16059.94 | 2017 | 45535.94 | 2024 | 
top_3_loi_nhuan <- fpt_ty_dong %>%
  arrange(desc(LoiNhuanSauThue)) %>%
  slice(1:3)
top_3_loi_nhuan %>%
  kbl(
    caption = "Top 3 Năm Lợi nhuận Cao nhất",
    digits = 2,
    align = "c",
    booktabs = TRUE
  ) %>%
  kable_styling(
    position = "center",            # <--- Căn giữa bảng
    full_width = FALSE,
    font_size = 10,
    
    # Gộp "scale_down" (tự co) và "hold_position" (đứng yên)
    latex_options = c("hold_position", "scale_down")
  ) %>%
  column_spec(1:ncol(top_3_loi_nhuan), width = "2.2cm")| Nam | DoanhThuThuan | GiaVon | ChiPhiBanHang | ChiPhiQLDN | LoiNhuanSauThue | ChiPhiTaiChinh | LuuChuyenTienHDKD | TaiSanNganHan | TaiSanDaiHan | NoPhaiTra | 
|---|---|---|---|---|---|---|---|---|---|---|
| 2024 | 62848.79 | 39150.45 | 6115.96 | 7074.04 | 9427.42 | 1811.55 | 11703.78 | 45535.94 | 26464.05 | 36272.46 | 
| 2023 | 52617.90 | 32298.35 | 5242.55 | 6625.37 | 7788.05 | 1718.30 | 9517.10 | 36705.75 | 23577.08 | 30349.82 | 
| 2022 | 44009.53 | 26842.25 | 4526.44 | 5846.28 | 6491.34 | 1687.37 | 5053.83 | 30937.71 | 20712.69 | 26294.28 | 
#--- 1. Lọc 3 năm có Doanh thu thấp nhất ---
bottom_3_doanh_thu <- fpt_ty_dong %>%
  arrange(DoanhThuThuan) %>% # Sắp xếp tăng dần
  slice(1:3) # Lấy 3 năm đầu
#--- 2. Hiển thị bảng  ---
kbl(
  bottom_3_doanh_thu,
  caption = "3 Năm Có Doanh Thu Thấp Nhất (Đơn vị: Tỷ đồng)",
  digits = 2,
  booktabs = TRUE # Thêm đường kẻ ngang
  # (Đã xóa 'format = "html"')
) %>%
  kable_styling(
    position = "center", # <--- Căn giữa bảng
    full_width = FALSE,
    
    # Gộp "scale_down" (tự co) và "hold_position" (đứng yên)
    latex_options = c("hold_position", "scale_down") 
  )| Nam | DoanhThuThuan | GiaVon | ChiPhiBanHang | ChiPhiQLDN | LoiNhuanSauThue | ChiPhiTaiChinh | LuuChuyenTienHDKD | TaiSanNganHan | TaiSanDaiHan | NoPhaiTra | 
|---|---|---|---|---|---|---|---|---|---|---|
| 2018 | 23213.54 | 14490.66 | 2047.83 | 3553.29 | 3234.00 | 361.05 | 3588.32 | 18406.09 | 11350.98 | 14982.10 | 
| 2019 | 27716.96 | 17004.91 | 2345.96 | 4219.25 | 3911.71 | 592.39 | 3898.75 | 18979.18 | 14414.99 | 16594.87 | 
| 2020 | 29830.40 | 18016.74 | 2713.56 | 4495.37 | 4423.75 | 548.17 | 6339.68 | 25612.49 | 16121.83 | 23128.66 | 
#--- 1. Lọc dữ liệu năm 2024 ---
data_2024 <- fpt_ty_dong %>%
  filter(Nam == 2024)
#--- 2. Hiển thị bảng ---
kbl(
  data_2024,
  caption = "Dữ liệu Chi Tiết Năm 2024 (Đơn vị: Tỷ đồng)",
  digits = 2,
  booktabs = TRUE # Thêm đường kẻ ngang
  # (Đã xóa 'format = "html"')
) %>%
  kable_styling(
    position = "center", # <--- Căn giữa bảng
    full_width = FALSE,
    
    # Gộp "scale_down" (tự co) và "hold_position" (đứng yên)
    # Bảng này có 11 cột nên RẤT CẦN "scale_down"
    latex_options = c("hold_position", "scale_down") 
  )| Nam | DoanhThuThuan | GiaVon | ChiPhiBanHang | ChiPhiQLDN | LoiNhuanSauThue | ChiPhiTaiChinh | LuuChuyenTienHDKD | TaiSanNganHan | TaiSanDaiHan | NoPhaiTra | 
|---|---|---|---|---|---|---|---|---|---|---|
| 2024 | 62848.79 | 39150.45 | 6115.96 | 7074.04 | 9427.42 | 1811.55 | 11703.78 | 45535.94 | 26464.05 | 36272.46 | 
💡 Tổng quan: Năm 2024 là đỉnh tăng trưởng cả về doanh thu, lợi nhuận và dòng tiền, phản ánh hiệu quả quản trị – tài chính ổn định và xu hướng mở rộng bền vững.
#1. Đảm bảo dữ liệu fpt_ty_dong tồn tại
if (!exists("fpt_ty_dong")) {
  # Sửa lại đường dẫn tệp cho chuẩn R
  fpt <- read.csv("D:/rstudio/cuoikyrstudio/fpt.csv") 
  fpt_ty_dong <- fpt %>%
    mutate(across(.cols = -Nam, .fns = ~ . / 1000000000))
}
#2. Chuẩn bị dữ liệu (xoay dạng long)
fpt_long_format <- fpt_ty_dong %>%
  select(-Nam) %>%
  pivot_longer(
    cols = everything(),
    names_to = "ChiTieuTaiChinh",
    values_to = "GiaTri"
  )
#3. In 6 dòng đầu của dữ liệu đã xoay (Dùng kbl)
kbl(
  head(fpt_long_format),
  caption = "Dữ liệu đã được 'xoay' (Long Format) để phân tích đơn biến",
  digits = 2,
  booktabs = TRUE,
  align = "c"
) %>%
  kable_styling(
    full_width = FALSE,
    position = "center",            # <--- Căn giữa
    font_size = 10,
    
    # Gộp "scale_down" (tự co) và "hold_position" (đứng yên)
    latex_options = c("hold_position", "scale_down") 
  )| ChiTieuTaiChinh | GiaTri | 
|---|---|
| DoanhThuThuan | 37959.70 | 
| GiaVon | 30465.88 | 
| ChiPhiBanHang | 2226.87 | 
| ChiPhiQLDN | 2331.79 | 
| LoiNhuanSauThue | 2438.08 | 
| ChiPhiTaiChinh | 620.41 | 
# --- 1. Làm sạch tên chỉ tiêu (Giữ nguyên) ---
# (Code này sẽ chạy nếu 'fpt_long_format_cleaned' chưa tồn tại)
if (!exists("fpt_long_format_cleaned")) { 
  fpt_long_format_cleaned <- fpt_long_format %>%
    mutate(ChiTieuTaiChinh_Dep = str_replace_all(ChiTieuTaiChinh, "([A-Z])", " \\1") %>% str_trim())
}
# --- 2. Dữ liệu trung bình (Giữ nguyên) ---
mean_data <- fpt_long_format_cleaned %>%
  group_by(ChiTieuTaiChinh_Dep) %>% 
  summarise(GiaTriTrungBinh = mean(GiaTri, na.rm = TRUE))
# --- 3. Biểu đồ Histogram (Giữ nguyên, code đã chuẩn) ---
ggplot(fpt_long_format_cleaned, aes(x = GiaTri, fill = ChiTieuTaiChinh_Dep)) +
  # --- Layer 1 -> 4 (Giữ nguyên) ---
  geom_histogram(bins = 10, color = "white", alpha = 0.8, show.legend = FALSE) +
  geom_vline(
    data = mean_data,
    aes(xintercept = GiaTriTrungBinh),
    color = "red", linetype = "dashed", size = 0.8
  ) +
  facet_wrap(~ ChiTieuTaiChinh_Dep, scales = "free", ncol = 4) + 
  scale_x_continuous(labels = label_number(scale_cut = cut_short_scale())) +
  scale_y_continuous(breaks = scales::pretty_breaks()) +
  # --- Layer 5: Tiêu đề và nhãn (Giữ nguyên) ---
  labs(
    title = "Phân phối của 10 Biến Tài chính (2015–2024)",
    subtitle = "Đường gạch đỏ biểu thị giá trị Trung bình (Mean) của mỗi biến",
    x = "Giá trị (Tỷ đồng)",
    y = "Tần suất (Số năm)"
  ) +
  # --- Layer 6: Theme và Font (Giữ nguyên) ---
  theme_minimal(base_family = "Roboto") + # <--- Đã chuẩn
  theme(
    plot.title = element_text(face = "bold", size = 13, hjust = 0.5),
    plot.subtitle = element_text(size = 11, hjust = 0.5),
    strip.text = element_text(face = "bold", size = 10), 
    axis.text.x = element_text(size = 8, angle = 0, hjust = 0.5), 
    axis.text.y = element_text(size = 8),
    panel.grid.minor = element_blank(),
    plot.margin = margin(10, 10, 10, 10)
  )Các biểu đồ phân phối tần suất của 10 biến tài chính trong 10 năm qua cung cấp những cái nhìn sâu sắc về đặc điểm hoạt động và rủi ro của doanh nghiệp:
Doanh Thu Thuần,
Giá Vốn, Tài Sản Ngắn Hạn và
Nợ Phải Trả đều cho thấy rõ phân phối có 2 cụm
(bimodal) (tức là có 2 đỉnh tần suất).Chi Phí QLDN, Chi Phí Tài Chính,
Lợi Nhuận Sau Thuế và Tài Sản Dài Hạn có dạng
lệch phải (positively skewed).Lưu Chuyển Tiền HDKD (Dòng tiền từ Hoạt động Kinh
doanh) có phân phối trải rộng và không có đỉnh rõ rệt.
Tần suất gần như bằng nhau ở các mức từ 0 đến hơn 12,500 tỷ.Lợi Nhuận Sau Thuế có mức phổ biến nhất (mode) chỉ
khoảng 2,000-4,000 tỷ, nhưng mức trung bình bị kéo lên 4,500 tỷ do các
năm tăng trưởng đột biến.Kết luận: Bộ dữ liệu cho thấy một doanh nghiệp có sự tăng trưởng về quy mô (bimodal) nhưng đi kèm với sự bất ổn định đáng kể về dòng tiền từ hoạt động kinh doanh.
# --- Chuẩn bị dữ liệu định dạng dài ---
if (!exists("fpt_long_format")) {
  fpt_long_format <- fpt_ty_dong %>%
    select(-Nam) %>%
    pivot_longer(
      cols = everything(),
      names_to = "ChiTieuTaiChinh",
      values_to = "GiaTri"
    )
}
# --- Biểu đồ Boxplot cho 10 biến tài chính ---
ggplot(fpt_long_format, aes(x = "", y = GiaTri)) +
  # --- Layer 1: Vẽ Boxplot ---
  geom_boxplot(aes(fill = ChiTieuTaiChinh), show.legend = FALSE, outlier.color = "red", outlier.alpha = 0.6) +
  # --- Layer 2: Thêm điểm dữ liệu (Jitter) ---
  geom_jitter(width = 0.15, alpha = 0.5, color = "black", size = 1) +
  # --- Layer 3: Facet chia thành 10 biểu đồ con ---
  facet_wrap(~ ChiTieuTaiChinh, scales = "free", ncol = 5) +
  # --- Layer 4: Tiêu đề và nhãn ---
  labs(
    title = "Biểu đồ Hộp (Boxplot) của 10 Biến Tài chính (2015–2024)",
    subtitle = "Thể hiện 5 giá trị tóm tắt (Min, Q1, Median, Q3, Max) và các điểm ngoại lai (Outliers)",
    x = "Chỉ tiêu tài chính",
    y = "Giá trị (Tỷ đồng)"
  ) +
  # --- Layer 5: Lật ngang biểu đồ ---
  coord_flip() +
  # --- Layer 6: Theme nền sáng (ĐÃ SỬA FONT) ---
  theme_light(base_family = "Roboto") + # <--- Đổi sang font "Roboto"
  # --- Layer 7: Định dạng hiển thị ---
  theme(
    # (Đã xóa 'text = element_text(family = "sans")' vì đã có 'base_family')
    plot.title = element_text(face = "bold", size = 13, hjust = 0.5),
    plot.subtitle = element_text(size = 11, hjust = 0.5),
    strip.text = element_text(face = "bold", size = 9),
    axis.text.x = element_text(angle = 20, size = 9, hjust = 1),
    axis.text.y = element_blank(),
    panel.grid.minor = element_blank(),
    plot.margin = margin(10, 10, 10, 10)
  )Biểu đồ boxplot (biểu đồ hộp) cung cấp một cái nhìn trực quan về phân phối dữ liệu và các giá trị bất thường (outliers). Các outliers này không hẳn là “lỗi”, mà chúng đại diện cho những năm hoạt động đặc biệt (cực tốt hoặc cực xấu), và là trọng tâm của phân tích rủi ro.
LuuChuyenTienHDKD (Dòng tiền từ Hoạt động Kinh doanh)
có một outlier âm sâu (khoảng -12,000 tỷ, được tô
đỏ).DoanhThuThuan có một outlier dương
(khoảng 60,000 tỷ, tô đỏ).ChiPhiTaiChinh (Chi phí Tài chính) và
ChiPhiQLDN (Chi phí Quản lý) là hai biến có nhiều
outliers ở cả hai phía (cao và thấp).Kết luận: Phân tích outliers chỉ ra hai sự kiện mấu chốt: một năm tăng trưởng doanh thu “thần kỳ” và một năm “thảm họa” về dòng tiền. Sự đối lập này cho thấy hoạt động của doanh nghiệp có tính biến động cao và tiềm ẩn rủi ro lớn về khả năng chuyển đổi lợi nhuận thành tiền mặt.
# --- 1. Tính toán dữ liệu ---
fpt_analyzed <- fpt_ty_dong %>%
  arrange(Nam) %>%
  mutate(
    DoanhThu_Truoc = lag(DoanhThuThuan, 1),
    TangTruong_DoanhThu_Rate = (DoanhThuThuan / DoanhThu_Truoc - 1) * 100
  )
# --- 2. Tính tốc độ tăng trưởng trung bình ---
avg_growth <- mean(fpt_analyzed$TangTruong_DoanhThu_Rate, na.rm = TRUE)
# --- 3. Tạo bảng tóm tắt gồm 3 cột chính ---
fpt_growth_table <- fpt_analyzed %>%
  select(Nam, DoanhThu_Truoc, TangTruong_DoanhThu_Rate)
# --- 4. In bảng (ĐÃ SỬA) ---
kbl(
  fpt_growth_table,
  caption = "Bảng : Tốc độ Tăng trưởng Doanh thu của FPT (2015–2024)",
  digits = 2,
  
  # --- ĐÃ SỬA LỖI ENCODING (BỎ DẤU) ---
  col.names = c("Nam", "Doanh thu Nam truoc (Ty dong)", "Tang truong (%)"),
  
  align = c("c", "r", "r"),
  booktabs = TRUE # Thêm đường kẻ ngang
) %>%
  kableExtra::kable_styling(
    position = "center", # <--- Căn giữa
    full_width = FALSE,
    font_size = 12,
    
    # Gộp "scale_down" (tự co) và "hold_position" (đứng yên)
    latex_options = c("hold_position", "scale_down")
    
    # (Đã xóa 'bootstrap_options')
  )| Nam | Doanh thu Nam truoc (Ty dong) | Tang truong (%) | 
|---|---|---|
| 2015 | ||
| 2016 | 37959.70 | 4.14 | 
| 2017 | 39531.47 | 7.91 | 
| 2018 | 42658.61 | -45.58 | 
| 2019 | 23213.54 | 19.40 | 
| 2020 | 27716.96 | 7.63 | 
| 2021 | 29830.40 | 19.53 | 
| 2022 | 35657.26 | 23.42 | 
| 2023 | 44009.53 | 19.56 | 
| 2024 | 52617.90 | 19.44 | 
# --- 5. Thêm dòng ghi chú tốc độ tăng trưởng trung bình ---
cat(sprintf("\n**Tốc độ tăng trưởng trung bình:** %.2f%%", avg_growth))## 
## **Tốc độ tăng trưởng trung bình:** 8.38%
# --- Biểu đồ Cột: Tốc độ Tăng trưởng Doanh thu (%), 2015–2024 ---
ggplot(
  fpt_analyzed %>% filter(!is.na(TangTruong_DoanhThu_Rate)),
  aes(x = as.factor(Nam), y = TangTruong_DoanhThu_Rate, fill = TangTruong_DoanhThu_Rate)
) +
  # --- Layer 1: Biểu đồ cột ---
  geom_col(alpha = 0.85, color = "black", width = 0.7) +
  # --- Layer 2: Đường trung bình (Mean) ---
  geom_hline(yintercept = avg_growth, linetype = "dashed", color = "red", size = 0.9) +
  # --- Layer 3: Nhãn giá trị (NÂNG CẤP) ---
  # Dùng 'ggrepel' để các nhãn không bị đè lên nhau
  ggrepel::geom_text_repel(
    aes(label = paste0(round(TangTruong_DoanhThu_Rate, 1), "%")),
    size = 3, 
    color = "black",
    direction = "y", # Chỉ đẩy nhãn theo chiều dọc
    vjust = -0.5
  ) +
  # --- Layer 4: Màu sắc chuyển tiếp ---
  scale_fill_gradient2(
    low = "blue", mid = "white", high = "red",
    midpoint = avg_growth
  ) +
  # --- Layer 5: Giới hạn trục Y để nhãn không bị che ---
  expand_limits(y = max(fpt_analyzed$TangTruong_DoanhThu_Rate, na.rm = TRUE) * 1.15) +
  
  # --- Layer 6: Tiêu đề & phụ đề ---
  labs(
    title = "Tốc độ Tăng trưởng Doanh thu (%) qua các năm",
    subtitle = paste(
      "Đường gạch đỏ biểu thị mức tăng trưởng trung bình 10 năm:",
      round(avg_growth, 2), "%"
    ),
    x = "Năm",
    y = "Tốc độ Tăng trưởng (%)",
    caption = "Nguồn: Dữ liệu FPT (2015–2024)"
  ) +
  # --- Layer 7: Định dạng trục Y (NÂNG CẤP) ---
  # Thêm định dạng % cho trục Y
  scale_y_continuous(labels = scales::percent_format(scale = 1)) +
  # --- Layer 8: Theme và căn chỉnh (NÂNG CẤP) ---
  theme_minimal(base_family = "Roboto") + # <-- Đổi font sang "Roboto"
  theme(
    plot.title = element_text(face = "bold", size = 13, hjust = 0.5),
    plot.subtitle = element_text(size = 11, hjust = 0.5),
    axis.title = element_text(size = 10),
    axis.text = element_text(size = 9),
    panel.grid.minor = element_blank(),
    panel.grid.major.x = element_blank(),
    plot.caption = element_text(size = 8, hjust = 1)
  ) +
  # --- Layer 9: Ẩn legend ---
  guides(fill = "none")Biểu đồ này là chìa khóa để hiểu về tính chu kỳ và rủi ro của doanh nghiệp, thay vì chỉ nhìn vào các giá trị tuyệt đối. Phân tích cho thấy hai bức tranh hoàn toàn trái ngược:
Kết luận: Không thể đánh giá doanh nghiệp này qua con số trung bình 8.38%. Dữ liệu cho thấy hai doanh nghiệp khác nhau: một doanh nghiệp tăng trưởng chậm và sụp đổ (trước 2018) và một doanh nghiệp mới, năng động với tốc độ tăng trưởng cao, ổn định (sau 2019). Rủi ro lớn nhất trong quá khứ đã được thay thế bằng một mô hình tăng trưởng ấn tượng.
✍️ Mục tiêu :
- Phân tích (Logic): Sau khi xác nhận FPT có tăng trưởng doanh thu tiếp theo là kiểm tra xem sự tăng trưởng đó có mang lại lợi nhuận hay không. Chúng ta phân tích 2 chỉ số:
 
- Biên Lợi nhuận Gộp : Đo lường hiệu quả kinh doanh cốt lõi (khả năng kiểm soát
 GiaVon).- Biên Lợi nhuận Ròng: Đo lường hiệu quả cuối cùng sau khi trừ tất cả các chi phí vận hành.
 
# --- Tính toán dữ liệu Biên LN ---
if (!exists("fpt_analyzed")) {
  fpt_analyzed <- fpt_ty_dong %>%
    arrange(Nam) %>%
    mutate(
      DoanhThu_Truoc = lag(DoanhThuThuan, 1),
      TangTruong_DoanhThu_Rate = (DoanhThuThuan / DoanhThu_Truoc - 1) * 100
    )
}
fpt_analyzed <- fpt_analyzed %>%
  mutate(
    Bien_LN_Gop_Rate = (DoanhThuThuan - GiaVon) / DoanhThuThuan * 100,
    Bien_LN_Rong_Rate = LoiNhuanSauThue / DoanhThuThuan * 100
  )
# --- Chuẩn bị bảng tóm tắt ---
fpt_margins_table <- fpt_analyzed %>%
  select(Nam, Bien_LN_Gop_Rate, Bien_LN_Rong_Rate)
# --- Tạo bảng đẹp (ĐÃ SỬA) ---
fpt_margins_table %>%
  kbl(
    caption = "Bang Bien Loi nhuan Gop va Rong", # <--- Đã bỏ dấu
    digits = 2,
    col.names = c("Nam", "Bien LN Gop", "Bien LN Rong"), # <--- Đã bỏ dấu
    booktabs = TRUE,
    escape = TRUE   # Giữ nguyên, tốt cho PDF
  ) %>%
  kable_styling(
    full_width = FALSE,
    position = "center", # <--- Căn giữa
    
    # (Đã xóa 'bootstrap_options' vì chỉ dành cho HTML)
    
    # Giữ nguyên các tùy chọn PDF của bạn vì đã có 'hold_position'
    latex_options = c("striped", "hold_position", "scale_down") 
  ) %>%
  column_spec(1, bold = TRUE, border_right = TRUE) %>%
  row_spec(0, background = "#f2f2f2", bold = TRUE)| Nam | Bien LN Gop | Bien LN Rong | 
|---|---|---|
| 2015 | 19.74 | 6.42 | 
| 2016 | 21.35 | 6.52 | 
| 2017 | 22.70 | 8.27 | 
| 2018 | 37.58 | 13.93 | 
| 2019 | 38.65 | 14.11 | 
| 2020 | 39.60 | 14.83 | 
| 2021 | 38.23 | 15.00 | 
| 2022 | 39.01 | 14.75 | 
| 2023 | 38.62 | 14.80 | 
| 2024 | 37.71 | 15.00 | 
# Kiểm tra ggrepel (Giữ nguyên, đây là code tốt)
use_repel <- requireNamespace("ggrepel", quietly = TRUE)
# Tạo cột nhãn
fpt_analyzed <- fpt_analyzed %>%
  mutate(Label_Gop = paste0(round(Bien_LN_Gop_Rate, 1), "%"))
# Vẽ biểu đồ
ggplot(fpt_analyzed, aes(x = Nam)) +
  geom_line(aes(y = Bien_LN_Gop_Rate, color = "Biên LN Gộp"),
            size = 1.2, linetype = "dashed") +
  geom_point(aes(y = Bien_LN_Gop_Rate, color = "Biên LN Gộp"),
             size = 3, shape = 18) +
  geom_smooth(aes(y = Bien_LN_Gop_Rate, color = "Xu hướng (hồi quy tuyến tính)"),
              method = "lm", se = FALSE, linetype = "dotted", size = 1) +
  
  # (Phần code 'if (use_repel)' của bạn đã rất tốt, giữ nguyên)
  {if(use_repel) {
      ggrepel::geom_text_repel(aes(y = Bien_LN_Gop_Rate, label = Label_Gop),
                               size = 3, color = "black", max.overlaps = 20)
    } else {
      geom_text(aes(y = Bien_LN_Gop_Rate, label = Label_Gop),
                vjust = -0.6, size = 3, color = "black")
    }
  } +
  
  labs(
    title = "Xu hướng Biên lợi nhuận Gộp (%) của FPT (2015–2024)",
    subtitle = "Đường đứt nét: Biên LN Gộp  |  Đường chấm: Xu hướng hồi quy tuyến tính",
    x = "Năm",
    y = "Biên lợi nhuận Gộp (%)",
    color = "Chú thích"
  ) +
  scale_color_manual(values = c(
    "Biên LN Gộp" = "darkgreen",
    "Xu hướng (hồi quy tuyến tính)" = "black"
  )) +
  scale_y_continuous(labels = function(x) paste0(x, "%")) +
  
  # --- NÂNG CẤP: ĐỒNG BỘ FONT ---
  theme_minimal(base_family = "Roboto") + # <--- Đổi sang "Roboto"
  
  theme(
    # (Đã xóa 'text = element_text(family = "sans")' vì đã có 'base_family')
    plot.title = element_text(face = "bold", size = 13, hjust = 0.5),
    plot.subtitle = element_text(size = 10, hjust = 0.5),
    legend.title = element_text(face = "bold"),
    legend.position = "right",
    axis.text.x = element_text(angle = 15, hjust = 1),
    panel.grid.minor = element_blank()
  )Biểu đồ này là bằng chứng rõ ràng nhất giải thích cho sự kiện “Thiên nga đen” năm 2018 và xác nhận giả thuyết về việc tái cấu trúc doanh nghiệp:
Kết luận: Biểu đồ này xác nhận doanh nghiệp đã tái cấu trúc thành công rực rỡ. “Doanh nghiệp FPT” của giai đoạn 2018-2024 là một thực thể hoàn toàn khác biệt về chất so với chính nó ở giai đoạn trước, với trọng tâm là các mảng kinh doanh có giá trị gia tăng và hiệu quả sinh lời cao vượt trội.
# --- Biểu đồ Biên Lợi nhuận Ròng (%) - ĐÃ ĐỒNG BỘ ---
# Kiểm tra ggrepel
use_repel <- requireNamespace("ggrepel", quietly = TRUE)
# --- Vẽ biểu đồ ---
ggplot(fpt_analyzed, aes(x = Nam)) +
  # --- Layer 1 & 2: Dùng tên "Biên LN Ròng" (CÓ DẤU) ---
  geom_line(aes(y = Bien_LN_Rong_Rate, color = "Biên LN Ròng"),
            size = 1.2, linetype = "solid") +
  geom_point(aes(y = Bien_LN_Rong_Rate, color = "Biên LN Ròng"),
             size = 3, shape = 17) +
  # --- Layer 3: Dùng tên "Xu hướng (hồi quy tuyến tính)" (CÓ DẤU) ---
  geom_smooth(aes(y = Bien_LN_Rong_Rate, color = "Xu hướng (hồi quy tuyến tính)"),
              method = "lm", se = FALSE, linetype = "dotted", size = 1) +
  # --- Layer 4: Nhãn giá trị (Giữ nguyên) ---
  {
    if (use_repel) {
      ggrepel::geom_text_repel(
        aes(y = Bien_LN_Rong_Rate, label = paste0(round(Bien_LN_Rong_Rate, 1), "%")),
        size = 3, color = "black", max.overlaps = 20
      )
    } else {
      geom_text(
        aes(y = Bien_LN_Rong_Rate, label = paste0(round(Bien_LN_Rong_Rate, 1), "%")),
        vjust = -0.6, size = 3, color = "black"
      )
    }
  } +
  # --- Layer 5: Tiêu đề (CÓ DẤU) ---
  labs(
    title = "Xu hướng Biên lợi nhuận Ròng (%) của FPT (2015-2024)",
    subtitle = "Đường tím: Biên LN Ròng  |  Đường chấm đen: Xu hướng hồi quy tuyến tính",
    x = "Năm",
    y = "Biên lợi nhuận Ròng (%)",
    color = "Chú thích"
  ) +
  # --- Layer 6: Gán màu (CÓ DẤU, PHẢI KHỚP VỚI LAYER 1, 2, 3) ---
  scale_y_continuous(labels = function(x) paste0(x, "%")) +
  scale_color_manual(
    values = c(
      "Biên LN Ròng" = "purple",  # <--- Phải có dấu
      "Xu hướng (hồi quy tuyến tính)" = "black" # <--- Phải có dấu
    )
  ) +
  # --- Layer 7: Theme (Giữ nguyên) ---
  theme_minimal(base_family = "Roboto") +
  theme(
    plot.title = element_text(face = "bold", size = 13, hjust = 0.5),
    plot.subtitle = element_text(size = 10, hjust = 0.5),
    legend.title = element_text(face = "bold"),
    legend.position = "right",
    axis.text.x = element_text(angle = 15, hjust = 1),
    panel.grid.minor = element_blank()
  )Biểu đồ này là kết quả sau cùng của quá trình tái cấu trúc và khẳng định sự thành công của mô hình kinh doanh mới:
Kết luận: Biểu đồ này chứng minh rằng cuộc tái cấu trúc năm 2018 là hoàn toàn đúng đắn. Doanh nghiệp đã chấp nhận hy sinh quy mô (doanh thu giảm mạnh) và tăng chi phí hoạt động (OPEX) để đổi lấy một mô hình kinh doanh bền vững và có hiệu quả sinh lời ròng (sau cùng) cao hơn hẳn.
# (Đảm bảo 'fpt_analyzed' đã tồn tại từ các bước trước)
if (!exists("fpt_analyzed")) {
    fpt_analyzed <- fpt_ty_dong 
}
# --- 1. Tính toán Tỷ lệ 3 Chi phí trên Doanh thu ---
fpt_analyzed <- fpt_analyzed %>%
  mutate(
    TyLe_CP_BanHang_Rate = (ChiPhiBanHang / DoanhThuThuan) * 100,
    TyLe_CP_QLDN_Rate = (ChiPhiQLDN / DoanhThuThuan) * 100,
    TyLe_CP_TaiChinh_Rate = (ChiPhiTaiChinh / DoanhThuThuan) * 100
  )
# --- 2. Chuẩn bị dữ liệu (Xoay) để vẽ biểu đồ xếp chồng ---
fpt_cost_structure <- fpt_analyzed %>%
  select(Nam, TyLe_CP_BanHang_Rate, TyLe_CP_QLDN_Rate, TyLe_CP_TaiChinh_Rate) %>%
  pivot_longer(
    cols = -Nam,
    names_to = "LoaiChiPhi",
    values_to = "TyLe"
  )
# --- 3. In bảng dữ liệu chi phí (3 năm cuối) - (ĐÃ SỬA LỖI UTF-8) ---
fpt_analyzed %>%
  select(Nam, TyLe_CP_BanHang_Rate, TyLe_CP_QLDN_Rate, TyLe_CP_TaiChinh_Rate) %>%
  tail(3) %>% # Lấy 3 dòng cuối
  kbl(
    caption = "Tỷ lệ Chi phí trên Doanh thu (3 năm cuối)", # (Giữ tiếng Việt ở caption)
    digits = 2,
    
    col.names = c("Nam", "CP Ban Hang (%)", "CP QLDN (%)", "CP Tai Chinh (%)"),
    
    booktabs = TRUE
  ) %>%
  kable_styling(
    full_width = FALSE,
    position = "center",
    latex_options = c("striped", "hold_position", "scale_down") 
  )| Nam | CP Ban Hang (%) | CP QLDN (%) | CP Tai Chinh (%) | |
|---|---|---|---|---|
| 8 | 2022 | 10.29 | 13.28 | 3.83 | 
| 9 | 2023 | 9.96 | 12.59 | 3.27 | 
| 10 | 2024 | 9.73 | 11.26 | 2.88 | 
# --- Bước 1: Kiểm tra thư viện ggrepel ---
use_repel <- requireNamespace("ggrepel", quietly = TRUE)
# --- Bước 2: Chuẩn bị dữ liệu và tạo nhãn ---
fpt_cost_structure_labeled <- fpt_cost_structure %>%
  mutate(
    # Tạo cột nhãn (Label) để hiển thị trên biểu đồ
    Label_Cost = paste0(round(TyLe, 1), "%")
  )
# --- Bước 3: Vẽ biểu đồ (ĐÃ KHÔI PHỤC DẤU) ---
print( # Dùng print() để đảm bảo hiển thị khi Knit
  ggplot(fpt_cost_structure_labeled, 
         aes(x = Nam, y = TyLe, fill = LoaiChiPhi)) +
    
    # Layer 1: Biểu đồ diện xếp chồng
    geom_area(alpha = 0.8, position = "stack") +
    
    # Layer 2: Đường viền trắng mỏng
    geom_line(position = "stack", color = "white", size = 0.2) +
    
    # Layer 3: Thêm nhãn (Label) vào giữa các vùng
    {if(use_repel) {
      ggrepel::geom_text_repel(
        aes(label = Label_Cost),
        position = position_stack(vjust = 0.5), 
        size = 3, 
        color = "black",
        direction = "y",
        max.overlaps = 15
      )
    } else {
      geom_text(
        aes(label = Label_Cost),
        position = position_stack(vjust = 0.5),
        size = 3, 
        color = "black"
      )
    }} +
    
    # Layer 4: Tiêu đề và nhãn (ĐÃ KHÔI PHỤC DẤU)
    labs(
      title = "Phân tích Cấu trúc Chi phí (tính trên % Doanh thu)",
      subtitle = "Cho thấy 3 chi phí vận hành chiếm bao nhiêu % trong Doanh thu",
      x = "Năm",
      y = "Tỷ lệ trên Doanh thu (%)",
      fill = "Loại Chi phí" # <--- Đã sửa
    ) +
    
    # Layer 5: Đổi bảng màu và nhãn legend (ĐÃ KHÔI PHỤC DẤU)
    scale_fill_brewer(
      palette = "Pastel1",
      labels = c("TyLe_CP_BanHang_Rate" = "CP Bán Hàng", # <--- Đã sửa
                 "TyLe_CP_QLDN_Rate" = "CP QLDN", 
                 "TyLe_CP_TaiChinh_Rate" = "CP Tài Chính") # <--- Đã sửa
    ) +
    
    # Layer 6: Định dạng trục Y
    scale_y_continuous(labels = scales::percent_format(scale = 1)) +
    
    # Layer 7 & 8: Gộp và chuẩn hóa Theme
    theme_minimal(base_family = "Roboto") +
    theme(
      plot.title = element_text(face = "bold", size = 13, hjust = 0.5),
      plot.subtitle = element_text(size = 10, hjust = 0.5),
      legend.title = element_text(face = "bold"),
      legend.position = "bottom",
      legend.text = element_text(size = 10),
      axis.text.x = element_text(angle = 15, hjust = 1),
      panel.grid.minor = element_blank()
    )
)Biểu đồ này là một “lát cắt” chi tiết, giải thích chính xác những gì đã xảy ra “bên dưới” sự thay đổi của Biên Lợi nhuận gộp và Biên Lợi nhuận ròng. Nó cho thấy rõ chi phí của mô hình kinh doanh mới.
CP QLDN (màu xanh) và
CP Bán Hàng (màu hồng) đều tăng mạnh về tỷ
trọng.CP Tài Chính (màu xanh lá) có xu hướng tăng dần về tỷ
trọng (từ 1.4% lên đỉnh 3.8% và ổn định quanh 3%).Kết luận: Biểu đồ này đã hoàn thiện bức tranh. Cuộc tái cấu trúc là một sự đánh đổi có tính toán: chấp nhận hy sinh quy mô doanh thu (tạm thời) và tăng chi phí hoạt động (Opex) để theo đuổi một mô hình kinh doanh có giá trị gia tăng cao hơn, và cuối cùng mang lại Biên lợi nhuận ròng cao hơn và bền vững hơn.
# --- 1. Gộp 2 bước tính toán vào một hàm mutate() ---
fpt_analyzed <- fpt_analyzed %>%
  mutate(
    # Tinh Tong Tai San
    TongTaiSan = TaiSanNganHan + TaiSanDaiHan,
    # Tinh Vong quay Tong Tai san (Asset Turnover)
    VongQuay_TTS = DoanhThuThuan / TongTaiSan
  )
# --- 2. In bảng kết quả (ĐÃ SỬA) ---
fpt_analyzed %>%
  select(Nam, TongTaiSan, VongQuay_TTS) %>%
  kbl( # Đổi sang kbl()
    caption = "Bảng Tổng Tài Sản và Vòng quay Tổng Tài Sản", # Giữ dấu ở caption
    digits = 2,
    
    # --- ĐÃ SỬA LỖI ENCODING (BỎ DẤU) ---
    col.names = c("Nam", "Tong Tai San (Ty dong)", "Vong quay TTS (lan)"), 
    
    booktabs = TRUE # Quan trọng cho PDF
  ) %>%
  kable_styling(
    position = "center", # Căn giữa
    full_width = FALSE,
    
    # Tùy chọn cho PDF (Đã thêm scale_down để co nhỏ bảng)
    latex_options = c("striped", "hold_position", "scale_down")
    
    # (Đã xóa bootstrap_options)
  )| Nam | Tong Tai San (Ty dong) | Vong quay TTS (lan) | 
|---|---|---|
| 2015 | 26045.59 | 1.46 | 
| 2016 | 29833.26 | 1.33 | 
| 2017 | 24999.68 | 1.71 | 
| 2018 | 29757.07 | 0.78 | 
| 2019 | 33394.16 | 0.83 | 
| 2020 | 41734.32 | 0.71 | 
| 2021 | 53697.94 | 0.66 | 
| 2022 | 51650.40 | 0.85 | 
| 2023 | 60282.83 | 0.87 | 
| 2024 | 72000.00 | 0.87 | 
# --- TRỰC QUAN HOÁ VÒNG QUAY TÀI SẢN (ĐÃ KHÔI PHỤC VÀ NÂNG CẤP) ---
# 1. Đảm bảo 'fpt_analyzed' và 'VongQuay_TTS' tồn tại
if (!exists("fpt_analyzed") || !"VongQuay_TTS" %in% names(fpt_analyzed)) {
    fpt_analyzed <- fpt_ty_dong %>%
      mutate(
        TongTaiSan = TaiSanNganHan + TaiSanDaiHan,
        VongQuay_TTS = DoanhThuThuan / TongTaiSan
      )
}
# 2. Tính giá trị trung bình
avg_turnover <- mean(fpt_analyzed$VongQuay_TTS, na.rm = TRUE)
# 3. Vẽ biểu đồ (Đã đồng bộ)
print(
  ggplot(fpt_analyzed, aes(x = Nam, y = VongQuay_TTS)) +
    
    # Layer 1: Vẽ đường thực tế (CÓ DẤU)
    geom_line(aes(color = "Vòng quay TTS (Thực tế)"), size = 1.2) +
    
    # Layer 2 (ĐÃ SỬA): Gộp chung 'color' với Layer 1
    # Bằng cách đưa 'color' vào aes(), điểm sẽ có cùng màu "orange"
    # và Chú thích sẽ hiển thị cả điểm và đường.
    geom_point(aes(color = "Vòng quay TTS (Thực tế)"), size = 3, shape = 15) +
    
    # Layer 3: Vẽ đường xu hướng (CÓ DẤU)
    geom_smooth(aes(color = "Xu hướng (Tuyến tính)"), 
                method = "lm", se = FALSE, linetype = "dotted", size = 1) +
    
    # Layer 4 (ĐÃ SỬA): Thêm đường trung bình VÀO CHÚ THÍCH (CÓ DẤU)
    # Dùng geom_line(aes(y=...)) thay vì geom_hline() để đưa vào legend
    geom_line(aes(y = avg_turnover, color = "Trung bình 10 năm"),
              size = 1, linetype = "dashed") +
    # Layer 5: Nhãn giá trị (Giữ nguyên)
    geom_text_repel(aes(label = round(VongQuay_TTS, 2)), size = 3.5, color = "black") +
    
    # Layer 6: Tiêu đề và nhãn (ĐÃ KHÔI PHỤC DẤU)
    labs(
      title = "Xu hướng Vòng quay Tổng Tài sản (Asset Turnover)",
      subtitle = "1 đồng Tài sản tạo ra bao nhiêu đồng Doanh thu",
      x = "Năm",
      y = "Số lần (Doanh thu / Tổng Tài sản)",
      color = "Chú Thích" # <--- Đã sửa
    ) +
    
    # Layer 7 (ĐÃ SỬA): Định nghĩa màu cho TẤT CẢ 3 MỤC
    scale_color_manual(
      name = "Chú Thích",
      values = c(
        "Vòng quay TTS (Thực tế)" = "darkorange", # <--- Đã sửa
        "Xu hướng (Tuyến tính)" = "black",  # <--- Đã sửa
        "Trung bình 10 năm" = "blue"      # <--- Đã thêm
      )
    ) +
    
    # Layer 8 (ĐÃ SỬA): Đồng bộ theme cho chuyên nghiệp
    # (Đã xóa geom_hline và annotate() vì đã đưa vào Layer 4 & 7)
    theme_classic(base_family = "Roboto") + 
    theme(
      plot.title = element_text(size = 16, face = "bold", hjust = 0.5),
      plot.subtitle = element_text(size = 12, hjust = 0.5),
      axis.title = element_text(size = 12, face = "bold"),
      axis.text = element_text(size = 10),
      legend.title = element_text(size = 12, face = "bold"),
      legend.text = element_text(size = 10),
      legend.position = "bottom"
    )
)Vòng quay Tổng Tài sản (VQTTS) đo lường 1 đồng tài sản tạo ra bao nhiêu đồng doanh thu, cho thấy hiệu quả sử dụng tài sản của doanh nghiệp. Biểu đồ này cho thấy một sự “đảo cực” hoàn toàn về mô hình kinh doanh.
VQTTS = Doanh Thu / Tổng Tài Sản. Chúng ta biết rằng
Doanh Thu đã giảm mạnh (do thoái vốn mảng cũ) và
Tổng Tài Sản đã tăng lên (do mô hình kinh doanh mới cần
nhiều tài sản hơn, như chúng ta thấy chi phí QLDN và tài sản dài hạn
tăng lên). Cả hai yếu tố này đồng thời xảy ra đã khiến chỉ số “lao
dốc”.Kết luận: Biểu đồ này xác nhận doanh nghiệp đã đánh đổi hiệu quả (turnover) để lấy lợi nhuận (margin). Doanh nghiệp đã chuyển đổi thành công từ mô hình “tài sản nhẹ - quay vòng nhanh - biên lợi nhuận mỏng” sang mô hình “tài sản nặng - quay vòng chậm - biên lợi nhuận cao”.
# --- 1. Tinh Ty le No tren Tong Tai san ---
fpt_analyzed <- fpt_analyzed %>%
  mutate(
    TyLe_No_tren_TTS_Rate = (NoPhaiTra / TongTaiSan) * 100
  )
  
# --- 2. In bang ket qua (ĐÃ SỬA) ---
fpt_analyzed %>%
  select(Nam, TongTaiSan, NoPhaiTra, TyLe_No_tren_TTS_Rate) %>%
  kbl( # Đổi sang kbl()
    caption = "Bảng Tỷ lệ Nợ trên Tổng Tài Sản", # Giữ dấu ở caption
    digits = 2,
    
    # --- ĐÃ SỬA LỖI ENCODING (BỎ DẤU) ---
    col.names = c("Nam", "Tong Tai San (Ty dong)", "No Phai Tra (Ty dong)", "Ty le No/TTS (%)"), 
    
    booktabs = TRUE # Quan trọng cho PDF
  ) %>%
  kable_styling(
    position = "center", # Căn giữa
    full_width = FALSE,
    
    # Tùy chọn cho PDF (Đã thêm scale_down để co nhỏ bảng)
    latex_options = c("striped", "hold_position", "scale_down") 
    
    # (Đã xóa bootstrap_options)
  )| Nam | Tong Tai San (Ty dong) | No Phai Tra (Ty dong) | Ty le No/TTS (%) | 
|---|---|---|---|
| 2015 | 26045.59 | 15863.30 | 60.91 | 
| 2016 | 29833.26 | 18385.19 | 61.63 | 
| 2017 | 24999.68 | 11761.30 | 47.05 | 
| 2018 | 29757.07 | 14982.10 | 50.35 | 
| 2019 | 33394.16 | 16594.87 | 49.69 | 
| 2020 | 41734.32 | 23128.66 | 55.42 | 
| 2021 | 53697.94 | 32279.96 | 60.11 | 
| 2022 | 51650.40 | 26294.28 | 50.91 | 
| 2023 | 60282.83 | 30349.82 | 50.35 | 
| 2024 | 72000.00 | 36272.46 | 50.38 | 
# --- 3. Đảm bảo dữ liệu đầy đủ và đúng kiểu ---
if (!exists("fpt_analyzed") || !"TyLe_No_tren_TTS_Rate" %in% names(fpt_analyzed)) {
  fpt_analyzed <- fpt_ty_dong %>%
    mutate(
      Nam = as.numeric(Nam),  # đảm bảo là số
      TongTaiSan = TaiSanNganHan + TaiSanDaiHan,
      TyLe_No_tren_TTS_Rate = (NoPhaiTra / TongTaiSan) * 100
    ) %>%
    filter(!is.na(TyLe_No_tren_TTS_Rate))
}
# --- 4. Tính trung bình ---
avg_leverage <- mean(fpt_analyzed$TyLe_No_tren_TTS_Rate, na.rm = TRUE)
# --- 5. Vẽ biểu đồ ---
library(ggrepel)
ggplot(fpt_analyzed, aes(x = Nam, y = TyLe_No_tren_TTS_Rate)) +
  # Layer 1: Đường thực tế
  geom_line(aes(color = "Tỷ lệ Nợ thực tế (%)"), size = 1.2) +
  # Layer 2: Điểm dữ liệu
  geom_point(aes(color = "Tỷ lệ Nợ thực tế (%)"), size = 3, shape = 17) +
  # Layer 3: Nhãn giá trị
  geom_text_repel(aes(label = round(TyLe_No_tren_TTS_Rate, 1)),
                  size = 3.5, color = "black") +
  # Layer 4: Xu hướng tuyến tính
  geom_smooth(aes(color = "Xu hướng (Tuyến tính)"),
              method = "lm", se = FALSE, linetype = "dotted", size = 1) +
  # Layer 5: Đường trung bình 10 năm
  geom_line(aes(y = avg_leverage, color = "Trung bình 10 năm"),
            size = 1, linetype = "dashed") +
  # Layer 6: Màu chú thích
  scale_color_manual(
    name = "Chú thích",
    values = c(
      "Tỷ lệ Nợ thực tế (%)" = "red",
      "Xu hướng (Tuyến tính)" = "black",
      "Trung bình 10 năm" = "blue"
    )
  ) +
  # Layer 7: Định dạng trục
  scale_y_continuous(labels = function(x) paste0(x, "%")) +
  # Layer 8: Nhãn và tiêu đề
  labs(
    title = "Xu hướng Tỷ lệ Nợ trên Tổng Tài sản (%) của FPT",
    subtitle = "Đường đỏ: Tỷ lệ thực tế | Đường đen chấm: Xu hướng tuyến tính | Đường xanh: Trung bình 10 năm",
    x = "Năm",
    y = "Tỷ lệ Nợ (%)"
  ) +
  # Layer 9: Theme đẹp
  theme_classic(base_family = "Roboto") +
  theme(
    plot.title = element_text(size = 16, face = "bold", hjust = 0.5),
    plot.subtitle = element_text(size = 12, hjust = 0.5),
    axis.title = element_text(size = 12, face = "bold"),
    axis.text = element_text(size = 10),
    legend.title = element_text(size = 12, face = "bold"),
    legend.text = element_text(size = 10),
    legend.position = "bottom"
  )
::: {.callout-note} #### ⚖️ Phân tích Cấu trúc Vốn và Rủi ro (Tỷ lệ Nợ
trên Tổng Tài sản)
Biểu đồ này cho thấy một sự thay đổi toàn diện không chỉ trong mô hình kinh doanh mà còn trong chính sách cấu trúc vốn (financial policy) của doanh nghiệp.
Kết luận: Doanh nghiệp đã chuyển đổi từ một mô hình “Đòn bẩy cao - Tĩnh” (luôn vay nợ nhiều) sang một mô hình “Đòn bẩy thấp hơn - Động” (chủ động vay và trả nợ linh hoạt theo nhu cầu kinh doanh). Mặc dù đường xu hướng tuyến tính (chấm) cho thấy xu hướng giảm nợ dài hạn, thực tế cho thấy một chính sách tài chính năng động và phức tạp hơn nhiều. :::
fpt_analyzed <- fpt_analyzed %>%
  mutate(ROA_Rate = LoiNhuanSauThue / TongTaiSan * 100)
# Thao tac 38: In bang ket qua cho ROA
fpt_roa_table <- fpt_analyzed %>%
  select(Nam, LoiNhuanSauThue, TongTaiSan, ROA_Rate)
# In bang dep (ĐÃ SỬA)
kbl( # Đổi sang kbl()
  fpt_roa_table,
  caption = "Bang Tinh toan Ty suat Sinh loi tren Tai san (ROA)", # Đã bỏ dấu
  digits = 2,
  
  # ĐÃ BỎ DẤU ĐỂ TRÁNH LỖI ENCODING
  col.names = c("Nam", "Loi nhuan Sau thue (Ty dong)", "Tong Tai san (Ty dong)", "ROA (%)"),
  
  booktabs = TRUE # Quan trọng cho PDF
) %>%
  kable_styling(
    position = "center", # Căn giữa
    full_width = FALSE,
    
    # ĐÃ THÊM hold_position và scale_down
    latex_options = c("striped", "hold_position", "scale_down") 
  )| Nam | Loi nhuan Sau thue (Ty dong) | Tong Tai san (Ty dong) | ROA (%) | 
|---|---|---|---|
| 2015 | 2438.08 | 26045.59 | 9.36 | 
| 2016 | 2575.69 | 29833.26 | 8.63 | 
| 2017 | 3528.11 | 24999.68 | 14.11 | 
| 2018 | 3234.00 | 29757.07 | 10.87 | 
| 2019 | 3911.71 | 33394.16 | 11.71 | 
| 2020 | 4423.75 | 41734.32 | 10.60 | 
| 2021 | 5349.30 | 53697.94 | 9.96 | 
| 2022 | 6491.34 | 51650.40 | 12.57 | 
| 2023 | 7788.05 | 60282.83 | 12.92 | 
| 2024 | 9427.42 | 72000.00 | 13.09 | 
# Tinh gia tri trung binh cho ROA
avg_roa <- mean(fpt_analyzed$ROA_Rate, na.rm = TRUE) # Thêm na.rm = TRUE để tính toán an toàn# Tinh gia tri trung binh cho ROA (Đảm bảo giá trị này tồn tại)
if (!exists("avg_roa")) {
  avg_roa <- mean(fpt_analyzed$ROA_Rate, na.rm = TRUE)
}
print(
  ggplot(fpt_analyzed, aes(x = Nam, y = ROA_Rate)) +
    
    # Layer 1: Đường ROA thực tế
    geom_line(aes(color = "ROA Thực tế (%)"), size = 1.2) +
    
    # Layer 2: Đường xu hướng tuyến tính
    geom_smooth(aes(color = "Xu hướng (Tuyến tính)"), method = "lm", se = FALSE, linetype = "dotted") +
    
    # Layer 3: Điểm dữ liệu
    geom_point(color = "blue", size = 3, shape = 18) +
    
    # Layer 4: Label giá trị từng điểm
    ggrepel::geom_text_repel(aes(label = round(ROA_Rate, 1)), size = 3.5) +
    
    # Layer 5: Đường trung bình 10 năm (ẨN để nó xuất hiện trong Legend)
    geom_line(aes(y = avg_roa, color = "Trung bình 10 năm"), size=0, linetype="dashed") +
    
    # Layer 6: Tiêu đề, nhãn trục (ĐÃ THÊM LẠI TIẾNG VIỆT)
    labs(
      title = "Xu hướng Tỷ suất Sinh lợi trên Tổng Tài sản (ROA %)",
      subtitle = "100 đồng Tài sản tạo ra bao nhiêu đồng Lợi nhuận",
      x = "Năm", 
      y = "ROA (%)", 
      color = "Chú thích"
    ) +
    
    # Layer 7: Định dạng trục Y theo %
    scale_y_continuous(labels = scales::percent_format(scale = 1)) +
    
    # Layer 8: Chú thích màu cho các đường (ĐÃ THÊM CHÚ THÍCH CHI TIẾT)
    scale_color_manual(
      name = "Chú Thích",
      values = c("ROA Thực tế (%)" = "blue", 
                 "Xu hướng (Tuyến tính)" = "black",
                 "Trung bình 10 năm" = "darkgreen"
      ),
      # THÊM CHÚ THÍCH CHI TIẾT TẠI ĐÂY
      labels = c("ROA Thực tế (%) (Đường liền xanh)", 
                 "Xu hướng (Tuyến tính) (Đường chấm đen)", 
                 paste0("Trung bình 10 năm (", round(avg_roa, 2), "%) (Đường gạch xanh)")
                )
    ) +
    
    # Layer 9: Đường HLine thực tế 
    geom_hline(yintercept = avg_roa, linetype = "dashed", color = "darkgreen") +
    
    # Layer 10: Theme đẹp, font chuẩn
    theme_bw(base_family = "Roboto") + 
    theme(
      plot.title = element_text(size = 16, face = "bold", hjust = 0.5),
      plot.subtitle = element_text(size = 12, hjust = 0.5),
      axis.title = element_text(size = 12, face = "bold"),
      axis.text = element_text(size = 10),
      legend.position = "bottom" 
    )
)Biểu đồ ROA này là “bản án” cuối cùng, xác nhận tính đúng đắn của cuộc tái cấu trúc. Nó cho thấy một câu chuyện gồm 3 hồi:
Biên LN Ròng vẫn còn thấp (8.3%) nhưng
Vòng quay Tài sản đạt đỉnh lịch sử (1.71 lần).ROA 2017 = 8.3% * 1.71 = 14.19%. Con số này cho thấy
một mô hình “chạy hết công suất” nhưng không bền vững.Biên LN Ròng cao (13.9%) không thể bù đắp
ngay lập tức.ROA 2018 = 13.9% * 0.78 = 10.84%.Kết luận: Giá trị trung bình 10 năm (11.38%) là vô nghĩa vì nó trộn lẫn hai mô hình kinh doanh. Thực tế, doanh nghiệp đã hy sinh hiệu quả sinh lời ngắn hạn (ROA 2018) để đổi lấy một nền tảng sinh lời bền vững (ROA 2019-2024) với xu hướng tăng trưởng rõ rệt dựa trên lợi thế cạnh tranh về chất lượng, không phải về tốc độ.
# --- 1. Tinh Von Chu So Huu (Equity) va ROE ---
fpt_analyzed <- fpt_analyzed %>%
  mutate(
    VonChuSoHuu = TongTaiSan - NoPhaiTra,
    ROE_Rate = LoiNhuanSauThue / VonChuSoHuu * 100
  )
  
# --- 2. In bang ket qua cho ROE (ĐÃ SỬA) ---
fpt_analyzed %>%
  select(Nam, LoiNhuanSauThue, VonChuSoHuu, ROE_Rate) %>%
  kbl( # Đổi sang kbl()
    caption = "Bảng Tính toán Tỷ suất Sinh lợi trên Vốn CSH (ROE)", # Giữ dấu ở caption
    digits = 2,
    
    # --- ĐÃ SỬA LỖI ENCODING (BỎ DẤU) ---
    col.names = c("Nam", "Loi nhuan Sau thue (Ty dong)", "Von CSH (Ty dong)", "ROE (%)"),
    
    booktabs = TRUE # Quan trọng cho PDF
  ) %>%
  kable_styling(
    position = "center", # Căn giữa
    full_width = FALSE,
    
    # Tùy chọn cho PDF (Đã thêm scale_down để co nhỏ bảng)
    latex_options = c("striped", "hold_position", "scale_down") 
    
    # (Đã xóa bootstrap_options)
  )| Nam | Loi nhuan Sau thue (Ty dong) | Von CSH (Ty dong) | ROE (%) | 
|---|---|---|---|
| 2015 | 2438.08 | 10182.29 | 23.94 | 
| 2016 | 2575.69 | 11448.08 | 22.50 | 
| 2017 | 3528.11 | 13238.38 | 26.65 | 
| 2018 | 3234.00 | 14774.97 | 21.89 | 
| 2019 | 3911.71 | 16799.29 | 23.28 | 
| 2020 | 4423.75 | 18605.67 | 23.78 | 
| 2021 | 5349.30 | 21417.99 | 24.98 | 
| 2022 | 6491.34 | 25356.12 | 25.60 | 
| 2023 | 7788.05 | 29933.01 | 26.02 | 
| 2024 | 9427.42 | 35727.54 | 26.39 | 
# --- 3. Đảm bảo dữ liệu (Giữ nguyên) ---
# (Đảm bảo giá trị avg_roe đã được tính toán ở khối trước)
if (!exists("avg_roe")) {
  # Đây là logic fallback nếu avg_roe chưa được tính
  if (!exists("fpt_analyzed") || !"ROE_Rate" %in% names(fpt_analyzed)) {
    # Tinh toan lai neu can
    fpt_analyzed <- fpt_ty_dong %>%
      mutate(
        TongTaiSan = TaiSanNganHan + TaiSanDaiHan,
        VonChuSoHuu = TongTaiSan - NoPhaiTra,
        ROE_Rate = LoiNhuanSauThue / VonChuSoHuu * 100
      )
  }
  avg_roe <- mean(fpt_analyzed$ROE_Rate, na.rm = TRUE)
}
# --- 4. Vẽ biểu đồ ROE (ĐÃ NÂNG CẤP LEGEND) ---
print(
  ggplot(fpt_analyzed, aes(x = Nam, y = ROE_Rate)) +
    
    # Layer 1: Đường ROE thực tế
    geom_line(aes(color = "ROE Thực tế (%)"), size = 1.2) +
    
    # Layer 2: Điểm dữ liệu
    geom_point(color = "darkviolet", size = 3, shape = 15) +
    
    # Layer 3: Label giá trị từng điểm
    geom_text_repel(aes(label = round(ROE_Rate, 1)), size = 3.5) +
    
    # Layer 4: Đường xu hướng tuyến tính
    geom_smooth(aes(color = "Xu hướng (Tuyến tính)"), method = "lm", se = FALSE, linetype = "dotted") +
    
    # Layer 5: Đường trung bình 10 năm (ĐƯỜNG THỰC TẾ)
    geom_hline(yintercept = avg_roe, linetype = "dashed", color = "darkorange") +
    
    # Layer 6 (NÂNG CẤP): Tạo đường ẩn để chú thích cho đường trung bình
    geom_line(aes(y = avg_roe, color = "Trung bình 10 năm"), size=0, linetype="dashed") +
    
    # Layer 7 (NÂNG CẤP): Chú thích màu cho các đường (Tích hợp tất cả vào Legend)
    scale_color_manual(
      name = "Chú Thích",
      values = c(
        "ROE Thực tế (%)" = "darkviolet",
        "Xu hướng (Tuyến tính)" = "black",
        "Trung bình 10 năm" = "darkorange"
      ),
      # Thêm chú thích chi tiết vào labels
      labels = c("ROE Thực tế (%) (Đường liền tím)", 
                 "Xu hướng (Tuyến tính) (Đường chấm đen)", 
                 paste0("Trung bình 10 năm (", round(avg_roe, 2), "%) (Đường gạch cam)")
                )
    ) +
    
    # Layer 8: Trục Y hiển thị %  
    scale_y_continuous(labels = scales::percent_format(scale = 1)) +
    
    # Layer 9: Tiêu đề, nhãn trục
    labs(
      title = "Xu hướng Tỷ suất Sinh lợi trên Vốn Chủ Sở Hữu (ROE %)",
      subtitle = "100 đồng Vốn CSH tạo ra bao nhiêu đồng Lợi nhuận",
      x = "Năm", y = "ROE (%)"
    ) +
    
    # Layer 10: Theme đẹp, font chuẩn
    theme_light(base_family = "roboto") +
    theme(
      plot.title = element_text(size = 16, face = "bold", hjust = 0.5),
      plot.subtitle = element_text(size = 12, hjust = 0.5),
      axis.title = element_text(size = 12, face = "bold"),
      axis.text = element_text(size = 10),
      legend.title = element_text(size = 12, face = "bold"),
      legend.text = element_text(size = 10),
      legend.position = "bottom" # Đổi vị trí Legend xuống dưới
    )
)
::: {.callout-note}
Chỉ số ROE (Lợi nhuận ròng / Vốn CSH) là thước đo quan trọng nhất đối với cổ đông. Biểu đồ này, khi kết hợp với các phân tích trước đó (đặc biệt là ROA và Tỷ lệ Nợ), đã kể một câu chuyện trọn vẹn.
Công thức: ROE = ROA * Đòn bẩy tài chính (Trong đó Đòn
bẩy TC = Tổng Tài sản / Vốn CSH, chịu ảnh hưởng trực tiếp từ Tỷ lệ
Nợ)
ROA giảm mạnh (từ 14.1% xuống 10.9%) do Vòng quay Tài
sản sụp đổ.Đòn bẩy tài chính giảm mạnh (do Tỷ lệ Nợ giảm từ 61.6%
xuống 47%).Kết luận chung: Toàn bộ chuỗi phân tích cho thấy một cuộc tái cấu trúc thành công rực rỡ. Doanh nghiệp đã chấp nhận hy sinh quy mô và lợi nhuận ngắn hạn (năm 2018) để chuyển đổi từ mô hình “Bán lẻ/Phân phối” (Biên mỏng, Vòng quay nhanh, Nợ cao) sang mô hình “Công nghệ/Dịch vụ” (Biên cao, Vòng quay chậm, Quản trị Nợ linh hoạt). Kết quả là một doanh nghiệp có chất lượng lợi nhuận và tiềm năng tăng trưởng bền vững hơn hẳn cho cổ đông. :::
# 2. Dam bao 'fpt_analyzed' va cac cot can thiet ton tai
if (!exists("fpt_analyzed") || !"LuuChuyenTienHDKD" %in% names(fpt_analyzed)) {
    # Fallback: Chỉ dùng fpt_ty_dong nếu fpt_analyzed chưa tồn tại
    fpt_analyzed <- fpt_ty_dong 
}
# Thao tac 43: Chuan bi du lieu (Xoay) de ve bieu do so sanh (Long Format)
fpt_cash_profit <- fpt_analyzed %>%
    select(Nam, LoiNhuanSauThue, LuuChuyenTienHDKD) %>%
    pivot_longer(
        cols = -Nam, 
        names_to = "ChiTieu", 
        values_to = "GiaTri"
    )
# =========================================================
# === IN KẾT QUẢ (PHẦN BẠN YÊU CẦU) ===
# =========================================================
library(kableExtra) # Đảm bảo thư viện được gọi nếu bạn tách khối code
fpt_cash_profit %>%
  head(6) %>%
  kbl(
    caption = "Dữ liệu so sánh Lợi nhuận và Dòng tiền (Định dạng dài)",
    digits = 0,
    col.names = c("Năm", "Chỉ Tiêu", "Giá trị (Tỷ đồng)"), # Đã thêm dấu để hiển thị tiếng Việt
    booktabs = TRUE
  ) %>%
  kable_styling(
    position = "center",
    latex_options = "hold_position" # Giữ bảng đứng yên
  )| Năm | Chỉ Tiêu | Giá trị (Tỷ đồng) | 
|---|---|---|
| 2015 | LoiNhuanSauThue | 2438 | 
| 2015 | LuuChuyenTienHDKD | 1156 | 
| 2016 | LoiNhuanSauThue | 2576 | 
| 2016 | LuuChuyenTienHDKD | 4312 | 
| 2017 | LoiNhuanSauThue | 3528 | 
| 2017 | LuuChuyenTienHDKD | 1988 | 
# --- Bieu do Chat luong Loi nhuan (Loi nhuan Ke toan vs. Dong tien Thuc te) ---
# Kiểm tra nếu có thể dùng ggrepel (Giữ nguyên)
use_repel <- requireNamespace("ggrepel", quietly = TRUE)
print(
  ggplot(fpt_cash_profit, aes(x = Nam, y = GiaTri, color = ChiTieu)) +
    
    # Layer 1 & 2: Vẽ đường và điểm
    geom_line(aes(linetype = ChiTieu), size = 1.2) +
    geom_point(aes(shape = ChiTieu), size = 3.5) +
    
    # Layer 3: Đường mốc 0
    geom_hline(yintercept = 0, linetype = "dotted", color = "black") +
    
    # Layer 4: Tiêu đề (ĐÃ THÊM LẠI TIẾNG VIỆT CÓ DẤU)
    labs(
      title = "Chất lượng Lợi nhuận: Lợi nhuận (Kế toán) vs. Dòng tiền (Thực tế)",
      subtitle = "Lý tưởng nhất: Đường 'Dòng tiền' (Xanh) phải luôn bằng hoặc cao hơn đường 'Lợi nhuận' (Đỏ)",
      x = "Năm", y = "Giá trị (Tỷ đồng)", 
      color = "Chú Thích"
    ) +
    
    # Layer 5, 6, 7: Định nghĩa Legend (ĐÃ THÊM LẠI TIẾNG VIỆT VÀ TỐI ƯU CẤU TRÚC)
    scale_color_manual(
      name = "Chỉ tiêu", # Chỉ dùng một tiêu đề cho Legend
      labels = c("LuuChuyenTienHDKD" = "Dòng tiền từ HDKD (Thực tế)", 
                 "LoiNhuanSauThue" = "Lợi nhuận Sau thuế (Kế toán)"),
      values = c("LuuChuyenTienHDKD" = "blue", "LoiNhuanSauThue" = "red")
    ) +
    scale_linetype_manual(
      values = c("LuuChuyenTienHDKD" = "dashed", "LoiNhuanSauThue" = "solid")
    ) +
    scale_shape_manual(
      values = c("LuuChuyenTienHDKD" = 17, "LoiNhuanSauThue" = 16)
    ) +
    
    # Layer 8: Theme (ĐÃ ĐỒNG BỘ FONT)
    theme_minimal(base_family = "Roboto") + 
    
    # Layer 9: Vị trí chú giải và Label
    theme(legend.position = "bottom") + # Đổi xuống dưới để biểu đồ có thêm không gian
    
    # Layer 10: Thêm nhãn cho các điểm
    {if(use_repel) {
      ggrepel::geom_text_repel(aes(label = round(GiaTri, 0)), size = 3)
    } else {
      geom_text(aes(label = round(GiaTri, 0)), size = 3, vjust = -1)
    }}
)Biểu đồ này so sánh Lợi nhuận sau thuế (LNST - đường đỏ, lợi nhuận kế toán) với Dòng tiền từ HĐKD (LCT - đường xanh, tiền thật). Một doanh nghiệp “khỏe mạnh” lý tưởng sẽ có đường xanh (tiền) luôn bằng hoặc cao hơn đường đỏ (lợi nhuận).
Kết luận: Doanh nghiệp không chỉ tái cấu trúc thành công để có Biên lợi nhuận cao hơn (như các biểu đồ trước đã thấy), mà còn tái cấu trúc thành công để tạo ra Chất lượng lợi nhuận vượt trội. Mô hình kinh doanh mới (sau 2021) đang tạo ra tiền thật còn nhiều hơn cả lợi nhuận trên sổ sách, cho thấy sự bền vững và rủi ro thấp hơn nhiều.
# Thao tac 45: Tinh Ty le Chuyen doi Tien mat (Cash Conversion Ratio)
fpt_analyzed <- fpt_analyzed %>%
  mutate(Cash_Conversion_Rate = LuuChuyenTienHDKD / LoiNhuanSauThue)
# Thao tac 46: In bang ket qua
fpt_cash_table <- fpt_analyzed %>%
  select(Nam, LoiNhuanSauThue, LuuChuyenTienHDKD, Cash_Conversion_Rate)
# In bang dep (ĐÃ SỬA)
kbl( # Đổi sang kbl()
  fpt_cash_table,
  
  # Giữ tiếng Việt có dấu nếu máy bạn đã chạy được UTF-8
  caption = "Bảng Tỷ lệ Chuyển đổi Tiền mặt (Cash Conversion Ratio)", 
  digits = 2,
  
  # Giữ tiếng Việt có dấu (Nếu bị lỗi, hãy bỏ dấu đi như các lần trước)
  col.names = c("Năm", "Lợi nhuận (Tỷ đồng)", "Dòng tiền HDKD (Tỷ đồng)", "Tỷ lệ (Tiền/Lợi nhuận)"), 
  
  booktabs = TRUE # Quan trọng cho PDF
) %>%
  kable_styling(
    position = "center", # Căn giữa
    full_width = FALSE,
    
    # ĐÃ THÊM hold_position và scale_down (vì bảng này rộng)
    latex_options = c("striped", "hold_position", "scale_down") 
  )| Năm | Lợi nhuận (Tỷ đồng) | Dòng tiền HDKD (Tỷ đồng) | Tỷ lệ (Tiền/Lợi nhuận) | 
|---|---|---|---|
| 2015 | 2438.08 | 1155.89 | 0.47 | 
| 2016 | 2575.69 | 4311.66 | 1.67 | 
| 2017 | 3528.11 | 1988.18 | 0.56 | 
| 2018 | 3234.00 | 3588.32 | 1.11 | 
| 2019 | 3911.71 | 3898.75 | 1.00 | 
| 2020 | 4423.75 | 6339.68 | 1.43 | 
| 2021 | 5349.30 | 5839.69 | 1.09 | 
| 2022 | 6491.34 | 5053.83 | 0.78 | 
| 2023 | 7788.05 | 9517.10 | 1.22 | 
| 2024 | 9427.42 | 11703.78 | 1.24 | 
# Thao tac 47: Truc quan hoa Ty le Chuyen doi (8 Layers)
print(
  ggplot(fpt_analyzed, aes(x = as.factor(Nam), y = Cash_Conversion_Rate)) +
    
    # Layer 1: Ve cot, to mau dua tren dieu kien (> 1 la Tot)
    geom_bar(stat = "identity", aes(fill = Cash_Conversion_Rate > 1), alpha = 0.8) +
    
    # Layer 2: Duong moc 1 (tuong duong 100%)
    geom_hline(yintercept = 1, linetype = "dashed", color = "red", size = 1) +
    
    # Layer 3: Them nhan gia tri (so lan)
    geom_text(aes(label = round(Cash_Conversion_Rate, 2)), 
              vjust = -0.5, size = 3.5, color = "black") +
    
    # Layer 4: Tieu de (ĐÃ THÊM LẠI TIẾNG VIỆT CÓ DẤU)
    labs(
      title = "Tỷ lệ Chuyển đổi Lợi nhuận thành Tiền",
      subtitle = "Mốc 1 = Dòng tiền bằng Lợi nhuận. Tốt nhất là > 1.",
      x = "Năm",
      y = "Tỷ lệ (Dòng tiền / Lợi nhuận)",
      fill = "Chất lượng Lợi nhuận" # Đổi tên chú giải (fill)
    ) +
    
    # Layer 5: Dinh nghia mau thu cong (ĐÃ THÊM LẠI TIẾNG VIỆT CÓ DẤU)
    scale_fill_manual(
      name = "Chất lượng Lợi nhuận",
      values = c("TRUE" = "darkgreen", "FALSE" = "gray50"),
      labels = c("TRUE" = "Tốt (> 1)", "FALSE" = "Kém (< 1)")
    ) +
    
    # Layer 6: Theme (ĐÃ ĐỒNG BỘ FONT)
    theme_classic(base_family = "Roboto") + 
    
    # Layer 7: Chú thích thủ công cho đường mốc 1
    annotate("text", x = 1.5, y = 1.05, label = "Mốc 100%", color = "red", vjust = -0.5) +
    
    # Layer 8: Tùy chỉnh hiển thị
    theme(
      legend.position = "top",
      plot.title = element_text(face = "bold", size = 13, hjust = 0.5),
      plot.subtitle = element_text(size = 11, hjust = 0.5)
    )
)
::: {.callout-note}
Biểu đồ này so sánh Lợi nhuận sau thuế (LNST - đường đỏ, lợi nhuận kế toán) với Dòng tiền từ HĐKD (LCT - đường xanh, tiền thật). Một doanh nghiệp “khỏe mạnh” lý tưởng sẽ có đường xanh (tiền) luôn bằng hoặc cao hơn đường đỏ (lợi nhuận).
Kết luận: Câu chuyện tái cấu trúc đã được xác nhận. Doanh nghiệp đã trải qua một cuộc khủng hoảng dòng tiền nghiêm trọng vào năm 2018, nhưng đã tái cấu trúc thành công. Mô hình kinh doanh mới (sau 2021) không chỉ có biên lợi nhuận cao mà còn có chất lượng lợi nhuận vượt trội, tạo ra tiền thật còn nhiều hơn cả lợi nhuận trên sổ sách. :::
# 2. Dam bao 'fpt_analyzed' va cac cot can thiet ton tai
if (!exists("fpt_analyzed") || !"TongTaiSan" %in% names(fpt_analyzed)) {
    fpt_analyzed <- fpt_ty_dong %>%
      mutate(
        TongTaiSan = TaiSanNganHan + TaiSanDaiHan
      )
}
# Thao tac 48: Chuan bi du lieu (Xoay)
# Chung ta chi lay cac cot Tai san de ve bieu do 100%
fpt_asset_structure <- fpt_analyzed %>%
  select(Nam, TaiSanNganHan, TaiSanDaiHan) %>%
  pivot_longer(
    cols = -Nam, 
    names_to = "LoaiTaiSan", 
    values_to = "GiaTri"
  )
# In bang ket qua (vi du 4 dong dau) - ĐÃ SỬA CHUẨN KABLE
kbl( # Đổi sang kbl()
  head(fpt_asset_structure, 4),
  caption = "Dữ liệu Cấu trúc Tài sản đã được 'xoay'", # Thêm lại dấu
  digits = 0,
  col.names = c("Năm", "Loại Tài Sản", "Giá trị (Tỷ đồng)"),
  booktabs = TRUE
) %>%
  kable_styling(
    position = "center",
    full_width = FALSE,
    latex_options = "hold_position" # Giữ bảng đứng yên (không cần scale_down vì bảng hẹp)
  )| Năm | Loại Tài Sản | Giá trị (Tỷ đồng) | 
|---|---|---|
| 2015 | TaiSanNganHan | 18959 | 
| 2015 | TaiSanDaiHan | 7087 | 
| 2016 | TaiSanNganHan | 21909 | 
| 2016 | TaiSanDaiHan | 7925 | 
print( 
  ggplot(fpt_asset_structure, aes(x = Nam, y = GiaTri, fill = LoaiTaiSan)) +
    
    # --- Layer 1: Vẽ biểu đồ cột 100% (position = "fill") ---
    geom_bar(stat = "identity", position = "fill", alpha = 0.8) +
    
    # --- Layer 2: Thêm đường viền trắng ngăn cách ---
    geom_bar(stat = "identity", position = "fill", color = "white", size = 0.1, show.legend = FALSE) +
    
    # --- Layer 3: Thêm nhãn % (đã dùng '..y..' là kỹ thuật đúng) ---
    geom_text(
      # Thêm các tham số cho position_fill (để tương thích với ggplot mới hơn)
      aes(label = scales::percent(..y.., accuracy = 1), group = LoaiTaiSan), 
      position = position_fill(vjust = 0.5), 
      stat = "identity",
      size = 3.5,
      color = "black"
    ) +
    
    # --- Layer 4: Tiêu đề và nhãn (ĐÃ THÊM LẠI TIẾNG VIỆT CÓ DẤU) ---
    labs(
      title = "Phân tích Cấu trúc Tài sản (2015–2024)",
      subtitle = "Tỷ trọng Tài sản Ngắn hạn (TSNH) vs. Tài sản Dài hạn (TSDH)",
      x = "Năm",
      y = "Tỷ trọng (%)",
      fill = "Loại Tài sản"
    ) +
    
    # --- Layer 5: Định dạng trục Y hiển thị % ---
    scale_y_continuous(labels = scales::percent_format()) +
    
    # --- Layer 6: Đổi bảng màu (ĐÃ THÊM LẠI TIẾNG VIỆT CÓ DẤU) ---
    scale_fill_brewer(
      palette = "Set2", 
      labels = c("TaiSanDaiHan" = "Tài sản Dài hạn", "TaiSanNganHan" = "Tài sản Ngắn hạn")
    ) +
    
    # --- Layer 7: Theme (ĐÃ ĐỒNG BỘ FONT) ---
    theme_minimal(base_family = "Roboto") +
    
    # --- Layer 8: Tùy chỉnh hiển thị ---
    theme(
      legend.position = "bottom", # Đổi xuống dưới cho không gian biểu đồ
      legend.title = element_text(size = 12, face = "bold"),
      plot.title = element_text(size = 16, face = "bold", hjust = 0.5),
      plot.subtitle = element_text(size = 12, hjust = 0.5),
      axis.title = element_text(size = 12, face = "bold"),
      axis.text.x = element_text(angle = 0)
    )
)Biểu đồ này cho thấy sự thay đổi trong “thành phần” tài sản mà doanh nghiệp sử dụng để tạo ra doanh thu, và nó xác nhận hoàn hảo câu chuyện tái cấu trúc:
Kết luận: Biểu đồ này giải thích tại sao Vòng quay Tổng Tài sản lại sụp đổ. Doanh nghiệp đã chủ động thay đổi chiến lược: từ bỏ mô hình “tài sản nhẹ” (nhẹ về TSDH, nặng về TSNH) để chuyển sang mô hình “tài sản nặng” (nặng về TSDH). Cấu trúc tài sản đã thay đổi vĩnh viễn để phù hợp với mô hình kinh doanh “Biên lợi nhuận cao” mới.
# 2. Dam bao 'fpt_analyzed' va cac cot can thiet ton tai
if (!exists("fpt_analyzed") || !"VonChuSoHuu" %in% names(fpt_analyzed)) {
    fpt_analyzed <- fpt_analyzed %>%
      mutate(
        TongTaiSan = TaiSanNganHan + TaiSanDaiHan,
        VonChuSoHuu = TongTaiSan - NoPhaiTra
      )
}
# Thao tac 50: Chuan bi du lieu (Xoay)
fpt_capital_structure <- fpt_analyzed %>%
  select(Nam, NoPhaiTra, VonChuSoHuu) %>%
  pivot_longer(
    cols = -Nam, 
    names_to = "LoaiNguonVon", 
    values_to = "GiaTri"
  )
# In bang ket qua (vi du 4 dong dau) - ĐÃ SỬA CHUẨN KABLE
kbl( # Đổi sang kbl()
  head(fpt_capital_structure, 4),
  caption = "Dữ liệu Cấu trúc Nguồn vốn đã được 'xoay'", # Thêm lại dấu
  digits = 0,
  col.names = c("Năm", "Loại Nguồn Vốn", "Giá trị (Tỷ đồng)"),
  booktabs = TRUE
) %>%
  kable_styling(
    position = "center",
    full_width = FALSE,
    latex_options = "hold_position" # Giữ bảng đứng yên
  )| Năm | Loại Nguồn Vốn | Giá trị (Tỷ đồng) | 
|---|---|---|
| 2015 | NoPhaiTra | 15863 | 
| 2015 | VonChuSoHuu | 10182 | 
| 2016 | NoPhaiTra | 18385 | 
| 2016 | VonChuSoHuu | 11448 | 
print( 
  ggplot(fpt_capital_structure, aes(x = Nam, y = GiaTri, fill = LoaiNguonVon)) +
    
    # Layer 1: Biểu đồ cột 100% (position = "fill")
    geom_bar(stat = "identity", position = "fill", alpha = 0.8) +
    
    # Layer 2: Thêm đường viền trắng ngăn cách
    geom_bar(stat = "identity", position = "fill", color = "white", size = 0.1, show.legend = FALSE) +
    
    # Layer 3: Thêm nhãn %
    geom_text(
      # Thêm group aesthetic cho compatibility
      aes(label = scales::percent(..y.., accuracy = 1), group = LoaiNguonVon), 
      position = position_fill(vjust = 0.5),
      stat = "identity",
      size = 3.5,
      color = "black"
    ) +
    
    # Layer 4: Tiêu đề và nhãn (ĐÃ THÊM LẠI TIẾNG VIỆT CÓ DẤU)
    labs(
      title = "Phân tích Cấu trúc Nguồn vốn (2015–2024)",
      subtitle = "Tỷ trọng Nợ Phải Trả vs. Vốn Chủ Sở Hữu (VCSH)",
      x = "Năm",
      y = "Tỷ trọng (%)",
      fill = "Loại Nguồn vốn"
    ) +
    
    # Layer 5: Định dạng trục Y
    scale_y_continuous(labels = scales::percent_format()) +
    
    # Layer 6: Đổi màu thủ công (ĐÃ THÊM LẠI TIẾNG VIỆT CÓ DẤU)
    scale_fill_manual(
      labels = c("NoPhaiTra" = "Nợ Phải Trả", "VonChuSoHuu" = "Vốn Chủ Sở Hữu"),
      values = c("NoPhaiTra" = "#E41A1C", "VonChuSoHuu" = "#377EB8") # Đỏ và Xanh
    ) +
    
    # Layer 7: Theme (ĐÃ ĐỒNG BỘ FONT)
    theme_minimal(base_family = "Roboto") + 
    
    # Layer 8: Tùy chỉnh hiển thị
    theme(
      legend.position = "bottom", # <--- Đổi vị trí chú giải
      legend.title = element_text(face = "bold"),
      plot.title = element_text(size = 16, face = "bold", hjust = 0.5),
      plot.subtitle = element_text(size = 12, hjust = 0.5),
      axis.title = element_text(size = 12, face = "bold"),
      axis.text.x = element_text(angle = 0)
    )
)Biểu đồ này minh họa rõ nét sự thay đổi trong chính sách tài trợ và mức độ rủi ro mà doanh nghiệp chấp nhận, đồng bộ hoàn hảo với các phân tích trước đó.
Kết luận: Biểu đồ này xác nhận doanh nghiệp đã thay đổi hoàn toàn chính sách tài chính: từ bỏ mô hình “Nợ cao cố định” sang mô hình “Quản trị Nợ linh hoạt” và duy trì cấu trúc vốn ở mức an toàn, cân bằng (50% Nợ - 50% Vốn CSH) trong giai đoạn ổn định.
library(reshape2) # Đảm bảo thư viện được gọi
# 2. Dam bao 'fpt_analyzed' ton tai
if (!exists("fpt_analyzed")) {
    fpt_analyzed <- fpt_ty_dong 
}
# Thao tac 52: Tinh toan va "Melt" Ma tran Tuong quan
# 1. Chon cac cot tai chinh (bo cot 'Nam' va cac cot phai sinh nhu % rate)
fpt_financial_data <- fpt_analyzed %>%
    select(DoanhThuThuan, GiaVon, ChiPhiBanHang, ChiPhiQLDN, 
           LoiNhuanSauThue, ChiPhiTaiChinh, LuuChuyenTienHDKD, 
           TaiSanNganHan, TaiSanDaiHan, NoPhaiTra)
# 2. Tinh ma tran tuong quan
correlation_matrix <- cor(fpt_financial_data)
# 3. "Melt" (Lam tan chay) ma tran de ggplot doc duoc
melted_corr <- melt(correlation_matrix)
# In 4 dong dau cua bang du lieu da "melt" - ĐÃ SỬA CHUẨN KABLE
kbl( # Đổi sang kbl()
  head(melted_corr, 4),
  caption = "Dữ liệu ma trận tương quan đã 'melt'", # Thêm lại dấu
  digits = 2,
  
  # ĐÃ THÊM LẠI TIẾNG VIỆT CÓ DẤU
  col.names = c("Biến 1", "Biến 2", "Giá trị Tương quan"),
  
  booktabs = TRUE
) %>%
  kable_styling(
    position = "center",
    full_width = FALSE,
    # Giữ bảng đứng yên. Không cần scale_down vì bảng hẹp.
    latex_options = "hold_position" 
  )| Biến 1 | Biến 2 | Giá trị Tương quan | 
|---|---|---|
| DoanhThuThuan | DoanhThuThuan | 1.00 | 
| GiaVon | DoanhThuThuan | 0.91 | 
| ChiPhiBanHang | DoanhThuThuan | 0.90 | 
| ChiPhiQLDN | DoanhThuThuan | 0.66 | 
print(
  ggplot(melted_corr, aes(x = Var1, y = Var2, fill = value)) +
    
    # Layer 1: Vẽ các ô (tile)
    geom_tile(color = "white") +
    
    # Layer 2: Thêm nhãn (số tương quan)
    geom_text(aes(label = round(value, 2)), color = "black", size = 3) +
    
    # Layer 3: Định nghĩa dải màu (ĐÃ THÊM LẠI TIẾNG VIỆT CÓ DẤU)
    scale_fill_gradient2(
      low = "blue",        # Màu cho tương quan âm
      high = "red",         # Màu cho tương quan dương
      mid = "white",        # Màu cho tương quan = 0
      midpoint = 0,           # Đặt số 0 ở giữa
      limit = c(-1, 1),       # Giới hạn từ -1 đến 1
      name = "Tương quan\nPearson" # Thêm lại dấu
    ) +
    
    # Layer 4: Theme (ĐÃ ĐỒNG BỘ FONT)
    theme_minimal(base_family = "Roboto") +
    
    # Layer 5: Tiêu đề (ĐÃ THÊM LẠI TIẾNG VIỆT CÓ DẤU)
    labs(
      title = "Biểu đồ nhiệt Ma trận Tương quan",
      subtitle = "Mối quan hệ tuyến tính giữa các biến tài chính",
      x = "", y = ""
    ) +
    
    # Layer 6: Giữ tỷ lệ các ô vuông
    coord_fixed() +
    
    # Layer 7: Xoay nhãn trục X 45 độ
    theme(
      axis.text.x = element_text(angle = 45, vjust = 1, hjust = 1),
      plot.title = element_text(face = "bold", size = 14, hjust = 0.5),
      plot.subtitle = element_text(size = 10, hjust = 0.5)
    ) +
    
    # Layer 8: Vị trí chú giải (ĐỔI XUỐNG DƯỚI)
    theme(legend.position = "bottom")
)Ma trận tương quan này cung cấp cái nhìn tổng thể về mối quan hệ tuyến tính giữa các biến, xác nhận các nhóm chỉ số và củng cố thêm câu chuyện tái cấu trúc.
TaiSanNganHan, TaiSanDaiHan, và
NoPhaiTra có tương quan cực cao với nhau (0.9 - 1.0). Điều
này hợp lý về mặt kinh tế: khi doanh nghiệp mở rộng quy mô, tài sản (cả
ngắn và dài hạn) và nợ (để tài trợ cho tài sản) đều phải tăng theo.DoanhThuThuan, LoiNhuanSauThue,
ChiPhiBanHang, ChiPhiQLDN cũng tương quan rất
chặt chẽ (hầu hết > 0.85). Điều này cho thấy mô hình kinh doanh (cả
cũ và mới) đều có đặc điểm là khi doanh thu tăng, các chi phí và lợi
nhuận cũng tăng tỷ lệ thuận.LoiNhuanSauThue và
LuuChuyenTienHDKD là rất cao (0.92).GiaVon vs. TaiSanDaiHan (Tài sản dài hạn)
có tương quan rất yếu (0.24).GiaVon vs. NoPhaiTra cũng yếu (0.33).GiaVon cao nhưng TaiSanDaiHan thấp. Mô hình
mới (2018-2024) có GiaVon thấp hơn nhưng
TaiSanDaiHan lại cao. Vì hai xu hướng này ngược nhau nên
khi gộp chung 10 năm, mối tương quan bị triệt tiêu và trở nên rất
yếu.Kết luận: Ma trận tương quan xác nhận các mối quan hệ kinh tế hợp lý (quy mô tăng cùng quy mô, lợi nhuận tăng cùng chi phí) và vô tình cung cấp bằng chứng cuối cùng về cuộc tái cấu trúc thông qua các mối tương quan yếu bất thường.
# 2. Dam bao 'fpt_analyzed' va cac cot can thiet ton tai
if (!exists("fpt_analyzed") || !"ROE_Rate" %in% names(fpt_analyzed)) {
    fpt_analyzed <- fpt_ty_dong %>%
      mutate(
        TongTaiSan = TaiSanNganHan + TaiSanDaiHan,
        VonChuSoHuu = TongTaiSan - NoPhaiTra,
        ROE_Rate = LoiNhuanSauThue / VonChuSoHuu * 100,
        Bien_LN_Rong_Rate = LoiNhuanSauThue / DoanhThuThuan * 100,
        VongQuay_TTS = DoanhThuThuan / TongTaiSan
      )
}
# Thao tac 54: Tinh toan 3 yeu to DuPont
fpt_dupont <- fpt_analyzed %>%
  mutate(
    # Yeu to 1: Bien Loi nhuan Rong 
    DuPont_BienLN = Bien_LN_Rong_Rate / 100, # (Dua ve so thap phan)
    
    # Yeu to 2: Vong quay Tong Tai san 
    DuPont_VongQuay = VongQuay_TTS, # (So lan)
    
    # Yeu to 3: Don bay Tai chinh (Tai san / Von CSH)
    DuPont_DonBay = TongTaiSan / VonChuSoHuu, # (So lan)
    
    # Kiem tra: Nhan 3 yeu to lai co ra ROE khong?
    ROE_DuPont_Check = DuPont_BienLN * DuPont_VongQuay * DuPont_DonBay * 100
  )
# Thao tac 55: In bang ket qua DuPont (ĐÃ SỬA CHUẨN KABLE)
fpt_dupont_table <- fpt_dupont %>%
  select(Nam, DuPont_BienLN, DuPont_VongQuay, DuPont_DonBay, ROE_Rate, ROE_DuPont_Check)
kbl( # Đổi sang kbl()
  fpt_dupont_table,
  caption = "Bảng bóc tách ROE theo 3 yếu tố DuPont", # Giữ dấu ở caption
  digits = 3, # Hien thi 3 chu so thap phan
  
  # --- ĐÃ SỬA LỖI ENCODING (BỎ DẤU) ---
  col.names = c("Nam", "Bien LN Rong (lan)", "Vong quay TS (lan)", "Don bay TC (lan)", "ROE Goc (%)", "ROE DuPont (%)"),
  
  booktabs = TRUE
) %>%
  kable_styling(
    position = "center",
    full_width = FALSE,
    # ĐÃ THÊM hold_position và scale_down (vì bảng này rộng)
    latex_options = c("hold_position", "scale_down") 
  )| Nam | Bien LN Rong (lan) | Vong quay TS (lan) | Don bay TC (lan) | ROE Goc (%) | ROE DuPont (%) | 
|---|---|---|---|---|---|
| 2015 | 0.064 | 1.457 | 2.558 | 23.944 | 23.944 | 
| 2016 | 0.065 | 1.325 | 2.606 | 22.499 | 22.499 | 
| 2017 | 0.083 | 1.706 | 1.888 | 26.651 | 26.651 | 
| 2018 | 0.139 | 0.780 | 2.014 | 21.888 | 21.888 | 
| 2019 | 0.141 | 0.830 | 1.988 | 23.285 | 23.285 | 
| 2020 | 0.148 | 0.715 | 2.243 | 23.776 | 23.776 | 
| 2021 | 0.150 | 0.664 | 2.507 | 24.976 | 24.976 | 
| 2022 | 0.147 | 0.852 | 2.037 | 25.601 | 25.601 | 
| 2023 | 0.148 | 0.873 | 2.014 | 26.018 | 26.018 | 
| 2024 | 0.150 | 0.873 | 2.015 | 26.387 | 26.387 | 
# Chung ta se "xoay" du lieu de ve 3 bieu do con
fpt_dupont_long <- fpt_dupont %>%
  select(Nam, DuPont_BienLN, DuPont_VongQuay, DuPont_DonBay) %>%
  pivot_longer(
    cols = -Nam,
    names_to = "YeuTo_DuPont",
    values_to = "GiaTri"
  )
print(
  ggplot(fpt_dupont_long, aes(x = Nam, y = GiaTri)) +
    
    # Layer 1: Vẽ đường
    geom_line(aes(color = YeuTo_DuPont), size = 1.2) +
    
    # Layer 2: Vẽ điểm
    geom_point(aes(color = YeuTo_DuPont), size = 3) +
    
    # Layer 3 (NÂNG CẤP): Thêm nhãn giá trị
    ggrepel::geom_text_repel(
      aes(label = round(GiaTri, 2), color = YeuTo_DuPont), 
      size = 3, 
      show.legend = FALSE
    ) +
    
    # Layer 4: Tiêu đề (ĐÃ THÊM LẠI TIẾNG VIỆT CÓ DẤU)
    labs(
      title = "Phân tích DuPont: 3 Yếu tố cấu thành ROE",
      subtitle = "ROA = Biên LN * Vòng quay | ROE = ROA * Đòn bẩy (Đơn vị: Số lần)",
      x = "Năm", y = "Giá trị (Số lần)"
    ) +
    
    # Layer 5: Hàm FACET (chia thành 3 biểu đồ con)
    facet_wrap(~ YeuTo_DuPont, ncol = 3, scales = "free_y") +
    
    # Layer 6: Theme (ĐÃ ĐỒNG BỘ FONT)
    theme_bw(base_family = "Roboto") +
    
    # Layer 7: An chu giai & tùy chỉnh
    theme(
      legend.position = "none", # Giữ nguyên: Ẩn chú giải
      plot.title = element_text(face = "bold", size = 14, hjust = 0.5),
      plot.subtitle = element_text(size = 10, hjust = 0.5),
      strip.text = element_text(face = "bold") # Nhãn Facet đậm hơn
    )
)Dưới đây là phần nhận xét cho “Biểu đồ Phân tích DuPont”.
Đây là biểu đồ quan trọng nhất trong tất cả các biểu đồ bạn gửi. Nó “bóc tách” chỉ số ROE (Lợi nhuận Cổ đông) thành 3 thành tố cốt lõi và là bằng chứng không thể chối cãi, xác nhận toàn bộ câu chuyện tái cấu trúc mà chúng ta đã phân tích.
Công thức: ROE = Biên Lợi nhuận (Đỏ) * Vòng quay (Xanh dương) * Đòn bẩy (Xanh lá)
Markdown
Biểu đồ này là bản tóm tắt hoàn hảo cho toàn bộ câu chuyện. Nó cho thấy rõ doanh nghiệp đã chủ động “đánh đổi” các yếu tố nào để tạo ra mô hình kinh doanh mới.
DuPont_VongQuay (Xanh dương): Sụp đổ
từ đỉnh 1.71 (năm 2017) xuống còn 0.78.DuPont_BienLN (Đỏ): Tăng vọt từ 8.3%
(năm 2017) lên 13.9%.DuPont_DonBay (Xanh lá): Lao dốc từ
2.61 (năm 2016) xuống 1.89 (năm 2017).image_428e08.png), chúng ta thấy
ROE 2017 (26.7%) và ROE 2024 (26.4%) gần như bằng nhau. Nhưng phân tích
DuPont cho thấy chất lượng hoàn toàn khác biệt:Thấp (Biên 8.3%) * Cao (Vòng quay 1.71) * Vừa (Đòn bẩy 1.89)
-> ROE dựa trên Vòng quay và Rủi ro.Cao (Biên ~15%) * Thấp (Vòng quay ~0.87) * Vừa (Đòn bẩy ~2.0)
-> ROE dựa trên Chất lượng và Biên lợi nhuận.Kết luận: Phân tích DuPont là kết luận cuối cùng: Doanh nghiệp đã thực hiện một cuộc tái cấu trúc thành công vang dội, chấp nhận “đánh đổi” Vòng quay tài sản để lấy Biên lợi nhuận, đồng thời quản lý Đòn bẩy tài chính ở mức an toàn, tạo ra một chỉ số ROE bền vững hơn cho cổ đông.
# 2. Dam bao 'fpt_analyzed' va cac cot can thiet ton tai
if (!exists("fpt_analyzed") || !"Bien_LN_Rong_Rate" %in% names(fpt_analyzed)) {
    fpt_analyzed <- fpt_ty_dong %>%
      mutate(
        Bien_LN_Rong_Rate = LoiNhuanSauThue / DoanhThuThuan * 100
      )
}
# Thao tac 52: Tinh Bien Dong tien Hoat dong (CFO Margin)
fpt_analyzed <- fpt_analyzed %>%
  mutate(
    CFO_Margin_Rate = (LuuChuyenTienHDKD / DoanhThuThuan) * 100
  )
# Thao tac 53: Chuan bi du lieu (Xoay)
fpt_margin_compare <- fpt_analyzed %>%
  select(Nam, Bien_LN_Rong_Rate, CFO_Margin_Rate) %>%
  pivot_longer(
    cols = -Nam,
    names_to = "LoaiBien",
    values_to = "TyLe"
  )
  
# In bang ket qua (ĐÃ SỬA CHUẨN KABLE)
kbl( # Đổi sang kbl()
  fpt_margin_compare %>% head(6), # In 6 dong dau
  
  # ĐÃ THÊM LẠI TIẾNG VIỆT CÓ DẤU
  caption = "So sánh Biên Lợi nhuận Ròng và Biên Dòng tiền HDKD",
  digits = 2,
  col.names = c("Năm", "Loại Biên (%)", "Tỷ lệ (%)"),
  
  booktabs = TRUE
) %>%
  kable_styling(
    position = "center",
    full_width = FALSE,
    # ĐÃ THÊM hold_position (không cần scale_down vì bảng hẹp)
    latex_options = "hold_position" 
  )| Năm | Loại Biên (%) | Tỷ lệ (%) | 
|---|---|---|
| 2015 | Bien_LN_Rong_Rate | 6.42 | 
| 2015 | CFO_Margin_Rate | 3.05 | 
| 2016 | Bien_LN_Rong_Rate | 6.52 | 
| 2016 | CFO_Margin_Rate | 10.91 | 
| 2017 | Bien_LN_Rong_Rate | 8.27 | 
| 2017 | CFO_Margin_Rate | 4.66 | 
print(
  ggplot(fpt_margin_compare, aes(x = Nam, y = TyLe, fill = LoaiBien)) +
    
    # Layer 1 & 2: Vẽ biểu đồ cột (Bar plot)
    geom_bar(stat = "identity", position = "dodge", alpha = 0.8) +
    
    # Layer 3: Thêm nhãn giá trị
    geom_text(
      aes(label = round(TyLe, 1)), 
      position = position_dodge(width = 0.9), 
      vjust = -0.5, 
      size = 3
    ) +
    
    # Layer 4: Tiêu đề (ĐÃ THÊM LẠI TIẾNG VIỆT CÓ DẤU)
    labs(
      title = "So sánh Biên Lợi nhuận Ròng (Kế toán) vs. Biên Dòng tiền (Tiền mặt)",
      subtitle = "Khoảng cách (Gap) giữa 2 cột càng lớn, chất lượng lợi nhuận càng thấp",
      x = "Năm",
      y = "Tỷ lệ (%) so với Doanh thu",
      fill = "Loại Biên (Margin)"
    ) +
    
    # Layer 5: Định dạng trục Y
    scale_y_continuous(labels = scales::percent_format(scale = 1)) +
    
    # Layer 6: Đổi màu thủ công (ĐÃ THÊM LẠI TIẾNG VIỆT CÓ DẤU)
    scale_fill_manual(
      labels = c("Bien_LN_Rong_Rate" = "Biên Lợi nhuận Ròng (Kế toán)", 
                 "CFO_Margin_Rate" = "Biên Dòng tiền HDKD (Tiền mặt)"),
      values = c("Bien_LN_Rong_Rate" = "#F8766D", 
                 "CFO_Margin_Rate" = "#00BFC4")
    ) +
    
    # Layer 7: Đường mốc 0
    geom_hline(yintercept = 0, color = "black") +
    
    # Layer 8: Theme (ĐÃ ĐỒNG BỘ FONT)
    theme_minimal(base_family = "Roboto") + 
    
    # Layer 9: Vị trí chú giải (ĐỔI XUỐNG DƯỚI)
    theme(
      legend.position = "bottom",
      plot.title = element_text(face = "bold", size = 13, hjust = 0.5),
      plot.subtitle = element_text(size = 10, hjust = 0.5)
    )
)Biểu đồ này trực quan hóa “chất lượng lợi nhuận” bằng cách so sánh Biên Lợi nhuận Ròng (LNST/Doanh thu - màu đỏ) với Biên Dòng tiền (Dòng tiền HDKD/Doanh thu - màu xanh).
Kết luận: Doanh nghiệp không chỉ tái cấu trúc thành công để có Biên Lợi nhuận cao hơn, mà còn thành công trong việc tạo ra một mô hình có Chất lượng Lợi nhuận vượt trội. Mô hình mới (sau 2019) có khả năng chuyển đổi doanh thu thành tiền mặt thực sự, cho thấy sự bền vững và rủi ro thấp hơn nhiều.
# 2. Dam bao 'fpt_analyzed' va cac cot can thiet ton tai
if (!exists("fpt_analyzed") || !"NoPhaiTra" %in% names(fpt_analyzed)) {
    fpt_analyzed <- fpt_ty_dong 
}
# Thao tac 55: Tinh Ty le Dong tien HDKD / Tong No
fpt_analyzed <- fpt_analyzed %>%
  mutate(
    # Ty le nay cho biet 1 nam Dong tien HDKD tra duoc bao nhieu % Tong No
    CFO_to_Debt_Rate = (LuuChuyenTienHDKD / NoPhaiTra) * 100
  )
# Thao tac 56: In bang ket qua
fpt_debt_coverage_table <- fpt_analyzed %>%
  select(Nam, LuuChuyenTienHDKD, NoPhaiTra, CFO_to_Debt_Rate)
# In bang dep (ĐÃ SỬA CHUẨN KABLE)
kbl( # Đổi sang kbl()
  fpt_debt_coverage_table,
  
  # ĐÃ THÊM LẠI TIẾNG VIỆT CÓ DẤU
  caption = "Bảng Khả năng trả nợ bằng Dòng tiền HDKD", 
  digits = 2,
  col.names = c("Năm", "Dòng tiền HDKD (Tỷ đồng)", "Tổng Nợ (Tỷ đồng)", "Tỷ lệ Trả Nợ (%)"),
  
  booktabs = TRUE
) %>%
  kable_styling(
    position = "center",
    full_width = FALSE,
    # ĐÃ THÊM hold_position và scale_down (vì bảng này rộng)
    latex_options = c("striped", "hold_position", "scale_down") 
  )| Năm | Dòng tiền HDKD (Tỷ đồng) | Tổng Nợ (Tỷ đồng) | Tỷ lệ Trả Nợ (%) | 
|---|---|---|---|
| 2015 | 1155.89 | 15863.30 | 7.29 | 
| 2016 | 4311.66 | 18385.19 | 23.45 | 
| 2017 | 1988.18 | 11761.30 | 16.90 | 
| 2018 | 3588.32 | 14982.10 | 23.95 | 
| 2019 | 3898.75 | 16594.87 | 23.49 | 
| 2020 | 6339.68 | 23128.66 | 27.41 | 
| 2021 | 5839.69 | 32279.96 | 18.09 | 
| 2022 | 5053.83 | 26294.28 | 19.22 | 
| 2023 | 9517.10 | 30349.82 | 31.36 | 
| 2024 | 11703.78 | 36272.46 | 32.27 | 
# Tinh gia tri trung binh (Đảm bảo giá trị này tồn tại)
avg_cfo_debt <- mean(fpt_analyzed$CFO_to_Debt_Rate, na.rm = TRUE)
print(
  ggplot(fpt_analyzed, aes(x = Nam, y = CFO_to_Debt_Rate)) +
    
    # Layer 1 & 2: Vẽ đường thực tế và điểm
    geom_line(aes(color = "Tỷ lệ thực tế (%)"), size = 1.2) +
    geom_point(aes(color = "Tỷ lệ thực tế (%)"), size = 3, shape = 18) +
    
    # Layer 3: Đường xu hướng (Linear Model)
    geom_smooth(aes(color = "Xu hướng (Tuyến tính)"), method = "lm", se = FALSE, linetype = "dotted") +
    
    # Layer 4: Thêm nhãn (ggrepel)
    geom_text_repel(aes(label = round(CFO_to_Debt_Rate, 1)), size = 3.5) +
    
    # Layer 5: Đường trung bình 10 năm (Đường HLine thực tế)
    geom_hline(yintercept = avg_cfo_debt, linetype = "dashed", color = "blue") +
    
    # Layer 6 (NÂNG CẤP): Tạo đường ẩn cho Legend
    geom_line(aes(y = avg_cfo_debt, color = "Trung bình 10 năm"), size=0, linetype="dashed") +
    
    # Layer 7: Chú thích màu cho các đường (Tích hợp tất cả vào Legend)
    scale_color_manual(
      name = "Chú Thích",
      values = c(
        "Tỷ lệ thực tế (%)" = "brown",
        "Xu hướng (Tuyến tính)" = "black",
        "Trung bình 10 năm" = "blue"
      ),
      labels = c("Tỷ lệ thực tế (%)", "Xu hướng (Tuyến tính)", "Trung bình 10 năm")
    ) +
    
    # Layer 8: Định dạng trục Y theo %
    scale_y_continuous(labels = scales::percent_format(scale = 1)) +
    
    # Layer 9: Tiêu đề (ĐÃ THÊM LẠI TIẾNG VIỆT CÓ DẤU)
    labs(
      title = "Phân tích Khả năng Trả nợ (CFO / Tổng Nợ)",
      subtitle = "Tỷ lệ này càng cao, rủi ro tài chính càng thấp",
      x = "Năm",
      y = "Tỷ lệ Trả Nợ (%)"
    ) +
    
    # Layer 10: Theme (ĐÃ ĐỒNG BỘ FONT)
    theme_light(base_family = "Roboto") +
    theme(
      plot.title = element_text(size = 16, face = "bold", hjust = 0.5),
      plot.subtitle = element_text(size = 12, hjust = 0.5),
      axis.title = element_text(size = 12, face = "bold"),
      legend.position = "bottom"
    )
)Biểu đồ này cho thấy khả năng tạo tiền từ kinh doanh (CFO) để trả tổng nợ. Tỷ lệ càng cao, rủi ro càng thấp.