PHẦN 1:GIỚI THIỆU VỀ BỘ DỮ LIỆU & MỘT SỐ THAO TÁC CƠ BẢN

GIỚI THIỆU TỔNG QUAN VỀ BỘ DỮ LIỆU

Tải và Kiểm tra Dữ liệu

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: 1. 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). 2. 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")

# 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 knitr và "vẽ" bảng đẹp
library(knitr)
kable(
  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
)
Kết quả Kiểm tra Kỹ thuật Bộ dữ liệu
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ối cảnh và Nguồn gốc

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:

  • Phân tích cấu trúc chi phí và khả năng sinh lời.
  • Phân tích hiệu quả sử dụng tài sản và đòn bẩy tài chính.
  • Phân tích chất lượng dòng tiền so với lợi nhuận kế toán.

Xem các dòng đầu của bộ dữ liệu

# Dùng kable() để in bảng head() đẹp
kable(
 head(fpt),
 caption = "6 Dòng dữ liệu đầu tiên (Dữ liệu gốc)"
) 
6 Dòng dữ liệu đầu tiên (Dữ liệu gốc)
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

Xem dòng cuối của bộ dữ liệu

kable(
  tail(fpt, 3), 
  caption = "3 Dòng dữ liệu cuối cùng"
)
3 Dòng dữ liệu cuối cùng
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

Kiểm tra cấu trú và tên biến

# Tải thư viện knitr
library(knitr)

# 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
kable(bang_cau_truc, row.names = FALSE)
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ả trên xác nhận 11 biến và kiểu dữ liệu của chúng (chủ yếu là dbl, tức là số thực/numeric, hoàn toàn phù hợp để phân tích).

  • Biến độc lập (Biến định danh): Nam (kiểu số), đại diện cho mốc thời gian quan sát.
  • Các biến phụ thuộc (Biến quan sát): 10 biến tài chính còn lại (kiểu số), được nhóm như sau:

  • Nhóm 1: Các chỉ tiêu từ Báo cáo Kết quả Kinh doanh
    • 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.
  • Nhóm 2: Các chỉ tiêu từ Bảng Cân đối Kế toán
    • TaiSanNganHan: Toàn bộ tài sản ngắn hạn.
    • TaiSanDaiHan: Toàn bộ tài sản dài hạn.
    • NoPhaiTra: Tổng nợ phải trả (ngắn hạn và dài hạn).
  • Nhóm 3: Chỉ tiêu từ Báo cáo Lưu chuyển Tiền tệ
    • LuuChuyenTienHDKD: Dòng tiền thuần từ hoạt động kinh doanh cốt lõi.

