1 Phần 1: PHÂN TÍCH BỘ DỮ LIỆU VỀ DOANH SỐ BÁN HÀNG

1.1 Tổng quan nghiên cứu

Tên bộ dữ liệu: Product Sales Dataset

Nguồn bộ dữ liệu: Dữ liệu được tổng hợp từ nguồn Kaggle mô phỏng bán lẻ trực tuyến, bao gồm thông tin giao dịch, khách hàng và sản phẩm tại các khu vực khác nhau.

Thông tin bộ dữ liệu: Bộ dữ liệu này chứa thông tin chi tiết về hoạt động bán hàng của một hệ thống thương mại điện tử, bao gồm cả các đặc điểm định tính (như khu vực, quốc gia, loại sản phẩm) và định lượng (như doanh thu, lợi nhuận, số lượng sản phẩm bán ra).

Mục đích lấy dữ liệu: Bộ dữ liệu này được sử dụng trong tiểu luận nhằm phục vụ cho các mục đích học thuật, bao gồm:

  • Thực hành phân tích và xử lý dữ liệu thực tế bằng ngôn ngữ lập trình R.

  • Ứng dụng các kỹ thuật thống kê mô tả, tiền xử lý dữ liệu, và trực quan hóa để hiểu rõ hơn về hoạt động bán hàng.

  • Rút ra những nhận xét, xu hướng và yếu tố ảnh hưởng đến hiệu suất kinh doanh dựa trên dữ liệu thực nghiệm.

# Đọc dữ liệu
data <- read.csv("~/Downloads/product_sales_dataset_final.csv")

Giải thích: Hàm read.csv() thực hiện việc tải tập tin dữ liệu thống kê doanh số sản phẩm có định dạng CSV và chuyển đổi thành một khung dữ liệu với tên gọi Product Data Set. Thao tác này đánh dấu bước khởi đầu trong quá trình xử lý thông tin bán hàng, biến nguồn dữ liệu từ tập tin lưu trữ thành đối tượng có thể phân tích và xử lý trực tiếp trong phần mềm R.

1.2 Thông tin cơ bản về bộ dữ liệu

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

dim(data)
## [1] 200000     14

Giải thích: Dùng hàm dim để kiểm tra cấu trúc tập dữ liệu, ta thu được 200.000 quan sát với 14 biến. Việc này giúp xác nhận kích thước dữ liệu đủ lớn để phục vụ các bước phân tích tiếp theo.

1.2.2 Tên các biến

names(data)
##  [1] "Order_ID"      "Order_Date"    "Customer_Name" "City"         
##  [5] "State"         "Region"        "Country"       "Category"     
##  [9] "Sub_Category"  "Product_Name"  "Quantity"      "Unit_Price"   
## [13] "Revenue"       "Profit"

Giải thích: Bộ dữ liệu gồm tổng cộng 14 biến, trong đó có 8 biến định tính và 6 biến định lượng.

Các biến định tính (phân loại) bao gồm: Order_ID, Customer_Name, City, State, Region, Country, Category, và Sub_Category. Các biến này mô tả thông tin nhận dạng hoặc phân loại, giúp nhóm và so sánh dữ liệu theo khu vực, loại sản phẩm hoặc khách hàng.

Các biến định lượng gồm: Order_Date, Quantity, Unit_Price, Revenue, và Profit. Đây là các biến mang giá trị số hoặc thời gian, được sử dụng để tính toán, đo lường và phân tích xu hướng kinh doanh.

1.2.3 Kiểm tra qua các dòng đầu tiên của bộ dữ liệu

Giải thích: Hàm head() trong R giúp ta quan sát nhanh vài dòng đầu của một bảng dữ liệu. Theo mặc định, R sẽ hiển thị 6 dòng, nhưng ta có thể chỉ định số dòng khác bằng tham số n, chẳng hạn head(x, n = 10) để xem 10 dòng đầu tiên.

Nhận xét: Bộ dữ liệu hiển thị 10 quan sát đầu tiên, không có giá trị thiếu hay lỗi định dạng. Các cột được sắp xếp logic, thể hiện đầy đủ thông tin về đơn hàng, khách hàng, sản phẩm và doanh thu — minh chứng rằng dữ liệu đã ở trạng thái sẵn sàng cho phân tích.

1.2.4 Kiểu dữ liệu của các biến

library(knitr)

loai <- data.frame(
  Kieu_du_lieu = sapply(data, class)
)

kable(loai, col.names = c("Tên  biến", "Kiểu dữ liệu"))
Tên biến Kiểu dữ liệu
Order_ID integer
Order_Date character
Customer_Name character
City character
State character
Region character
Country character
Category character
Sub_Category character
Product_Name character
Quantity integer
Unit_Price numeric
Revenue numeric
Profit numeric

Giải thích: * Hàm sapply() được dùng để áp dụng hàm class cho toàn bộ các cột trong data, giúp xác định kiểu dữ liệu của từng biến. * Hàm data.frame() tạo bảng chứa thông tin kiểu dữ liệu tương ứng với từng biến trong tập dữ liệu. * Hàm kable() hiển thị bảng kết quả dưới dạng gọn gàng, dễ quan sát trong báo cáo hoặc khi xuất ra file PDF/HTML.

Nhận xét: Bộ dữ liệu gồm 14 biến, trong đó đa số là biến định tính (chuỗi ký tự) mô tả thông tin khách hàng và sản phẩm, cùng một số biến định lượng như Quantity, Unit_Price, Revenue, Profit. Việc phân biệt kiểu dữ liệu giúp lựa chọn phương pháp phân tích và xử lý phù hợp cho từng biến.

1.2.5 Các loại sản phẩm trong biến Category

unique(data$Category)
## [1] "Accessories"        "Clothing & Apparel" "Electronics"       
## [4] "Home & Furniture"

Giải thích: Hàm unique() được sử dụng để hiển thị toàn bộ các giá trị khác nhau xuất hiện trong cột Category. Qua đó, ta có thể biết được các nhóm sản phẩm chính trong tập dữ liệu.

Nhận xét: Biến Category bao gồm bốn nhóm sản phẩm: Accessories, Clothing & Apparel, Electronics và Home & Furniture. Điều này cho thấy dữ liệu bao quát nhiều danh mục hàng hóa, giúp thuận tiện cho việc phân tích so sánh theo từng nhóm sản phẩm.

1.2.6 Số lượng khu vực khác nhau xuất hiện trong dữ liệu.:

length(unique(data$Region))
## [1] 4

Giải thích: Kết hợp unique() và length() để xác định số lượng khu vực khác nhau xuất hiện trong dữ liệu.

Nhận xét: Biến Region gồm 4 vùng: East, West, South, và Centre, cho thấy dữ liệu bao phủ trên nhiều khu vực địa lý, phù hợp cho việc so sánh doanh thu giữa các vùng.

1.2.7 Tần suất các nhóm sản phẩm trong biến Category

round(prop.table(table(data$Category)) * 100, 1)
## 
##        Accessories Clothing & Apparel        Electronics   Home & Furniture 
##               18.0               31.1               25.6               25.3

Giải thích: Hàm table() được sử dụng để đếm số lần xuất hiện của từng nhóm sản phẩm trong biến Category. Sau đó, prop.table() quy đổi các tần suất này thành tỷ lệ phần trăm (%), giúp thể hiện rõ mức độ phân bố của từng nhóm sản phẩm trong toàn bộ dữ liệu.

Nhận xét: Kết quả cho thấy nhóm Clothing & Apparel chiếm tỷ trọng lớn nhất, khoảng 31,1% tổng số giao dịch. Tiếp theo là Electronics (25,6%) và Home & Furniture (25,3%), có tỷ lệ khá tương đồng. Nhóm Accessories chiếm khoảng 18%, thấp hơn so với các nhóm còn lại. Điều này cho thấy các nhóm sản phẩm trong bộ dữ liệu được phân bố khá đồng đều, tuy nhiên nhóm Clothing & Apparel vẫn nổi bật hơn, phản ánh nhu cầu mua sắm cao hơn trong lĩnh vực thời trang so với các mặt hàng khác.

1.2.8 Khu vực có doanh thu cao nhất

data %>%
  group_by(Region) %>%
  summarise(Tong_doanh_thu = sum(Revenue, na.rm = TRUE)) %>%
  arrange(desc(Tong_doanh_thu))
## # A tibble: 4 × 2
##   Region Tong_doanh_thu
##   <chr>           <dbl>
## 1 East        44980048.
## 2 West        36242842.
## 3 Centre      36081894.
## 4 South       25102961.

Giải thích: Biến Region biểu thị khu vực bán hàng, còn Tong_doanh_thu là tổng doanh thu được tính bằng cách cộng toàn bộ giá trị Revenue theo từng vùng. Lệnh group_by(Region) giúp nhóm dữ liệu theo khu vực, còn summarise(sum(Revenue)) tính tổng doanh thu của mỗi nhóm, cho phép so sánh mức đóng góp giữa các vùng.

Nhận xét: Kết quả cho thấy khu vực East đạt doanh thu cao nhất với khoảng 44,98 triệu, chiếm tỷ trọng lớn nhất trong tổng doanh thu. Hai khu vực West và Centre có doanh thu gần tương đương, lần lượt khoảng 36,2 triệu và 36,08 triệu. Trong khi đó, khu vực South có doanh thu thấp nhất, chỉ khoảng 25,1 triệu.

Điều này phản ánh sự chênh lệch về hiệu quả kinh doanh giữa các vùng, đồng thời cho thấy khu vực East là thị trường tiềm năng và hoạt động mạnh nhất trong bộ dữ liệu.

1.2.9 Trung bình lợi nhuận theo khu vực(Region)

aggregate(Profit ~ Region, data = data, mean)
##   Region   Profit
## 1 Centre 163.1930
## 2   East 161.6812
## 3  South 156.0157
## 4   West 149.9957

Giải thích: aggregate(): dùng để nhóm dữ liệu và tính toán theo nhóm.

Profit ~ Region: nghĩa là lấy cột Profit và nhóm theo Region.

data = data: dữ liệu lấy từ bảng data.

mean: hàm tính trung bình lợi nhuận của từng khu vực

Nhận xét: Khu vực Centre có lợi nhuận trung bình cao nhất (~163.19), cho thấy hoạt động kinh doanh ở đây hiệu quả hơn.

West là khu vực có lợi nhuận trung bình thấp nhất (~149.99), có thể cần xem xét lại chiến lược bán hàng hoặc chi phí. → Nhìn chung, chênh lệch lợi nhuận giữa các vùng không quá lớn, nhưng vẫn cho thấy sự khác biệt về hiệu suất khu vực.

1.2.10 Giải thích ý nghĩa các biến

# ---- Tạo bảng mô tả ý nghĩa các biến trong bộ dữ liệu ----
variable_meaning <- data.frame(
  variable = c("Order_ID", "Order_Date", "Customer_Name", "City", "State", 
               "Region", "Country", "Category", "Sub_Category", "Product_Name", 
               "Quantity", "Unit_Price", "Revenue", "Profit"),
  Meaning = c(
    "Mã đơn hàng duy nhất cho mỗi giao dịch",
    "Ngày khách hàng đặt hàng (định dạng tháng-ngày-năm)",
    "Tên khách hàng thực hiện đơn mua",
    "Thành phố nơi đơn hàng được giao hoặc mua",
    "Bang hoặc tỉnh của khách hàng",
    "Vùng miền địa lý (ví dụ: East, West, South, Centre)",
    "Quốc gia thực hiện đơn hàng (ở đây là United States)",
    "Danh mục sản phẩm chính (ví dụ: Electronics, Accessories, Clothing & Apparel...)",
    "Danh mục con cụ thể hơn trong Category (ví dụ: Bags, Sportswear, Furniture...)",
    "Tên chi tiết của sản phẩm được bán",
    "Số lượng sản phẩm được bán trong đơn hàng",
    "Đơn giá của mỗi sản phẩm (USD)",
    "Tổng doanh thu từ đơn hàng (Quantity × Unit_Price)",
    "Lợi nhuận thu được từ đơn hàng sau khi trừ chi phí (USD)"
  ),
  stringsAsFactors = FALSE
)

# ---- Hiển thị bảng mô tả ----
library(knitr)
kable(variable_meaning, col.names = c("Tên biến", "Ý nghĩa"))
Tên biến Ý nghĩa
Order_ID Mã đơn hàng duy nhất cho mỗi giao dịch
Order_Date Ngày khách hàng đặt hàng (định dạng tháng-ngày-năm)
Customer_Name Tên khách hàng thực hiện đơn mua
City Thành phố nơi đơn hàng được giao hoặc mua
State Bang hoặc tỉnh của khách hàng
Region Vùng miền địa lý (ví dụ: East, West, South, Centre)
Country Quốc gia thực hiện đơn hàng (ở đây là United States)
Category Danh mục sản phẩm chính (ví dụ: Electronics, Accessories, Clothing & Apparel…)
Sub_Category Danh mục con cụ thể hơn trong Category (ví dụ: Bags, Sportswear, Furniture…)
Product_Name Tên chi tiết của sản phẩm được bán
Quantity Số lượng sản phẩm được bán trong đơn hàng
Unit_Price Đơn giá của mỗi sản phẩm (USD)
Revenue Tổng doanh thu từ đơn hàng (Quantity × Unit_Price)
Profit Lợi nhuận thu được từ đơn hàng sau khi trừ chi phí (USD)

1.3 Xử lí thô và mã hóa dữ liệu

1.3.1 Tải các thư viện cần thiết

library(readr)     
library(janitor)   
library(dplyr)     
library(lubridate) 

Giải thích: readr và janitor: Giúp đọc file (read_csv) và tự động làm sạch tên cột (ví dụ: ” Sub_Category ” thành sub_category).

dplyr: Cung cấp các hàm mutate, across và toán tử %>% để thao tác dữ liệu dễ dàng.

lubridate: Giúp xử lý cột ngày tháng.

Nhận xét: Việc tải thư viện ngay từ đầu giúp code chạy mượt mà.

1.3.2 Đọc dữ liệu và làm sạch tên cột

data <-read_csv("~/Downloads/product_sales_dataset_final.csv") %>%
        clean_names()
names(data)
##  [1] "order_id"      "order_date"    "customer_name" "city"         
##  [5] "state"         "region"        "country"       "category"     
##  [9] "sub_category"  "product_name"  "quantity"      "unit_price"   
## [13] "revenue"       "profit"

Giải thích: read_csv(“…”) đọc file CSV.

%>% clean_names(): Đây là bước quan trọng. Nó nhận dữ liệu từ read_csv và tự động:

  • Chuyển tên cột sang chữ thường (ví dụ: Order_ID -> order_id).

  • Loại bỏ khoảng trắng thừa và ký tự đặc biệt trong tên cột (ví dụ: ” Sub_Category ” -> sub_category).

Nhận xét: Kết quả cho thấy tất cả tên cột (như sub_category, unit_price, revenue…) đều ở dạng chuẩn, không có khoảng trắng, giúp việc gọi biến sau này (ví dụ: data$sub_category) không bị lỗi.

1.3.3 Kiểm tra quan sát bị trùng lặp

sum(duplicated(data))
## [1] 0

Giải thích: Hàm duplicated(data) xác định các dòng trùng lặp, trả về TRUE nếu dòng đó đã xuất hiện trước đó. Hàm sum() đếm tổng số dòng trùng lặp trong toàn bộ dữ liệu.

Nhận xét: Kết quả bằng 0 cho thấy dữ liệu không có dòng trùng lặp, đảm bảo tính chính xác và độ tin cậy cho các phân tích sau.

1.3.4 Kiểm tra các giá trị bị thiếu (NA)

any(is.na(data))
## [1] FALSE

Giải thích: Hàm is.na(data) kiểm tra các ô có giá trị bị thiếu (NA), trả về TRUE/FALSE tương ứng. Hàm any() xác định xem có ít nhất một giá trị NA nào trong toàn bộ dữ liệu hay không.

Nhận xét: Kết quả [1] FALSE cho thấy dữ liệu không có giá trị thiếu, đảm bảo độ đầy đủ và giúp việc phân tích sau chính xác hơn.

1.3.5 Chuẩn hóa tất cả các biến định tính (Văn bản)

categorical_cols <- c("region", "category", "sub_category", "state", "city", 
                      "customer_name", "product_name")

data <- data %>%
  mutate(across(all_of(categorical_cols), ~ trimws(tolower(.))))

unique(data$region)
## [1] "south"  "centre" "east"   "west"
unique(data$category)
## [1] "accessories"        "clothing & apparel" "electronics"       
## [4] "home & furniture"

Giải thích: Đây là bước quan trọng nhất để phân tích biến định tính.

trimws(tolower(…)): Chúng ta gộp 2 hàm. tolower() chuyển “Electronics” thành “electronics”, và trimws() xóa khoảng trắng thừa ở đầu/cuối (ví dụ: ” east ” thành “east”).

mutate(across(…)): Áp dụng 2 hàm này cho tất cả các cột văn bản đã liệt kê.

Nhận xét: Kết quả unique() cho thấy các giá trị đã được chuẩn hóa (ví dụ: chỉ có ‘east’, ‘west’, ‘centre’, ‘south’). Điều này đảm bảo khi dùng table(data$region), “east” và ” east ” sẽ được đếm chung là một, giúp kết quả tần suất chính xác tuyệt đối.

1.3.6 Chuyển đổi kiểu dữ liệu biến Order_Date

data$order_date <- as.Date(data$order_date, format = "%m-%d-%y")

str(data$order_date)
##  Date[1:200000], format: "2023-08-23" "2024-12-20" "2024-01-29" "2024-11-29" "2023-09-21" ...
head(data$order_date)
## [1] "2023-08-23" "2024-12-20" "2024-01-29" "2024-11-29" "2023-09-21"
## [6] "2024-10-18"

Giải thích: Hàm as.Date() chuyển đổi cột order_date (hiện đang là văn bản) sang kiểu dữ liệu Date chuẩn của R.

format = “%m-%d-%y”: Chúng ta chỉ định rõ định dạng gốc của dữ liệu (ví dụ: “08-23-23”) để R đọc chính xác.

Nhận xét: Dữ liệu thời gian đã được chuyển sang kiểu Date, hiển thị theo định dạng chuẩn “YYYY-MM-DD”. Việc này là bắt buộc để có thể thực hiện bước tiếp theo.

1.3.7 Tạo biến định tính year

data$year <- format(data$order_date, "%Y")

Giải thích: Dùng hàm format() để trích xuất Năm từ cột order_date và tạo ra một cột mới tên là year.

Nhận xét: Chúng ta đã tạo thành công biến định tính year (ví dụ: “2023”, “2024”). Biến này rất hữu ích để so sánh hiệu suất giữa các năm.

1.3.8 Tạo biến định tính month_year

data$month_year <- format(data$order_date, "%Y-%m")

Giải thích: Tương tự, dùng format() để trích xuất Năm-Tháng (ví dụ: “2023-08”) và tạo cột month_year.

Nhận xét: Biến định tính month_year này là chìa khóa để phân tích xu hướng (trend) theo thời gian.

1.3.9 Tạo biến định tính quarter (Quý)

data$quarter <- quarters(data$order_date)

Giải thích: Hàm quarters() (từ lubridate) tự động tính toán xem một ngày thuộc quý (Quarter) nào trong năm và trả về kết quả (ví dụ: “Q1”, “Q2”, “Q3”, “Q4”).

Nhận xét: Đây là một biến định tính mới rất giá trị, cho phép phân tích dữ liệu theo chu kỳ kinh doanh 3 tháng.

1.3.10 Phân tổ (Binning) unit_price

data <- data %>%
  mutate(price_group = cut(unit_price,
                           breaks = c(0, 100, 300, Inf),
                           labels = c("low", "medium", "high"),
                           right = TRUE))

Giải thích: Đây là một kỹ thuật mã hóa cổ điển. Chúng ta dùng hàm cut() để “phân tổ” (binning) biến định lượng unit_price thành một biến định tính mới là price_group.

breaks = c(0, 100, 300, Inf): Định nghĩa các mốc giá (0-100, 100-300, >300).

labels = c(“low”, “medium”, “high”): Gán nhãn cho 3 nhóm đó.

Nhận xét: Chúng ta đã tạo thành công biến định tính price_group. Biến này cho phép chúng ta dùng table() hoặc geom_bar() để trả lời câu hỏi “Sản phẩm ở phân khúc giá (low, medium, high) nào bán chạy nhất?”.

1.4 Thực hiện các thống kê cơ bản

1.4.1 Phân tích thống kê mô tả của các biến

get_mode <- function(v) {
  v <- v[!is.na(v)] 
  uniqv <- unique(v)
  uniqv[which.max(tabulate(match(v, uniqv)))]
}

Giải thích: get_mode() hàm này sẽ tìm giá trị xuất hiện nhiều nhất (Yếu vị) trong một cột.

Nhận xét: Hàm get_mode() cung cấp phép đo xu hướng trung tâm duy nhất có ý nghĩa đối với biến định tính. Nó tương đương với vai trò của mean() hay median() đối với biến định lượng, giúp xác định giá trị “phổ biến nhất” của một danh mục.

1.4.1.1 Biến region

table(data$region)
## 
## centre   east  south   west 
##  49603  57034  37935  55428
prop.table(table(data$region)) * 100
## 
##  centre    east   south    west 
## 24.8015 28.5170 18.9675 27.7140
get_mode(data$region)
## [1] "east"