Biến đổi dữ liệu sang đơn vị Tỷ đồng và xem thống kê mô tả

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:

  1. Chuyển đổi đơn vị: Chúng ta sẽ tạo một data frame mới (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.
  2. Tạo Bảng tóm tắt nâng cao: Chúng ta sẽ sử dụng hàm 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.
3 Dòng đầu của Dữ liệu (Đã đổi sang Tỷ đồng)
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

Thống kê tổng quan về bộ dữ liệu

# 1. Sử dụng skim() và "vẽ" bằng kable()
thong_ke_skim <- skim(fpt_ty_dong) # Lưu kết quả

kable(
  thong_ke_skim, 
  caption = "Bảng Thống kê Mô tả Chi tiết (Đơn vị: Tỷ đồng)",
  digits = 2
)
Bảng Thống kê Mô tả Chi tiết (Đơn vị: Tỷ đồng)
skim_type skim_variable n_missing complete_rate numeric.mean numeric.sd numeric.p0 numeric.p25 numeric.p50 numeric.p75 numeric.p100 numeric.hist
numeric Nam 0 1 2019.50 3.03 2015.00 2017.25 2019.50 2021.75 2024.00 ▇▇▇▇▇
numeric DoanhThuThuan 0 1 39604.42 11842.39 23213.54 31287.12 38745.58 43671.80 62848.79 ▇▅▇▂▂
numeric GiaVon 0 1 26436.41 8157.27 14490.66 19018.88 28654.06 31997.09 39150.45 ▆▂▂▇▂
numeric ChiPhiBanHang 0 1 3453.69 1395.47 2047.83 2419.08 2894.10 4295.98 6115.96 ▇▃▁▃▂
numeric ChiPhiQLDN 0 1 4495.00 1592.47 2331.79 3469.17 4357.31 5537.79 7074.04 ▅▇▅▂▅
numeric LoiNhuanSauThue 0 1 4916.75 2330.82 2438.08 3307.53 4167.73 6205.83 9427.42 ▇▃▃▂▂
numeric ChiPhiTaiChinh 0 1 977.85 561.58 361.05 594.51 657.31 1551.57 1811.55 ▇▂▂▁▅
numeric LuuChuyenTienHDKD 0 1 5339.69 3235.59 1155.89 3665.93 4682.75 6214.68 11703.78 ▃▇▃▂▂
numeric TaiSanNganHan 0 1 26822.31 9827.73 16059.94 18964.05 23760.58 34073.21 45535.94 ▇▂▂▃▂
numeric TaiSanDaiHan 0 1 15517.21 6766.67 7086.58 9542.55 15268.41 20179.41 26464.05 ▇▅▅▂▅
numeric NoPhaiTra 0 1 22591.19 8362.23 11761.30 16046.20 20756.92 29335.93 36272.46 ▇▂▃▂▃

Thống kê Min/Max theo từng biến

# Tải các thư viện cần thiết
library(dplyr)
library(tidyr)  # Để dùng pivot_longer()
library(knitr)

# 1. Xoay dữ liệu (nếu chưa có fpt_long)
fpt_long <- fpt_ty_dong %>%
  pivot_longer(
    cols = -Nam,           # Chọn tất cả cột trừ 'Nam'
    names_to = "ChiTieu",  # Tên biến mới
    values_to = "GiaTri"   # Giá trị mới
  )

# 2. Nhóm theo ChiTieu và tìm Min/Max (cả Giá trị và Năm)
bang_min_max <- fpt_long %>%
  group_by(ChiTieu) %>%
  summarise(
    GiaTri_NhoNhat = min(GiaTri),
    Nam_NhoNhat = Nam[which.min(GiaTri)], # Lấy năm tại vị trí min
    GiaTri_LonNhat = max(GiaTri),
    Nam_LonNhat = Nam[which.max(GiaTri)]  # Lấy năm tại vị trí max
  ) %>%
  arrange(ChiTieu) # Sắp xếp theo A-Z cho dễ nhìn

# 3. In bảng kết quả đẹp
kable(
  bang_min_max,
  caption = "Giá trị Min/Max (và Năm) cho từng Biến (Đơn vị: Tỷ đồng)",
  digits = 2,
  col.names = c("Chỉ Tiêu", "Giá trị Min", "Năm (Min)", "Giá trị Max", "Năm (Max)")
)
Giá trị Min/Max (và Năm) cho từng Biến (Đơn vị: Tỷ đồng)
Chỉ Tiêu Giá trị Min Năm (Min) Giá trị Max Năm (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

Xem 3 năm có Lợii nhuận sau thuế cao nhất

top_3_loi_nhuan <- fpt_ty_dong %>%
  arrange(desc(LoiNhuanSauThue)) %>% # Sắp xếp giảm dần
  slice(1:3) # Lấy 3 hàng đầu
  
kable(top_3_loi_nhuan, caption = "Top 3 Năm Lợi nhuận Cao nhất", digits = 2)
Top 3 Năm Lợi nhuận Cao nhất
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

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 (mặc định)
  slice(1:3) # Lấy 3 hàng đầu
  
kable(bottom_3_doanh_thu, caption = "3 Năm Doanh thu Thấp nhất", digits = 2)
3 Năm Doanh thu Thấp nhất
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

In ra các thông số của năm 2024(năm mới đây)

data_2024 <- fpt_ty_dong %>%
  filter(Nam == 2024)
  
kable(data_2024, caption = "Dữ liệu chi tiết năm 2024", digits = 2)
Dữ liệu chi tiết năm 2024
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

PHẦN 2: PHÂN TÍCH CHI TIẾT.

Tính toán Tốc độ Tăng trưởng Doanh thu

# 1. Tải tất cả thư viện cần thiết
library(dplyr)
library(knitr)    # Cho kable()
library(ggplot2)  # Cho ggplot()
library(scales)   # Cho scale_fill_gradient2()

# 2. Tính toán data frame chính
fpt_analyzed <- fpt_ty_dong %>%
  arrange(Nam) %>% # Đảm bảo sắp xếp đúng theo năm
  mutate(
    DoanhThu_Truoc = lag(DoanhThuThuan, 1), # Lấy doanh thu năm trước
    TangTruong_DoanhThu_Rate = (DoanhThuThuan / DoanhThu_Truoc - 1) * 100
  )

# 3. SỬA LỖI: Tính 'avg_growth' ngay sau khi có 'fpt_analyzed'
avg_growth <- mean(fpt_analyzed$TangTruong_DoanhThu_Rate, na.rm = TRUE)
  
# 4. In bảng tóm tắt 3 cột (như bạn yêu cầu)
# Dùng select() để chọn 3 cột bạn muốn xem
fpt_growth_table <- fpt_analyzed %>%
  select(Nam, DoanhThu_Truoc, TangTruong_DoanhThu_Rate)
  
# In bảng đẹp chỉ cho 3 cột này
kable(
  fpt_growth_table,
  caption = "Bảng Tốc độ Tăng trưởng Doanh thu",
  digits = 2,
  col.names = c("Năm", "Doanh thu Năm trước (Tỷ đồng)", "Tăng trưởng (%)")
)
Bảng Tốc độ Tăng trưởng Doanh thu
Năm Doanh thu Năm trước (Tỷ đồng) Tăng trưởng (%)
2015 NA NA
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

Trực quan hoá dữ liệu

# (Đảm bảo các thư viện này đã được tải)
# library(ggplot2)
# library(dplyr)
# library(scales)

# (Đảm bảo 'fpt_analyzed' và 'avg_growth' đã tồn tại)
# if (!exists("fpt_analyzed")) { ... }
# if (!exists("avg_growth")) { ... }

ggplot(fpt_analyzed %>% filter(!is.na(TangTruong_DoanhThu_Rate)), # Lọc bỏ năm 2015 (bị NA)
       aes(x = as.factor(Nam), y = TangTruong_DoanhThu_Rate)) +
  
  # Layer 1: Biểu đồ cột, tô màu theo giá trị
  geom_bar(stat = "identity", aes(fill = TangTruong_DoanhThu_Rate), alpha = 0.8) +
  
  # Layer 2: Thêm đường trung bình (màu đỏ)
  # (Giờ đã tìm thấy 'avg_growth')
  geom_hline(yintercept = avg_growth, linetype = "dashed", color = "red", size = 1) +
  
  # Layer 3: Thêm nhãn giá trị (%) trên mỗi cột
  geom_text(aes(label = paste0(round(TangTruong_DoanhThu_Rate, 1), "%")), 
            vjust = -0.5, size = 3.5, color = "black") +
  
  # Layer 4: Đổi dải màu (từ Xanh -> Đỏ)
  scale_fill_gradient2(low = "blue", mid = "white", high = "red", midpoint = avg_growth) +
  
  # Layer 5: Thêm tiêu đề, phụ đề, và nhãn trục
  labs(
    title = "Tốc độ Tăng trưởng Doanh thu (%) qua các năm",
    subtitle = paste("Đường gạch đỏ là 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 = "Phân tích dựa trên dữ liệu FPT 2015-2024"
  ) +
  
  # Layer 6: Thay đổi theme (nền trắng)
  theme_bw() +
  
  # Layer 7: Ẩn chú giải (legend) của màu tô (vì đã có nhãn)
  guides(fill = "none")

✍️ Nhận xét:

  • Phát hiện chính: Biểu đồ trực quan hóa tốc độ tăng trưởng doanh thu hàng năm, cho thấy điểm bất thường (outlier) lớn nhất là sự sụt giảm tăng trưởng -45.6% vào năm 2018. Điều này có thể xuất phát từ việc thay đổi phương pháp hạch toán, tái cấu trúc, hoặc thoái vốn.

  • Hệ quả: Giá trị ngoại lai này đã kéo mức tăng trưởng trung bình 9 năm (biểu thị bằng đường gạch đỏ) xuống rất thấp, chỉ còn 8.37%.

  • Xu hướng thực: Nếu tạm bỏ qua sự kiện năm 2018, “câu chuyện” thực sự từ 2019-2024 là một xu hướng tăng trưởng rất ổn định và mạnh mẽ, duy trì đều đặn ở mức 19% đến 23%.

  • Kết luận: Hầu hết các năm gần đây (được tô màu đỏ) đều có hiệu suất tăng trưởng vượt trội so với mức trung bình (vốn đã bị bóp méo bởi dữ liệu năm 2018).

Phân tích Khả năng Sinh lời (Profitability)

Tính biến lợi nhuận gộp và lợi nhuận ròng

# (Đảm bảo fpt_analyzed đã tồn tại từ khối code trước)
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
    )
}

# Tính các Biên Lợi nhuận (Margins)
fpt_analyzed <- fpt_analyzed %>%
  mutate(
    # Tính Biên Lợi nhuận Gộp (%)
    Bien_LN_Gop_Rate = (DoanhThuThuan - GiaVon) / DoanhThuThuan * 100,
    # Tính Biên Lợi nhuận Ròng (%)
    Bien_LN_Rong_Rate = LoiNhuanSauThue / DoanhThuThuan * 100
  )

# In bảng tóm tắt 3 cột vừa tính
fpt_margins_table <- fpt_analyzed %>%
  select(Nam, Bien_LN_Gop_Rate, Bien_LN_Rong_Rate)
kable(
  fpt_margins_table,
  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
)
Bang Bien Loi nhuan Gop va Rong (%)
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

✍️ Nhận xét :

  • 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ố:
    1. 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).
    2. 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.

Trực quan hoá dữ liệu lợi nhuận gộp

library(ggrepel)

#Trực quan hóa Biên Lợi nhuận Gộp
print(
  ggplot(fpt_analyzed, aes(x = Nam, y = Bien_LN_Gop_Rate)) +
    geom_line(color = "darkgreen", size = 1.2, linetype = "dashed") +
    geom_point(color = "darkgreen", size = 3, shape = 18) +
    geom_smooth(method = "lm", se = FALSE, color = "black", linetype = "dotted") +
    geom_text_repel(aes(label = round(Bien_LN_Gop_Rate, 1)), size = 3) + 
    
    
    labs(title = "Xu huong Bien Loi nhuan Gop (%)", 
         subtitle = "Do luong hieu qua kiem soat Gia Von",
         x = "Nam", y = "Bien LN Gop (%)") +
         
    scale_y_continuous(labels = scales::percent_format(scale = 1)) +
    theme_minimal() 
)

Trực quan hoá lợi nhuận ròng

#Trực quan hóa Biên Lợi nhuận Ròng
print(
  ggplot(fpt_analyzed, aes(x = Nam, y = Bien_LN_Rong_Rate)) +
    geom_line(color = "purple", size = 1.2) +
    geom_point(color = "purple", size = 3, shape = 17) +
    geom_smooth(method = "lm", se = FALSE, color = "black", linetype = "dotted") +
    geom_text_repel(aes(label = round(Bien_LN_Rong_Rate, 1)), size = 3) + 
    
    labs(title = "Xu huong Bien Loi nhuan Rong (%)", 
         subtitle = "Loi nhuan cuoi cung sau moi chi phi",
         x = "Nam", y = "Bien LN Rong (%)") +
         
    scale_y_continuous(labels = scales::percent_format(scale = 1)) +
    
    theme_classic() 
)

  • Kết quả (Nhận xét):
  • Biểu đồ Biên LN Gộp (màu xanh lá) cho thấy một xu hướng rất ổn định và tăng nhẹ. Đường xu hướng tuyến tính (lm, chấm đen) xác nhận điều này. Đây là một dấu hiệu rất tích cực, cho thấy FPT đang kiểm soát tốt chi phí GiaVon (chi phí chính) ngay cả khi quy mô mở rộng.
  • Biểu đồ Biên LN Ròng (màu tím) cũng cho thấy xu hướng tăng trưởng đều đặn qua các năm (ví dụ: từ 6.4% năm 2015 lên 15.0% năm 2024). Đây là xác nhận cuối cùng rằng lợi nhuận cuối đang tăng nhanh hơn cả tốc độ tăng doanh thu.

Phân tích Cấu trúc Chi phí Vận hành

# (Đảm bảo fpt_analyzed đã tồn tại từ khối code trước)
if (!exists("fpt_analyzed")) {
  # ... (Khối code này giả định fpt_analyzed đã có
  # Bien_LN_Gop_Rate và Bien_LN_Rong_Rate từ Thao tác 23)
  fpt_analyzed <- fpt_ty_dong %>%
    arrange(Nam) %>%
    mutate(
      Bien_LN_Gop_Rate = (DoanhThuThuan - GiaVon) / DoanhThuThuan * 100,
      Bien_LN_Rong_Rate = LoiNhuanSauThue / DoanhThuThuan * 100
    )
}

Tính toán Tỷ lệ 3 Chi phí trên Doanh thu

  • Phân tích (Logic): Chúng ta đã thấy Biên LN Ròng (Thao tác 25) tăng. Logic tiếp theo là phải “bóc tách” các chi phí vận hành (trừ GiaVon, vì đã xem ở Biên LN Gộp) để xem FPT đã kiểm soát chúng tốt đến đâu. Chúng ta cộng dồn 3 chi phí này (BanHang, QLDN, TaiChinh) xem chúng chiếm bao nhiêu % doanh thu.
# (Đảm bảo 'fpt_analyzed' đã tồn tại từ các bước trước)
if (!exists("fpt_analyzed")) {
    # This is a fallback, assuming fpt_ty_dong exists
    fpt_analyzed <- fpt_ty_dong 
}

#  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
  )

#  Chuẩn bị dữ liệu (Xoay) để vẽ biểu đồ xếp chồng
# (Đối tượng này được tạo để dùng cho biểu đồ sau)
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"
  )

# In bảng dữ liệu chi phí (3 năm cuối)
  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
    kable(
      caption = "Ty le Chi phi tren Doanh thu (3 nam cuoi)", # Đã bỏ dấu
      digits = 2,
      col.names = c("Nam", "CP Ban Hang (%)", "CP QLDN (%)", "CP Tai Chinh (%)") # Đã bỏ dấu
    )
Ty le Chi phi tren Doanh thu (3 nam cuoi)
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

Trực quan hoá dữ liệu

  • Phân tích (Logic): Chúng ta đã thấy Biên LN Ròng (Thao tác 25) tăng. Logic tiếp theo là phải “bóc tách” các chi phí vận hành (trừ GiaVon, vì đã xem ở Biên LN Gộp) để xem FPT đã kiểm soát chúng tốt đến đâu. Chúng ta cộng dồn 3 chi phí này (BanHang, QLDN, TaiChinh) xem chúng chiếm bao nhiêu % doanh thu.
# (Đảm bảo 'fpt_cost_structure' và các thư viện 'ggplot2', 'scales' đã tồn tại)
# if (!exists("fpt_cost_structure")) { ... }

# Trực quan hóa Cấu trúc Chi phí (Biểu đồ 8 Layer)
print( # Thêm 'print()' để đảm bảo ggplot hiển thị khi Knit
  ggplot(fpt_cost_structure, aes(x = Nam, y = TyLe, fill = LoaiChiPhi)) +
    # Layer 1: Biểu đồ diện xếp chồng (stacked area)
    geom_area(alpha = 0.8, position = "stack") +
    
    # Layer 2: Thêm đường viền mỏng giữa các vùng
    geom_line(position = "stack", color = "white", size = 0.2) +
    
    # Layer 3: Thêm tiêu đề và nhãn (đã bỏ dấu)
    labs(
      title = "Phan tich Cau truc Chi phi (tinh tren % Doanh thu)",
      subtitle = "Cho thay 3 chi phi van hanh chiem bao nhieu % trong Doanh thu",
      x = "Nam", 
      y = "Ty le tren Doanh thu (%)", 
      fill = "Loai Chi phi"
    ) +
    
    # Layer 4: Đổi bảng màu (Palette)
    scale_fill_brewer(
      palette = "Pastel1",
      labels = c("TyLe_CP_BanHang_Rate" = "CP Ban Hang", 
                 "TyLe_CP_QLDN_Rate" = "CP QLDN", 
                 "TyLe_CP_TaiChinh_Rate" = "CP Tai Chinh")
    ) +
    
    # Layer 5: Định dạng trục Y (thêm dấu %)
    scale_y_continuous(labels = scales::percent_format(scale = 1)) +
    
    # Layer 6, 7 & 8: GỘP 2 LỆNH THEME LÀM MỘT
    theme_minimal() +
    theme(
      legend.position = "bottom",
      legend.text = element_text(size = 10)
    )
)

  • Kết quả (Nhận xét):

    • Biểu đồ diện xếp chồng (stacked area chart) cho thấy tổng % doanh thu bị “ăn” bởi 3 chi phí này.
    • Xu hướng TyLe_CP_QLDN_Rate (Chi phí Quản lý): Đây là điểm mấu chốt. Chúng ta có thể thấy tỷ lệ chi phí QLDN trên doanh thu (vùng màu xanh lá) có xu hướng giảm qua các năm. Đây là dấu hiệu rõ ràng của “lợi thế kinh tế theo quy mô” (Economies of Scale). Khi FPT lớn mạnh, chi phí quản lý “đầu não” không tăng nhanh bằng doanh thu, giúp cải thiện Biên LN Ròng.
    • Xu hướng TyLe_CP_BanHang_Rate (Chi phí Bán hàng): Vùng này (màu hồng) có vẻ khá ổn định, nghĩa là FPT không phải “đốt” quá nhiều tiền cho quảng cáo để có doanh thu.
    • Xu hướng TyLe_CP_TaiChinh_Rate (Chi phí Tài chính): Vùng này (màu cam) có vẻ tăng nhẹ, có thể do công ty vay nợ nhiều hơn (chúng ta sẽ kiểm tra ở phần sau).
  • Kết luận: Động lực chính giúp Biên Lợi nhuận Ròng tăng ) đến từ việc FPT quản lý Chi phí QLDN ngày càng hiệu quả khi quy mô công ty lớn lên.

  • Câu hỏi tiếp theo: Chúng ta đã phân tích rất kỹ “Phần nổi” (Báo cáo Kết quả Kinh doanh - P&L). Bây giờ, chúng ta phải lặn xuống “Phần chìm” (Bảng Cân đối Kế toán - Balance Sheet) để trả lời câu hỏi: “FPT đã dùng Tài sản hiệu quả đến đâu để tạo ra doanh thu và lợi nhuận này?”. Điều này dẫn chúng ta đến Thao tác 30: Vòng quay Tổng Tài sản.