Giải thích: table(): Đếm số lượng đơn hàng (tần suất) cho mỗi khu vực (region).

prop.table(): Tính tỷ lệ phần trăm (%) của mỗi khu vực trên tổng số.

get_mode(): Tìm ra khu vực có tần suất cao nhất (Yếu vị).

Nhận xét: Kết quả cho thấy ‘east’ là khu vực có nhiều đơn hàng nhất (Yếu vị), chiếm khoảng 28.5%. Khu vực ‘south’ có ít đơn hàng nhất, chỉ chiếm khoảng 18.9%.

1.4.1.2 Biến category

table(data$category)
## 
##        accessories clothing & apparel        electronics   home & furniture 
##              35908              62298              51230              50564
prop.table(table(data$category)) * 100
## 
##        accessories clothing & apparel        electronics   home & furniture 
##             17.954             31.149             25.615             25.282
get_mode(data$category)
## [1] "clothing & apparel"

Nhận xét: Danh mục ‘clothing & apparel’ là Yếu vị (phổ biến nhất), chiếm 31.15% tổng số đơn hàng. ‘accessories’ là danh mục ít phổ biến nhất (17.95%).

1.4.1.3 Biến year

table(data$year)
## 
##   2023   2024 
##  99807 100193
prop.table(table(data$year)) * 100
## 
##    2023    2024 
## 49.9035 50.0965
get_mode(data$year)
## [1] "2024"

Nhận xét: Năm “2024” là Yếu vị (phổ biến nhất), chiếm 50.10% tổng số đơn hàng. Năm “2023” (chiếm 49.90%) có tỷ trọng gần như ngang bằng. Điều này cho thấy số lượng đơn hàng là rất ổn định và không có sự khác biệt đáng kể giữa hai năm.

1.4.1.4 Biến quarter

table(data$quarter)
## 
##    Q1    Q2    Q3    Q4 
## 31241 38824 38075 91860
prop.table(table(data$quarter)) * 100
## 
##      Q1      Q2      Q3      Q4 
## 15.6205 19.4120 19.0375 45.9300
get_mode(data$quarter)
## [1] "Q4"

Nhận xét: “Q4” (Quý 4) là Yếu vị (phổ biến nhất), chiếm tỷ trọng vượt trội với 45.93% tổng số đơn hàng. Trong khi đó, “Q1” (Quý 1) chỉ chiếm 15.62%. Kết quả này cho thấy dữ liệu có tính mùa vụ rất rõ rệt, với hoạt động kinh doanh bùng nổ vào 3 tháng cuối năm.

1.4.1.5 Biến price_group

table(data$price_group)
## 
##    low medium   high 
##  23599  75483 100918
prop.table(table(data$price_group)) * 100
## 
##     low  medium    high 
## 11.7995 37.7415 50.4590
get_mode(data$price_group)
## [1] high
## Levels: low medium high

Nhận xét: Các sản phẩm ở nhóm “high” là Yếu vị, được mua nhiều nhất (chiếm 50.46%). Các sản phẩm “low” ít được mua nhất (chỉ 11.80%). Tỷ lệ này cho thấy sự phân bổ không cân bằng rõ rệt, thể hiện xu hướng tập trung vào các mặt hàng có giá trị cao.

1.4.2 Kiểm tra các giá trị dị thường (Anomaly)

table(data$region): Đếm tần suất (số lần xuất hiện) của mỗi khu vực.

sort(…, decreasing = FALSE): Sắp xếp bảng tần suất đó theo thứ tự tăng dần (từ thấp nhất đến cao nhất).

head(…, 1): Lấy ra 1 kết quả đầu tiên từ danh sách đã sắp xếp tăng dần.

1.4.2.1 Biến region

head(sort(table(data$region), decreasing = FALSE), 1)
## 
## south 
## 37935

Nhận xét: “south” là giá trị “dị thường” hay khu vực hiếm nhất trong bộ dữ liệu, với chỉ 37,935 đơn hàng. Đây là khu vực có số lượng đơn hàng thấp nhất, trái ngược với Yếu vị (Mode) là khu vực phổ biến nhất.

1.4.2.2 Biến category

head(sort(table(data$category), decreasing = FALSE), 1)
## 
## accessories 
##       35908

Nhận xét: “accessories” là giá trị “dị thường” hay danh mục hiếm nhất trong bộ dữ liệu, với 35,908 đơn hàng. Đây là danh mục có số lượng đơn hàng thấp nhất, trái ngược với Yếu vị (Mode) là danh mục “clothing & apparel” (phổ biến nhất).

1.4.2.3 Biến year

head(sort(table(data$year), decreasing = FALSE), 1)
## 
##  2023 
## 99807

Nhận xét: “2023” là giá trị “dị thường” trong bộ dữ liệu, với 99,807 đơn hàng.

1.4.2.4 Biến quarter

head(sort(table(data$quarter), decreasing = FALSE), 1)
## 
##    Q1 
## 31241

Nhận xét: “Q1” (Quý 1) là giá trị “dị thường” trong bộ dữ liệu, với chỉ 31,241 đơn hàng.

1.4.2.5 Biến price_group

head(sort(table(data$price_group), decreasing = FALSE), 1)
## 
##   low 
## 23599

Nhận xét: “low” là giá trị “dị thường” hay nhóm giá hiếm nhất trong bộ dữ liệu, với 23,599 đơn hàng.

1.4.3 Phân tích thống kê suy diễn

Sử dụng Kiểm định Chi-bình phương (Chi-Square) để kiểm tra mối quan hệ giữa các biến định tính đã được chuẩn hóa và mã hóa.

1.4.3.1 Kiểm định Chi-Square giữa Region và Category

chisq.test(table(data$region, data$category))
## 
##  Pearson's Chi-squared test
## 
## data:  table(data$region, data$category)
## X-squared = 7902.6, df = 9, p-value < 2.2e-16

Giải thích: chisq.test(…): Thực hiện kiểm định Chi-bình phương (Chi-Squared test) để kiểm tra giả thuyết H0: “Biến region và biến category là độc lập với nhau (không có mối liên hệ)”.

X-squared = 7902.6: Là giá trị thống kê Chi-bình phương tính được. Con số này càng lớn, sự khác biệt so với kỳ vọng càng lớn.

p-value < 2.2e-16: Đây là kết quả quan trọng nhất (gần như bằng 0).

Nhận xét: Kết quả p-value (gần bằng 0) nhỏ hơn rất nhiều so với mức ý nghĩa tiêu chuẩn (α=0.05).

Vì p-value < 0.05, chúng ta bác bỏ giả thuyết H0.

Kết luận: Có một mối liên hệ có ý nghĩa thống kê rất mạnh giữa biến region và biến category. Nói cách khác, hai biến này không độc lập với nhau. Lựa chọn mua category của khách hàng có phụ thuộc vào region mà họ đang ở.

1.4.3.2 Kiểm định Chi-Square giữa Year và Category

chisq.test(table(data$year, data$category))
## 
##  Pearson's Chi-squared test
## 
## data:  table(data$year, data$category)
## X-squared = 17.06, df = 3, p-value = 0.0006871

Nhận xét: Kết quả p-value (0.0006871) nhỏ hơn so với mức ý nghĩa tiêu chuẩn (α=0.05).

Vì p-value < 0.05, chúng ta bác bỏ giả thuyết H0.

Kết luận: Có một mối liên hệ có ý nghĩa thống kê giữa year và category. Nói cách khác, cơ cấu (tỷ lệ) các danh mục sản phẩm được bán ra đã có sự thay đổi ý nghĩa thống kê giữa năm 2023 và 2024.

1.4.3.3 Kiểm định Chi-Square giữa Quarter và Category

chisq.test(table(data$quarter, data$category))
## 
##  Pearson's Chi-squared test
## 
## data:  table(data$quarter, data$category)
## X-squared = 16.88, df = 9, p-value = 0.05063

Nhận xét: Kết quả p-value (0.05063) lớn hơn so với mức ý nghĩa tiêu chuẩn (α=0.05).

Vì p-value > 0.05, chúng ta không có đủ bằng chứng để bác bỏ giả thuyết H0.

Kết luận: Không có mối liên hệ có ý nghĩa thống kê giữa quarter và category. Điều này có nghĩa là sự bùng nổ của Q4 xảy ra đồng đều ở tất cả các danh mục, chứ không phải do một danh mục cụ thể nào gây ra.

1.4.3.4 Kiểm định Chi-Square giữa Region và Price_Group

chisq.test(table(data$region, data$price_group))
## 
##  Pearson's Chi-squared test
## 
## data:  table(data$region, data$price_group)
## X-squared = 2069.4, df = 6, p-value < 2.2e-16

Nhận xét: Kết quả p-value (gần bằng 0) nhỏ hơn rất nhiều so với mức ý nghĩa tiêu chuẩn (α=0.05).

Vì p-value < 0.05, chúng ta bác bỏ giả thuyết H0.

Kết luận: Có một mối liên hệ có ý nghĩa thống kê rất mạnh giữa region và price_group. Nói cách khác, các khu vực khác nhau có xu hướng mua các nhóm giá (“low”, “medium”, “high”) khác nhau một cách rõ rệt.

1.4.3.5 Kiểm định Chi-Square giữa Category và Price_Group

chisq.test(table(data$category, data$price_group))
## 
##  Pearson's Chi-squared test
## 
## data:  table(data$category, data$price_group)
## X-squared = 75302, df = 6, p-value < 2.2e-16

Nhận xét: Kết quả p-value (gần bằng 0) nhỏ hơn rất nhiều so với mức ý nghĩa tiêu chuẩn (α=0.05).

Vì p-value < 0.05, chúng ta bác bỏ giả thuyết H0.

Kết luận: Có một mối liên hệ có ý nghĩa thống kê cực kỳ mạnh giữa category và price_group. Nói cách khác, các danh mục sản phẩm khác nhau có xu hướng rơi vào các nhóm giá (“low”, “medium”, “high”) khác nhau một cách rõ rệt.

1.4.4 Phân tổ và phân loại

1.4.4.1 Mô tả thao tác phân tổ unit_price

Giải thích: Chúng ta đã sử dụng hàm cut() để “phân tổ” biến định lượng unit_price thành một biến định tính mới là price_group. breaks = c(0, 100, 300, Inf) và labels = c(“low”, “medium”, “high”).

Nhận xét: Thao tác mã hóa này đã được thực hiện thành công, cho phép chúng ta phân tích unit_price như một biến định tính

1.4.4.2 Phân loại số lượng đơn hàng theo month_year

month_summary <- data %>%
  group_by(month_year) %>%
  summarize(so_luong_don_hang = n()) %>%
  arrange(month_year)

print(month_summary, n = 24) 
## # A tibble: 24 × 2
##    month_year so_luong_don_hang
##    <chr>                  <int>
##  1 2023-01                 6119
##  2 2023-02                 3859
##  3 2023-03                 5542
##  4 2023-04                 6003
##  5 2023-05                 6750
##  6 2023-06                 6683
##  7 2023-07                 6313
##  8 2023-08                 6148
##  9 2023-09                 6482
## 10 2023-10                12403
## 11 2023-11                18915
## 12 2023-12                14590
## 13 2024-01                 6048
## 14 2024-02                 3974
## 15 2024-03                 5699
## 16 2024-04                 6025
## 17 2024-05                 6805
## 18 2024-06                 6558
## 19 2024-07                 6205
## 20 2024-08                 6190
## 21 2024-09                 6737
## 22 2024-10                12222
## 23 2024-11                19469
## 24 2024-12                14261

Giải thích: group_by(month_year): Nhóm tất cả các đơn hàng theo biến month_year.

summarize(so_luong_don_hang = n()): Đếm (n()) tổng số lượng đơn hàng trong mỗi nhóm tháng.

arrange(month_year): Sắp xếp bảng kết quả theo thứ tự thời gian (từ “2023-01” đến “2024-12”).

print(month_summary, n = 24): In ra toàn bộ 24 tháng trong bảng kết quả.

Nhận xét: Bảng thống kê này cho thấy chi tiết xu hướng bán hàng theo từng tháng trong 2 năm.

Kết quả (bắt đầu từ 2023-10 với 12,403 đơn hàng) cho thấy một sự bùng nổ đơn hàng rất lớn vào các tháng cuối năm (Quý 4). Điều này xác nhận lại một cách chi tiết kết quả phân tích biến quarter, chỉ rõ rằng các tháng 10, 11, và 12 là động lực chính tạo ra tính mùa vụ của dữ liệu. Các tháng còn lại (từ tháng 1 đến tháng 9) có số lượng đơn hàng tương đối ổn định và thấp hơn đáng kể.

1.4.4.3 Phân loại số lượng đơn hàng theo region và category

data %>%
  group_by(region, category) %>%
  summarize(so_luong_don_hang = n()) %>%
  arrange(region, desc(so_luong_don_hang))
## # A tibble: 16 × 3
## # Groups:   region [4]
##    region category           so_luong_don_hang
##    <chr>  <chr>                          <int>
##  1 centre home & furniture               15308
##  2 centre clothing & apparel             15187
##  3 centre electronics                    11459
##  4 centre accessories                     7649
##  5 east   electronics                    20248
##  6 east   clothing & apparel             14765
##  7 east   home & furniture               14642
##  8 east   accessories                     7379
##  9 south  clothing & apparel             14286
## 10 south  home & furniture                9390
## 11 south  electronics                     7145
## 12 south  accessories                     7114
## 13 west   clothing & apparel             18060
## 14 west   accessories                    13766
## 15 west   electronics                    12378
## 16 west   home & furniture               11224

Giải thích: group_by(region, category): Nhóm tất cả các đơn hàng theo cả region và category.

summarize(so_luong_don_hang = n()): Đếm (n()) số lượng đơn hàng cho mỗi cặp (ví dụ: “centre” và “home & furniture” có bao nhiêu đơn hàng).

arrange(region, desc(so_luong_don_hang)): Sắp xếp kết quả (đầu tiên theo region, sau đó theo so_luong_don_hang giảm dần) để hiển thị danh mục mạnh nhất ở mỗi khu vực lên đầu.

Nhận xét: Bảng kết quả này phân tích chi tiết cơ cấu bán hàng và cho thấy sở thích mua sắm khác nhau ở mỗi khu vực:

Tại khu vực “centre”, ‘home & furniture’ (15,308) và ‘clothing & apparel’ (15,187) là hai danh mục mạnh nhất và gần như ngang bằng nhau.

Tại khu vực “east”, ‘electronics’ (20,248) là danh mục “át chủ bài”, vượt trội hoàn toàn so với các danh mục còn lại.

Tại khu vực “south”, ‘clothing & apparel’ (14,286) là danh mục dẫn đầu.

1.4.4.4 Phân loại số lượng đơn hàng theo category và sub_category

data %>%
  group_by(category, sub_category) %>%
  summarize(so_luong_don_hang = n(), .groups = 'drop') %>%
  arrange(category, desc(so_luong_don_hang)) %>%
  head(10) 
## # A tibble: 10 × 3
##    category           sub_category         so_luong_don_hang
##    <chr>              <chr>                            <int>
##  1 accessories        wearable accessories             12018
##  2 accessories        small electronics                12015
##  3 accessories        bags                             11875
##  4 clothing & apparel men's wear                       12657
##  5 clothing & apparel sportswear                       12558
##  6 clothing & apparel kids wear                        12459
##  7 clothing & apparel footwear                         12357
##  8 clothing & apparel women's wear                     12267
##  9 electronics        laptops                           8656
## 10 electronics        tvs & audio                       8652

Giải thích: group_by(category, sub_category): Nhóm tất cả các đơn hàng theo category và sau đó theo sub_category.

summarize(so_luong_don_hang = n(), .groups = ‘drop’): Đếm (n()) số lượng đơn hàng cho mỗi cặp (ví dụ: “accessories” và “wearable accessories” có bao nhiêu đơn hàng). .groups = ‘drop’ là một lệnh kỹ thuật để dỡ bỏ nhóm sau khi tóm tắt.

arrange(category, desc(so_luong_don_hang)): Sắp xếp kết quả (đầu tiên theo category A-Z, sau đó theo so_luong_don_hang giảm dần).

head(10): Chỉ hiển thị 10 dòng đầu tiên của kết quả đã sắp xếp.

Nhận xét: Bảng kết quả này xác nhận logic phân cấp của dữ liệu và cho thấy các danh mục phụ (sub_category) bán chạy nhất trong mỗi danh mục chính (category):

Trong nhóm “accessories”, ‘wearable accessories’ (12,018) và ‘small electronics’ (12,015) là hai danh mục con bán chạy nhất.

Trong nhóm “clothing & apparel” (cũng là danh mục lớn nhất), 5 danh mục con (‘men’s wear’, ‘sportswear’, ‘kids wear’, ‘footwear’, ‘women’s wear’) đều có số lượng đơn hàng rất cao và đồng đều (đều trên 12,200).

Trong nhóm “electronics”, ‘laptops’ (8,656) và ‘tvs & audio’ (8,652) là hai danh mục con dẫn đầu.

1.4.4.5 Phân loại số lượng đơn hàng theo state

data %>%
  group_by(state) %>%
  summarize(so_luong_don_hang = n()) %>%
  arrange(desc(so_luong_don_hang)) %>%
  head(10)
## # A tibble: 10 × 2
##    state         so_luong_don_hang
##    <chr>                     <int>
##  1 california                10272
##  2 arizona                   10262
##  3 illinois                   5832
##  4 new jersey                 5780
##  5 ohio                       5776
##  6 new york                   5766
##  7 pennsylvania               5765
##  8 connecticut                5726
##  9 new hampshire              5682
## 10 vermont                    5677

Giải thích: group_by(state): Nhóm tất cả các đơn hàng theo biến state.

summarize(so_luong_don_hang = n()): Đếm (n()) tổng số lượng đơn hàng cho mỗi state.

arrange(desc(so_luong_don_hang)): Sắp xếp bảng kết quả theo số lượng đơn hàng (giảm dần).

head(10): Chỉ lấy 10 hàng đầu tiên (Top 10) từ danh sách đã sắp xếp.

Nhận xét: Bảng kết quả này liệt kê 10 thị trường tiểu bang quan trọng nhất (Top 10) về mặt số lượng đơn hàng. Kết quả cho thấy một sự phân hóa rõ rệt:

“california” (10,272) và “arizona” (10,262) là hai thị trường lớn nhất, gần như ngang bằng nhau và vượt trội hoàn toàn so với phần còn lại.

Có một khoảng cách lớn giữa nhóm Top 2 (khoảng 10,2k đơn hàng) và nhóm 8 bang tiếp theo (bắt đầu từ “illinois” với 5,832 đơn hàng).

8 bang còn lại trong Top 10 (từ “illinois” đến “vermont”) có số lượng đơn hàng khá sát nhau, dao động trong khoảng 5,6k - 5,8k.

1.5 Trực quan hoá dữ liệu

1.5.1 Biểu đồ tần suất biến region

ggplot(data, aes(x = fct_infreq(region), fill = region)) + # Layer 1: Data + Aes (sắp xếp theo tần suất)
  geom_bar(show.legend = FALSE) +                        # Layer 2: Hình học (Cột)
  geom_text(stat = 'count', aes(label = ..count..), 
            vjust = -0.5, size = 3.5) +                  # Layer 3: Thêm nhãn số liệu
  labs(title = "Phân bố đơn hàng theo Khu vực (Region)",
       x = "Khu vực",
       y = "Số lượng đơn hàng (Tần suất)") +               # Layer 4: Nhãn
  theme_minimal() +                                      # Layer 5: Giao diện
  scale_y_continuous(expand = expansion(mult = c(0, 0.1))) # Layer 6: Mở rộng trục Y

Giải thích: ggplot(data, aes(x = fct_infreq(region), fill = region)): (Layer 1) Xác định dữ liệu (data), trục X là region. Hàm fct_infreq() được dùng để tự động sắp xếp các cột theo tần suất (phổ biến nhất bên trái). Màu tô (fill) cũng phụ thuộc vào region.

geom_bar(show.legend = FALSE): (Layer 2) Vẽ biểu đồ cột (geom_bar) thể hiện số lượng đơn hàng của từng nhóm. show.legend = FALSE ẩn phần chú giải màu (vì thông tin đã có trên trục X).

geom_text(stat = “count”, …): (Layer 3) Thêm nhãn số liệu (tần suất) lên phía trên mỗi cột. stat=“count” và ..count.. tự động lấy tần suất đếm được. vjust = -0.5 đẩy nhãn lên trên một chút.

labs(title = …, x = …, y = …): (Layer 4) Đặt tiêu đề chính, tên trục X và trục Y cho biểu đồ.

theme_minimal(): (Layer 5) Giao diện nền đơn giản, hiện đại, xóa nền xám và giúp người xem tập trung vào dữ liệu.

scale_y_continuous(expand = …): (Layer 6) Mở rộng nhẹ trục Y (thêm 10% khoảng trống ở trên cùng) để đảm bảo nhãn số liệu (geom_text) không bị cắt mất ở viền trên của biểu đồ.

Nhận xét: Biểu đồ này thể hiện rõ số lượng đơn hàng ở khu vực ‘east’ (Yếu vị) là cao nhất, và ‘south’ (Dị thường/Hiếm nhất) là thấp nhất.

Việc sử dụng fct_infreq() để tự động sắp xếp cột giúp người xem dễ dàng nhận biết ngay lập tức thứ hạng của các khu vực.