Phân tích Hiệu quả Sử dụng Tài sản

  • Mở đầu Chúng ta đã phân tích rất kỹ “Phần nổi” (Báo cáo Kết quả Kinh doanh - P&L). Bây giờ, chúng ta phải lặn xuống “Phần chìm” (Bảng Cân đối Kế toán - Balance Sheet) để trả lời câu hỏi: “FPT đã dùng Tài sản hiệu quả đến đâu để tạo ra doanh thu và lợi nhuận này?”. Điều này dẫn chúng ta đến : Vòng quay Tổng Tài sản.
# (Dam bao 'fpt_analyzed' da ton tai tu cac buoc truoc)
if (!exists("fpt_analyzed")) {
    fpt_analyzed <- fpt_ty_dong 
    # (Day la mot fallback don gian, gia dinh fpt_analyzed da co cac cot truoc)
}

Thao tac 30 & 31: Tinh Tong Tai San va Vong quay TTS

* **MỤC ĐÍCH** tính toán `TongTaiSan` (Tỷ đồng) và `VongQuay_TTS` (số lần). Chỉ số này cho biết 1 đồng Tài sản tạo ra được bao nhiêu đồng Doanh thu.
# Chung ta gop 2 buoc tinh toan vao mot ham 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
  )

#  In bang ket qua
fpt_turnover_table <- fpt_analyzed %>%
  select(Nam, TongTaiSan, VongQuay_TTS)

# In bang dep (goi kable() truc tiep, khong dung print())
kable(
  fpt_turnover_table,
  caption = "Bang Tong Tai San va Vong quay TTS (lan)", # Da bo dau
  digits = 2,
  col.names = c("Nam", "Tong Tai San (Ty dong)", "Vong quay TTS (lan)") # Da bo dau
)
Bang Tong Tai San va Vong quay TTS (lan)
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á dữ liệu

# 2. Dam bao 'fpt_analyzed' va 'VongQuay_TTS' ton tai
if (!exists("fpt_analyzed") || !"VongQuay_TTS" %in% names(fpt_analyzed)) {
    fpt_analyzed <- fpt_ty_dong %>%
      mutate(
        TongTaiSan = TaiSanNganHan + TaiSanDaiHan,
        VongQuay_TTS = DoanhThuThuan / TongTaiSan
      )
}

# Tinh gia tri trung binh
avg_turnover <- mean(fpt_analyzed$VongQuay_TTS)

# 3. Truc quan hoa 
print(
  ggplot(fpt_analyzed, aes(x = Nam, y = VongQuay_TTS)) +
    
    # --- PHAN SUA CHINH DE TAO CHU THICH ---
    
    # Layer 1: Ve duong (DAT 'color' BEN TRONG aes())
    # Ta noi voi ggplot: "Gia tri 'color' duoc quyet dinh boi bien 'Vong quay TTS (Thuc te)'"
    geom_line(aes(color = "Vong quay TTS (Thuc te)"), size = 1.2) +
    
    # Layer 3: Ve duong xu huong (DAT 'color' BEN TRONG aes())
    # Ta noi: "Gia tri 'color' duoc quyet dinh boi bien 'Xu huong (Tuyen tinh)'"
    geom_smooth(aes(color = "Xu huong (Tuyen tinh)"), method = "lm", se = FALSE, linetype = "dotted") +
    
    # --- Cac layer khac giu nguyen ---
    geom_point(color = "darkorange", size = 3, shape = 15) + # Layer 2
    geom_text_repel(aes(label = round(VongQuay_TTS, 2)), size = 3.5) + # Layer 4
    
    labs(
      title = "Xu huong Vong quay Tong Tai san (Asset Turnover)", # Layer 5
      subtitle = "1 dong Tai san tao ra bao nhieu dong Doanh thu",
      x = "Nam",
      y = "So lan (Doanh thu / Tong Tai san)",
      color = "Chu Thich" # <-- Tieu de cho hop chu thich
    ) +
    
    theme_light() + # Layer 6
    
    # Layer 7: Duong trung binh (ve thu cong)
    geom_hline(yintercept = avg_turnover, linetype = "dashed", color = "blue") +
    
    # Layer 8 (MOI): Chu thich thu cong cho duong trung binh
    annotate("text", x = 2016, y = avg_turnover, 
             label = "Trung binh 10 nam", color = "blue", vjust = -0.5) +
             
    # Layer 9 (MOI): Dinh nghia mau cho chu thich
    # Ta noi: "Neu bien la 'Vong quay...', hay to mau orange. Neu la 'Xu huong...', hay to mau den."
    scale_color_manual(
      name = "Chu Thich", # Tieu de hop chu thich
      values = c("Vong quay TTS (Thuc te)" = "orange", 
                 "Xu huong (Tuyen tinh)" = "black")
    )
)

  • Kết quả (Nhận xét):
* **Xu hướng:** Biểu đồ đường (màu cam) cho thấy xu hướng của Vòng quay Tài sản. Đường xu hướng tuyến tính (`lm`, chấm đen) có vẻ đi ngang hoặc giảm nhẹ.
* Điều này có nghĩa là `TongTaiSan` đang tăng nhanh hơn (hoặc tương đương) với `DoanhThuThuan`. Đây không hẳn là xấu. Nó có thể ám chỉ FPT đang trong chu kỳ **đầu tư mạnh** vào tài sản dài hạn (ví dụ: xây văn phòng, trung tâm dữ liệu) và những tài sản này cần thời gian để bắt đầu tạo ra doanh thu tương xứng (chúng ta sẽ kiểm tra điều này ở phần Cấu trúc Tài sản).

Phân tích Đòn bẩy Tài chính (Leverage)

  • DẪN CHỨNG Chúng ta đã biết FPT đầu tư vào Tài sản như thế nào. Vậy FPT lấy tiền ở đâu để tài trợ cho số Tài sản đó? Từ Nợ (Liabilities) hay từ Vốn Chủ Sở Hữu (Equity)? Điều này dẫn chúng ta đến phân tích Đòn bẩy Tài chính (Leverage).
# 2. Dam bao 'fpt_analyzed' (voi TongTaiSan) ton tai
# (Neu khong, code se bi loi 'object not found')
if (!exists("fpt_analyzed") || !"TongTaiSan" %in% names(fpt_analyzed)) {
    fpt_analyzed <- fpt_ty_dong %>%
      mutate(
        TongTaiSan = TaiSanNganHan + TaiSanDaiHan
      )
}

tính toán

# Tinh Ty le No tren Tong Tai san
fpt_analyzed <- fpt_analyzed %>%
  mutate(
    TyLe_No_tren_TTS_Rate = (NoPhaiTra / TongTaiSan) * 100
  )
  
# In bang ket qua
fpt_leverage_table <- fpt_analyzed %>%
  select(Nam, TongTaiSan, NoPhaiTra, TyLe_No_tren_TTS_Rate)

# In bang dep (goi kable() truc tiep)
kable(
  fpt_leverage_table,
  caption = "Bang Ty le No tren Tong Tai san", # Da bo dau
  digits = 2,
  col.names = c("Nam", "Tong Tai San (Ty dong)", "No Phai Tra (Ty dong)", "Ty le No/TTS (%)") # Da bo dau
)
Bang Ty le No tren Tong Tai san
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

TRực quan hoá dữ liệu

# 1. Tai cac thu vien can thiet
library(ggplot2)
library(ggrepel) # Cho geom_text_repel()
library(dplyr)   # Cho mutate()
library(scales)  # Cho percent_format()

# 2. Dam bao 'fpt_analyzed' (voi TyLe_No_tren_TTS_Rate) ton tai
if (!exists("fpt_analyzed") || !"TyLe_No_tren_TTS_Rate" %in% names(fpt_analyzed)) {
    fpt_analyzed <- fpt_ty_dong %>%
      mutate(
        TongTaiSan = TaiSanNganHan + TaiSanDaiHan,
        TyLe_No_tren_TTS_Rate = (NoPhaiTra / TongTaiSan) * 100
      )
}

# Tinh gia tri trung binh
avg_leverage <- mean(fpt_analyzed$TyLe_No_tren_TTS_Rate)

# 3. Truc quan hoa (DA THEM CHU THICH)
print(
  ggplot(fpt_analyzed, aes(x = Nam, y = TyLe_No_tren_TTS_Rate)) +
    
    # --- PHAN SUA CHINH DE TAO CHU THICH ---
    
    # Layer 1: Ve duong (DAT 'color' BEN TRONG aes())
    geom_line(aes(color = "Ty le No thuc te (%)"), size = 1.2) +
    
    # Layer 3: Ve duong xu huong (DAT 'color' BEN TRONG aes())
    geom_smooth(aes(color = "Xu huong (Tuyen tinh)"), method = "lm", se = FALSE, linetype = "dotted") +
    
    # --- Cac layer khac giu nguyen ---
    geom_point(color = "darkred", size = 3, shape = 17) + # Layer 2
    geom_text_repel(aes(label = round(TyLe_No_tren_TTS_Rate, 1)), size = 3.5) + # Layer 4
    
    # Layer 5: Tieu de (da bo dau)
    labs(
      title = "Xu huong Ty le No tren Tong Tai san (%)",
      subtitle = "Bao nhieu % Tai san duoc tai tro bang No",
      x = "Nam",
      y = "Ty le No (%)",
      color = "Chu Thich" # Tieu de hop chu thich
    ) +
    
    # Layer 6: Dinh dang truc Y (them dau %)
    scale_y_continuous(labels = scales::percent_format(scale = 1)) +
    
    # Layer 7: Duong trung binh (ve thu cong)
    geom_hline(yintercept = avg_leverage, linetype = "dashed", color = "blue") +
    
    # Layer 8 (MOI): Chu thich thu cong cho duong trung binh
    annotate("text", x = 2016, y = avg_leverage, 
             label = "Trung binh 10 nam", color = "blue", vjust = -0.5) +
             
    # Layer 9 (MOI): Dinh nghia mau cho chu thich
    scale_color_manual(
      name = "Chu Thich", # Tieu de hop chu thich
      values = c("Ty le No thuc te (%)" = "red", 
                 "Xu huong (Tuyen tinh)" = "black")
    ) +
    
    # Layer 10: Theme
    theme_classic()
)

  • Kết quả (Nhận xét):
* **Xu hướng ):** Biểu đồ đường (màu đỏ) cho thấy xu hướng FPT sử dụng nợ. Đường xu hướng tuyến tính (`lm`, chấm đen) cho thấy xu hướng tổng thể là... (tăng/giảm/đi ngang - *tùy vào dữ liệu của bạn*).
* **Đánh giá:** Một tỷ lệ nợ cao (ví dụ, > 60-70%) không nhất thiết là xấu nếu công ty quản lý tốt, nhưng nó *tiềm ẩn rủi ro* (ví dụ: `ChiPhiTaiChinh` sẽ tăng, như chúng ta đã thấy ở Thao tác 29). Ngược lại, một tỷ lệ nợ quá thấp có thể cho thấy FPT "thận trọng" và chưa tận dụng hết lợi ích của "lá chắn thuế" từ nợ vay.

Phân tích Tổng hợp (ROA & ROE)

# 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
      )
}

Tinh Ty suat Sinh loi tren Tai san (ROA)

fpt_analyzed <- fpt_analyzed %>%
  mutate(ROA_Rate = LoiNhuanSauThue / TongTaiSan * 100) # <-- DA SUA 'a' thanh 'u'

# Thao tac 38: In bang ket qua cho ROA
fpt_roa_table <- fpt_analyzed %>%
  select(Nam, LoiNhuanSauThue, TongTaiSan, ROA_Rate) # <-- DA SUA 'a' thanh 'u'

# In bang dep
kable(
  fpt_roa_table,
  caption = "Bang Tinh toan Ty suat Sinh loi tren Tai san (ROA)", 
  digits = 2,
  col.names = c("Nam", "Loi nhuan Sau thue (Ty dong)", "Tong Tai san (Ty dong)", "ROA (%)")
)
Bang Tinh toan Ty suat Sinh loi tren Tai san (ROA)
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)

TRực quan hoá dữ liệu

print(
  ggplot(fpt_analyzed, aes(x = Nam, y = ROA_Rate)) +
    geom_line(aes(color = "ROA Thuc te (%)"), size = 1.2) + 
    geom_smooth(aes(color = "Xu huong (Tuyen tinh)"), method = "lm", se = FALSE, linetype = "dotted") + 
    geom_point(color = "blue", size = 3, shape = 18) + 
    geom_text_repel(aes(label = round(ROA_Rate, 1)), size = 3.5) + 
    labs(
      title = "Xu huong Ty suat Sinh loi tren Tong Tai san (ROA %)",
      subtitle = "100 dong Tai san tao ra bao nhieu dong Loi nhuan",
      x = "Nam", y = "ROA (%)", color = "Chu Thich" 
    ) +
    scale_y_continuous(labels = scales::percent_format(scale = 1)) +
    geom_hline(yintercept = avg_roa, linetype = "dashed", color = "darkgreen") +
    annotate("text", x = 2016, y = avg_roa, 
             label = "Trung binh 10 nam", color = "darkgreen", vjust = -0.5) +
    scale_color_manual(
      name = "Chu Thich",
      values = c("ROA Thuc te (%)" = "blue", "Xu huong (Tuyen tinh)" = "black")
    ) +
    theme_bw()
)

  • Kết quả (Nhận xét):
* **Thao tác 37 & 38** tính toán và lập bảng $ROA$ hàng năm.
* **Xu hướng (Thao tác 39):** Biểu đồ $ROA$ (đường màu xanh) cho thấy xu hướng tăng trưởng rõ rệt, được xác nhận bởi đường xu hướng tuyến tính (chấm đen).
* **Lý giải:** Mặc dù **Vòng quay Tài sản** (Thao tác 33) có xu hướng *giảm nhẹ* (do FPT đầu tư nhiều), nhưng **Biên Lợi nhuận Ròng** (Thao tác 25) đã *tăng rất mạnh* (do kiểm soát tốt chi phí QLDN). Sự cải thiện vượt bậc về Biên Lợi nhuận đã "gánh" cho sự sụt giảm hiệu quả tài sản, giúp $ROA$ tổng thể vẫn tăng trưởng tốt.

# 2. Dam bao 'fpt_analyzed' va cac cot can thiet ton tai
if (!exists("fpt_analyzed") || !"TongTaiSan" %in% names(fpt_analyzed) || !"NoPhaiTra" %in% names(fpt_analyzed)) {
    fpt_analyzed <- fpt_ty_dong %>%
      mutate(
        TongTaiSan = TaiSanNganHan + TaiSanDaiHan,
        NoPhaiTra = NoPhaiTra 
      )
}
# Thao tac 40: Tinh Von Chu So Huu (Equity) va ROE
fpt_analyzed <- fpt_analyzed %>%
  mutate(
    VonChuSoHuu = TongTaiSan - NoPhaiTra,
    ROE_Rate = LoiNhuanSauThue / VonChuSoHuu * 100 # <-- DA SUA 'a' thanh 'u'
  )
  