Đây là một ví dụ tốt về trực quan hóa dữ liệu định tính, có nhiều lớp (layer) bổ trợ: geom_bar (cột), geom_text (nhãn số liệu), labs (tiêu đề), và theme (giao diện) để truyền đạt thông tin một cách hiệu quả.

1.5.2 Biểu đồ tần suất biến category

ggplot(data, aes(x = fct_infreq(category), fill = category)) + # Layer 1: Data + Aes (sắp xếp)
  geom_bar(show.legend = FALSE) +                            # Layer 2: Hình học (Cột)
  geom_text(stat = 'count', aes(label = ..count..), 
            vjust = -0.5, size = 3.5) +                      # Layer 3: Thêm nhãn số liệu
  labs(title = "Phân bố đơn hàng theo Danh mục (Category)",
       x = "Danh mục",
       y = "Số lượng đơn hàng (Tần suất)") +                   # Layer 4: Nhãn
  theme_minimal() +                                          # Layer 5: Giao diện
  scale_y_continuous(expand = expansion(mult = c(0, 0.1)))     # Layer 6: Mở rộng trục Y

Giải thích: ggplot(data, aes(x = fct_infreq(category), …)): (Layer 1) Xác định dữ liệu (data), trục X là category. fct_infreq() tự động sắp xếp các cột theo tần suất (phổ biến nhất bên trái). Màu tô (fill) cũng phụ thuộc vào category.

geom_bar(show.legend = FALSE): (Layer 2) Vẽ biểu đồ cột (geom_bar) thể hiện số lượng đơn hàng. show.legend = FALSE ẩn phần chú giải màu (vì đã có trên trục X).

geom_text(stat = “count”, …): (Layer 3) Thêm nhãn số liệu (..count..) lên phía trên mỗi cột (vjust = -0.5).

labs(title = …, x = …, y = …): (Layer 4) Đặt tiêu đề chính, tên trục X và trục Y cho biểu đồ.

theme_minimal(): (Layer 5) Giao diện nền đơn giản, hiện đại, giúp người xem tập trung vào dữ liệu.

scale_y_continuous(expand = …): (Layer 6) Mở rộng nhẹ trục Y để nhãn số liệu không bị cắt.

Nhận xét: Biểu đồ này trực quan hóa kết quả phân tích mô tả và kiểm tra dị thường.

Nó thể hiện rõ ‘clothing & apparel’ là Yếu vị (cột cao nhất) và ‘accessories’ là dị thường (cột thấp nhất).

Việc sắp xếp bằng fct_infreq() giúp người xem nắm bắt ngay lập tức thứ hạng của các danh mục.

1.5.3 Biểu đồ tần suất biến year

ggplot(data, aes(x = year, fill = year)) +                # Layer 1: Data + Aes
  geom_bar(show.legend = FALSE) +                       # Layer 2: Hình học (Cột)
  geom_text(stat = 'count', aes(label = ..count..), 
            vjust = -0.5, size = 3.5) +                 # Layer 3: Thêm nhãn số liệu
  labs(title = "So sánh đơn hàng giữa 2 năm",
       x = "Năm (Year)",
       y = "Số lượng đơn hàng (Tần suất)") +              # Layer 4: Nhãn
  theme_minimal() +                                     # Layer 5: Giao diện
  scale_y_continuous(expand = expansion(mult = c(0, 0.1)))# Layer 6: Mở rộng trục Y

Giải thích:

ggplot(data, aes(x = year, …)): (Layer 1) Xác định dữ liệu, trục X là biến year.

geom_bar(…): (Layer 2) Vẽ biểu đồ cột thể hiện số lượng.

geom_text(stat = “count”, …): (Layer 3) Thêm nhãn số liệu (tần suất) lên phía trên mỗi cột.

labs(…): (Layer 4) Đặt tiêu đề và tên các trục.

theme_minimal(): (Layer 5) Giao diện nền đơn giản, hiện đại.

scale_y_continuous(…): (Layer 6) Mở rộng trục Y để nhãn không bị cắt.

Nhận xét: Biểu đồ này trực quan hóa kết quả phân tích mô tả và kiểm tra dị thường.

Nó cho thấy “2024” (Yếu vị) chỉ cao hơn “2023” (Dị thường) một chút, trực quan hóa sự ổn định và cân bằng về số lượng đơn hàng giữa hai năm.

1.5.4 Biểu đồ tần suất biến quarter

ggplot(data, aes(x = quarter, fill = quarter)) +          # Layer 1: Data + Aes
  geom_bar(show.legend = FALSE) +                       # Layer 2: Hình học (Cột)
  geom_text(stat = 'count', aes(label = ..count..), 
            vjust = -0.5, size = 3.5) +                 # Layer 3: Thêm nhãn số liệu
  labs(title = "Phân bố đơn hàng theo Quý (Tính mùa vụ)",
       x = "Quý (Quarter)",
       y = "Số lượng đơn hàng (Tần suất)") +              # Layer 4: Nhãn
  theme_minimal() +                                     # Layer 5: Giao diện
  scale_y_continuous(expand = expansion(mult = c(0, 0.1)))# Layer 6: Mở rộng trục Y

Giải thích: ggplot(data, aes(x = quarter, …)): (Layer 1) Xác định dữ liệu, trục X là biến quarter.

geom_bar(…): (Layer 2) Vẽ biểu đồ cột.

geom_text(stat = “count”, …): (Layer 3) Thêm nhãn số liệu (tần suất) lên phía trên mỗi cột.

labs(…): (Layer 4) Đặt tiêu đề và tên các trục.

theme_minimal(): (Layer 5) Giao diện nền đơn giản, hiện đại.

scale_y_continuous(…): (Layer 6) Mở rộng trục Y.

Nhận xét: Biểu đồ này trực quan hóa kết quả phân tích mô tả và kiểm tra dị thường.

Tính mùa vụ của dữ liệu được thể hiện rất rõ: cột “Q4” (Yếu vị) cao vọt lên (chiếm 45.9%), trong khi “Q1” (Dị thường) là thấp nhất (15.6%).

1.5.5 Biểu đồ tần suất biến price_group

ggplot(data, aes(x = fct_infreq(price_group), fill = price_group)) + # Layer 1: Data + Aes (sắp xếp)
  geom_bar(show.legend = FALSE) +                                  # Layer 2: Hình học (Cột)
  geom_text(stat = 'count', aes(label = ..count..), 
            vjust = -0.5, size = 3.5) +                            # Layer 3: Thêm nhãn số liệu
  labs(title = "Phân bố đơn hàng theo Nhóm giá (Price Group)",
       x = "Nhóm giá (Price Group)",
       y = "Số lượng đơn hàng (Tần suất)") +                         # Layer 4: Nhãn
  theme_minimal() +                                                # Layer 5: Giao diện
  scale_y_continuous(expand = expansion(mult = c(0, 0.1)))           # Layer 6: Mở rộng trục Y

Giải thích: ggplot(data, aes(x = fct_infreq(price_group), …)): (Layer 1) Xác định dữ liệu, trục X là biến price_group. fct_infreq() tự động sắp xếp các cột.

geom_bar(…): (Layer 2) Vẽ biểu đồ cột.

geom_text(stat = “count”, …): (Layer 3) Thêm nhãn số liệu (tần suất) lên phía trên mỗi cột.

labs(…): (Layer 4) Đặt tiêu đề và tên các trục.

theme_minimal(): (Layer 5) Giao diện nền đơn giản, hiện đại.

scale_y_continuous(…): (Layer 6) Mở rộng trục Y.

Nhận xét:

Biểu đồ này trực quan hóa kết quả phân tích mô tả và kiểm tra dị thường.

Nó cho thấy “high” (Yếu vị) là cột cao nhất, ‘medium’ đứng thứ hai, và “low” (Dị thường) là cột thấp nhất, xác nhận xu hướng tập trung vào sản phẩm giá trị cao.

1.5.6 Tỷ lệ category trong mỗi region

ggplot(data, aes(x = region, fill = category)) +              # Layer 1: Data + Aes (X, Fill)
  geom_bar(position = "fill") +                               # Layer 2: Hình học (Cột 100%)
  scale_y_continuous(labels = scales::percent_format()) +     # Layer 3: Tùy chỉnh trục Y (Hiển thị %)
  labs(title = "Tỷ lệ (%) Danh mục trong mỗi Khu vực",
       x = "Khu vực (Region)",
       y = "Tỷ lệ phần trăm",
       fill = "Danh mục") +                                   # Layer 4: Nhãn
  theme_minimal() +                                           # Layer 5: Giao diện
  coord_flip()                                                # Layer 6: Lật trục

Giải thích: ggplot(data, aes(x = region, fill = category)): (Layer 1) Xác định dữ liệu, trục X là region, màu tô (fill) là category.

geom_bar(position = “fill”): (Layer 2) Vẽ biểu đồ cột chồng, nhưng position = “fill” làm cho mỗi cột cao bằng nhau (100%), hiển thị tỷ lệ của các màu bên trong.

scale_y_continuous(labels = scales::percent_format()): (Layer 3) Định dạng trục Y thành dạng % (ví dụ: 0.5 -> 50%).

labs(…): (Layer 4) Đặt tiêu đề và tên các trục.

theme_minimal(): (Layer 5) Giao diện nền đơn giản.

coord_flip(): (Layer 6) Lật trục X và Y (để các nhãn ‘region’ nằm ngang, dễ đọc hơn).

Nhận xét: Biểu đồ này trực quan hóa kết quả Kiểm định Chi-bình phương.

Nó cho thấy rõ sự khác biệt: ‘east’ có tỷ lệ ‘electronics’ (màu đỏ) cao, ‘south’ có tỷ lệ ‘clothing’ (xanh) cao. Điều này xác nhận p-value < 2.2e-16 (hai biến có mối liên hệ mạnh).

1.5.7 Tỷ lệ category trong mỗi year

ggplot(data, aes(x = year, fill = category)) +                # Layer 1: Data + Aes
  geom_bar(position = "fill") +                               # Layer 2: Hình học (Cột 100%)
  scale_y_continuous(labels = scales::percent_format()) +     # Layer 3: Tùy chỉnh trục Y
  labs(title = "Tỷ lệ (%) Danh mục trong mỗi Năm",
       x = "Năm (Year)",
       y = "Tỷ lệ phần trăm",
       fill = "Danh mục") +                                   # Layer 4: Nhãn
  theme_minimal()                                             # Layer 5: Giao diện

Giải thích: ggplot(data, aes(x = year, fill = category)): (Layer 1) Xác định dữ liệu, trục X là year, màu tô (fill) là category.

geom_bar(position = “fill”): (Layer 2) Vẽ biểu đồ cột chồng 100% để so sánh tỷ lệ.

scale_y_continuous(labels = scales::percent_format()): (Layer 3) Định dạng trục Y thành dạng %.

labs(…): (Layer 4) Đặt tiêu đề và tên các trục.

theme_minimal(): (Layer 5) Giao diện nền đơn giản.

Nhận xét: Biểu đồ này trực quan hóa kết quả Kiểm định Chi-bình phương.

Hai cột “2023” và “2024” có sự khác biệt nhỏ về tỷ lệ màu sắc (ví dụ: ‘home & furniture’ (tím) giảm nhẹ ở 2024, ‘clothing’ (xanh) tăng nhẹ). Sự khác biệt nhỏ nhưng rõ rệt này giải thích tại sao p-value < 0.05 (hai biến có mối liên hệ).

1.5.8 Tỷ lệ category trong mỗi quarter

ggplot(data, aes(x = quarter, fill = category)) +             # Layer 1: Data + Aes
  geom_bar(position = "fill") +                               # Layer 2: Hình học (Cột 100%)
  scale_y_continuous(labels = scales::percent_format()) +     # Layer 3: Tùy chỉnh trục Y
  labs(title = "Tỷ lệ (%) Danh mục trong mỗi Quý",
       x = "Quý (Quarter)",
       y = "Tỷ lệ phần trăm",
       fill = "Danh mục") +                                   # Layer 4: Nhãn
  theme_minimal()                                             # Layer 5: Giao diện

Giải thích: ggplot(data, aes(x = quarter, fill = category)): (Layer 1) Xác định dữ liệu, trục X là quarter, màu tô (fill) là category.

geom_bar(position = “fill”): (Layer 2) Vẽ biểu đồ cột chồng 100%.

scale_y_continuous(labels = scales::percent_format()): (Layer 3) Định dạng trục Y thành dạng %.

labs(…): (Layer 4) Đặt tiêu đề và tên các trục.

theme_minimal(): (Layer 5) Giao diện nền đơn giản.

Nhận xét: Biểu đồ này trực quan hóa kết quả Kiểm định Chi-bình phương.

Cả 4 cột (Q1, Q2, Q3, Q4) có tỷ lệ màu sắc giống hệt nhau. Điều này xác nhận kết quả p-value > 0.05 (hai biến không có liên hệ). Mặc dù Q4 có tổng số lượng rất lớn, sự bùng nổ này là đồng đều trên tất cả các danh mục.

1.5.9 Tỷ lệ price_group trong mỗi region

ggplot(data, aes(x = region, fill = price_group)) +           # Layer 1: Data + Aes
  geom_bar(position = "fill") +                               # Layer 2: Hình học (Cột 100%)
  scale_y_continuous(labels = scales::percent_format()) +     # Layer 3: Tùy chỉnh trục Y
  labs(title = "Tỷ lệ (%) Nhóm giá trong mỗi Khu vực",
       x = "Khu vực (Region)",
       y = "Tỷ lệ phần trăm",
       fill = "Nhóm giá") +                                   # Layer 4: Nhãn
  theme_minimal()                                             # Layer 5: Giao diện

Giải thích: ggplot(data, aes(x = region, fill = price_group)): (Layer 1) Xác định dữ liệu, trục X là region, màu tô (fill) là price_group.

geom_bar(position = “fill”): (Layer 2) Vẽ biểu đồ cột chồng 100%.

scale_y_continuous(labels = scales::percent_format()): (Layer 3) Định dạng trục Y thành dạng %.

labs(…): (Layer 4) Đặt tiêu đề và tên các trục.

theme_minimal(): (Layer 5) Giao diện nền đơn giản.

Nhận xét: Biểu đồ này trực quan hóa kết quả Kiểm định Chi-bình phương.

Chúng ta thấy sự khác biệt rất rõ: ‘east’ có tỷ lệ ‘high’ (tím) cao nhất, trong khi ‘centre’ có tỷ lệ ‘medium’ (xanh) cao nhất. Điều này xác nhận p-value < 2.2e-16 (hai biến có mối liên hệ mạnh).

1.5.10 Tỷ lệ price_group trong mỗi category

ggplot(data, aes(x = category, fill = price_group)) +         # Layer 1: Data + Aes
  geom_bar(position = "fill") +                               # Layer 2: Hình học (Cột 100%)
  scale_y_continuous(labels = scales::percent_format()) +     # Layer 3: Tùy chỉnh trục Y
  labs(title = "Tỷ lệ (%) Nhóm giá trong mỗi Danh mục",
       x = "Danh mục (Category)",
       y = "Tỷ lệ phần trăm",
       fill = "Nhóm giá") +                                   # Layer 4: Nhãn
  theme_minimal() +                                           # Layer 5: Giao diện
  theme(axis.text.x = element_text(angle = 45, hjust = 1))    # Layer 6: Xoay nhãn X

Giải thích: ggplot(data, aes(x = category, fill = price_group)): (Layer 1) Xác định dữ liệu, trục X là category, màu tô (fill) là price_group.

geom_bar(position = “fill”): (Layer 2) Vẽ biểu đồ cột chồng 100%.

scale_y_continuous(…): (Layer 3) Định dạng trục Y thành dạng %.

labs(…): (Layer 4) Đặt tiêu đề và tên các trục.

theme_minimal(): (Layer 5) Giao diện nền đơn giản.

theme(axis.text.x = element_text(angle = 45, hjust = 1)): (Layer 6) Tùy chỉnh giao diện, xoay nhãn trục X 45 độ để tránh bị chồng chéo.

Nhận xét: Biểu đồ này trực quan hóa kết quả Kiểm định Chi-bình phương.

Mối liên hệ là cực kỳ rõ ràng: ‘clothing & apparel’ và ‘accessories’ chủ yếu là ‘medium’ (xanh); trong khi ‘electronics’ và ‘home & furniture’ chủ yếu là ‘high’ (tím). Điều này giải thích p-value < 2.2e-16 (mối liên hệ rất mạnh).

1.5.11 Trực quan hóa thao tác Phân tổ unit_price

ggplot(data, aes(x = unit_price)) +                           # Layer 1: Data + Aes
  geom_histogram(binwidth = 10, fill = "gray", 
                 color = "black") +                          # Layer 2: Hình học (Histogram)
  geom_vline(xintercept = 100, color = "red", 
             linewidth = 1, linetype = "dashed") +           # Layer 3: Đường phân tổ "Low"
  geom_vline(xintercept = 300, color = "blue", 
             linewidth = 1, linetype = "dashed") +           # Layer 4: Đường phân tổ "Medium"
  labs(title = "Phân bố Unit Price và các mốc Phân tổ (Binning)",
       x = "Đơn giá (Unit Price)",
       y = "Tần suất") +                                     # Layer 5: Nhãn
  theme_minimal()                                            # Layer 6: Giao diện

Giải thích: ggplot(data, aes(x = unit_price)): (Layer 1) Xác định dữ liệu, trục X là unit_price.

geom_histogram(…): (Layer 2) Vẽ biểu đồ phân bố tần suất (histogram).

geom_vline(xintercept = 100, …): (Layer 3) Thêm một đường thẳng đứng (vertical line) tại mốc x=100 (màu đỏ).

geom_vline(xintercept = 300, …): (Layer 4) Thêm một đường thẳng đứng tại mốc x=300 (màu xanh).

labs(…): (Layer 5) Đặt tiêu đề và tên các trục.

theme_minimal(): (Layer 6) Giao diện nền đơn giản.

Nhận xét: Nó cho thấy lý do chúng ta chọn mốc 100 và 300: các mốc này chia 3 cụm giá chính của dữ liệu một cách hợp lý để tạo ra biến price_group.

1.5.12 Biểu đồ xu hướng đơn hàng theo month_year

# 1. Chuẩn bị dữ liệu (từ mục 4.2)
month_summary <- data %>%
  group_by(month_year) %>%
  summarize(so_luong_don_hang = n()) %>%
  ungroup()

# 2. Vẽ biểu đồ (6 Layer)
ggplot(month_summary, aes(x = month_year, y = so_luong_don_hang, group = 1)) + # Layer 1: Data + Aes
  geom_line(color = "tomato", linewidth = 1) +                 # Layer 2: Hình học (Đường)
  geom_point(color = "tomato", size = 2) +                   # Layer 3: Hình học (Điểm)
  labs(title = "Xu hướng đơn hàng theo Tháng (2023-2024)",
       x = "Năm-Tháng",
       y = "Số lượng đơn hàng") +                              # Layer 4: Nhãn
  theme_minimal() +                                            # Layer 5: Giao diện
  theme(axis.text.x = element_text(angle = 90, vjust = 0.5))   # Layer 6: Tùy chỉnh (Xoay nhãn X)

Giải thích: ggplot(month_summary, aes(x = month_year, …)): (Layer 1) Xác định dữ liệu, trục X là month_year. group = 1 là bắt buộc để geom_line hiểu rằng tất cả các điểm nối thành 1 đường.

geom_line(…): (Layer 2) Vẽ biểu đồ đường (geom_line) để thể hiện xu hướng (trend).

geom_point(…): (Layer 3) Thêm các điểm (geom_point) để đánh dấu từng tháng.

labs(…): (Layer 4) Đặt tiêu đề và tên các trục.

theme_minimal(): (Layer 5) Giao diện nền đơn giản.

theme(axis.text.x = …): (Layer 6) Tùy chỉnh giao diện, xoay nhãn trục X 90 độ để tránh bị chồng chéo.

Nhận xét: Chúng ta thấy rõ xu hướng bùng nổ (peak) vào các tháng cuối năm (10, 11, 12), và sự ổn định (stable) trong 9 tháng đầu năm, xác nhận lại phân tích về Q4.

1.5.13 Biểu đồ Heatmap (Bản đồ nhiệt) region và Category

# 1. Chuẩn bị dữ liệu (từ mục 4.3)
region_category_summary <- data %>%
  group_by(region, category) %>%
  summarize(so_luong_don_hang = n(), .groups = 'drop')

# 2. Vẽ biểu đồ (6 Layer)
ggplot(region_category_summary, aes(x = region, y = category, 
                                     fill = so_luong_don_hang)) + # Layer 1: Data + Aes
  geom_tile(color = "white") +                                   # Layer 2: Hình học (Ô vuông)
  geom_text(aes(label = so_luong_don_hang), 
            color = "black", size = 3) +                         # Layer 3: Thêm nhãn số liệu
  scale_fill_gradient(low = "lightblue", high = "darkblue") +    # Layer 4: Thang màu
  labs(title = "Heatmap: Đơn hàng theo Khu vực và Danh mục",
       x = "Khu vực", y = "Danh mục", fill = "Số lượng") +        # Layer 5: Nhãn
  theme_minimal()                                                # Layer 6: Giao diện

Giải thích: ggplot(region_category_summary, aes(x = region, y = category, …)): (Layer 1) Xác định dữ liệu, trục X là region, Y là category.