# Thao tac 41: In bang ket qua cho ROE
fpt_roe_table <- fpt_analyzed %>%
  select(Nam, LoiNhuanSauThue, VonChuSoHuu, ROE_Rate) # <-- DA SUA 'a' thanh 'u'

# In bang dep
kable(
  fpt_roe_table,
  caption = "Bang Tinh toan Ty suat Sinh loi tren Von CSH (ROE)", 
  digits = 2,
  col.names = c("Nam", "Loi nhuan Sau thue (Ty dong)", "Von CSH (Ty dong)", "ROE (%)")
)
Bang Tinh toan Ty suat Sinh loi tren Von CSH (ROE)
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
# Tinh gia tri trung binh cho ROE
avg_roe <- mean(fpt_analyzed$ROE_Rate)

Trực quan hoá dũ liệu

print(
  ggplot(fpt_analyzed, aes(x = Nam, y = ROE_Rate)) +
    geom_line(aes(color = "ROE Thuc te (%)"), size = 1.2) + 
    geom_smooth(aes(color = "Xu huong (Tuyen tinh)"), method = "lm", se = FALSE, linetype = "dotted") + 
    geom_point(color = "darkviolet", size = 3, shape = 15) + 
    geom_text_repel(aes(label = round(ROE_Rate, 1)), size = 3.5) + 
    labs(
      title = "Xu huong Ty suat Sinh loi tren Von Chu So Huu (ROE %)",
      subtitle = "100 dong Von CSH tao ra bao nhieu dong Loi nhuan",
      x = "Nam", y = "ROE (%)", color = "Chu Thich" 
    ) +
    scale_y_continuous(labels = scales::percent_format(scale = 1)) +
    geom_hline(yintercept = avg_roe, linetype = "dashed", color = "darkorange") +
    annotate("text", x = 2016, y = avg_roe, 
             label = "Trung binh 10 nam", color = "darkorange", vjust = -0.5) +
    scale_color_manual(
      name = "Chu Thich",
      values = c("ROE Thuc te (%)" = "darkviolet", 
                 "Xu huong (Tuyen tinh)" = "black")
    ) +
    theme_light()
)

  • Kết quả (Nhận xét):
* **Thao tác 37 & 38** tính toán và lập bảng $ROA$ hàng năm.
* **Xu hướng (Thao tác 39):** Biểu đồ $ROA$ (đường màu xanh) cho thấy xu hướng tăng trưởng rõ rệt, được xác nhận bởi đường xu hướng tuyến tính (chấm đen).
* **Lý giải:** Mặc dù **Vòng quay Tài sản** (Thao tác 33) có xu hướng *giảm nhẹ* (do FPT đầu tư nhiều), nhưng **Biên Lợi nhuận Ròng** (Thao tác 25) đã *tăng rất mạnh* (do kiểm soát tốt chi phí QLDN). Sự cải thiện vượt bậc về Biên Lợi nhuận đã "gánh" cho sự sụt giảm hiệu quả tài sản, giúp $ROA$ tổng thể vẫn tăng trưởng tốt.
  • Kết luận: FPT đang vận hành ngày càng hiệu quả, tạo ra nhiều lợi nhuận hơn trên mỗi đồng tài sản mà công ty sở hữu.

Phân tích Chất lượng Dòng tiền (Cash Flow Quality)

  • Câu hỏi tiếp theo: Chúng ta đã kết luận FPT làm ăn rất tốt trên “giấy tờ” (Báo cáo KQKD, Bảng CĐKT). Nhưng liệu “Lợi nhuận” đó có phải là “Tiền mặt” thật không? Bước cuối cùng là kiểm tra Chất lượng Dòng tiền
# 1. Tai cac thu vien can thiet
library(dplyr)
library(knitr)
library(ggplot2)
library(ggrepel)   # Cho geom_text_repel()
library(scales)    # Cho percent_format()
library(tidyr)     # Cho pivot_longer()

# 2. Dam bao 'fpt_analyzed' va cac cot can thiet ton tai
# (Code da duoc don dep ky tu la)
if (!exists("fpt_analyzed") || !"LuuChuyenTienHDKD" %in% names(fpt_analyzed)) {
    fpt_analyzed <- fpt_ty_dong 
}

# Thao tac 43: Chuan bi du lieu (Xoay) de ve bieu do so sanh
fpt_cash_profit <- fpt_analyzed %>%
  select(Nam, LoiNhuanSauThue, LuuChuyenTienHDKD) %>%
  pivot_longer(
    cols = -Nam, 
    names_to = "ChiTieu", 
    values_to = "GiaTri"
  )

TRực quan hoá

print(
  ggplot(fpt_cash_profit, aes(x = Nam, y = GiaTri, color = ChiTieu)) +
    # Layer 1: Ve duong
    geom_line(aes(linetype = ChiTieu), size = 1.2) +
    
    # Layer 2: Ve diem
    geom_point(aes(shape = ChiTieu), size = 3.5) +
    
    # Layer 3: Duong moc 0
    geom_hline(yintercept = 0, linetype = "dotted", color = "black") +
    
    # Layer 4: Tieu de (DA BO DAU de tranh loi Encoding)
    labs(
      title = "Chat luong Loi nhuan: Loi nhuan (Ke toan) vs. Dong tien (Thuc te)",
      subtitle = "Ly tuong nhat: Duong 'Tien' (xanh) phai luon bang hoac cao hon duong 'Loi nhuan' (do)",
      x = "Nam", y = "Gia tri (Ty dong)", 
      color = "Chu Thich", linetype = "Chu Thich", shape = "Chu Thich"
    ) +
    
    # Layer 5: Dinh nghia mau thu cong
    scale_color_manual(
      labels = c("LuuChuyenTienHDKD" = "Dong tien tu HDKD (Thuc te)", # Da bo dau
                 "LoiNhuanSauThue" = "Loi nhuan Sau thue (Ke toan)"), # Da bo dau
      values = c("LuuChuyenTienHDKD" = "blue", 
                 "LoiNhuanSauThue" = "red")
    ) +
    
    # Layer 6: Dinh nghia kieu duong
    scale_linetype_manual(
      labels = c("LuuChuyenTienHDKD" = "Dong tien tu HDKD (Thuc te)", # Da bo dau
                 "LoiNhuanSauThue" = "Loi nhuan Sau thue (Ke toan)"), # Da bo dau
      values = c("LuuChuyenTienHDKD" = "dashed", # Duong gach
                 "LoiNhuanSauThue" = "solid")  # Duong lien
    ) +
    
    # Layer 7: Dinh nghia hinh dang diem
    scale_shape_manual(
      labels = c("LuuChuyenTienHDKD" = "Dong tien tu HDKD (Thuc te)", # Da bo dau
                 "LoiNhuanSauThue" = "Loi nhuan Sau thue (Ke toan)"), # Da bo dau
      values = c("LuuChuyenTienHDKD" = 17, # Hinh tam giac
                 "LoiNhuanSauThue" = 16) # Hinh tron
    ) +
    
    # Layer 8: Theme
    theme_minimal() +
    
    # Layer 9: Vi tri chu giai
    theme(legend.position = "top") +
    
    # Layer 10: Them nhan cho cac diem
    geom_text_repel(aes(label = round(GiaTri, 0)), size = 3)
)

#### tỷ lệ chuyển đổi tiền mặt

# 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)