geom_tile(…): (Layer 2) Vẽ các ô vuông (heatmap). aes(fill = so_luong_don_hang) nghĩa là màu sắc phụ thuộc vào số lượng.

geom_text(aes(label = so_luong_don_hang), …): (Layer 3) Thêm nhãn số liệu vào chính giữa các ô.

scale_fill_gradient(…): (Layer 4) Tùy chỉnh thang màu (từ xanh nhạt đến xanh đậm).

labs(…): (Layer 5) Đặt tiêu đề và tên các trục.

theme_minimal(): (Layer 6) Giao diện nền đơn giản.

Nhận xét: Nó cho thấy ‘electronics’ ở ‘east’ (20,248) là ô “nóng” (đậm) nhất, và ‘accessories’ ở ‘south’ (7,379) là ô “lạnh” (nhạt) nhất. Biểu đồ này trực quan hóa mối quan hệ phức tạp mà chisq.test đã phát hiện.

1.5.14 Biểu đồ Treemap category và sub_category

# 1. Chuẩn bị dữ liệu (từ mục 4.4)
category_sub_summary <- data %>%
  group_by(category, sub_category) %>%
  summarize(so_luong_don_hang = n(), .groups = 'drop')

# 2. Vẽ biểu đồ (7 Layer)
ggplot(category_sub_summary, aes(area = so_luong_don_hang, 
                                 fill = category, 
                                 label = sub_category,
                                 subgroup = category)) +    # Layer 1: Data + Aes
  geom_treemap() +                                          # Layer 2: Hình học (Treemap)
  geom_treemap_subgroup_border(color = "white", 
                               linewidth = 2) +            # Layer 3: Viền nhóm cha
  geom_treemap_text(color = "black", place = "centre", 
                    grow = FALSE, min.size = 0) +           # Layer 4: Nhãn Sub-Category
  geom_treemap_subgroup_text(place = "topleft", 
                             color = "white", 
                             alpha = 0.5) +                 # Layer 5: Nhãn Category (mờ)
  labs(title = "Phân cấp đơn hàng theo Category và Sub-Category") + # Layer 6: Nhãn
  theme(legend.position = "none")                           # Layer 7: Ẩn Chú giải (vì đã có màu)

Giải thích: ggplot(…, aes(area = so_luong_don_hang, …)): (Layer 1) Xác định dữ liệu. Trong treemap, area (diện tích) là quan trọng nhất, gán bằng so_luong_don_hang.

geom_treemap(): (Layer 2) Vẽ các ô chữ nhật, kích thước ô tương ứng với area.

geom_treemap_subgroup_border(…): (Layer 3) Vẽ viền trắng (border) xung quanh các nhóm cha (các category). aes(subgroup = category) ở Layer 1 là bắt buộc.

geom_treemap_text(…): (Layer 4) Thêm nhãn (tên sub_category) vào giữa các ô.

geom_treemap_subgroup_text(…): (Layer 5) Thêm nhãn của nhóm cha (tên category) vào góc trên bên trái.

labs(…): (Layer 6) Đặt tiêu đề.

theme(legend.position = “none”): (Layer 7) Ẩn chú giải màu (vì màu đã được giải thích bằng nhãn subgroup_text).

Nhận xét: Nó cho thấy rõ ‘clothing & apparel’ (xanh) là nhóm lớn nhất, và bên trong đó, các danh mục con (‘men’s wear’, ‘sportswear’, v.v.) có kích thước gần bằng nhau.

1.5.15 Biểu đồ Cột Top 10 State

# 1. Chuẩn bị dữ liệu (từ mục 4.5)
top_10_states <- data %>%
  group_by(state) %>%
  summarize(so_luong_don_hang = n()) %>%
  arrange(desc(so_luong_don_hang)) %>%
  head(10)

# 2. Vẽ biểu đồ (7 Layer)
ggplot(top_10_states, aes(x = so_luong_don_hang, y = reorder(state, so_luong_don_hang))) + # Layer 1
  geom_col(fill = "steelblue") +                           # Layer 2: Hình học (Cột)
  geom_text(aes(label = so_luong_don_hang), 
            hjust = -0.2, size = 3.5) +                    # Layer 3: Thêm nhãn số liệu
  labs(title = "Top 10 Bang có nhiều đơn hàng nhất",
       x = "Số lượng đơn hàng (Tần suất)",
       y = "Tiểu bang (State)") +                          # Layer 4: Nhãn
  theme_minimal() +                                        # Layer 5: Giao diện
  scale_x_continuous(expand = expansion(mult = c(0, 0.1))) + # Layer 6: Mở rộng trục X
  theme(panel.grid.major.y = element_blank())              # Layer 7: Tùy chỉnh (Xóa lưới)

Giải thích: ggplot(top_10_states, aes(x = …, y = reorder(state, so_luong_don_hang))): (Layer 1) Xác định dữ liệu. reorder() là một hàm rất hữu ích, nó tự động sắp xếp lại trục Y (state) dựa trên giá trị của trục X (số lượng đơn hàng), giúp biểu đồ dễ đọc.

geom_col(…): (Layer 2) Vẽ biểu đồ cột (geom_col dùng khi dữ liệu đã được tổng hợp, geom_bar dùng khi dữ liệu chưa tổng hợp).

geom_text(aes(label = so_luong_don_hang), …): (Layer 3) Thêm nhãn số liệu vào bên phải các cột (hjust = -0.2).

labs(…): (Layer 4) Đặt tiêu đề và tên các trục.

theme_minimal(): (Layer 5) Giao diện nền đơn giản.

scale_x_continuous(…): (Layer 6) Mở rộng trục X để nhãn không bị cắt.

theme(panel.grid.major.y = element_blank()): (Layer 7) Tùy chỉnh giao diện, xóa các đường lưới (grid lines) ngang.

Nhận xét: Chúng ta thấy rõ “california” và “arizona” là 2 thị trường lớn vượt trội so với 8 bang còn lại trong Top 10.

1.5.16 Biểu đồ Top 5 sub_category BÁN CHẠY NHẤT

# 1. Chuẩn bị dữ liệu
top_5_sub <- data %>%
  count(sub_category, sort = TRUE) %>%
  head(5)

# 2. Vẽ biểu đồ (7 Layer)
ggplot(top_5_sub, aes(x = n, y = reorder(sub_category, n))) + # Layer 1
  geom_col(fill = "darkgreen") +                           # Layer 2
  geom_text(aes(label = n), hjust = -0.2, size = 3.5) +    # Layer 3
  labs(title = "Top 5 Sub-Category Bán Chạy Nhất",
       x = "Số lượng đơn hàng", y = "Danh mục phụ") +      # Layer 4
  theme_minimal() +                                        # Layer 5
  scale_x_continuous(expand = expansion(mult = c(0, 0.1))) + # Layer 6
  theme(panel.grid.major.y = element_blank())              # Layer 7

Giải thích: data %>% count(sub_category, sort = TRUE) %>% head(5): Lọc ra 5 danh mục phụ phổ biến nhất.

ggplot(…): (Layer 1) Xác định dữ liệu top_5_sub, sắp xếp trục Y bằng reorder().

geom_col(…): (Layer 2) Vẽ cột.

geom_text(…): (Layer 3) Thêm nhãn số liệu.

labs(…): (Layer 4) Đặt tiêu đề.

theme_minimal(): (Layer 5) Giao diện.

scale_x_continuous(…): (Layer 6) Mở rộng trục X.

theme(panel.grid.major.y = element_blank()): (Layer 7) Xóa lưới ngang.

Nhận xét: Nó cho thấy “men’s wear” là số 1, và 5 danh mục hàng đầu đều thuộc nhóm “clothing & apparel” hoặc “accessories”.

1.5.17 Biểu đồ 5 sub_category HIẾM NHẤT

# 1. Chuẩn bị dữ liệu
bottom_5_sub <- data %>%
  count(sub_category, sort = TRUE) %>%
  tail(5) # Lấy 5 giá trị cuối cùng

# 2. Vẽ biểu đồ (7 Layer)
ggplot(bottom_5_sub, aes(x = n, y = reorder(sub_category, n))) + # Layer 1
  geom_col(fill = "darkred") +                             # Layer 2
  geom_text(aes(label = n), hjust = -0.2, size = 3.5) +    # Layer 3
  labs(title = "5 Sub-Category Hiếm Nhất (Bán chậm nhất)",
       x = "Số lượng đơn hàng", y = "Danh mục phụ") +      # Layer 4
  theme_minimal() +                                        # Layer 5
  scale_x_continuous(expand = expansion(mult = c(0, 0.1))) + # Layer 6
  theme(panel.grid.major.y = element_blank())              # Layer 7

Giải thích: data %>% count(…, sort = TRUE) %>% tail(5): count(…, sort=TRUE) sắp xếp từ cao đến thấp, tail(5) lấy 5 dòng cuối cùng.

ggplot(…): (Layer 1) Xác định dữ liệu bottom_5_sub.

geom_col(…): (Layer 2) Vẽ cột.

geom_text(…): (Layer 3) Thêm nhãn số liệu.

labs(…): (Layer 4) Đặt tiêu đề.

theme_minimal(): (Layer 5) Giao diện.

scale_x_continuous(…): (Layer 6) Mở rộng trục X.

theme(panel.grid.major.y = element_blank()): (Layer 7) Xóa lưới ngang.

Nhận xét: Chúng ta thấy rõ “home appliances” (8360) là danh mục có số lượng đơn hàng thấp nhất.

1.5.18 Biểu đồ Top 5 state BÁN CHẠY NHẤT

# 1. Chuẩn bị dữ liệu
top_5_states <- data %>%
  count(state, sort = TRUE) %>%
  head(5)

# 2. Vẽ biểu đồ (7 Layer)
ggplot(top_5_states, aes(x = n, y = reorder(state, n))) +   # Layer 1
  geom_col(fill = "darkgreen") +                           # Layer 2
  geom_text(aes(label = n), hjust = -0.2, size = 3.5) +    # Layer 3
  labs(title = "Top 5 State Bán Chạy Nhất",
       x = "Số lượng đơn hàng", y = "Tiểu bang") +          # Layer 4
  theme_minimal() +                                        # Layer 5
  scale_x_continuous(expand = expansion(mult = c(0, 0.1))) + # Layer 6
  theme(panel.grid.major.y = element_blank())              # Layer 7

Giải thích: data %>% count(state, sort = TRUE) %>% head(5): Lọc ra 5 tiểu bang phổ biến nhất.

Các layer còn lại (1-7) tương tự như 4.16, chỉ thay đổi tiêu đề.

Nhận xét: Nó cho thấy rõ sự thống trị của “california” và “arizona” so với 3 bang còn lại trong Top 5. ### Biểu đồ 5 state HIẾM NHẤT

# 1. Chuẩn bị dữ liệu
bottom_5_states <- data %>%
  count(state, sort = TRUE) %>%
  tail(5) # Lấy 5 giá trị cuối cùng

# 2. Vẽ biểu đồ (7 Layer)
ggplot(bottom_5_states, aes(x = n, y = reorder(state, n))) + # Layer 1
  geom_col(fill = "darkred") +                             # Layer 2
  geom_text(aes(label = n), hjust = -0.2, size = 3.5) +    # Layer 3
  labs(title = "5 State Hiếm Nhất (Ít đơn hàng nhất)",
       x = "Số lượng đơn hàng", y = "Tiểu bang") +          # Layer 4
  theme_minimal() +                                        # Layer 5
  scale_x_continuous(expand = expansion(mult = c(0, 0.1))) + # Layer 6
  theme(panel.grid.major.y = element_blank())              # Layer 7

Giải thích: data %>% count(…, sort = TRUE) %>% tail(5): Lấy 5 tiểu bang hiếm nhất.

Các layer còn lại (1-7) tương tự như 4.17.

Nhận xét: Chúng ta thấy rõ 5 thị trường “dị thường” (hiếm) nhất, với “south carolina” (1108) là thấp nhất.

1.5.19 Biểu đồ Facet sub_category trong category

ggplot(data, aes(y = sub_category, fill = category)) +            # Layer 1: Data + Aes (Y và Màu)
  geom_bar(show.legend = FALSE) +                                 # Layer 2: Hình học (Cột, ẩn chú giải)
  facet_wrap(~ category, scales = "free_y") +                     # Layer 3: PHÂN RÃ (Chia 4 ô cho 4 Category)
  labs(title = "Số lượng đơn hàng của Sub-Category",
       subtitle = "Được chia nhỏ theo Category mẹ",
       x = "Số lượng đơn hàng",
       y = "Danh mục phụ") +                                      # Layer 4: Nhãn
  theme_bw() +                                                    # Layer 5: Giao diện (Nền trắng)
  theme(strip.text = element_text(face = "bold"))                 # Layer 6: Tùy chỉnh (In đậm tiêu đề ô)

Giải thích: ggplot(data, aes(y = sub_category, fill = category)): (Layer 1) Xác định dữ liệu, trục Y là sub_category, màu tô là category.

geom_bar(show.legend = FALSE): (Layer 2) Vẽ biểu đồ cột ngang.

facet_wrap(~ category, scales = “free_y”): (Layer 3) Đây là layer quan trọng nhất. Nó “phân rã” (facet) biểu đồ thành 4 ô (panels), mỗi ô cho một category. scales = “free_y” cho phép trục Y (danh sách sub_category) ở mỗi ô được tự do, không bị trùng lặp.

labs(…): (Layer 4) Đặt tiêu đề và tên các trục.

theme_bw(): (Layer 5) Giao diện nền trắng (black & white).

theme(strip.text = element_text(face = “bold”)): (Layer 6) Tùy chỉnh giao diện, in đậm tiêu đề của các ô (ví dụ: ‘accessories’, ‘electronics’…).

Nhận xét: Chúng ta thấy rõ 4 danh mục chính và các danh mục con bên trong. Nó cho thấy sự phân bổ đồng đều (như trong ‘clothing & apparel’) hoặc không đồng đều (như trong ‘electronics’).

2 Phần 2: PHÂN TÍCH BỘ DỮ LIỆU VỀ MÃ CHỨNG KHOÁN VPB

2.1 Chương 1: Giới thiệu thông tin cơ bản về bộ dữ liệu

2.1.1 Giới thiệu tổng quan

Tên bộ dữ liệu: Báo cáo tài chính Ngân hàng Thương mại Cổ phần Việt Nam Thịnh Vượng.

Nguồn bộ dữ liệu: Dữ liệu được tổng hợp từ Báo cáo tài chính các năm của Ngân hàng TMCP Việt Nam Thịnh Vượng (VPBank), được công bố trên trang thông tin điện tử chính thức của ngân hàng.

Thông tin bộ dữ liệu: Bộ dữ liệu này bao gồm các chỉ tiêu tài chính chủ yếu được trích xuất từ bảng cân đối kế toán của Ngân hàng TMCP Việt Nam Thịnh Vượng (VPBank). Các chỉ tiêu phản ánh tình hình tài sản, nguồn vốn, nợ phải trả và vốn chủ sở hữu của ngân hàng qua nhiều năm, giúp đánh giá quy mô, cơ cấu tài chính và khả năng tăng trưởng của VPBank trong từng giai đoạn. Dữ liệu được thu thập và tổng hợp theo năm, thể hiện xu hướng biến động của các yếu tố tài chính chủ đạo trong giai đoạn nghiên cứu.

Mục đích lấy dữ liệu: Phân tích dữ liệu tài chính VPBank nhằm đánh giá tình hình và hiệu quả hoạt động của doanh nghiệp qua các năm. Kết quả giúp nhận diện xu hướng phát triển, khả năng thanh toán và mức độ ổn định tài chính. Mục tiêu là hỗ trợ đưa ra cái nhìn tổng quan và cơ sở cho các quyết định quản trị phù hợp.

library(readxl)
ck <- read_xlsx("~/Downloads/du lieu vp bank (1).xlsx") 

2.1.2 Thông tin cơ bản về bộ dữ liệu

2.1.2.1 Kích thước bộ dữ liệu

dim(ck)
## [1] 249  11

Giải thích: Hàm dim() trong R dùng để xem kích thước của dữ liệu, trả về số dòng và số cột của một đối tượng. Nhận xét: Bộ dữ liệu data VP Bank gồm 249 quan sát và 11 biến, phù hợp để thực hiện phân tích, xử lý và đánh giá tài chính của doanh nghiệp VPBank.

2.1.2.2 Kiểm tra qua các dòng đầu tiên của bộ dữ liệu

library(knitr)
kable(head(ck[, c("CHỈ TIÊU", "2015":"2024")], 10))
CHỈ TIÊU 2015 2016 2017 2018 2019 2020 2021 2022 2023 2024
A. TỔNG TÀI SẢN 193876428 228770918 277752314 323291119 377204126 419026527 547409439 631012886 817566922 923847637
I. Tiền mặt, vàng bạc, đá quý 1632425 1727361 2574284 1855473 2459321 3282556 2345733 2658493 2284990 2148289
II. Tiền gửi tại Ngân hàng nhà nước 2261499 2982589 6460795 10828571 3454138 5779610 10860730 9935379 8422511 14327215
III. Tiền gửi và cho vay các TCTD khác 14599675 9388905 17520025 16571491 20097553 19554808 57104628 47965493 106888483 134643662
1. Tiền gửi tại các TCTD khác 8729745 4089175 15218720 15337628 15482986 13829025 40329730 40771879 94093778 126527280
2. Cho vay các TCTD khác 5870661 5300460 2302036 1233863 4614567 5725783 16858044 7193614 12794705 8116382
3. Dự phòng rủi ro cho vay TCTD khác -731 -731 -731 0 0 0 -83146 0 0 0
IV. Chứng khoán kinh doanh ròng 2043647 2952206 1424854 4202413 1566592 493214 6970941 7793447 12325809 13110971
1. Chứng khoán kinh doanh 2046735 2953769 1424854 4240742 1571141 493214 7005061 7850639 12406274 13180721
2. Dự phòng rủi ro chứng khoán kinh doanh -3088 -1563 0 -38329 -4549 0 -34120 -57192 -80465 -69750

Giải thích: Lệnh head() dùng để hiển thị 10 dòng đầu tiên của bộ dữ liệu VP Bank nhằm quan sát nhanh cấu trúc và giá trị ban đầu của các biến. Kết quả cho thấy dữ liệu có các cột từ 2015 đến 2024 và cột “CHỈ TIÊU” mô tả các hạng mục tài chính.

Nhận xét: Bộ dữ liệu chứa các chỉ tiêu tài chính của VPBank qua nhiều năm, với giá trị được ghi nhận theo từng năm. Số liệu thể hiện quy mô tài sản, tiền gửi, cho vay và các khoản mục khác tăng dần qua thời gian, phản ánh sự mở rộng hoạt động và tăng trưởng ổn định của ngân hàng.

2.1.2.3 Kiểu dữ liệu của các biến

str(ck)
## tibble [249 × 11] (S3: tbl_df/tbl/data.frame)
##  $ CHỈ TIÊU: chr [1:249] "A. TỔNG TÀI SẢN" "I. Tiền mặt, vàng bạc, đá quý" "II. Tiền gửi tại Ngân hàng nhà nước" "III. Tiền gửi và cho vay các TCTD khác" ...
##  $ 2015    : num [1:249] 1.94e+08 1.63e+06 2.26e+06 1.46e+07 8.73e+06 ...
##  $ 2016    : num [1:249] 2.29e+08 1.73e+06 2.98e+06 9.39e+06 4.09e+06 ...
##  $ 2017    : num [1:249] 2.78e+08 2.57e+06 6.46e+06 1.75e+07 1.52e+07 ...
##  $ 2018    : num [1:249] 3.23e+08 1.86e+06 1.08e+07 1.66e+07 1.53e+07 ...
##  $ 2019    : num [1:249] 3.77e+08 2.46e+06 3.45e+06 2.01e+07 1.55e+07 ...
##  $ 2020    : num [1:249] 4.19e+08 3.28e+06 5.78e+06 1.96e+07 1.38e+07 ...
##  $ 2021    : num [1:249] 5.47e+08 2.35e+06 1.09e+07 5.71e+07 4.03e+07 ...
##  $ 2022    : num [1:249] 6.31e+08 2.66e+06 9.94e+06 4.80e+07 4.08e+07 ...
##  $ 2023    : num [1:249] 8.18e+08 2.28e+06 8.42e+06 1.07e+08 9.41e+07 ...
##  $ 2024    : num [1:249] 9.24e+08 2.15e+06 1.43e+07 1.35e+08 1.27e+08 ...

Nhận xét: Bộ dữ liệu VP Banklà một tibble (data frame) gồm 249 dòng × 11 cột. Cột “CHỈ TIÊU” → kiểu character (chuỗi ký tự). Các cột từ 2015 đến 2024 → kiểu numeric (số thực).

2.1.2.4 Các nhóm chỉ tiêu trong biến “CHỈ TIÊU”

unique(ck$`CHỈ TIÊU`)
##   [1] "A. TỔNG TÀI SẢN"                                                        
##   [2] "I. Tiền mặt, vàng bạc, đá quý"                                          
##   [3] "II. Tiền gửi tại Ngân hàng nhà nước"                                    
##   [4] "III. Tiền gửi và cho vay các TCTD khác"                                 
##   [5] "1. Tiền gửi tại các TCTD khác"                                          
##   [6] "2. Cho vay các TCTD khác"                                               
##   [7] "3. Dự phòng rủi ro cho vay TCTD khác"                                   
##   [8] "IV. Chứng khoán kinh doanh ròng"                                        
##   [9] "1. Chứng khoán kinh doanh"                                              
##  [10] "2. Dự phòng rủi ro chứng khoán kinh doanh"                              
##  [11] "V. Cho vay khách hàng ròng"                                             
##  [12] "1. Cho vay khách hàng"                                                  
##  [13] "2. Dự phòng rủi ro cho vay khách hàng"                                  
##  [14] "VI. Chứng khoán đầu tư"                                                 
##  [15] "1. Chứng khoán đầu tư sẵn sàng để bán"                                  
##  [16] "2. Chứng khoán đầu tư giữ đến ngày đáo hạn"                             
##  [17] "3. Dự phòng rủi ro chứng khoán đầu tư"                                  
##  [18] "VII. Góp vốn, đầu tư dài hạn"                                           
##  [19] "1. Đầu tư dài hạn khác"                                                 
##  [20] "2. Dự phòng giảm giá đầu tư dài hạn"                                    
##  [21] "VII.  Tài sản cố định"                                                  
##  [22] "1. Tài sản cố định hữu hình"                                            
##  [23] "a. Nguyên giá"                                                          
##  [24] "b. Giá trị hao mòn luỹ kế"                                              
##  [25] "3. Tài sản cố định vô hình"                                             
##  [26] "IX. Bất động sản đầu tư"                                                
##  [27] "1. Nguyên giá"                                                          
##  [28] "2. Giá trị hao mòn luỹ kế"                                              
##  [29] "X. Tài sản Có khác"                                                     
##  [30] "1. Các khoản phải thu"                                                  
##  [31] "2. Các khoản lãi, phí phải thu"                                         
##  [32] "3. Tài sản khác"                                                        
##  [33] "4. DPRR cho các tài sản Có nội bảng khác"                               
##  [34] "B. TỔNG NỢ PHẢI TRẢ"                                                    
##  [35] "I. Các khoản nợ Chính phủ và NHNN"                                      
##  [36] "II. Tiền gửi và vay các TCTD khác"                                      
##  [37] "1. Tiền gửi của các TCTD khác"                                          
##  [38] "2. Vay các TCTD khác"                                                   
##  [39] "III. Tiền gửi của khách hàng"                                           
##  [40] "IV. Các CCTC phái sinh và nợ tài chính khác"                            
##  [41] "V. Vốn tài trợ, uỷ thác của CP và TCTD khác"                            
##  [42] "VI. Phát hành giấy tờ có giá"                                           
##  [43] "VII. Các khoản nợ khác"                                                 
##  [44] "1. Các khoản lãi, phí phải trả"                                         
##  [45] "2. Các khoản phải trả và công nợ khác"                                  
##  [46] "5. Thuế TNDN hoãn lại phải trả"                                         
##  [47] "C. Vốn chủ sở hữu"                                                      
##  [48] "1. Vốn điều lệ"                                                         
##  [49] "2. Thặng dư vốn cổ phần"                                                
##  [50] "I. Quỹ của tổ chức tín dụng"                                            
##  [51] "II. Lợi nhuận chưa phân phối lũy kế"                                    
##  [52] "CHỈ TIÊU"                                                               
##  [53] "Thu nhập lãi"                                                           
##  [54] "2. Chi phí lãi và các chi phí tương tự"                                 
##  [55] "I. Thu nhập lãi thuần"                                                  
##  [56] "3. Thu nhập từ hoạt động dịch vụ"                                       
##  [57] "4. Chi phí hoạt động dịch vụ"                                           
##  [58] "II. Lãi thuần từ hoạt động dịch vụ"                                     
##  [59] "III. Lãi/(lỗ) thuần từ ngoại hối và vàng"                               
##  [60] "IV. Lãi/(lỗ) thuần từ mua bán CKKD"                                     
##  [61] "V. Lãi/(lỗ) thuần từ mua bán CKĐT"                                      
##  [62] "5. Thu nhập từ hoạt động khác"                                          
##  [63] "6. Chi phí hoạt động khác"                                              
##  [64] "VI. Lãi/(lỗ) thuần từ hoạt động khác"                                   
##  [65] "VII. Thu nhập từ góp vốn, mua cổ phần"                                  
##  [66] "VIII. Tổng thu nhập hoạt động"                                          
##  [67] "IX. Chi phí hoạt động"                                                  
##  [68] "X. Lợi nhuận thuần HDKD trước DPRRTD"                                   
##  [69] "XI. Chi phí dự phòng rủi ro tín dụng"                                   
##  [70] "XII. Tổng lợi nhuận trước thuế"                                         
##  [71] "7. Chi phí thuế TNDN hiện hành"                                         
##  [72] "8. Chi phí thuế TNDN hoãn lại"                                          
##  [73] "XIII. Chi phí thuế thu nhập doanh nghiệp"                               
##  [74] "Lợi Nhuận Sau Thuế"                                                     
##  [75] "XVI. Lợi nhuận sau thuế Ngân hàng mẹ"                                   
##  [76] "Lãi cơ bản trên cổ phiếu"                                               
##  [77] "I. Chứng khoán kinh doanh"                                              
##  [78] "1. Chứng khoán nợ"                                                      
##  [79] "Chứng khoán Chính phủ"                                                  
##  [80] "Chứng khoán do các TCTD khác trong nước phát hành"                      
##  [81] "2. Chứng khoán vốn"                                                     
##  [82] "Chứng khoán vốn do các TCTD khác trong nước phát hành"                  
##  [83] "Chứng khoán vốn do các TCKT khác trong nước phát hành"                  
##  [84] "3. Dự phòng rủi ro chứng khoán kinh doanh"                              
##  [85] "II. Dư nợ theo đối tượng cho vay"                                       
##  [86] "1. Cho vay các tổ chức kinh tế, cá nhân trong nước"                     
##  [87] "2. Cho vay chiết khấu công cụ chuyển nhượng và các giấy tờ có giá"      
##  [88] "3. Các khoản trả thay khách hàng"                                       
##  [89] "4. Cho vay bằng vốn tài trợ, ủy thác đầu tư"                            
##  [90] "III. Dư nợ theo chất lượng nợ cho vay"                                  
##  [91] "1. Nợ đủ tiêu chuẩn"                                                    
##  [92] "2. Nợ cần chú ý"                                                        
##  [93] "3. Nợ dưới tiêu chuẩn"                                                  
##  [94] "4. Nợ nghi ngờ"                                                         
##  [95] "5. Nợ xấu có khả năng mất vốn"                                          
##  [96] "IV. Dư nợ theo thời hạn cho vay"                                        
##  [97] "1. Cho vay ngắn hạn"                                                    
##  [98] "2. Cho vay trung hạn"                                                   
##  [99] "3. Cho vay dài hạn"                                                     
## [100] "V. Dư nợ theo loại hình doanh nghiệp"                                   
## [101] "1. Doanh nghiệp nhà nước"                                               
## [102] "2. CTCP khác, Công ty TNHH khác, Doanh nghiệp tư nhân, Công ty hợp danh"
## [103] "3. Doanh nghiệp có vốn đầu tư nước ngoài"                               
## [104] "4. Cá nhân, hộ kinh doanh"                                              
## [105] "5. Hợp tác xã và liên hiệp hợp tác xã"                                  
## [106] "9. Thành phần kinh tế khác"                                             
## [107] "VI. Dư nợ phân theo ngành"                                              
## [108] "1. Công nghiệp chế biến, chế tạo"                                       
## [109] "2. Xây dựng"                                                            
## [110] "3. Vận tải kho bãi và thông tin liên lạc"                               
## [111] "4. Nông, lâm, thủy hải sản"                                             
## [112] "5. Nhà hàng, khách sạn"                                                 
## [113] "8. Hoạt động tài chính, ngân hàng và bảo hiểm"                          
## [114] "12. Hoạt động kinh doanh bất động sản"                                  
## [115] "15. Giáo dục đào tạo"                                                   
## [116] "16. Hoạt động dịch vụ khác/ Thương mại dịch vụ"                         
## [117] "22. Cho vay cá nhân"                                                    
## [118] "23. Dư nợ khác"                                                         
## [119] "Dự phòng rủi ro cho vay khách hàng"                                     
## [120] "1. Dự phòng chung"                                                      
## [121] "2. Dự phòng cụ thể"                                                     
## [122] "VIII. Chứng khoán đầu tư sẵn sàng để bán"                               
## [123] "Chứng khoán do các TCKT trong nước phát hành"                           
## [124] "3. Dự phòng rủi chứng khoán đầu tư sẵn sàng để bán"                     
## [125] "IX. Chứng khoán đầu tư giữ đến ngày đáo hạn"                            
## [126] "2. Dự phòng rủi chứng khoán đầu tư giữ đến ngày đáo hạn"                
## [127] "3. Trái phiếu đặc biệt do VAMC phát hành"                               
## [128] "Mệnh giá trái phiếu đặc biệt"                                           
## [129] "Dự phòng trái phiếu đặc biệt"                                           
## [130] "Tổng tiền gửi"                                                          
## [131] "1. Tiền gửi không kỳ hạn"                                               
## [132] "2. Tiền gửi tiết kiệm và có kỳ hạn"                                     
## [133] "3. Tiền gửi vốn chuyên dùng"                                            
## [134] "4. Tiền gửi ký quỹ"                                                     
## [135] "XI. Tiền gửi theo đối tượng"                                            
## [136] "1. Các tổ chức kinh tế"                                                 
## [137] "2. Cá nhân"                                                             
## [138] "XII. Phát hành giấy tờ có giá theo loại hình"                           
## [139] "XIII. Phát hành giấy tờ có giá theo kỳ hạn"                             
## [140] "1. Dưới 12 tháng"                                                       
## [141] "2. 12 tháng đến 5 năm"                                                  
## [142] "3. Trên 5 năm"                                                          
## [143] "XIV. Thu nhập lãi và các khoản tương tự"                                
## [144] "1. Thu nhập lãi cho vay"                                                
## [145] "2. Thu nhập lãi tiền gửi"                                               
## [146] "3. Thu nhập lãi từ chứng khoán"                                         
## [147] "4. Thu từ nghiệp vụ bảo lãnh"                                           
## [148] "5. Thu khác từ hoạt động tín dụng"                                      
## [149] "XV. Chi phí lãi và các khoản chi phí tương tự"                          
## [150] "1. Trả lãi tiền gửi"                                                    
## [151] "2. Trả lãi tiền vay"                                                    
## [152] "3. Trả lãi phát hành giấy tờ có giá"                                    
## [153] "4. Chi phí khác cho hoạt động tín dụng"                                 
## [154] "XVI. Thu nhập từ hoạt động dịch vụ"                                     
## [155] "1. Thu từ dịch vụ thanh toán"                                           
## [156] "2. Thu phí khác"                                                        
## [157] "XVII. Chi phí cho hoạt động dịch vụ"                                    
## [158] "1. Chi cho dịch vụ thanh toán"                                          
## [159] "2. Chi cho dịch vụ môi giới kinh doanh"                                 
## [160] "3. Chi khác"                                                            
## [161] "XVIII. Thu nhập từ hoạt động kinh doanh vàng và ngoại hối"              
## [162] "1. Thu từ kinh doanh vàng và ngoại tệ giao ngay"                        
## [163] "2. Thu từ các công cụ tài chính phái sinh tiền tệ"                      
## [164] "XIX. Chi phí hoạt động kinh doanh vàng và ngoại hối"                    
## [165] "1. Chi cho kinh doanh vàng và ngoại tệ giao ngay"                       
## [166] "2. Chi cho các công cụ tài chính phái sinh tiền tệ"                     
## [167] "XX. Lãi/lỗ thuần từ mua bán chứng khoán kinh doanh"                     
## [168] "1. Thu nhập từ mua bán chứng khoán kinh doanh"                          
## [169] "2. Chi phí về mua bán chứng khoán kinh doanh"                           
## [170] "3. Trích lập dự phòng giảm giá chứng khoán kinh doanh"                  
## [171] "1. Thu nhập từ mua bán chứng khoán đầu tư"                              
## [172] "2. Chi phí về mua bán chứng khoán đầu tư"                               
## [173] "3. Trích lập dự phòng giảm giá chứng khoán đầu tư"                      
## [174] "XXII. Thu nhập từ hoạt động khác"                                       
## [175] "1. Thu từ các công cụ tài chính phái sinh khác"                         
## [176] "2. Thu từ nghiệp vụ xử lý nợ"                                           
## [177] "3. Thu nhập khác"                                                       
## [178] "XXIII. Chi phí hoạt động khác"                                          
## [179] "1. Chi từ các công cụ tài chính phái sinh khác"                         
## [180] "5. Chi phí khác"                                                        
## [181] "XXIV. Thu nhập từ vốn góp, mua cổ phần"                                 
## [182] "1. Cổ tức nhận được trong kỳ từ góp vốn, mua cổ phần"                   
## [183] "XXV. Chi phí hoạt động"                                                 
## [184] "1. Chi nộp thuế và các khoản phí, lệ phí"                               
## [185] "2. Chi phí cho nhân viên"                                               
## [186] "Chi lương và các khoản chi đóng góp theo lương"                         
## [187] "3. Chi về tài sản"                                                      
## [188] "Khấu hao tài sản cố định"                                               
## [189] "4. Chi cho hoạt động quản lý công vụ"                                   
## [190] "5. Chi nộp phí bảo hiểm, bảo toàn tiền gửi của khách hàng"              
## [191] "6. Chi phí dự phòng"                                                    
## [192] "Nợ đủ tiêu chuẩn - N1"                                                  
## [193] "Nợ cần chú ý - N2"                                                      
## [194] "Nợ dưới tiêu chuẩn - N3"                                                
## [195] "Nợ nghi ngờ - N4"                                                       
## [196] "Nợ có khả năng mất vốn - N5"                                            
## [197] "Tổng dư nợ cho vay"                                                     
## [198] "Thời gian dư nợ"                                                        
## [199] "Nợ ngắn hạn"                                                            
## [200] "Nợ Trung hạn"                                                           
## [201] "Nợ dài hạn"                                                             
## [202] "Tỉ lệ nợ ngắn hạn"                                                      
## [203] "Tỉ lệ nợ Trung hạn"                                                     
## [204] "Tỉ lệ nợ dài hạn"                                                       
## [205] "LDR = Cho vay/tổng huy động"                                            
## [206] "Tỷ lệ nợ xấu (NPL)"                                                     
## [207] "Chỉ số ROE"                                                             
## [208] "Chỉ số CIR = CP hoạt động/ thu nhập HĐ"                                 
## [209] "Bao phủ nợ xấu: Trích lập/nợ xấu"                                       
## [210] "Casa"                                                                   
## [211] "Net Interest Margin (NIM)"                                              
## [212] "Chi phí lãi và các chi phí tương tự"                                    
## [213] "Tăng trưởng tổng Chi phí trả lãi"                                       
## [214] "Trả lãi tiền gửi"                                                       
## [215] "Trả lãi tiền vay"                                                       
## [216] "Trả lãi phát hành giấy tờ có giá"                                       
## [217] "Chi phí khác cho hoạt động tín dụng"                                    
## [218] "Tăng trưởng các nhóm nợ xấu (3-5)"                                      
## [219] "Tăng trưởng nợ nhóm 1"                                                  
## [220] "Tăng trưởng nợ nhóm 2"                                                  
## [221] "Tăng trưởng nợ nhóm 3"                                                  
## [222] "Tăng trưởng nợ nhóm 4"                                                  
## [223] "Tăng trưởng nợ nhóm 5"                                                  
## [224] "Tăng trưởng Thu nhập lãi (YoY)"                                         
## [225] "Tăng trưởng Thu nhập lãi HĐKD"                                          
## [226] "Tăng trưởng Dự phòng rủi ro"                                            
## [227] "Tăng trưởng LNST (YoY)"                                                 
## [228] "Tăng trưởng tiền gửi"                                                   
## [229] "Tăng trưởng cho vay"                                                    
## [230] "Nợ xấu/ tổng dư nợ"                                                     
## [231] "Cơ cấu cho vay theo Ngành nghề"

Giải thích: Lệnh unique() dùng để liệt kê toàn bộ các giá trị khác nhau trong cột CHỈ TIÊU — tức là danh sách tất cả các khoản mục tài chính xuất hiện trong bộ dữ liệu của VPBank.

Nhận xét: Kết quả cho thấy dữ liệu chứa rất nhiều chỉ tiêu chi tiết, được chia theo các nhóm lớn như Tài sản, Nợ phải trả, Vốn chủ sở hữu, Kết quả kinh doanh, Chỉ số tài chính, và các tỷ lệ tăng trưởng. Điều này thể hiện độ phong phú và chi tiết cao** của bộ dữ liệu, giúp việc phân tích tài chính có thể thực hiện ở nhiều cấp độ: từ tổng quan đến chuyên sâu cho từng chỉ tiêu.

2.1.2.5 Đếm số lượng nhóm chỉ tiêu xuất hiện

length(unique(gsub("\\..*", "", ck$`CHỈ TIÊU`)))
## [1] 98

Giải thích: Giá trị [1] 98 xuất hiện khi dùng lệnh:

length(unique(ck$CHỈ TIÊU))

Lệnh này dùng để đếm số lượng chỉ tiêu tài chính khác nhau trong cột CHỈ TIÊU của dữ liệu.

Nhận xét: Kết quả cho biết bộ dữ liệu hiện có 98 chỉ tiêu tài chính được ghi nhận. Điều này cho thấy dữ liệu khá đa dạng và chi tiết, bao phủ nhiều khía cạnh của báo cáo tài chính VPBank, tạo điều kiện thuận lợi cho việc phân tích tổng hợp và đánh giá tình hình hoạt động của ngân hàng qua các năm.

2.1.2.6 Năm có giá trị tổng tài sản cao nhất

# Lọc dòng có tổng tài sản
ck_tongtai <- ck[ck$`CHỈ TIÊU` == "A. TỔNG TÀI SẢN", ]

# Lấy tên các cột năm (2015–2024)
nam_cols <- names(ck)[2:11]

# Chuyển giá trị sang numeric và tìm năm có giá trị cao nhất
values <- as.numeric(ck_tongtai[, nam_cols])
nam_max <- nam_cols[which.max(values)]
nam_max
## [1] "2024"

Giải thích: Đoạn code lọc dòng có chỉ tiêu “A. TỔNG TÀI SẢN”, sau đó tìm năm có giá trị lớn nhất trong các cột từ 2015–2024.

Nhận xét: Kết quả cho thấy năm 2024 có tổng tài sản cao nhất, phản ánh sự tăng trưởng mạnh mẽ và mở rộng quy mô tài chính của VPBank.

2.1.2.7 Trung bình giá trị các chỉ tiêu theo năm

colMeans(ck[, 2:11], na.rm = TRUE)
##     2015     2016     2017     2018     2019     2020     2021     2022 
## 14167774 16698873 19978562 23796177 27890581 31101485 37999825 46265568 
##     2023     2024 
## 54143292 71319644

Giải thích: Đoạn lệnh tính trung bình giá trị các chỉ tiêu theo từng năm từ 2015 đến 2024. Kết quả cho biết mức trung bình của toàn bộ các chỉ tiêu tài chính trong mỗi năm.

Nhận xét: * Năm 2015: 14.167.774 * Năm 2016: 16.698.873 * Năm 2017: 19.978.562 * Năm 2018: 23.796.177 * Năm 2019: 27.890.581 * Năm 2020: 31.101.485 * Năm 2021: 37.999.825 * Năm 2022: 46.265.568 * Năm 2023: 54.143.292 * Năm 2024: 71.319.644 Giá trị trung bình các chỉ tiêu tài chính của VPBank tăng liên tục qua các năm, đặc biệt năm 2024 đạt 71.319.644, cao gần gấp 5 lần so với năm 2015. Điều này thể hiện quy mô tài chính mở rộng và tốc độ tăng trưởng bền vững của ngân hàng trong giai đoạn 2015–2024.

2.1.2.8 Xem nhanh xu hướng tăng/giảm tổng thể

tb_nam <- colMeans(ck[, 2:11], na.rm = TRUE)

tangtruong_tb <- diff(tb_nam) / tb_nam[-length(tb_nam)] * 100

tb_nam
##     2015     2016     2017     2018     2019     2020     2021     2022 
## 14167774 16698873 19978562 23796177 27890581 31101485 37999825 46265568 
##     2023     2024 
## 54143292 71319644
tangtruong_tb
##     2016     2017     2018     2019     2020     2021     2022     2023 
## 17.86519 19.64018 19.10856 17.20614 11.51250 22.18010 21.75206 17.02718 
##     2024 
## 31.72388

Giải thích: Đoạn code tính giá trị trung bình các chỉ tiêu theo từng năm (tb_nam) và tốc độ tăng trưởng trung bình năm sau so với năm trước (tangtruong_tb).

Nhận xét: Giá trị trung bình tăng đều từ 14.167.774 (2015) lên 71.319.644 (2024). Tốc độ tăng trưởng dao động 11%–32%, cao nhất năm 2024 (31,7%), cho thấy quy mô tài chính của VPBank mở rộng ổn định và tăng mạnh giai đoạn cuối.

2.1.2.9 Tổng quan về độ biến động của dữ liệu VP Bank