kable(
  fpt_cash_table,
  caption = "Bang Ty le Chuyen doi Tien mat (Cash Conversion Ratio)", # Da bo dau
  digits = 2,
  col.names = c("Nam", "Loi nhuan (Ty dong)", "Dong tien HDKD (Ty dong)", "Ty le (Tien/Loi nhuan)") # Da bo dau
)
Bang Ty le Chuyen doi Tien mat (Cash Conversion Ratio)
Nam Loi nhuan (Ty dong) Dong tien HDKD (Ty dong) Ty le (Tien/Loi nhuan)
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

Trực quan hoá

# 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 (da bo dau)
    labs(
      title = "Ty le Chuyen doi Loi nhuan thanh Tien",
      subtitle = "Moc 1 = Dong tien bang Loi nhuan. Tot nhat la > 1.",
      x = "Nam",
      y = "Ty le (Dong tien / Loi nhuan)"
    ) +
    
    # Layer 5: Dinh nghia mau thu cong (TRUE = xanh, FALSE = xam)
    scale_fill_manual(
      name = "Chat luong Loi nhuan",
      values = c("TRUE" = "darkgreen", "FALSE" = "gray50"),
      labels = c("TRUE" = "Tot (> 1)", "FALSE" = "Kem (< 1)")
    ) +
    
    # Layer 6: Theme
    theme_classic() +
    
    # Layer 7: Chu thich thu cong cho duong moc 1
    annotate("text", x = 1.5, y = 1.05, label = "Moc 100%", color = "red", vjust = -0.5) +
    
    # Layer 8: Di chuyen chu giai
    theme(legend.position = "top")
)

Phân tích Cấu trúc TÀI SẢN (Asset Structure)

# 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)
kable(
  head(fpt_asset_structure, 4),
  caption = "Du lieu Cau truc Tai san da duoc 'xoay'", # Da bo dau
  digits = 0
)
Du lieu Cau truc Tai san da duoc ‘xoay’
Nam LoaiTaiSan GiaTri
2015 TaiSanNganHan 18959
2015 TaiSanDaiHan 7087
2016 TaiSanNganHan 21909
2016 TaiSanDaiHan 7925

Trực quan hoá dữ liệu

library(ggplot2)

print(
  ggplot(fpt_asset_structure, aes(x = Nam, y = GiaTri, fill = LoaiTaiSan)) +
    # Layer 1: Bieu do cot 100% (position = "fill")
    # 'position="fill"' tu dong tinh toan ty le %
    geom_bar(stat = "identity", position = "fill", alpha = 0.8) +
    
    # Layer 2: Them duong vien trang ngan cach
    geom_bar(stat = "identity", position = "fill", color = "white", size = 0.1, show.legend = FALSE) +
    
    # Layer 3: Them nhan % (ky thuat nang cao)
    geom_text(
      # '..y..' la mot bien dac biet, lay gia tri % da duoc tinh toan
      aes(label = scales::percent(..y.., accuracy = 1)),
      position = position_fill(vjust = 0.5), # Dat nhan o giua khoi
      stat = "identity",
      size = 3.5
    ) +
    
    # Layer 4: Tieu de (da bo dau)
    labs(
      title = "Phan tich Cau truc Tai san (2015-2024)",
      subtitle = "Ty trong Tai san Ngan han (TSNH) vs. Tai san Dai han (TSDH)",
      x = "Nam",
      y = "Ty trong (%)",
      fill = "Loai Tai san"
    ) +
    
    # Layer 5: Dinh dang truc Y (thanh dau %)
    scale_y_continuous(labels = scales::percent_format()) +
    
    # Layer 6: Doi bang mau
    scale_fill_brewer(
      palette = "Set2", # Palette mau
      labels = c("TaiSanDaiHan" = "Tai san Dai han", "TaiSanNganHan" = "Tai san Ngan han")
    ) +
    
    # Layer 7: Theme
    theme_minimal() +
    
    # Layer 8: Vi tri chu giai
    theme(legend.position = "top")
)

Phân tích Cấu trúc NGUỒN VỐN (Capital Structure)

# 2. Dam bao 'fpt_analyzed' va cac cot can thiet ton tai
# (VonChuSoHuu da duoc tinh o Thao tac 40)
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)
kable(
  head(fpt_capital_structure, 4),
  caption = "Du lieu Cau truc Nguon von da duoc 'xoay'", # Da bo dau
  digits = 0
)
Du lieu Cau truc Nguon von da duoc ‘xoay’
Nam LoaiNguonVon GiaTri
2015 NoPhaiTra 15863
2015 VonChuSoHuu 10182
2016 NoPhaiTra 18385
2016 VonChuSoHuu 11448

Trực quan hoá dữ liệu

print(
  ggplot(fpt_capital_structure, aes(x = Nam, y = GiaTri, fill = LoaiNguonVon)) +
    # Layer 1: Bieu do cot 100% (position = "fill")
    geom_bar(stat = "identity", position = "fill", alpha = 0.8) +
    
    # Layer 2: Them duong vien trang
    geom_bar(stat = "identity", position = "fill", color = "white", size = 0.1, show.legend = FALSE) +
    
    # Layer 3: Them nhan %
    geom_text(
      aes(label = scales::percent(..y.., accuracy = 1)),
      position = position_fill(vjust = 0.5),
      stat = "identity",
      size = 3.5,
      color = "black"
    ) +
    
    # Layer 4: Tieu de (da bo dau)
    labs(
      title = "Phan tich Cau truc Nguon von (2015-2024)",
      subtitle = "Ty trong No Phai Tra vs. Von Chu So Huu (VCSH)",
      x = "Nam",
      y = "Ty trong (%)",
      fill = "Loai Nguon von"
    ) +
    
    # Layer 5: Dinh dang truc Y
    scale_y_continuous(labels = scales::percent_format()) +
    
    # Layer 6: Doi mau thu cong (Do = No, Xanh = Von)
    scale_fill_manual(
      labels = c("NoPhaiTra" = "No Phai Tra", "VonChuSoHuu" = "Von Chu So Huu"),
      values = c("NoPhaiTra" = "#E41A1C", "VonChuSoHuu" = "#377EB8") # Do va Xanh
    ) +
    
    # Layer 7: Theme
    theme_minimal() +
    
    # Layer 8: Vi tri chu giai
    theme(legend.position = "top")
)

Tính toán & Trực quan hóa Ma trận Tương quan

library(reshape2)

# 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"
kable(
  head(melted_corr, 4),
  caption = "Du lieu ma tran tuong quan da 'melt'",
  digits = 2,
  col.names = c("Bien 1", "Bien 2", "Gia tri Tuong quan")
)
Du lieu ma tran tuong quan da ‘melt’
Bien 1 Bien 2 Gia tri Tuong quan
DoanhThuThuan DoanhThuThuan 1.00
GiaVon DoanhThuThuan 0.91
ChiPhiBanHang DoanhThuThuan 0.90
ChiPhiQLDN DoanhThuThuan 0.66

Trực quan hoá dữ liệu

print(
  ggplot(melted_corr, aes(x = Var1, y = Var2, fill = value)) +
    # Layer 1: Ve cac o (tile)
    geom_tile(color = "white") +
    
    # Layer 2: Them nhan (so tuong quan)
    geom_text(aes(label = round(value, 2)), color = "black", size = 3) +
    
    # Layer 3: Dinh nghia dai mau (Do -> Trang -> Xanh)
    scale_fill_gradient2(
      low = "blue",        # Mau cho tuong quan am
      high = "red",         # Mau cho tuong quan duong
      mid = "white",        # Mau cho tuong quan = 0
      midpoint = 0,           # Dat so 0 o giua
      limit = c(-1, 1),       # Gioi han tu -1 den 1
      name = "Tuong quan\nPearson" # Ten chu giai (bo dau)
    ) +
    
    # Layer 4: Theme
    theme_minimal() +
    
    # Layer 5: Tieu de (da bo dau)
    labs(
      title = "Bieu do nhiet Ma tran Tuong quan",
      subtitle = "Moi quan he tuyen tinh giua cac bien tai chinh",
      x = "", y = ""
    ) +
    
    # Layer 6: Giu ty le cac o vuong
    coord_fixed() +
    
    # Layer 7: Xoay nhan truc X 45 do
    theme(axis.text.x = element_text(angle = 45, vjust = 1, hjust = 1)) +
    
    # Layer 8: Vi tri chu giai
    theme(legend.position = "right")
)