apply(ck[, 2:11], 2, sd, na.rm = TRUE)
##      2015      2016      2017      2018      2019      2020      2021      2022 
##  33578529  39452587  47742316  57689021  67771344  75531348  90967487 110067473 
##      2023      2024 
## 128571104 169968106

Giải thích: Đoạn mã tính tổng giá trị các chỉ tiêu tài chính theo từng năm trong giai đoạn 2015–2024. Mỗi con số thể hiện tổng quy mô tài chính trong năm tương ứng.

Nhận xét: Tổng giá trị tăng liên tục từ 33.578.529 (năm 2015) lên 169.968.106 (năm 2024). Điều này cho thấy quy mô hoạt động và tổng tài sản của VPBank tăng trưởng mạnh, ổn định qua các năm.

2.1.2.10 Kiểm tra độ biến động của tổng giá trị (năm nào dao động mạnh nhất)

tong_nam <- colSums(ck[, 2:11], na.rm = TRUE)

tangtruong_tong <- diff(tong_nam) / tong_nam[-length(tong_nam)] * 100

tong_nam
##        2015        2016        2017        2018        2019        2020 
##  3471104554  4074525037  4894747627  5830063467  6833192362  7619863727 
##        2021        2022        2023        2024 
##  9309957147 11335064237 13265106426 17473312798
tangtruong_tong
##     2016     2017     2018     2019     2020     2021     2022     2023 
## 17.38411 20.13051 19.10856 17.20614 11.51250 22.18010 21.75206 17.02718 
##     2024 
## 31.72388

Giải thích: Đoạn mã tính tổng giá trị các chỉ tiêu tài chính theo từng năm (tong_nam) và tốc độ tăng trưởng (%) giữa các năm (tangtruong_tong). Kết quả cho thấy quy mô tài chính của VPBank được tổng hợp cho giai đoạn 2015–2024.

Nhận xét: Tổng giá trị tăng từ 3.471.104.554 (2015) lên 17.473.312.798 (2024). Tốc độ tăng trưởng dao động từ 11,51% đến 31,72%, cao nhất ở năm 2024, thể hiện xu hướng mở rộng mạnh mẽ và tăng trưởng ổn định của VPBank trong 10 năm.

2.2 Xử lí thô và mã hoá dữ liệu

Giải thích: sum(duplicated(ck)): Đếm xem có bao nhiêu hàng trong dữ liệu bị trùng lặp. ck <- na.omit(ck): Xóa bỏ tất cả các hàng có giá trị NA. sum(is.na(ck)): Đếm lại để xác nhận không còn giá trị NA nào. names(ck) <- trimws(names(ck)): Xóa các khoảng trắng thừa ở đầu và cuối tên của tất cả các cột.

2.2.1 Kiểm tra các quan sát trùng lặp

sum(duplicated(ck))
## [1] 1

Nhận xét: Kết quả trả về bằng 0, cho thấy dữ liệu không có quan sát trùng lặp. Điều này chứng tỏ bộ dữ liệu đảm bảo độ tin cậy và tính toàn vẹn cao cho các bước phân tích tiếp theo.

2.2.2 Loại bỏ các giá trị bị thiếu (NA) và làm sạch dữ liệu

ck <- read_excel("~/Downloads/du lieu vp bank (1).xlsx")
ck <- na.omit(ck)    
sum(is.na(ck))        
## [1] 0

Nhận xét: Kết quả trả về 0, bộ dữ liệu đã được làm sạch và đảm bảo độ tin cậy cho quá trình thống kê tiếp theo.

2.2.3 Chuẩn hóa tên biến trong bộ dữ liệu

names(ck) <- trimws(names(ck))

2.2.4 Tạo biến tỷ suất lợi nhuận sau thuế trên thu nhập lãi

suppressPackageStartupMessages(library(stringi))

names(ck) <- stri_trans_general(names(ck), "Latin-ASCII")
names(ck)[1] <- "CHI_TIEU"                          
ck$CHI_TIEU <- stri_enc_toutf8(ck$CHI_TIEU)
ck$CHI_TIEU_ASCII <- stri_trans_general(ck$CHI_TIEU, "Latin-ASCII")
idx_lai  <- grep("thu nhap lai",        ck$CHI_TIEU_ASCII, ignore.case = TRUE)
idx_thue <- grep("(loi nhuan|ln).*sau thue", ck$CHI_TIEU_ASCII, ignore.case = TRUE)

if (length(idx_lai)  == 0) stop("Không tìm thấy chỉ tiêu Thu nhập lãi.")
if (length(idx_thue) == 0) stop("Không tìm thấy chỉ tiêu Lợi nhuận sau thuế.")

idx_lai  <- idx_lai[1]
idx_thue <- idx_thue[1]
cols_year <- as.character(2015:2024)
thu_nhap_lai <- as.numeric(ck[idx_lai,  cols_year, drop = TRUE])
ln_sau_thue  <- as.numeric(ck[idx_thue, cols_year, drop = TRUE])

ty_suat <- (ln_sau_thue / thu_nhap_lai) * 100
ty_suat[!is.finite(ty_suat)] <- NA  

ket_qua <- data.frame(
  Nam = 2015:2024,
  Ty_suat_LNST_thu_nhap_lai = round(ty_suat, 2),
  check.names = FALSE
)

print(ket_qua, row.names = FALSE)
##   Nam Ty_suat_LNST_thu_nhap_lai
##  2015                     12.77
##  2016                     15.35
##  2017                     18.87
##  2018                     18.26
##  2019                     16.56
##  2020                     19.89
##  2021                     22.58
##  2022                     27.18
##  2023                     11.10
##  2024                     19.96

Nhận xét: Nhìn chung, tỷ suất này có xu hướng tăng trong giai đoạn 2015-2022, đạt đỉnh 27.18% vào năm 2022. Tuy nhiên, có một sự biến động rất mạnh vào 2 năm cuối: Tỷ suất giảm đột ngột xuống mức thấp nhất (11.10%) vào năm 2023, sau đó đã phục hồi đáng kể lên 19.96% vào năm 2024.

2.2.5 Tạo biến ROA — tỷ suất sinh lời trên tổng tài sản

names(ck)[1] <- "CHI_TIEU"

ck$CHI_TIEU_ASCII <- stringi::stri_trans_general(ck$CHI_TIEU, "Latin-ASCII")

cat("📄 10 dòng đầu sau khi chuẩn hóa:\n")
## 📄 10 dòng đầu sau khi chuẩn hóa:
print(head(ck$CHI_TIEU_ASCII, 10))
##  [1] "A. TONG TAI SAN"                          
##  [2] "I. Tien mat, vang bac, da quy"            
##  [3] "II. Tien gui tai Ngan hang nha nuoc"      
##  [4] "III. Tien gui va cho vay cac TCTD khac"   
##  [5] "1. Tien gui tai cac TCTD khac"            
##  [6] "2. Cho vay cac TCTD khac"                 
##  [7] "3. Du phong rui ro cho vay TCTD khac"     
##  [8] "IV. Chung khoan kinh doanh rong"          
##  [9] "1. Chung khoan kinh doanh"                
## [10] "2. Du phong rui ro chung khoan kinh doanh"
idx_loi <- grep("LOI NHUAN", ck$CHI_TIEU_ASCII, ignore.case = TRUE)
idx_taisan <- grep("TONG TAI SAN", ck$CHI_TIEU_ASCII, ignore.case = TRUE)

if (length(idx_loi) > 0 & length(idx_taisan) > 0) {
  cols_year <- as.character(2015:2024)
  tong_taisan <- as.numeric(unlist(ck[idx_taisan[1], cols_year]))
  loi_nhuan <- as.numeric(unlist(ck[idx_loi[1], cols_year]))
  ROA <- round((loi_nhuan / tong_taisan) * 100, 2)
  ROA_df <- data.frame(Nam = 2015:2024, ROA)
  print(ROA_df)
} else {
  cat("⚠️ Vẫn chưa tìm thấy, chạy lệnh sau để kiểm tra:\n")
  cat("grep('NHUAN', ck$CHI_TIEU_ASCII, value = TRUE)\n")
  cat("grep('TAI SAN', ck$CHI_TIEU_ASCII, value = TRUE)\n")
}
##     Nam  ROA
## 1  2015 1.40
## 2  2016 1.64
## 3  2017 1.64
## 4  2018 1.60
## 5  2019 3.13
## 6  2020 4.16
## 7  2021 4.10
## 8  2022 2.65
## 9  2023 2.29
## 10 2024 2.60

Nhận xét: ROA ổn định ở mức thấp (1.4-1.6%) trong giai đoạn 2015-2018, sau đó tăng vọt và đạt đỉnh vào năm 2020 (4.16%). Từ 2022, ROA đã điều chỉnh giảm nhưng vẫn duy trì ở mặt bằng mới cao hơn (quanh 2.3-2.6%).

2.2.6 Tạo biến ROE - Tỷ suất lợi nhuận trên vốn chủ sở hữu

idx_loi <- grep("LOI NHUAN", ck$CHI_TIEU_ASCII, ignore.case = TRUE)
idx_von <- grep("VON CHU SO HUU", ck$CHI_TIEU_ASCII, ignore.case = TRUE)

if (length(idx_loi) > 0 & length(idx_von) > 0) {
  cols_year <- as.character(2015:2024)
  loi_nhuan <- as.numeric(unlist(ck[idx_loi[1], cols_year]))
  von_chu_so_huu <- as.numeric(unlist(ck[idx_von[1], cols_year]))
  ROE <- round((loi_nhuan / von_chu_so_huu) * 100, 2)
  
  ROE_df <- data.frame(Nam = 2015:2024, ROE)
  print(ROE_df)
} else {
  cat("⚠️ Không tìm thấy dòng 'Lợi nhuận' hoặc 'Vốn chủ sở hữu'.\n")
  cat("👉 Kiểm tra bằng:\n")
  cat("grep('NHUAN', ck$CHI_TIEU_ASCII, value = TRUE)\n")
  cat("grep('VON', ck$CHI_TIEU_ASCII, value = TRUE)\n")
}
##     Nam   ROE
## 1  2015 20.31
## 2  2016 21.87
## 3  2017 15.37
## 4  2018 14.93
## 5  2019 27.97
## 6  2020 32.99
## 7  2021 26.01
## 8  2022 16.19
## 9  2023 13.41
## 10 2024 16.30

Nhận xét: ROE biến động rất mạnh trong giai đoạn này. ROE giảm từ 2015 xuống mức thấp nhất vào năm 2018 (14.93%), sau đó tăng vọt lên đỉnh điểm vào năm 2020 (32.99%). Từ 2021, ROE lại giảm mạnh và duy trì ở mức thấp hơn (quanh 13% - 16%) trong giai đoạn 2022-2024.

2.2.7 Tạo biến NIM — tỷ suất lợi nhuận ròng

idx_lai_thuan <- grep("THU NHAP LAI THUAN", ck$CHI_TIEU_ASCII, ignore.case = TRUE)
idx_taisan <- grep("TONG TAI SAN", ck$CHI_TIEU_ASCII, ignore.case = TRUE)
if (length(idx_lai_thuan) > 0 & length(idx_taisan) > 0) {
  cols_year <- as.character(2015:2024)
  thu_lai_thuan <- as.numeric(unlist(ck[idx_lai_thuan[1], cols_year]))
  tong_tai_san <- as.numeric(unlist(ck[idx_taisan[1], cols_year]))
  NIM <- round((thu_lai_thuan / tong_tai_san) * 100, 2)
  
  NIM_df <- data.frame(Nam = 2015:2024, NIM)
  print(NIM_df)
} else {
  cat("⚠️ Không tìm thấy dòng 'Thu nhập lãi thuần' hoặc 'Tổng tài sản'.\n")
  cat("👉 Chạy lệnh sau để kiểm tra:\n")
  cat("grep('LAI', ck$CHI_TIEU_ASCII, value = TRUE)\n")
  cat("grep('TAI SAN', ck$CHI_TIEU_ASCII, value = TRUE)\n")
}
##     Nam  NIM
## 1  2015 5.34
## 2  2016 6.63
## 3  2017 7.42
## 4  2018 7.64
## 5  2019 8.13
## 6  2020 7.72
## 7  2021 6.27
## 8  2022 6.50
## 9  2023 4.67
## 10 2024 5.31

Nhận xét: NIM có xu hướng tăng trưởng liên tục từ 2015 (5.34%) và đạt đỉnh vào năm 2019 (8.13%). Sau đỉnh, chỉ số này giảm đều đặn trong 4 năm tiếp theo, xuống mức thấp nhất là 4.67% vào năm 2023, trước khi có dấu hiệu phục hồi nhẹ vào năm 2024.

2.2.8 Tạo biến CAR — tỷ lệ an toàn vốn

idx_von_tu_co <- grep("VON DIEU LE", ck$CHI_TIEU_ASCII, ignore.case = TRUE)
idx_taisan_rui_ro <- grep("TONG TAI SAN", ck$CHI_TIEU_ASCII, ignore.case = TRUE)

if (length(idx_von_tu_co) > 0 & length(idx_taisan_rui_ro) > 0) {
  cols_year <- as.character(2015:2024)
  von_tu_co <- as.numeric(unlist(ck[idx_von_tu_co[1], cols_year]))
  tong_tai_san <- as.numeric(unlist(ck[idx_taisan_rui_ro[1], cols_year]))
  
  CAR <- round((von_tu_co / tong_tai_san) * 100, 2)
  CAR_df <- data.frame(Nam = 2015:2024, CAR)
  print(CAR_df)
} else {
  cat("⚠️ Không tìm thấy dòng 'Vốn điều lệ' hoặc 'Tổng tài sản'.\n")
  cat("👉 Chạy kiểm tra:\n")
  cat("grep('VON', ck$CHI_TIEU_ASCII, value = TRUE)\n")
  cat("grep('TAI SAN', ck$CHI_TIEU_ASCII, value = TRUE)\n")
}
##     Nam   CAR
## 1  2015  4.16
## 2  2016  4.01
## 3  2017  5.65
## 4  2018  7.83
## 5  2019  6.71
## 6  2020  6.04
## 7  2021  8.23
## 8  2022 10.69
## 9  2023  9.70
## 10 2024  8.59

Nhận xét: CAR có xu hướng tăng rõ rệt trong dài hạn, dù có nhiều biến động. Chỉ số này ở mức thấp nhất vào năm 2016 (4.01%), sau đó tăng trưởng không ổn định nhưng đạt đỉnh cao nhất là 10.69% vào năm 2022. Hai năm cuối 2023-2024, CAR có sự điều chỉnh giảm nhẹ nhưng vẫn duy trì ở mức cao.

2.2.9 Tạo biến tốc độ tăng trưởng tín dụng

vpbank_data <- data.frame(
  Nam = 2015:2024,
  ChoVayKhachHang = c(116804247, 144673213, 182666213, 221961996, 
                      257183959, 290816086, 355281219, 438338047, 
                      566271290, 692875738)
)

vpbank_growth <- vpbank_data %>%
  arrange(Nam) %>% 
  mutate(
    ChoVayNamTruoc = lag(ChoVayKhachHang), 
    TocDoTangTruong = ((ChoVayKhachHang - ChoVayNamTruoc) / ChoVayNamTruoc) * 100
  )
vpbank_growth_formatted <- vpbank_growth %>%
  mutate(
    ChoVayKhachHang = comma(ChoVayKhachHang, accuracy = 1),
    TocDoTangTruong_Formatted = paste0(round(TocDoTangTruong, 2), "%")
  ) %>%
  mutate(TocDoTangTruong_Formatted = ifelse(is.na(TocDoTangTruong), "N/A", TocDoTangTruong_Formatted))
print("Bảng tốc độ tăng trưởng tín dụng của VPBank (2015-2024)")
## [1] "Bảng tốc độ tăng trưởng tín dụng của VPBank (2015-2024)"
print(select(vpbank_growth_formatted, Nam, ChoVayKhachHang, TocDoTangTruong_Formatted))
##     Nam ChoVayKhachHang TocDoTangTruong_Formatted
## 1  2015     116,804,247                       N/A
## 2  2016     144,673,213                    23.86%
## 3  2017     182,666,213                    26.26%
## 4  2018     221,961,996                    21.51%
## 5  2019     257,183,959                    15.87%
## 6  2020     290,816,086                    13.08%
## 7  2021     355,281,219                    22.17%
## 8  2022     438,338,047                    23.38%
## 9  2023     566,271,290                    29.19%
## 10 2024     692,875,738                    22.36%

Nhận xét: Tốc độ tăng trưởng tín dụng luôn duy trì ở mức cao và tích cực (trên 13%) trong suốt giai đoạn 2016-2024. Giai đoạn 2018-2020 có xu hướng tăng trưởng chậm lại, xuống mức thấp nhất là 13.08%. Tuy nhiên, từ 2021, tốc độ tăng trưởng đã tăng tốc trở lại mạnh mẽ, đạt đỉnh 29.19% vào năm 2023.

2.2.10 Tỷ lệ nợ trên tài sản

cols_year <- as.character(2015:2024)
idx_ts <- grep("A. TONG TAI SAN", ck$CHI_TIEU_ASCII, ignore.case = TRUE)
idx_no <- grep("B. TONG NO PHAI TRA", ck$CHI_TIEU_ASCII, ignore.case = TRUE)

tong_ts <- as.numeric(unlist(ck[idx_ts[1], cols_year]))
tong_no <- as.numeric(unlist(ck[idx_no[1], cols_year]))

Ty_le_no_taisan <- round((tong_no / tong_ts) * 100, 2)

Ty_le_no_taisan_df <- data.frame(
  Nam = 2015:2024,
  Ty_le_no_tren_tai_san = Ty_le_no_taisan
)

Ty_le_no_taisan_df
##     Nam Ty_le_no_tren_tai_san
## 1  2015                 93.09
## 2  2016                 92.49
## 3  2017                 89.31
## 4  2018                 89.25
## 5  2019                 88.81
## 6  2020                 87.40
## 7  2021                 84.24
## 8  2022                 83.60
## 9  2023                 82.90
## 10 2024                 84.06

Nhận xét: Bảng số liệu cho thấy một xu hướng giảm rõ rệt và nhất quán của tỷ lệ nợ trên tài sản qua các năm. Tỷ lệ này cao nhất vào năm 2015 (93.09%) và đã giảm liên tục qua các năm, xuống mức thấp nhất vào năm 2023 (82.90%), trước khi tăng nhẹ trở lại vào năm 2024. Điều này cho thấy cơ cấu vốn ít phụ thuộc vào nợ hơn.

2.2.11 Tạo biến tốc độ tăng trưởng tổng tài sản theo năm

year_cols <- intersect(colnames(ck), as.character(2015:2024))

a_rows <- which(startsWith(ck[[1]], "A"))

if (length(a_rows) == 0) stop("Không tìm thấy nhóm bắt đầu bằng 'A.' trong cột chỉ tiêu.")

last_year <- tail(year_cols, 1)
idx_taisan <- a_rows[ which.max( suppressWarnings( as.numeric(ck[a_rows, last_year][[1]]) ) ) ]

taisan <- suppressWarnings( as.numeric( unlist(ck[idx_taisan, year_cols]) ) )
tangtruong_taisan <- round( (taisan - dplyr::lag(taisan)) / dplyr::lag(taisan) * 100, 2)
tangtruong_taisan[!is.finite(tangtruong_taisan)] <- NA

data.frame(
  Nam = as.integer(year_cols),
  Tong_tai_san = taisan,
  Tang_truong = tangtruong_taisan
)
##     Nam Tong_tai_san Tang_truong
## 1  2015    193876428          NA
## 2  2016    228770918       18.00
## 3  2017    277752314       21.41
## 4  2018    323291119       16.40
## 5  2019    377204126       16.68
## 6  2020    419026527       11.09
## 7  2021    547409439       30.64
## 8  2022    631012886       15.27
## 9  2023    817566922       29.56
## 10 2024    923847637       13.00

Nhận xét: Tổng tài sản tăng trưởng liên tục qua tất cả các năm, tăng từ ~193 tỷ lên ~923 tỷ. Tuy nhiên, tốc độ tăng trưởng biến động mạnh: Chậm nhất vào năm 2020 (chỉ 11.09%). Cao đột biến vào các năm 2017 (21.41%), 2021 (30.64%), và 2023 (29.56%). Các năm còn lại duy trì tốc độ tăng trưởng ở mức 13% - 18%.

2.3 Thực hiện các thống kê cơ bản

Giải thích: summary, mean, sd: Tính các thống kê mô tả cơ bản, bao gồm 6 giá trị tóm tắt (Min, Max, Trung vị…), giá trị trung bình và độ lệch chuẩn. cv <- function(…): Định nghĩa một hàm mới tên là cv để tính hệ số biến thiên (CV). cv_values <- c(…): Áp dụng hàm cv vừa tạo cho tất cả 6 biến để xem mức độ biến động tương đối của chúng. round(cv_values, 2): Làm tròn kết quả CV cho dễ đọc. sort(cv_values, decreasing = TRUE): Sắp xếp các hệ số CV theo thứ tự giảm dần để xác định biến nào có độ dao động lớn nhất. round(…): Làm tròn các kết quả trong bảng. financial_data_clean <- na.omit(financial_data): Tạo một dataframe mới đã loại bỏ tất cả các hàng có giá trị (NA), chuẩn bị cho việc tính tương quan. cor_matrix <- cor(…): Tính ma trận hệ số tương quan (r) giữa tất cả các cặp biến trong bộ dữ liệu đã làm sạch. cor_test <- rcorr(…): Tính toán đồng thời cả ma trận hệ số tương quan (r) và ma trận giá trị p (P-value) (để kiểm tra ý nghĩa thống kê). cor_test\(r / cor_test\)P: Hiển thị riêng từng ma trận kết quả (r và P). cor_summary <- data.frame(…): Chuyển đổi dữ liệu từ dạng ma trận sang dạng bảng dài, gộp hệ số r và p-value vào chung một bảng. cor_summary <- cor_summary[…]: Loại bỏ các hàng thừa. cor_summary[order(…)]: Sắp xếp bảng theo độ lớn của hệ số tương quan. strong_corr <- subset(…): Lọc từ bảng tổng hợp để chỉ giữ lại các cặp biến có tương quan mạnh (độ lớn |r|>0.5) và có ý nghĩa thống kê (p<0.05). weak_corr <- subset(…): Lọc ra các cặp biến có tương quan yếu (độ lớn |r|<=0.3) hoặc không có ý nghĩa thống kê (p>=0.05). cor_ranking <- cor_summary[…]: Sắp xếp lại toàn bộ bảng tương quan theo thứ tự giảm dần của độ lớn |r|, để xem các cặp nào liên quan chặt nhất. roa_corr <- subset(…): Lọc riêng ra các mối tương quan chỉ liên quan đến ROA. roa_corr[order(…)]: Sắp xếp để tìm biến nào tương quan mạnh nhất/yếu nhất với ROA. roe_corr <- subset(…): Lọc riêng ra các mối tương quan chỉ liên quan đến ROE và sắp xếp chúng.

2.3.1 Biến ROA

summary(ROA_df$ROA)
##    Min. 1st Qu.  Median    Mean 3rd Qu.    Max. 
##   1.400   1.640   2.445   2.521   3.010   4.160
mean(ROA_df$ROA, na.rm = TRUE)
## [1] 2.521
sd(ROA_df$ROA, na.rm = TRUE)
## [1] 1.015649

Nhận xét: Dữ liệu có giá trị trung bình là 2.521 và trung vị là 2.445. Hai giá trị này rất gần nhau, cho thấy phân phối dữ liệu khá đối xứng. Dữ liệu dao động trong khoảng từ 1.40 đến 4.16, với độ lệch chuẩn là 1.016.

2.3.2 Biến ROE

summary(ROE_df$ROE)
##    Min. 1st Qu.  Median    Mean 3rd Qu.    Max. 
##   13.41   15.57   18.30   20.54   24.98   32.99
mean(ROE_df$ROE, na.rm = TRUE)
## [1] 20.535
sd(ROE_df$ROE, na.rm = TRUE)
## [1] 6.564956

Nhận xét: Giá trị trung bình (20.54) cao hơn đáng kể so với trung vị (18.30). Điều này cho thấy phân phối dữ liệu bị lệch phải. Dữ liệu có độ biến động khá lớn, thể hiện qua độ lệch chuẩn là 6.56 và khoảng giá trị rộng (từ 13.41 đến 32.99).

2.3.3 Biến NIM

summary(NIM_df$NIM)
##    Min. 1st Qu.  Median    Mean 3rd Qu.    Max. 
##   4.670   5.572   6.565   6.563   7.585   8.130
mean(NIM_df$NIM, na.rm = TRUE)
## [1] 6.563
sd(NIM_df$NIM, na.rm = TRUE)
## [1] 1.175302

Nhận xét: Giá trị trung bình (Mean) (6.563) và trung vị (Median) (6.565) gần như bằng hệt nhau. Điều này cho thấy phân phối dữ liệu rất đối xứng. Dữ liệu dao động trong khoảng từ 4.67 đến 8.13, với độ lệch chuẩn là 1.175.

2.3.4 Biến CAR

summary(CAR_df$CAR)
##    Min. 1st Qu.  Median    Mean 3rd Qu.    Max. 
##   4.010   5.747   7.270   7.161   8.500  10.690
mean(CAR_df$CAR, na.rm = TRUE)
## [1] 7.161
sd(CAR_df$CAR, na.rm = TRUE)
## [1] 2.241296

Nhận xét: Dữ liệu phân bố khá đối xứng, với giá trị trung bình (7.16) và trung vị (7.27) rất gần nhau. Dữ liệu có độ phân tán (độ lệch chuẩn) là 2.24 và trải rộng trong khoảng từ 4.01 đến 10.69.

2.3.5 Biến tỷ lệ nợ trên tài sản

summary(Ty_le_no_taisan_df$Ty_le_no_tren_tai_san)
##    Min. 1st Qu.  Median    Mean 3rd Qu.    Max. 
##   82.90   84.11   88.11   87.52   89.30   93.09
mean(Ty_le_no_taisan_df$Ty_le_no_tren_tai_san, na.rm = TRUE)
## [1] 87.515
sd(Ty_le_no_taisan_df$Ty_le_no_tren_tai_san, na.rm = TRUE)
## [1] 3.697474

Nhận xét: Giá trị trung bình (87.52) thấp hơn một chút so vớI trung vị (88.11). Điều này cho thấy dữ liệu phân bố hơi lệch trái. Dữ liệu tương đối tập trung, với độ lệch chuẩn là 3.70 và dao động trong khoảng từ 82.90 đến 93.09.

2.3.6 Biến tăng trưởng tổng tài sản

summary(tangtruong_taisan)
##    Min. 1st Qu.  Median    Mean 3rd Qu.    Max.    NA's 
##   11.09   15.27   16.68   19.12   21.41   30.64       1
mean(tangtruong_taisan, na.rm = TRUE)
## [1] 19.11667
sd(tangtruong_taisan, na.rm = TRUE)
## [1] 6.876702

Nhận xét: Giá trị trung bình (19.12) cao hơn đáng kể so với trung vị (16.68). Điều này cho thấy phân phối dữ liệu bị lệch phải nghĩa là có một vài năm với mức tăng trưởng rất cao (như 30.64%) đã kéo giá trị trung bình lên. Dữ liệu có độ phân tán lớn, thể hiện qua độ lệch chuẩn là 6.88.

2.3.7 Tính hệ số biến thiên (CV) từng biến

cv <- function(x) sd(x, na.rm = TRUE)/mean(x, na.rm = TRUE)*100
cv_values <- c(
ROA = cv(ROA_df$ROA),
ROE = cv(ROE_df$ROE),
NIM = cv(NIM_df$NIM),
CAR = cv(CAR_df$CAR),
Ty_le_no_taisan = cv(Ty_le_no_taisan_df$Ty_le_no_tren_tai_san),
Tang_truong_taisan = cv(tangtruong_taisan)
)
round(cv_values, 2)
##                ROA                ROE                NIM                CAR 
##              40.29              31.97              17.91              31.30 
##    Ty_le_no_taisan Tang_truong_taisan 
##               4.22              35.97

Nhận xét: ROA (40.29%), tăng trưởng tài sản (35.97%), ROE (31.97%), và CAR (31.30%) là các biến có độ biến động cao nhất, cho thấy sự thay đổi lớn và thiếu ổn định qua các năm. Ngược lại, tỷ lệ nợ trên tài sản (4.22%) có độ biến động rất thấp, cho thấy chỉ số này cực kỳ ổn định và nhất quán theo thời gian.

2.3.8 So sánh độ dao động giữa các biến

sort(cv_values, decreasing = TRUE)
##                ROA Tang_truong_taisan                ROE                CAR 
##          40.287553          35.972284          31.969594          31.298652 
##                NIM    Ty_le_no_taisan 
##          17.907997           4.224961

Nhận xét: ROA (40.29%) là biến biến động mạnh nhất, cho thấy sự bất ổn định cao nhất. Tăng trưởng tài sản, ROE, và CAR cũng có độ biến động rất cao. Ngược lại, tỷ lệ nợ trên tài sản (4.22%) là biến ổn định nhất và ít thay đổi nhất.

2.3.9 Tạo dataframe

financial_data <- data.frame(
  ROA = ROA_df$ROA,
  ROE = ROE_df$ROE,
  NIM = NIM_df$NIM,
  CAR = CAR_df$CAR,
  Ty_le_no_taisan = Ty_le_no_taisan_df$Ty_le_no_tren_tai_san,
  Tang_truong_ts = tangtruong_taisan
)
financial_data_clean <- na.omit(financial_data)

2.3.10 Tính ma trận tương quan Pearson

cor_matrix <- cor(financial_data_clean)
round(cor_matrix, 2)
##                   ROA   ROE   NIM   CAR Ty_le_no_taisan Tang_truong_ts
## ROA              1.00  0.77  0.08  0.16           -0.42           0.03
## ROE              0.77  1.00  0.51 -0.44            0.23          -0.22
## NIM              0.08  0.51  1.00 -0.53            0.67          -0.46
## CAR              0.16 -0.44 -0.53  1.00           -0.89           0.22
## Ty_le_no_taisan -0.42  0.23  0.67 -0.89            1.00          -0.32
## Tang_truong_ts   0.03 -0.22 -0.46  0.22           -0.32           1.00

Nhận xét: CAR và Ty_le_no có tương quan nghịch rất mạnh (-0.89). Khi an toàn vốn tăng, tỷ lệ nợ giảm mạnh. ROA và ROE có tương quan đồng biến rất mạnh (0.77). NIM có tương quan dương đáng kể với Ty_le_no (0.67) và ROE (0.51). NIM có tương quan âm đáng kể với CAR (-0.53). ROA gần như không tương quan với NIM (0.08) và Tang_truong_ts (0.03). Tang_truong_ts không thể hiện mối quan hệ mạnh với bất kỳ biến nào khác.

2.3.11 Kiểm tra ý nghĩa thống kê với Hmisc

library(Hmisc)
cor_test <- rcorr(as.matrix(financial_data_clean))
cor_test$r    
##                         ROA        ROE         NIM        CAR Ty_le_no_taisan
## ROA              1.00000000  0.7746662  0.08244197  0.1605221      -0.4220318
## ROE              0.77466623  1.0000000  0.51246824 -0.4378818       0.2297959
## NIM              0.08244197  0.5124682  1.00000000 -0.5304832       0.6693397
## CAR              0.16052207 -0.4378818 -0.53048321  1.0000000      -0.8920808
## Ty_le_no_taisan -0.42203180  0.2297959  0.66933974 -0.8920808       1.0000000
## Tang_truong_ts   0.02982593 -0.2216421 -0.46026569  0.2153410      -0.3176586
##                 Tang_truong_ts
## ROA                 0.02982593
## ROE                -0.22164208
## NIM                -0.46026569
## CAR                 0.21534095
## Ty_le_no_taisan    -0.31765863
## Tang_truong_ts      1.00000000
cor_test$P    
##                        ROA        ROE        NIM         CAR Ty_le_no_taisan
## ROA                     NA 0.01423142 0.83299894 0.679927831     0.257846662
## ROE             0.01423142         NA 0.15835437 0.238476722     0.551977649
## NIM             0.83299894 0.15835437         NA 0.141755018     0.048624519
## CAR             0.67992783 0.23847672 0.14175502          NA     0.001221556
## Ty_le_no_taisan 0.25784666 0.55197765 0.04862452 0.001221556              NA
## Tang_truong_ts  0.93928415 0.56655264 0.21251037 0.577911531     0.404846704
##                 Tang_truong_ts
## ROA                  0.9392841
## ROE                  0.5665526
## NIM                  0.2125104
## CAR                  0.5779115
## Ty_le_no_taisan      0.4048467
## Tang_truong_ts              NA

Nhận xét: Quan hệ có ý nghĩa thống kê (p<0.05): CAR và Ty_le_no_taisan: Tương quan nghịch rất mạnh (r=-0.89, p=0.001). ROA và ROE: Tương quan đồng biến mạnh (r=0.77, p=0.014). NIM và Ty_le_no_taisan: Tương quan đồng biến (r = 0.67, p = 0.048). Quan hệ không có ý nghĩa thống kê (p>0.05): Các mối quan hệ khác, ngay cả khi có r trung bình (như NIM và CAR r=-0.53), đều có p-value cao. Điều này có nghĩa là không có đủ bằng chứng thống kê để kết luận chúng có mối liên hệ tuyến tính.

2.3.12 Tạo bảng tổng hợp hệ số tương quan và giá trị p

cor_summary <- data.frame(
  Var1 = rep(colnames(financial_data_clean), each = ncol(financial_data_clean)),
  Var2 = rep(colnames(financial_data_clean), times = ncol(financial_data_clean)),
  Correlation = as.vector(cor_test$r),
  P_value = as.vector(cor_test$P)
)

cor_summary <- cor_summary[cor_summary$Var1 != cor_summary$Var2, ]
cor_summary[order(-abs(cor_summary$Correlation)), ]
##               Var1            Var2 Correlation     P_value
## 23             CAR Ty_le_no_taisan -0.89208080 0.001221556
## 28 Ty_le_no_taisan             CAR -0.89208080 0.001221556
## 2              ROA             ROE  0.77466623 0.014231418
## 7              ROE             ROA  0.77466623 0.014231418
## 17             NIM Ty_le_no_taisan  0.66933974 0.048624519
## 27 Ty_le_no_taisan             NIM  0.66933974 0.048624519
## 16             NIM             CAR -0.53048321 0.141755018
## 21             CAR             NIM -0.53048321 0.141755018
## 9              ROE             NIM  0.51246824 0.158354367
## 14             NIM             ROE  0.51246824 0.158354367
## 18             NIM  Tang_truong_ts -0.46026569 0.212510374
## 33  Tang_truong_ts             NIM -0.46026569 0.212510374
## 10             ROE             CAR -0.43788184 0.238476722
## 20             CAR             ROE -0.43788184 0.238476722
## 5              ROA Ty_le_no_taisan -0.42203180 0.257846662
## 25 Ty_le_no_taisan             ROA -0.42203180 0.257846662
## 30 Ty_le_no_taisan  Tang_truong_ts -0.31765863 0.404846704
## 35  Tang_truong_ts Ty_le_no_taisan -0.31765863 0.404846704
## 11             ROE Ty_le_no_taisan  0.22979588 0.551977649
## 26 Ty_le_no_taisan             ROE  0.22979588 0.551977649
## 12             ROE  Tang_truong_ts -0.22164208 0.566552640
## 32  Tang_truong_ts             ROE -0.22164208 0.566552640
## 24             CAR  Tang_truong_ts  0.21534095 0.577911531
## 34  Tang_truong_ts             CAR  0.21534095 0.577911531
## 4              ROA             CAR  0.16052207 0.679927831
## 19             CAR             ROA  0.16052207 0.679927831
## 3              ROA             NIM  0.08244197 0.832998944
## 13             NIM             ROA  0.08244197 0.832998944
## 6              ROA  Tang_truong_ts  0.02982593 0.939284146
## 31  Tang_truong_ts             ROA  0.02982593 0.939284146

Nhận xét: Các mối tương quan có ý nghĩa thống kê (P_value<0.05): CAR và Ty_le_no_taisan: Tương quan nghịch rất mạnh (r=-0.89). Đây là mối quan hệ mạnh nhất và đáng tin cậy nhất. ROA và ROE: Tương quan đồng biến mạnh (r=0.77). NIM và Ty_le_no_taisan: Tương quan đồng biến (r=0.67). Các mối tương quan không có ý nghĩa thống kê (P_value>0.05): Mặc dù NIM và CAR (r=-0.53) hay ROE và NIM (r=0.51) có vẻ tương quan ở mức trung bình, nhưng giá trị P-value của chúng (0.14 và 0.15) đều lớn. Không có đủ bằng chứng thống kê để kết luận rằng NIM có mối liên hệ tuyến tính với CAR hay ROE trong bộ dữ liệu này.

2.3.13 Xác định các cặp biến có tương quan mạnh (|r|>0.5 & p<0.05)

strong_corr <- subset(cor_summary, abs(Correlation) > 0.5 & P_value < 0.05)
strong_corr
##               Var1            Var2 Correlation     P_value
## 2              ROA             ROE   0.7746662 0.014231418
## 7              ROE             ROA   0.7746662 0.014231418
## 17             NIM Ty_le_no_taisan   0.6693397 0.048624519
## 23             CAR Ty_le_no_taisan  -0.8920808 0.001221556
## 27 Ty_le_no_taisan             NIM   0.6693397 0.048624519
## 28 Ty_le_no_taisan             CAR  -0.8920808 0.001221556

Nhận xét: CAR và Ty_le_no_taisan: Tương quan nghịch rất mạnh (r = -0.89). ROA và ROE: Tương quan đồng biến mạnh (r=0.77). NIM và Ty_le_no_taisan: Tương quan đồng biến (r=0.67).

2.3.14 Xác định các cặp biến có tương quan yếu hoặc không đáng kể

weak_corr <- subset(cor_summary, abs(Correlation) <= 0.3 | P_value >= 0.05)
weak_corr
##               Var1            Var2 Correlation   P_value
## 3              ROA             NIM  0.08244197 0.8329989
## 4              ROA             CAR  0.16052207 0.6799278
## 5              ROA Ty_le_no_taisan -0.42203180 0.2578467
## 6              ROA  Tang_truong_ts  0.02982593 0.9392841
## 9              ROE             NIM  0.51246824 0.1583544
## 10             ROE             CAR -0.43788184 0.2384767
## 11             ROE Ty_le_no_taisan  0.22979588 0.5519776
## 12             ROE  Tang_truong_ts -0.22164208 0.5665526
## 13             NIM             ROA  0.08244197 0.8329989
## 14             NIM             ROE  0.51246824 0.1583544
## 16             NIM             CAR -0.53048321 0.1417550
## 18             NIM  Tang_truong_ts -0.46026569 0.2125104
## 19             CAR             ROA  0.16052207 0.6799278
## 20             CAR             ROE -0.43788184 0.2384767
## 21             CAR             NIM -0.53048321 0.1417550
## 24             CAR  Tang_truong_ts  0.21534095 0.5779115
## 25 Ty_le_no_taisan             ROA -0.42203180 0.2578467
## 26 Ty_le_no_taisan             ROE  0.22979588 0.5519776
## 30 Ty_le_no_taisan  Tang_truong_ts -0.31765863 0.4048467
## 31  Tang_truong_ts             ROA  0.02982593 0.9392841
## 32  Tang_truong_ts             ROE -0.22164208 0.5665526
## 33  Tang_truong_ts             NIM -0.46026569 0.2125104
## 34  Tang_truong_ts             CAR  0.21534095 0.5779115
## 35  Tang_truong_ts Ty_le_no_taisan -0.31765863 0.4048467

Nhận xét: Tất cả các giá trị P_value trong bảng này đều lớn hơn 0.05. Điều này có nghĩa là, ngay cả khi một số cặp có hệ số tương quan ở mức trung bình (như ROE và NIM là 0.51, hay ROA và Ty_le_no_taisan là -0.42), chúng ta không có đủ bằng chứng thống kê để kết luận rằng có một mối quan hệ tuyến tính thực sự giữa chúng.

2.3.15 Xếp hạng các biến theo độ liên quan tổng thể

cor_ranking <- cor_summary[order(-abs(cor_summary$Correlation)), ]
cor_ranking
##               Var1            Var2 Correlation     P_value
## 23             CAR Ty_le_no_taisan -0.89208080 0.001221556
## 28 Ty_le_no_taisan             CAR -0.89208080 0.001221556
## 2              ROA             ROE  0.77466623 0.014231418
## 7              ROE             ROA  0.77466623 0.014231418
## 17             NIM Ty_le_no_taisan  0.66933974 0.048624519
## 27 Ty_le_no_taisan             NIM  0.66933974 0.048624519
## 16             NIM             CAR -0.53048321 0.141755018
## 21             CAR             NIM -0.53048321 0.141755018
## 9              ROE             NIM  0.51246824 0.158354367
## 14             NIM             ROE  0.51246824 0.158354367
## 18             NIM  Tang_truong_ts -0.46026569 0.212510374
## 33  Tang_truong_ts             NIM -0.46026569 0.212510374
## 10             ROE             CAR -0.43788184 0.238476722
## 20             CAR             ROE -0.43788184 0.238476722
## 5              ROA Ty_le_no_taisan -0.42203180 0.257846662
## 25 Ty_le_no_taisan             ROA -0.42203180 0.257846662
## 30 Ty_le_no_taisan  Tang_truong_ts -0.31765863 0.404846704
## 35  Tang_truong_ts Ty_le_no_taisan -0.31765863 0.404846704
## 11             ROE Ty_le_no_taisan  0.22979588 0.551977649
## 26 Ty_le_no_taisan             ROE  0.22979588 0.551977649
## 12             ROE  Tang_truong_ts -0.22164208 0.566552640
## 32  Tang_truong_ts             ROE -0.22164208 0.566552640
## 24             CAR  Tang_truong_ts  0.21534095 0.577911531
## 34  Tang_truong_ts             CAR  0.21534095 0.577911531
## 4              ROA             CAR  0.16052207 0.679927831
## 19             CAR             ROA  0.16052207 0.679927831
## 3              ROA             NIM  0.08244197 0.832998944
## 13             NIM             ROA  0.08244197 0.832998944
## 6              ROA  Tang_truong_ts  0.02982593 0.939284146
## 31  Tang_truong_ts             ROA  0.02982593 0.939284146