Tính toán, Lập bảng & Trực quan hóa 3 yếu tố tác động đến ROE

library(tidyr)     # Cho pivot_longer()

# 2. Dam bao 'fpt_analyzed' va cac cot can thiet ton tai
# (Dam bao cac cot tinh o buoc truoc da co)
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 (da co, nhung tinh lai ro hon)
    DuPont_BienLN = Bien_LN_Rong_Rate / 100, # (Dua ve so thap phan)
    
    # Yeu to 2: Vong quay Tong Tai san (da co)
    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
fpt_dupont_table <- fpt_dupont %>%
  select(Nam, DuPont_BienLN, DuPont_VongQuay, DuPont_DonBay, ROE_Rate, ROE_DuPont_Check)

kable(
  fpt_dupont_table,
  caption = "Bang boc tach ROE theo 3 yeu to DuPont", # Da bo dau
  digits = 3, # Hien thi 3 chu so thap phan
  col.names = c("Nam", "Bien LN Rong (lan)", "Vong quay TS (lan)", "Don bay TC (lan)", "ROE Goc (%)", "ROE DuPont (%)")
)
Bang boc tach ROE theo 3 yeu to DuPont
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

Trực quan hoá dữ liệu

# 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: Ve duong
    geom_line(aes(color = YeuTo_DuPont), size = 1.2) +
    
    # Layer 2: Ve diem
    geom_point(aes(color = YeuTo_DuPont), size = 3) +
    
    # Layer 3: Tieu de (da bo dau)
    labs(
      title = "Phan tich DuPont: 3 Yeu to cau thanh ROE",
      subtitle = "ROA = Bien LN * Vong quay | ROE = ROA * Don bay",
      x = "Nam", y = "Gia tri (So lan)"
    ) +
    
    # Layer 4: Ham FACET (chia thanh 3 bieu do con)
    # 'scales = "free_y"' la mau chot, vi 3 bien co 3 thang do khac nhau
    facet_wrap(~ YeuTo_DuPont, ncol = 3, scales = "free_y") +
    
    # Layer 5: Theme
    theme_bw() +
    
    # Layer 6: An chu giai (vi facet da co tieu de)
    theme(legend.position = "none")
)

Biên Dòng tiền Hoạt động (CFO Margin): (So sánh Dòng tiền với Doanh thu)

library(ggrepel)   # Cho geom_text_repel()
library(scales)    # Cho percent_format()
library(tidyr)     # Cho pivot_longer()

# 2. Dam bao 'fpt_analyzed' va cac cot can thiet ton tai
# (Dam bao 'Bien_LN_Rong_Rate' da duoc tinh)
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
kable(
  fpt_margin_compare %>% head(6), # In 6 dong dau
  caption = "So sanh Bien Loi nhuan Rong va Bien Dong tien HDKD",
  digits = 2,
  col.names = c("Nam", "Loai Bien (%)", "Ty le (%)")
)
So sanh Bien Loi nhuan Rong va Bien Dong tien HDKD
Nam Loai Bien (%) Ty le (%)
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

Trực quan hoá dữ liệu

print(
  ggplot(fpt_margin_compare, aes(x = Nam, y = TyLe, fill = LoaiBien)) +
    # Layer 1 & 2: Ve bieu do cot (Bar plot) cho ca 2 bien
    # 'position="dodge"' dat 2 cot canh nhau
    geom_bar(stat = "identity", position = "dodge", alpha = 0.8) +
    
    # Layer 3: Them nhan gia tri (dung geom_text)
    geom_text(
      aes(label = round(TyLe, 1)), 
      position = position_dodge(width = 0.9), # Phai trung voi position cua cot
      vjust = -0.5, # Day nhan len tren
      size = 3
    ) +
    
    # Layer 4: Tieu de (da bo dau)
    labs(
      title = "So sanh Bien Loi nhuan Rong (Ke toan) vs. Bien Dong tien (Tien mat)",
      subtitle = "Khoang cach (Gap) giua 2 cot cang lon, chat luong loi nhuan cang thap",
      x = "Nam",
      y = "Ty le (%) so voi Doanh thu",
      fill = "Loai Bien (Margin)"
    ) +
    
    # Layer 5: Dinh dang truc Y
    scale_y_continuous(labels = scales::percent_format(scale = 1)) +
    
    # Layer 6: Doi mau thu cong
    scale_fill_manual(
      labels = c("Bien_LN_Rong_Rate" = "Bien Loi nhuan Rong (Ke toan)", 
                 "CFO_Margin_Rate" = "Bien Dong tien HDKD (Tien mat)"),
      values = c("Bien_LN_Rong_Rate" = "#F8766D", # Mau do nhat
                 "CFO_Margin_Rate" = "#00BFC4")  # Mau xanh nhat
    ) +
    
    # Layer 7: Duong moc 0
    geom_hline(yintercept = 0, color = "black") +
    
    # Layer 8: Theme
    theme_minimal() +
    
    # Layer 9: Vi tri chu giai
    theme(legend.position = "top")
)

Tính toán, Lập bảng & Trực quan hóa CFO-to-Debt

library(ggrepel)   # Cho geom_text_repel()

# 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)

kable(
  fpt_debt_coverage_table,
  caption = "Bang Kha nang tra no bang Dong tien HDKD", # Da bo dau
  digits = 2,
  col.names = c("Nam", "Dong tien HDKD (Ty dong)", "Tong No (Ty dong)", "Ty le Tra No (%)")
)
Bang Kha nang tra no bang Dong tien HDKD
Nam Dong tien HDKD (Ty dong) Tong No (Ty dong) Ty le Tra No (%)
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

Trực quan hoá dữ liệu

print(
  ggplot(fpt_analyzed, aes(x = Nam, y = CFO_to_Debt_Rate)) +
    # Layer 1: Ve duong
    geom_line(color = "brown", size = 1.2) +
    
    # Layer 2: Ve diem
    geom_point(color = "brown", size = 3, shape = 18) +
    
    # Layer 3: Them duong xu huong (Linear Model)
    # 'method = "lm"' ve duong hoi quy tuyen tinh
    geom_smooth(method = "lm", se = FALSE, color = "black", linetype = "dotted") +
    
    # Layer 4: Them nhan (dung ggrepel)
    geom_text_repel(aes(label = round(CFO_to_Debt_Rate, 1)), size = 3.5) +
    
    # Layer 5: Tieu de (da bo dau)
    labs(
      title = "Phan tich Kha nang Tra no (CFO / Tong No)",
      subtitle = "Ty le nay cang cao, rui ro tai chinh cang thap",
      x = "Nam",
      y = "Ty le Tra No (%)"
    ) +
    
    # Layer 6: Dinh dang truc Y
    scale_y_continuous(labels = scales::percent_format(scale = 1)) +
    
    # Layer 7: Them duong trung binh
    geom_hline(yintercept = mean(fpt_analyzed$CFO_to_Debt_Rate), 
               linetype = "dashed", color = "blue") +
    
    # Layer 8: Theme
    theme_light()
)