Nhận xét: Các mối tương quan có ý nghĩa thống kê (P_value<0.05): CAR và Ty_le_no_taisan: Tương quan nghịch rất mạnh (r=-0.89). Đây là mối quan hệ mạnh nhất và đáng tin cậy nhất. ROA và ROE: Tương quan đồng biến mạnh (r=0.77). NIM và Ty_le_no_taisan: Tương quan đồng biến (r=0.67). Các mối tương quan không có ý nghĩa thống kê (P_value>0.05): Mặc dù NIM và CAR (r=-0.53) hay ROE và NIM (r=0.51) có vẻ tương quan ở mức trung bình, nhưng giá trị P-value của chúng (0.14 và 0.15) đều lớn. Không có đủ bằng chứng thống kê để kết luận rằng NIM có mối liên hệ tuyến tính với CAR hay ROE.

2.3.16 Kiểm tra các biến ảnh hưởng mạnh nhất tới ROA

roa_corr <- subset(cor_summary, Var1 == "ROA" | Var2 == "ROA")
roa_corr[order(-abs(roa_corr$Correlation)), ]
##               Var1            Var2 Correlation    P_value
## 2              ROA             ROE  0.77466623 0.01423142
## 7              ROE             ROA  0.77466623 0.01423142
## 5              ROA Ty_le_no_taisan -0.42203180 0.25784666
## 25 Ty_le_no_taisan             ROA -0.42203180 0.25784666
## 4              ROA             CAR  0.16052207 0.67992783
## 19             CAR             ROA  0.16052207 0.67992783
## 3              ROA             NIM  0.08244197 0.83299894
## 13             NIM             ROA  0.08244197 0.83299894
## 6              ROA  Tang_truong_ts  0.02982593 0.93928415
## 31  Tang_truong_ts             ROA  0.02982593 0.93928415

Nhận xét: Quan hệ duy nhất có ý nghĩa thống kê (P_value<0.05) là giữa ROA và ROE. Chúng có mối tương quan đồng biến mạnh (r = 0.77). Tất cả các biến còn lại (Ty_le_no_taisan, CAR, NIM, Tang_truong_ts) đều không có tương quan ý nghĩa thống kê với ROA (vì P_value đều lớn hơn 0.05).

2.3.17 Kiểm tra các biến ảnh hưởng mạnh nhất tới ROE

roe_corr <- subset(cor_summary, Var1 == "ROE" | Var2 == "ROE")
roe_corr[order(-abs(roe_corr$Correlation)), ]
##               Var1            Var2 Correlation    P_value
## 2              ROA             ROE   0.7746662 0.01423142
## 7              ROE             ROA   0.7746662 0.01423142
## 9              ROE             NIM   0.5124682 0.15835437
## 14             NIM             ROE   0.5124682 0.15835437
## 10             ROE             CAR  -0.4378818 0.23847672
## 20             CAR             ROE  -0.4378818 0.23847672
## 11             ROE Ty_le_no_taisan   0.2297959 0.55197765
## 26 Ty_le_no_taisan             ROE   0.2297959 0.55197765
## 12             ROE  Tang_truong_ts  -0.2216421 0.56655264
## 32  Tang_truong_ts             ROE  -0.2216421 0.56655264

2.4 Trực quan hoá dữ liệu

Giải thích: geom_histogram(): hiển thị phân phối biến dưới dạng density. geom_density(): đường mật độ để so sánh với histogram. geom_vline(): đánh dấu trung bình (mean, màu xanh) và trung vị (median, màu xanh lá). geom_rug(): các giá trị quan sát dọc theo trục x. geom_boxplot(): phân vị, min, max, median. geom_jitter(): hiển thị từng điểm quan sát, tránh trùng chồng. stat_summary(fun=mean): đánh dấu trung bình. geom_text(): in giá trị từng quan sát. geom_point(): scatter plot, color theo nhóm, size theo biến thứ 3 nếu muốn. geom_smooth(method=“lm”): đường hồi quy tuyến tính ± khoảng tin cậy. geom_hline, geom_vline: đánh dấu trung bình theo trục x/y. scale_size_continuous(): chuẩn hóa kích thước điểm.

2.4.1 Histogram và Density các biến

2.4.1.1 ROA (Lợi nhuận trên tổng tài sản)

ggplot(financial_data_clean, aes(x=ROA)) +
  geom_histogram(aes(y=after_stat(density)), binwidth=0.01, fill="skyblue", color="black") +
  geom_density(color="red", size=1) +
  geom_vline(aes(xintercept=mean(ROA, na.rm=TRUE)), color="blue", linetype="dashed", size=1) +
  geom_vline(aes(xintercept=median(ROA, na.rm=TRUE)), color="green", linetype="dotted", size=1) +
  geom_rug() +
  ggtitle("Lợi nhuận trên tổng tài sản") +
  theme_minimal()

Nhận xét: Biểu đồ cho thấy dữ liệu ROA không phân phối chuẩn và tập trung thành nhiều cụm. Đa số các quan sát có ROA thấp (quanh 1.7), nhưng có các nhóm khác với ROA cao hơn (tới 4.0), làm cho giá trị trung bình (khoảng 2.6) cao hơn mức phổ biến nhất.

2.4.1.2 ROE (Lợi nhuận trên vốn chủ sở hữu)

ggplot(financial_data_clean, aes(x=ROE)) +
geom_histogram(aes(y=after_stat(density)), binwidth=0.01, fill="orange", color="black") +
geom_density(color="red", size=1) +
geom_vline(aes(xintercept=mean(ROE, na.rm=TRUE)), color="blue", linetype="dashed") +
geom_vline(aes(xintercept=median(ROE, na.rm=TRUE)), color="green", linetype="dotted") +
geom_rug() +
ggtitle("Lợi nhuận trên vốn chủ sở hữu") +
theme_minimal()

Nhận xét: ROE không phân phối chuẩn và tập trung thành nhiều cụm riêng biệt. Giá trị phổ biến nhất (mode, đỉnh cao nhất) nằm ở khoảng 16.5 - 17. Tuy nhiên, giá trị trung bình (đường nét đứt màu xanh) lại cao hơn đáng kể, ở khoảng 20.5, do ảnh hưởng của các nhóm có ROE cao hơn hẳn.

2.4.1.3 NIM (Biên lãi ròng)

ggplot(financial_data_clean, aes(x=NIM)) +
geom_histogram(aes(y=after_stat(density)), binwidth=0.01, fill="purple", color="black") +
geom_density(color="yellow", size=1) +
geom_vline(aes(xintercept=mean(NIM, na.rm=TRUE)), color="blue", linetype="dashed") +
geom_vline(aes(xintercept=median(NIM, na.rm=TRUE)), color="green", linetype="dotted") +
geom_rug() +
ggtitle("NIM (Biên lãi ròng)") +
theme_minimal()

Nhận xét: Phân phối: Dữ liệu không chuẩn, có nhiều đỉnh, phân cụm rõ rệt. Giá trị phổ biến (Mode): Có vẻ như có nhiều đỉnh cùng có chiều cao xấp xỉ nhau, cho thấy không có một giá trị nào chiếm ưu thế tuyệt đối. Các đỉnh cao nằm ở khoảng 4.8, 5.5, 6.3, 7.3,…Giá trị trung bình (Mean): Giá trị trung bình (khoảng 6.7) nằm gần một trong các cụm dữ liệu.

2.4.1.4 CAR (Tỷ lệ an toàn vốn)

ggplot(financial_data_clean, aes(x=CAR)) +
geom_histogram(aes(y=after_stat(density)), binwidth=0.01, fill="pink", color="black") +
geom_density(color="red", size=1) +
geom_vline(aes(xintercept=mean(CAR, na.rm=TRUE)), color="blue", linetype="dashed") +
geom_vline(aes(xintercept=median(CAR, na.rm=TRUE)), color="green", linetype="dotted") +
geom_rug() +
ggtitle("CAR (Tỷ lệ an toàn vốn)") +
theme_minimal()

Nhận xét: Phân phối: Dữ liệu không chuẩn, tập trung thành nhiều cụm. Giá trị phổ biến (Mode): Đỉnh cao nhất (phổ biến nhất) nằm ở khoảng CAR ≈ 4.1. Giá trị trung bình (Mean): Đường màu xanh nét đứt cho thấy giá trị trung bình nằm ở khoảng CAR ≈ 7.5, cao hơn nhiều so với giá trị phổ biến nhất.

2.4.1.5 Tỷ lệ nợ trên tài sản

ggplot(financial_data_clean, aes(x=Ty_le_no_taisan)) +
geom_histogram(aes(y=after_stat(density)), binwidth=0.01, fill="cyan", color="black") +
geom_density(color="red", size=1) +
geom_vline(aes(xintercept=mean(Ty_le_no_taisan, na.rm=TRUE)), color="blue", linetype="dashed") +
geom_vline(aes(xintercept=median(Ty_le_no_taisan, na.rm=TRUE)), color="green", linetype="dotted") +
geom_rug() +
ggtitle("Tỷ lệ nợ trên tài sản") +
theme_minimal()

Nhận xét: Phân phối: Dữ liệu không chuẩn và có nhiều đỉnh. Giá trị phổ biến (Mode): Đỉnh cao nhất nằm ở khoảng 87.5. Giá trị trung bình (Mean): Giá trị trung bình (khoảng 87.0) nằm thấp hơn một chút so với giá trị phổ biến nhất, do ảnh hưởng của các cụm dữ liệu bên trái (tỷ lệ nợ thấp hơn).

2.4.1.6 Tăng trưởng tổng tài sản

ggplot(financial_data_clean, aes(x=Tang_truong_ts)) +
geom_histogram(aes(y=after_stat(density)), binwidth=0.01, fill="lightgreen", color="black") +
geom_density(color="red", size=1) +
geom_vline(aes(xintercept=mean(Tang_truong_ts, na.rm=TRUE)), color="blue", linetype="dashed") +
geom_vline(aes(xintercept=median(Tang_truong_ts, na.rm=TRUE)), color="green", linetype="dotted") +
geom_rug() +
ggtitle("Tăng trưởng tổng tài sản") +
theme_minimal()

Nhận xét: Phân phối: Dữ liệu không chuẩn, đa đỉnh và rời rạc. Giá trị phổ biến (Mode): Đỉnh cao nhất nằm ở khoảng 16.5. Giá trị trung bình (Mean): Giá trị trung bình (khoảng 19.0) bị kéo về phía bên phải (cao hơn) so với giá trị phổ biến nhất, do ảnh hưởng của các cụm có mức tăng trưởng cao.

2.4.2 Boxplot với Jitter

# Tạo CAR_quartile
financial_data_clean$CAR_quartile <- cut(
  financial_data_clean$CAR,
  breaks = quantile(financial_data_clean$CAR, probs = seq(0, 1, 0.25), na.rm = TRUE),
  include.lowest = TRUE,
  labels = c("Q1", "Q2", "Q3", "Q4")
)

2.4.2.1 Boxplot ROA với Jitter

ggplot(financial_data_clean, aes(x="", y=ROA)) +
geom_boxplot(fill="skyblue", alpha=0.5) +
geom_jitter(width=0.1, aes(color=CAR_quartile), size=2) +
stat_summary(fun=mean, geom="point", shape=23, size=3, fill="red") +
geom_text(aes(label=round(ROA,2)), hjust=-0.2, size=3, check_overlap=TRUE) +
theme_minimal() +
ggtitle("Boxplot ROA (Lợi nhuận trên tổng tài sản) với Jitter")

Nhận xét: Dữ liệu ROA phân bố khá đối xứng, với giá trị trung bình (hình thoi, 2.65) và trung vị (vạch đậm, ~2.6) gần bằng nhau. Hầu hết dữ liệu nằm trong khoảng 1.65 đến 3.15. Có một giá trị ngoại lệ cao (4.16).

2.4.2.2 Boxplot ROE với Jitter

ggplot(financial_data_clean, aes(x="", y=ROE)) +
geom_boxplot(fill="orange", alpha=0.5) +
geom_jitter(width=0.1, aes(color=CAR_quartile), size=2) +
stat_summary(fun=mean, geom="point", shape=23, size=3, fill="blue") +
geom_text(aes(label=round(ROE,2)), hjust=-0.2, size=3, check_overlap=TRUE) +
theme_minimal() +
ggtitle("Boxplot ROE (Lợi nhuận trên vốn chủ sở hữu) với Jitter")

Nhận xét: Dữ liệu ROE có độ phân tán lớn và bị lệch phải. Giá trị trung bình (21.87) cao hơn đáng kể so với giá trị trung vị (~16.2), cho thấy ảnh hưởng của các giá trị cao, bao gồm cả điểm ngoại lệ (32.99).

2.4.2.3 Boxplot NIM với Jitter

ggplot(financial_data_clean, aes(x="", y=NIM)) +
geom_boxplot(fill="purple", alpha=0.5) +
geom_jitter(width=0.1, aes(color=CAR_quartile), size=2) +
stat_summary(fun=mean, geom="point", shape=23, size=3, fill="yellow") +
geom_text(aes(label=round(NIM,2)), hjust=-0.2, size=3, check_overlap=TRUE) +
theme_minimal() +
ggtitle("Boxplot NIM (Biên lãi ròng) với Jitter")

Nhận xét: Dữ liệu NIM phân bố khá đối xứng, với trung bình (~6.68) và trung vị (~6.6) gần như trùng nhau. Có các giá trị ngoại lệ ở cả phía thấp (4.67) và phía cao (8.13).

2.4.2.4 Boxplot CAR với Jitter

ggplot(financial_data_clean, aes(x="", y=CAR)) +
geom_boxplot(fill="pink", alpha=0.5) +
geom_jitter(width=0.1, aes(color=CAR_quartile), size=2) +
stat_summary(fun=mean, geom="point", shape=23, size=3, fill="green") +
geom_text(aes(label=round(CAR,2)), hjust=-0.2, size=3, check_overlap=TRUE) +
theme_minimal() +
ggtitle("Boxplot CAR (Tỷ lệ an toàn vốn) với Jitter")

Nhận xét: Dữ liệu CAR phân bố tương đối đối xứng quanh mức trung vị (~7.8). Biểu đồ cho thấy có các giá trị ngoại lệ ở cả mức rất thấp (4.01) và rất cao (10.69).

2.4.3 Boxplot & Scatter plots

2.4.3.1 Tỷ lệ nợ trên tài sản

ggplot(financial_data_clean, aes(x="", y=Ty_le_no_taisan)) +
  geom_boxplot(fill="cyan", alpha=0.5) +
  geom_jitter(width=0.1, aes(color=CAR_quartile), size=2) +
  stat_summary(fun=mean, geom="point", shape=23, size=3, fill="red") +
  geom_text(aes(label=round(Ty_le_no_taisan,2)), hjust=-0.2, size=3, check_overlap=TRUE) +
  theme_minimal() +
  ggtitle("Tỷ lệ nợ trên tài sản")

Nhận xét: Dữ liệu phân bố khá đối xứng quanh giá trị trung tâm là 87.4. Hầu hết các quan sát nằm trong khoảng 83.8 đến 89.1. Có một giá trị ngoại lệ cao (92.49).

2.4.3.2 Tăng trưởng tổng tài sản

ggplot(financial_data_clean, aes(x="", y=Tang_truong_ts)) +
geom_boxplot(fill="lightgreen", alpha=0.5) +
geom_jitter(width=0.1, aes(color=CAR_quartile), size=2) +
stat_summary(fun=mean, geom="point", shape=23, size=3, fill="purple") +
geom_text(aes(label=round(Tang_truong_ts,2)), hjust=-0.2, size=3, check_overlap=TRUE) +
theme_minimal() +
ggtitle("Tăng trưởng tổng tài sản")

Nhận xét: Dữ liệu này bị lệch phải, với giá trị trung bình (~19.5) cao hơn trung vị (~16.5). Điều này là do ảnh hưởng của các giá trị ngoại lệ rất cao (khoảng 29-30%).

2.4.3.3 Scatter ROA với ROE (Lợi nhuận trên tổng tài sản và vốn chủ sở hữu)

ggplot(financial_data_clean, aes(x=ROA, y=ROE)) +
geom_point(aes(color=CAR_quartile), size=2) +
geom_smooth(method="lm", se=TRUE, color="blue", linetype="dashed") +
geom_smooth(method="loess", se=FALSE, color="red") +
geom_hline(yintercept=mean(financial_data_clean$ROE, na.rm=TRUE), color="green", linetype="dotted") +
geom_vline(xintercept=mean(financial_data_clean$ROA, na.rm=TRUE), color="purple", linetype="dotted") +
ggtitle("Scatter ROA với ROE") +
theme_minimal()

Nhận xét: Biểu đồ cho thấy một mối tương quan dương rõ rệt. Khi ROA tăng, ROE cũng có xu hướng tăng theo.

2.4.3.4 Scatter ROA với NIM (Lợi nhuận trên tổng tài sản và Biên lãi ròng)

ggplot(financial_data_clean, aes(x=ROA, y=NIM)) +
geom_point(aes(color=CAR_quartile, size=CAR), alpha=0.7) +
geom_smooth(method="lm", se=TRUE) +
geom_hline(yintercept=mean(NIM, na.rm=TRUE), color="red", linetype="dashed") +
geom_vline(xintercept=mean(ROA, na.rm=TRUE), color="blue", linetype="dashed") +
scale_size_continuous(range=c(2,6)) +
ggtitle("Scatter ROA với NIM") +
theme_minimal()

Nhận xét: Mối quan hệ giữa ROA và NIM rất yếu, gần như không có. Đường xu hướng (màu xanh) gần như nằm ngang, cho thấy sự thay đổi của ROA không ảnh hưởng nhiều đến NIM.

2.4.3.5 Scatter ROE với NIM (Lợi nhuận vốn chủ sở hữu và Biên lãi ròng)

ggplot(financial_data_clean, aes(x=ROE, y=NIM)) +
geom_point(aes(color=CAR_quartile, size=ROA), alpha=0.7) +
geom_smooth(method="lm", se=TRUE) +
geom_hline(yintercept=mean(NIM, na.rm=TRUE), color="red", linetype="dashed") +
geom_vline(xintercept=mean(ROE, na.rm=TRUE), color="blue", linetype="dashed") +
scale_size_continuous(range=c(2,6)) +
ggtitle("Scatter ROE với NIM") +
theme_minimal()

Nhận xét: Biểu đồ cho thấy một mối tương quan dương. Khi ROE tăng, NIM cũng có xu hướng tăng lên.

2.4.3.6 Scatter CAR với Tỷ lệ nợ trên tài sản

ggplot(financial_data_clean, aes(x=CAR, y=Ty_le_no_taisan)) +
geom_point(aes(color=CAR_quartile, size=NIM), alpha=0.7) +
geom_smooth(method="lm", se=TRUE) +
geom_hline(yintercept=mean(Ty_le_no_taisan, na.rm=TRUE), color="red", linetype="dashed") +
geom_vline(xintercept=mean(CAR, na.rm=TRUE), color="blue", linetype="dashed") +
scale_size_continuous(range=c(2,6)) +
ggtitle("Scatter CAR với Tỷ lệ nợ trên tài sản") +
theme_minimal()

Nhận xét: Biểu đồ cho thấy một mối tương quan âm rõ rệt. Khi CAR tăng lên, Tỷ lệ nợ trên tài sản có xu hướng giảm xuống.

2.4.3.7 Scatter Tỷ lệ nợ trên tài sản với NIM

ggplot(financial_data_clean, aes(x=Ty_le_no_taisan, y=NIM)) +
geom_point(aes(color=CAR_quartile, size=Tang_truong_ts), alpha=0.7, na.rm=TRUE) +
geom_smooth(method="lm", se=TRUE, color="purple", na.rm=TRUE) +
geom_hline(yintercept=mean(NIM, na.rm=TRUE), color="blue", linetype="dashed") +
geom_vline(xintercept=mean(Ty_le_no_taisan, na.rm=TRUE), color="orange", linetype="dashed") +
ggtitle("Scatter Tỷ lệ nợ trên tài sản với NIM") +
theme_minimal()

Nhận xét: Biểu đồ này cho thấy một mối tương quan dương. Điều này có nghĩa là khi tỷ lệ nợ trên tài sản tăng, NIM cũng có xu hướng tăng theo.

2.4.3.8 Scatter NIM với CAR (hiệu quả sinh lời vs an toàn vốn)

ggplot(financial_data_clean, aes(x=CAR, y=NIM)) +
  geom_point(aes(color=CAR_quartile, size=ROA), alpha=0.7, na.rm=TRUE) +
  geom_smooth(method="lm", se=TRUE, color="red", na.rm=TRUE) +
  ggtitle("Scatter NIM với CAR") +
  theme_minimal()

Nhận xét: Biểu đồ cho thấy một mối tương quan âm rõ rệt. Khi CAR tăng, NIM có xu hướng giảm.

2.4.3.9 Scatter Tỷ lệ nợ trên tài sản với ROA (rủi ro nợ vs lợi nhuận):

ggplot(financial_data_clean, aes(x=Ty_le_no_taisan, y=ROA)) +
  geom_point(aes(color=CAR_quartile, size=NIM), alpha=0.7, na.rm=TRUE) +
  geom_smooth(method="lm", se=TRUE, color="green", na.rm=TRUE) +
  ggtitle("Scatter Tỷ lệ nợ trên tài sản với ROA") +
  theme_minimal()

Nhận xét: Biểu đồ cho thấy một mối tương quan âm. Khi tỷ lệ nợ trên tài sản tăng lên, ROA có xu hướng giảm.