1 LỜI CẢM ƠN

Nhóm xin gửi lời cảm ơn chân thành đến Thầy ThS. Trần Mạnh Tường đã tận tình hướng dẫn, hỗ trợ và định hướng trong suốt quá trình thực hiện tiểu luận. Nhờ sự chỉ dẫn và góp ý tận tâm của Thầy, nhóm đã hiểu sâu hơn về nội dung học phần, rèn luyện được tư duy phân tích dữ liệu và trong quá trình nghiên cứu và xử lý dữ liệu. Bài tiểu luận này là kết quả của sự nỗ lực và học hỏi không ngừng của nhóm dưới sự hướng dẫn của Thầy.

Xin chân thành cảm ơn Thầy!

2 LỜI CAM ĐOAN

Nhóm xin cam đoan rằng toàn bộ nội dung trong bài tiểu luận này là kết quả nghiên cứu, phân tích và trình bày của riêng nhóm, không sao chép hay vi phạm bản quyền. Các số liệu, bảng biểu và kết quả phân tích được thu thập, xử lý trung thực và có trích dẫn rõ ràng. Nhóm hoàn toàn chịu trách nhiệm về tính chính xác và trung thực của nội dung bài làm.

1. library(readxl) # Nạp thư viện 'readxl' để đọc dữ liệu từ các tệp Excel (.xlsx, .xls)
2. library(skimr) # Nạp thư viện 'skimr' để tạo bản tóm tắt thống kê nhanh chóng, đẹp mắt (giống như 'summary' nhưng chi tiết hơn)
3. library(tidyverse) # Nạp gói thư viện 'tidyverse' tổng hợp (bao gồm dplyr, ggplot2, tidyr, v.v.), mặc dù nhiều gói đã được tải riêng lẻ trước đó
4. library(ggplot2) # Nạp thư viện 'ggplot2' để tạo các đồ thị và biểu đồ trực quan hóa dữ liệu
5. library(dplyr) # Nạp thư viện 'dplyr' (một phần của tidyverse) để thao tác và xử lý dữ liệu hiệu quả
6. library(tidyr) # Nạp thư viện 'tidyr' (một phần của tidyverse) để làm sạch và định hình lại dữ liệu 
7. library(DT) # Nạp thư viện 'DT' để tạo các bảng dữ liệu tương tác, có thể tìm kiếm, sắp xếp
8. library(kableExtra) # Nạp thư viện 'kableExtra' để tùy chỉnh và làm đẹp các bảng HTML/LaTeX
9. library(lubridate) # Nạp thư viện 'lubridate' để thao tác và xử lý dữ liệu thời gian và ngày tháng
10. library(moments) # Nạp thư viện 'moments' để tính các đặc trưng phân phối như moment, skewness, kurtosis

3 . CHƯƠNG MỞ ĐẦU: GIỚI THIỆU ĐỀ TÀI

3.1 . Lý do chọn đề tài

  • Thị trường bất động sản Hoa Kỳ là một trong những thị trường lớn và có ảnh hưởng mạnh mẽ, phản ánh các xu hướng kinh tế và đầu tư toàn cầu. Việc phân tích dữ liệu giao dịch bất động sản giúp nhà đầu tư và cơ quan quản lý hiểu rõ hơn về giá cả, hành vi mua bán, và yếu tố chi phối cung cầu theo khu vực và thời gian.

  • Đồng thời, Ngân hàng TMCP Đầu tư và Phát triển Việt Nam (BIDV) là một trong bốn ngân hàng lớn nhất Việt Nam, đóng vai trò quan trọng trong cung cấp vốn cho nền kinh tế. Phân tích dữ liệu tài chính của BIDV sẽ giúp đánh giá sức khỏe tài chính và hiệu quả hoạt động của ngân hàng trong bối cảnh kinh tế biến động.

3.2 . Mục tiêu nghiên cứu

  • Phân tích thị trường bất động sản Hoa Kỳ và các yếu tố ảnh hưởng đến giá bán, diện tích đất và mức độ hấp dẫn của từng khu vực.

  • Đánh giá hiệu quả tài chính của BIDV giai đoạn 2010–2024, thông qua các chỉ số như NIM, NPM, tỷ lệ tiền mặt trên tổng tài sản, lợi nhuận sau thuế và thu nhập hoạt động.

  • Ứng dụng R trong việc phân tích, trực quan hóa dữ liệu và đưa ra các nhận định về hiệu quả hoạt động của BIDV.

3.3 . Đối tượng và phạm vi nghiên cứu

  • Đối tượng nghiên cứu: Giao dịch bất động sản tại Hoa Kỳ và các chỉ tiêu tài chính của BIDV.

  • Phạm vi dữ liệu: Dữ liệu từ bộ “USA Real Estate Dataset” (2015–2024) và bộ dữ liệu tài chính của BIDV (2010–2024).

3.4 . Đóng góp của nghiên cứu

  • Cung cấp cái nhìn tổng quan về thị trường bất động sản Hoa Kỳ và tình hình tài chính của BIDV.

  • Hỗ trợ ra quyết định cho nhà đầu tư và cơ quan quản lý trong việc phát triển chiến lược đầu tư và quản lý tài chính.

  • Minh họa khả năng ứng dụng các công cụ phân tích dữ liệu hiện đại để xử lý và trực quan hóa dữ liệu tài chính và bất động sản.

4 . CHƯƠNG I : PHÂN TÍCH DỮ LIỆU THỊ TRƯỜNG BẤT ĐỘNG SẢN HOA KỲ

5 . Giới thiệu về bộ

5.1 . Giới thiệu về bộ dữ liệu

Bộ dữ liệu “USA Real Estate Dataset” được thu thập tại trang web Kaggle . Đây là một bộ dữ liệu công khai được xây dựng nhằm phục vụ mục đích học tập và thực hành phân tích dữ liệu trong lĩnh vực bất động sản. Bộ dữ liệu mô tả thông tin chi tiết của hơn 2,2 triệu bất động sản trên khắp các bang, thành phố và mã vùng của Hoa Kỳ. Mỗi dòng dữ liệu tương ứng với một bất động sản cụ thể, bao gồm các thông tin như giá bán, diện tích đất, diện tích nhà, số phòng ngủ, số phòng tắm, vị trí địa lý, mã vùng bưu điện, trạng thái giao dịch và ngày bán gần nhất. Dữ liệu được tổ chức dưới dạng dữ liệu định lượng và định tính, phản ánh đặc điểm và xu hướng chung của thị trường nhà ở Hoa Kỳ.

5.2 . Đọc dữ liệu

Ta tiến hành đọc tệp CSV và gán dữ liệu vào một đối tượng có tên là tieuluan để phục vụ cho quá trình phân tích.

1. tieuluan <- read.csv("D:/TMT_R/realtor-data.zip.csv")
2. tieuluan$prev_sold_date <- as.Date(tieuluan$prev_sold_date, format = "%Y-%m-%d")

Giải thích kỹ thuật

Dòng 1 dùng để nạp dữ liệu đầu vào cho bài

Dòng 2 dùng để chuyển dữ liệu trong cột prev_sold_date của bảng tieuluan sang kiểu ngày (Date) theo định dạng năm-tháng-ngày (%Y-%m-%d)

5.3 . Xem thông tin chung của dữ liệu

1. head(tieuluan) 

Giải thích kỹ thuật

Dòng 1 dùng để xem 6 hàng đầu tiên của dữ liệu

1. tail(tieuluan)

Giải thích kỹ thuật

Dòng 1 dùng để xem 6 hàng cuối của dữ liệu

Ta sử dụng sử dụng một số lệnh bên dưới để xem thông tin chung của tieuluan.

1. dim(tieuluan)
## [1] 2226382      12

Giải thích kỹ thuật

Dòng 1 dùng để kiểm tra kích thước dữ liệu

Nhận xét: Sử dụng lệnh dim() kết quả trả về cho thấy bộ dữ liệu tieuluan có 2.226.382 hàng (quan sát) và 12 cột (biến), phản ánh quy mô và số lượng biến của tập dữ liệu.

1. names(tieuluan)
##  [1] "brokered_by"    "status"         "price"          "bed"           
##  [5] "bath"           "acre_lot"       "street"         "city"          
##  [9] "state"          "zip_code"       "house_size"     "prev_sold_date"

Giải thích kỹ thuật

Dòng 1 dùng để xem tên các biến trong bộ dữ liệu.

Nhận xét: Sử dụng lệnh names() kết quả trả về tên các biến trong bộ dữ liệu. Trong bộ dữ liệu tieuluan,có 12 biến bao gồm: “brokered_by”, “status”, “price”, “bed”, “bath”, “acre_lot”, “street”, “city”, “state”, “zip_code”, “house_size”, “prev_sold_date”.

Nhằm đảm bảo tính chính xác và phù hợp với mục tiêu nghiên cứu, tác giả đã chọn lọc 6 biến chính: status, price, bath, city, acre_lot và prev_sold_date. Thông tin chi tiết về các biến này được thể hiện trong bảng dưới đây.

1. tieuluan <- tieuluan[, c("status", "price", "bath", "city", "acre_lot", "prev_sold_date")]

Giải thích kỹ thuật

Dòng 1 dùng để giữ lại 6 biến phân tích.

Bảng 1. Danh sách các biến tác giả chọn để phân tích
STT Tên biến Mô tả
1 status Trạng thái bất động sản (đang bán hoặc sẵn sàng xây dựng)
2 price Giá của bất động sản (hiện tại hoặc gần nhất)
3 bath Số lượng phòng tắm của bất động sản
4 acre_lot Diện tích đất (tính bằng mẫu Anh - acre)
5 city Tên thành phố nơi bất động sản tọa lạc
6 prev_sold_date Ngày bán gần nhất trước đó (nếu có)

Giải thích kỹ thuật

Dòng 1 Dùng để tạo một bảng dữ liệu mới tên des bằng hàm data.frame().

Dòng 2 Dùng để tạo cột STT gồm các số thứ tự từ 1 đến 6.

Dòng 3-4 Dùng để tạo cột Tên_biến, chứa danh sách tên các biến trong bộ dữ liệu bất động sản.

Dòng 5-11 Dùng để mô tả các biến

Dòng 12 Dùng để gọi bảng dữ liệu des và truyền qua các hàm tiếp theo bằng toán tử %>%.

Dòng 13 Dùng hàm kable() để chuyển bảng des thành bảng HTML, với align = “c” để căn giữa tất cả các cột.

Dòng 14 Dùng col.names để đặt tiêu đề cột là STT, Tên biến, Mô tả (được in đậm).

Dòng 15 Dùng caption để thêm tiêu đề cho bảng, căn giữa và in đậm dòng chữ “Bảng 1. Danh sách các biến tác giả chọn để phân tích”.

Dòng 16 Dùng hàm kable_styling() để chỉnh giao diện bảng HTML.

Dòng 17 Các tùy chọn striped, hover, condensed, responsive giúp bảng xen kẽ màu, đổi màu khi rê chuột, gọn hơn và tự co giãn; full_width = F để bảng không chiếm toàn bộ chiều ngang, position = “center” để căn giữa, font_size = 14 để chỉnh cỡ chữ.

Dòng 18 Dùng để định dạng hàng tiêu đề in đậm và có nền đỏ đậm.

Dòng 19 Dùng để thêm viền phải cho cả ba cột trong bảng.

1. str(tieuluan)
## 'data.frame':    2226382 obs. of  6 variables:
##  $ status        : chr  "for_sale" "for_sale" "for_sale" "for_sale" ...
##  $ price         : num  105000 80000 67000 145000 65000 179000 50000 71600 100000 300000 ...
##  $ bath          : int  2 2 1 2 2 3 1 2 1 3 ...
##  $ city          : chr  "Adjuntas" "Adjuntas" "Juana Diaz" "Ponce" ...
##  $ acre_lot      : num  0.12 0.08 0.15 0.1 0.05 0.46 0.2 0.08 0.09 7.46 ...
##  $ prev_sold_date: Date, format: NA NA ...

Giải thích kỹ thuật

Dòng 1 dùng để xem cấu trúc tổng quát của dữ liệu

Nhận xét: Sử dụng lệnh str() kết quả trả về cấu trúc tổng quát của bộ dữ liệu, bao gồm số quan sát, số biến, tên biến và kiểu dữ liệu của từng biến. Trong bộ dữ liệu hiện tại có 982.413 quan sát và 6 biến với các kiểu dữ liệu như num (số thực), int (số nguyên) và chr (chuỗi ký tự). Các biến số như price, bath, acre_lot và là các biến định lượng, còn các biến status, city và prev_sold_date là chuỗi ký tự.

1. sapply(tieuluan, class)
##         status          price           bath           city       acre_lot 
##    "character"      "numeric"      "integer"    "character"      "numeric" 
## prev_sold_date 
##         "Date"

Giải thích kỹ thuật

Dòng 1 dùng để xem kiểu dữ liệu theo từng cột

Nhận xét: Sử dụng lệnh sapply() với class kết quả trả về kiểu dữ liệu của từng biến trong bộ dữ liệu. Trong tieuluan, các biến có kiểu factor như status; kiểu numeric như price, bath, acre_lot; kiểu character như city; và kiểu Date như prev_sold_date. Các thông tin này giúp xác định loại biến để phân tích và trực quan hóa dữ liệu phù hợp.

1. #Thống kê mô tả biến price
2. summary_price <- tieuluan$price
3. data.frame(
4.   Min = min(summary_price, na.rm = TRUE),
5.   Q1 = quantile(summary_price, 0.25, na.rm = TRUE),
6.   Median = median(summary_price, na.rm = TRUE),
7.   Mean = mean(summary_price, na.rm = TRUE),
8.   Q3 = quantile(summary_price, 0.75, na.rm = TRUE),
9.   Max = max(summary_price, na.rm = TRUE),
10.   SD = sd(summary_price, na.rm = TRUE),
11.   Variance = var(summary_price, na.rm = TRUE),
12.   Skewness = skewness(summary_price, na.rm = TRUE), 
13.   Kurtosis = kurtosis(summary_price, na.rm = TRUE))

Giải thích kỹ thuật

Dòng 1: Gán cột price từ bảng tieuluan vào biến summary_price để dễ thao tác.

Dòng 2: Bắt đầu tạo một bảng dữ liệu mới (data frame) chứa các chỉ số thống kê của summary_price.

Dòng 3-10: Tính các giá trị thống kê cơ bản gồm: giá trị nhỏ nhất (Min), tứ phân vị thứ nhất (Q1), trung vị (Median), trung bình (Mean), tứ phân vị thứ ba (Q3), giá trị lớn nhất (Max), độ lệch chuẩn (SD) và phương sai (Variance), tất cả đều bỏ qua giá trị thiếu (na.rm = TRUE).

Dòng 11: Tính độ lệch (Skewness) – đo độ nghiêng của phân phối: > 0 nghiêng phải, < 0 nghiêng trái.

Dòng 12: Tính độ nhọn (Kurtosis) – đo độ “nhọn” của phân phối: > 3 nhọn hơn chuẩn, < 3 dẹt hơn chuẩn.

Nhận xét: Biến price có giá trị dao động từ 0 đến 2.147.483.600, cho thấy sự chênh lệch rất lớn giữa các căn nhà, với sự xuất hiện của nhiều giá trị cực đoan. Giá trung vị (325.000) thấp hơn trung bình (524.195,5), cho thấy phân bố lệch phải mạnh. Độ lệch chuẩn (2.138.893) và phương sai (4,57E+12) cực kỳ cao, phản ánh mức độ phân tán lớn trong dữ liệu. Skewness = 546,30 và kurtosis = 492.425,1 cho thấy dữ liệu có đuôi phải rất dài và chứa nhiều giá trị ngoại lai, cần được xem xét hoặc loại bỏ khi thực hiện các phân tích thống kê tiếp theo để tránh sai lệch kết quả.

1. #Thống kê mô tả biến bath
2. summary_bath <- tieuluan$bath
3. data.frame(
4.   Min = min(summary_bath, na.rm = TRUE),
5.   Q1 = quantile(summary_bath, 0.25, na.rm = TRUE),
6.   Median = median(summary_bath, na.rm = TRUE),
7.   Mean = mean(summary_bath, na.rm = TRUE),
8.   Q3 = quantile(summary_bath, 0.75, na.rm = TRUE),
9.   Max = max(summary_bath, na.rm = TRUE),
10.   SD = sd(summary_bath, na.rm = TRUE),
11.   Variance = var(summary_bath, na.rm = TRUE),
12.   Skewness = skewness(summary_bath, na.rm = TRUE),
13.   Kurtosis = kurtosis(summary_bath, na.rm = TRUE)
14. )

Giải thích kỹ thuật: tương tự như thống kê mô tả của biến price

Nhận xét: Biến bath dao động từ 1 đến 830, với trung vị (Median = 2) thấp hơn trung bình (Mean = 2,50), cho thấy phần lớn các căn nhà có số phòng tắm thấp, nhưng tồn tại một số giá trị cực lớn (outliers). Độ lệch chuẩn (SD = 1,65) và phương sai (2,73) khá cao so với quy mô dữ liệu thông thường, phản ánh sự phân tán mạnh do ảnh hưởng của các giá trị bất thường. Skewness = 152,41 và kurtosis = 65.876,96 cho thấy dữ liệu có phân bố lệch phải rất mạnh và đuôi dài, cần kiểm tra và xử lý ngoại lai trước khi thực hiện các phân tích sâu hơn để đảm bảo độ tin cậy của kết quả.

1. #Thống kê mô tả biến acre_lot
2. summary_acre <- tieuluan$acre_lot
3. data.frame(
4.   Min = min(summary_acre, na.rm = TRUE),
5.   Q1 = quantile(summary_acre, 0.25, na.rm = TRUE),
6.   Median = median(summary_acre, na.rm = TRUE),
7.   Mean = mean(summary_acre, na.rm = TRUE),
8.   Q3 = quantile(summary_acre, 0.75, na.rm = TRUE),
9.   Max = max(summary_acre, na.rm = TRUE),
10.   SD = sd(summary_acre, na.rm = TRUE),
11.   Variance = var(summary_acre, na.rm = TRUE),
12.   Skewness = skewness(summary_acre, na.rm = TRUE),
13.   Kurtosis = kurtosis(summary_acre, na.rm = TRUE)
14. )

Giải thích kỹ thuật: tương tự như thống kê mô tả của biến price

Nhận xét: Biến acre_lot dao động từ 0 đến 100.000, với trung vị (Median = 0,26) thấp hơn trung bình (Mean = 15,22), cho thấy phần lớn các bất động sản có diện tích nhỏ nhưng tồn tại một số giá trị cực lớn (outliers). Độ lệch chuẩn (SD = 762,82) và phương sai (581.900,2) rất cao, phản ánh mức độ biến động mạnh trong dữ liệu. Skewness = 106,28 và kurtosis = 12.545,29 cho thấy dữ liệu có phân bố lệch phải rất mạnh và đuôi dài, nghĩa là có nhiều bất động sản có diện tích vượt trội so với đa số còn lại, cần được kiểm tra và xử lý ngoại lai khi phân tích chi tiết hơn.

1. status_tab <- table(tieuluan$status)  
2. status_freq <- as.data.frame(status_tab)   
3. names(status_freq) <- c("Trạng thái", "Tần số")
4. status_freq[["Tần suất (%)"]] <- round(100 * status_freq[["Tần số"]] / sum(status_freq[["Tần số"]]), 2)  
5. status_freq     

Giải thích kỹ thuật

Dòng 1: Dùng để đếm số lượng xuất hiện của từng loại trạng thái trong cột status, lưu kết quả vào biến status_tab.

Dòng 2: Dùng để chuyển bảng tần số status_tab sang dạng data frame, giúp dễ xử lý và hiển thị.

Dòng 3: Dùng để đặt lại tên hai cột của bảng thành “Trạng thái” và “Tần số”

Dòng 4: Thêm một cột mới “Tần suất (%)” bằng cách tính tỷ lệ phần trăm của từng trạng thái: lấy tần số chia tổng tần số rồi nhân 100, sau đó làm tròn 2 chữ số thập phân bằng round().

Dòng 5: Dùng để hiển thị bảng kết quả status_freq

Nhận xét: Biến status gồm ba nhóm chính là for_sale (62,40%), ready_to_build (1,13%) và sold (36,47%). Kết quả cho thấy phần lớn các bất động sản trong bộ dữ liệu đang ở trạng thái rao bán, trong khi số lượng đã bán chiếm tỷ lệ thấp hơn và ready_to_build chỉ chiếm một phần rất nhỏ. Điều này phản ánh nguồn cung trên thị trường đang lớn hơn nhu cầu giao dịch thực tế, thể hiện thị trường có mức độ thanh khoản chưa cao trong giai đoạn khảo sát.

1. city_freq <- tieuluan %>%
2.   count(city) %>%    
3.   mutate(`Tần suất (%)` = round(100 * n / sum(n), 2)) %>%  
4.   arrange(desc(n))     
5. topn <- 10     
6. top_city <- city_freq[1:topn, ]  
7. other_city <- city_freq[(topn + 1):nrow(city_freq), ] 
8. other_summary <- data.frame(
9.   city = "Khác",         
10.   n = sum(other_city$n),         
11.   `Tần suất (%)` = round(100 * sum(other_city$n) / sum(city_freq$n), 2), 
12.   stringsAsFactors = FALSE         )
13. names(other_summary) <- names(top_city)  
14. city_desc <- rbind(top_city, other_summary)    
15. names(city_desc) <- c("Thành phố", "Tần số", "Tần suất (%)")  
16. city_desc  

Giải thích kỹ thuật

Dòng 1: Gọi bảng dữ liệu tieuluan và bắt đầu chuỗi thao tác với toán tử %>%.

Dòng 2: Dùng count(city) để đếm số lượng từng thành phố trong cột city.

Dòng 3: Dùng mutate() để thêm cột “Tần suất (%)”, tính bằng công thức 100 * n / sum(n) và làm tròn 2 chữ số.

Dòng 4: Dùng arrange(desc(n)) để sắp xếp bảng giảm dần theo tần số.

Dòng 5: Gán topn <- 10 để xác định số lượng thành phố muốn lấy ở top đầu.

Dòng 6: Lấy top 10 thành phố phổ biến nhất và lưu vào top_city.

Dòng 7: Lấy các thành phố còn lại ngoài top 10 và lưu vào other_city.

Dòng 8–13: Tạo bảng other_summary gộp các thành phố còn lại thành nhóm “Khác”, gồm: tên nhóm “Khác”, tổng số lượng, tổng tần suất (%) và giữ chuỗi “Khác” ở dạng ký tự (không factor).

Dòng 14: Dùng để đồng nhất tên cột giữa hai bảng trước khi ghép.

Dòng 15: Dùng để ghép bảng top 10 và nhóm “Khác” thành bảng cuối city_desc.

Dòng 16: Đổi tên các cột trong bảng city_desc sang tiếng Việt có dấu: “Thành phố”, “Tần số”, “Tần suất (%)”.

Dòng 18: Hiển thị bảng city_desc – kết quả thống kê

Nhận xét: Biến city cho thấy phần lớn bất động sản thuộc nhóm “Khác” (94,54%), phản ánh phạm vi phân bố rất rộng, bao gồm nhiều khu vực nhỏ lẻ khác nhau. Trong nhóm các thành phố lớn, Houston (1,07%; 23.862 căn), Chicago (0,82%; 18.238 căn) và New York City (0,57%; 12.634 căn) là ba khu vực có số lượng bất động sản cao nhất. Các thành phố còn lại gồm Jacksonville (0,53%; 11.743 căn), Philadelphia (0,47%; 10.449 căn), Miami (0,44%; 9.737 căn), Los Angeles (0,40%; 8.984 căn), Tucson (0,40%; 8.943 căn), Dallas (0,38%; 8.569 căn) và Richmond (0,38%; 8.360 căn) có tỷ lệ thấp hơn. Điều này cho thấy dữ liệu có tính đa vùng rõ rệt, phản ánh thị trường bất động sản phân tán trên phạm vi toàn quốc, không tập trung vào một vài khu vực cụ thể.

6 . Xử lý dữ liệu thô

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

1. # Kiểm tra xem dữ liệu có giá trị NA nào không
2. any(is.na(tieuluan))
## [1] TRUE

Giải thích kỹ thuật: dùng để kiểm tra xem dữ liệu có giá trị NA nào không

Nhận xét: Sử dụng lệnh any(is.na()) kết quả trả về kiểm tra xem có bất kỳ giá trị thiếu nào trong toàn bộ bộ dữ liệu hay không. Trong tieuluan, kết quả là TRUE, cho thấy toàn bộ dữ liệu có giá trị NA.

1. sum(is.na(tieuluan))
## [1] 1573198

Giải thích kỹ thuật: dùng để đếm tổng số giá trị bị thiếu trong toàn bộ dataset

Nhận xét: Sử dụng lệnh sum(is.na()) kết quả trả về tổng số giá trị bị thiếu trong toàn bộ bộ dữ liệu. Trong tieuluan, kết quả là 1.573.198, nghĩa là có giá trị 1.573.198 NA trong dataset.

1. colSums(is.na(tieuluan))
##         status          price           bath           city       acre_lot 
##              0           1541         511771              0         325589 
## prev_sold_date 
##         734297

Giải thích kỹ thuật: dùng để đếm số lượng giá trị NA trong từng cột

Nhận xét: Sử dụng lệnh colSums(is.na()) trả về số lượng giá trị NA trong từng cột của bộ dữ liệu. Trong tieuluan, các biến có giá trị thiếu đáng chú ý là bath (511.771 NA), acre_lot (325.589 NA) và prev_sold_date (734.297 NA). Ngoài ra, biến price (1.541 NA) cũng có một lượng nhỏ giá trị bị thiếu, trong khi các biến phân loại như status và city không có giá trị NA. Kết quả này giúp xác định rõ các cột cần được xử lý dữ liệu thiếu trước khi tiến hành các bước phân tích thống kê và mô hình hóa tiếp theo.

1. names(tieuluan)[colSums(is.na(tieuluan)) > 0]
## [1] "price"          "bath"           "acre_lot"       "prev_sold_date"

Giải thích kỹ thuật: dùng để liệt kê tên các cột có giá trị bị thiếu

Nhận xét: Sử dụng lệnh names(tieuluan)[colSums(is.na(tieuluan)) > 0] trả về tên các cột có giá trị bị thiếu trong bộ dữ liệu. Kết quả cho thấy các cột bị thiếu dữ liệu là: price, bath, acre_lot và prev_sold_date. Thông tin này giúp xác định những biến cần được xử lý giá trị thiếu (NA) trước khi tiến hành phân tích, thống kê mô tả hoặc trực quan hóa dữ liệu, nhằm đảm bảo tính chính xác và toàn vẹn của kết quả.

1. tieuluan <- na.omit(tieuluan)
2. sum(is.na(tieuluan))
## [1] 0

Giải thích kỹ thuật

Dòng 1: dùng để loại bỏ tất cả giá trị NA trong dữ liệu tieuluan

Dòng 2 : dùng để kiểm tra tổng số giá trị NA còn lại (sau khi loại bỏ)

Nhận xét: Sử dụng lệnh na.omit() loại bỏ tất cả các giá trị NA trong bộ dữ liệu tieuluan. Sau khi thực hiện, lệnh sum(is.na(tieuluan)) trả về 0, cho thấy không còn giá trị thiếu trong dataset. Điều này đảm bảo dữ liệu đã sẵn sàng cho các bước phân tích và trực quan hóa tiếp theo.

6.2 . Xác định và loại bỏ dữ liệu trùng lặp

1. head(duplicated(tieuluan))
## [1] FALSE FALSE FALSE FALSE FALSE FALSE

Giải thích kỹ thuật:dùng để xem 6 giá trị đầu tiên của kết quả duplicated()

Nhận xét: Sử dụng lệnh duplicated() kết quả trả về kiểm tra các quan sát trùng lặp trong bộ dữ liệu. Trong tieuluan, 6 giá trị đầu tiên đều là FALSE, nghĩa là các quan sát này không bị trùng lặp.

1. sum(duplicated(tieuluan))
## [1] 2546

Giải thích kỹ thuật: dùng để đếm tổng số dòng bị trùng

Nhận xét: Sử dụng lệnh sum(duplicated()) cho kết quả 2546, nghĩa là trong tieuluan có 2.546 quan sát bị trùng lặp. Điều này cho thấy dữ liệu có sự lặp lại thông tin giữa các dòng, cần được kiểm tra và loại bỏ hoặc gộp lại trước khi thực hiện các bước phân tích tiếp theo để đảm bảo tính duy nhất và độ tin cậy của dữ liệu.

1. tieuluan <- tieuluan[!duplicated(tieuluan),]                                 

Giải thích kỹ thuật: dùng để xóa các dòng trùng lặp trong dữ liệu; hàm duplicated() xác định dòng trùng, dấu ! giữ lại dòng không trùng để tạo bảng dữ liệu duy nhất.

1. remove_extreme_outliers_multi <- function(df, vars) {
2.   for (var in vars) {           
3.     q1 <- quantile(df[[var]], 0.25, na.rm = TRUE)    
4.     q3 <- quantile(df[[var]], 0.75, na.rm = TRUE)    
5.     iqr <- q3 - q1                                  
6.     lower <- q1 - 3 * iqr      
7.     upper <- q3 + 3 * iqr     
8.     df <- df %>% filter(.data[[var]] >= lower, .data[[var]] <= upper) }
9.   return(df)}
10. vars_extreme <- c("price", "bath", "acre_lot")
11. tieuluan <- remove_extreme_outliers_multi(tieuluan, vars_extreme)
12. tieuluan <- tieuluan %>%
13.   filter(price >= 10000,       
14.          bath >= 1,           
15.          acre_lot > 0)        

Giải thích kỹ thuật

Dòng 1: Tạo hàm để loại bỏ các outlier cực đoan cho nhiều biến cùng lúc.

Dòng 2: Sử dụng vòng for để lặp qua từng biến trong danh sách vars.

Dòng 3-4: Tính tứ phân vị thứ nhất và thứ ba (Q1,Q3) của biến, loại bỏ giá trị thiếu (na.rm = TRUE).

Dòng 5: Tính khoảng tứ phân vị (IQR = Q3 - Q1).

Dòng 6: Xác định ngưỡng dưới để loại bỏ outlier cực đoan (Q1 - 3×IQR). Hệ số 3 giúp chỉ loại các điểm rất bất thường.

Dòng 7: Xác định ngưỡng trên để loại bỏ outlier cực đoan (Q3 + 3×IQR).

Dòng 8: Giữ lại các hàng có giá trị nằm trong khoảng [lower, upper] bằng hàm filter().

Dòng 9: Trả về dữ liệu đã được loại bỏ outlier.

Dòng 10: Tạo danh sách các biến liên tục vars_extreme gồm “price”, “bath”, “acre_lot”.

Dòng 11: Gọi hàm để loại bỏ các giá trị cực đoan khỏi các biến đã chọn trong tieuluan.

Dòng 12–15: Tiếp tục lọc dữ liệu giữ lại các quan sát hợp lệ: price >= 10000, bath >= 1, acre_lot > 0 để đảm bảo dữ liệu thực tế, hợp lý.
## . Sửa lỗi dữ liệu

1. subset(tieuluan, price <= 0)

Giải thích kỹ thuật: dùng để tìm các giao dịch có giá âm hoặc bằng 0.

Nhận xét: Sử dụng lệnh subset(tieuluan, price <= 0) tìm các giao dịch có giá âm hoặc bằng 0. Kết quả trả về 0 quan sát, cho thấy trong bộ dữ liệu tieuluan không có giao dịch nào có giá ≤ 0, đảm bảo dữ liệu giá nhà hợp lệ để phân tích.

1. subset(tieuluan, acre_lot <= 0)

Giải thích kỹ thuật: dùng để tìm các giao dịch có acre_lot <= 0

Nhận xét: Sử dụng lệnh subset(tieuluan, acre_lot <= 0) tìm các giao dịch có diện tích đất bằng hoặc nhỏ hơn 0. Kết quả trả về 0 quan sát, cho thấy trong bộ dữ liệu tieuluan không có giao dịch nào có diện tích đất ≤ 0, đảm bảo dữ liệu về diện tích đất hợp lệ để phân tích.

1. subset(tieuluan, bath <= 0)

Giải thích kỹ thuật : dùng để tìm các giao dịch có bath <= 0.

Nhận xét: Sử dụng lệnh subset(tieuluan, bath <= 0) tìm các giao dịch có số phòng tắm bằng hoặc nhỏ hơn 0. Kết quả trả về 0 quan sát, cho thấy trong bộ dữ liệu tieuluan không có giao dịch nào có số phòng tắm ≤ 0, đảm bảo dữ liệu về số phòng tắm hợp lệ để phân tích.

1. unique(tieuluan$status)
## [1] "for_sale" "sold"

Giải thích kỹ thuật : dùng để kiểm tra giá trị status chứa tất cả các trạng thái khác nhau, không lặp lại.

Nhận xét: Sử dụng lệnh unique() trả về các giá trị duy nhất của một biến trong bộ dữ liệu. Trong ví dụ này, unique(tieuluan$status) cho thấy biến status chỉ có hai giá trị “for_sale” và “sold”, không có lỗi chính tả hay giá trị bất thường, đảm bảo dữ liệu hợp lệ để phân nhóm và phân tích.

6.3 . Chuyển đổi kiểu dữ liệu

1. # Chuyển biến status từ character sang factor
2. tieuluan$status <- as.factor(tieuluan$status)

Giải thích kỹ thuật: dùng để chuyển biến status từ character sang factor

1. sapply(tieuluan, class)
##         status          price           bath           city       acre_lot 
##       "factor"      "numeric"      "integer"    "character"      "numeric" 
## prev_sold_date 
##         "Date"

Giải thích kỹ thuật : dùng để kiểm tra lại kiểu dữ liệu của toàn bộ biến

Nhận xét: Sử dụng lệnh sapply(tieuluan, class) trả về kiểu dữ liệu của từng biến trong bộ dữ liệu. Kết quả cho thấy các biến price và acre_lot có kiểu numeric; biến bath có kiểu integer; biến status có kiểu factor; biến city có kiểu character và biến prev_sold_date có kiểu Date. Thông tin này giúp xác định rõ loại dữ liệu của từng biến, từ đó lựa chọn phương pháp phân tích và trực quan hóa phù hợp trong các bước tiếp theo.

1. str(tieuluan)
## 'data.frame':    980077 obs. of  6 variables:
##  $ status        : Factor w/ 2 levels "for_sale","sold": 1 1 1 1 1 1 1 1 1 1 ...
##  $ price         : num  110000 950000 525000 289900 384900 ...
##  $ bath          : int  3 4 3 2 2 3 4 2 2 2 ...
##  $ city          : chr  "Dorado" "Saint Thomas" "Agawam" "Agawam" ...
##  $ acre_lot      : num  0.09 0.99 0.45 0.36 0.46 0.56 0.77 0.16 0.49 0.5 ...
##  $ prev_sold_date: Date, format: "2019-06-28" "2013-10-11" ...
##  - attr(*, "na.action")= 'omit' Named int [1:1078777] 1 2 3 4 5 6 7 8 9 10 ...
##   ..- attr(*, "names")= chr [1:1078777] "1" "2" "3" "4" ...

Giải thích kỹ thuật: Hàm str(tieuluan) hiển thị cấu trúc dữ liệu của tieuluan, gồm số dòng, cột, tên biến và kiểu dữ liệu, giúp xem nhanh tổng quan dữ liệu.

1. summary(tieuluan)
##       status           price              bath           city          
##  for_sale:426036   Min.   :  10000   Min.   :1.000   Length:980077     
##  sold    :554041   1st Qu.: 233000   1st Qu.:2.000   Class :character  
##                    Median : 360000   Median :2.000   Mode  :character  
##                    Mean   : 435034   Mean   :2.397                     
##                    3rd Qu.: 550000   3rd Qu.:3.000                     
##                    Max.   :1680000   Max.   :6.000                     
##     acre_lot      prev_sold_date      
##  Min.   :0.0100   Min.   :1901-01-01  
##  1st Qu.:0.1300   1st Qu.:2017-06-21  
##  Median :0.1900   Median :2021-12-07  
##  Mean   :0.2576   Mean   :2017-12-19  
##  3rd Qu.:0.3000   3rd Qu.:2022-03-07  
##  Max.   :1.1800   Max.   :2026-04-08

Giải thích kỹ thuật: Hàm summary(tieuluan) hiển thị thống kê mô tả nhanh cho các biến: với số là Min, Q1, Median, Mean, Q3, Max; với chuỗi là tần suất từng nhóm. Giúp nhìn tổng quan dữ liệu

7 . Thống kê cơ bản

7.1 . Lọc dữ liệu theo điều kiện

Tác giả thực hiện các lệnh lọc dữ liệu cơ bản theo điều kiện:

1. head(tieuluan[tieuluan$price >= quantile(tieuluan$price, 0.95, na.rm = TRUE), ], 5)

Giải thích kỹ thuật: dùng để lấy các nhà giá trong top 5% cao nhất và hiện 5 dòng đầu

1. head(tieuluan[tieuluan$acre_lot == max(tieuluan$acre_lot, na.rm = TRUE), ], )

Giải thích kỹ thuật: dùng để Lấy các nhà có diện tích đất lớn nhất (acre_lot) và hiện 6 dòng đầu

1. head(tieuluan[tieuluan$status == "sold", ], 7)

Giải thích kỹ thuật: dùng để lấy 7 dòng nhà đã sold

1. head(tieuluan[tieuluan$price >= 1670000 & tieuluan$price <= 1680000, ], 10)

Giải thích kỹ thuật: dùng để lấy các nhà giá từ 1670000 đến 1680000 và hiện 10 dòng đầu

1. head(tieuluan[tieuluan$bath >= 3 & tieuluan$acre_lot > 0.8, ], 10)

Giải thích kỹ thuật: dùng để lấy nhà có ít nhất 3 phòng tắm, diện tích đất > 0,8 mẫu Anh và hiện 10 dòng đầu

1. top_city <- tieuluan %>%
2.   count(city, sort = TRUE) %>%
3.   slice(1) %>%
4.   pull(city)
5. head(tieuluan[tieuluan$city == top_city, ], 10)

Giải thích kỹ thuật

Dòng 1–2: Sử dụng count(city, sort = TRUE) để đếm số lượng nhà theo từng thành phố và sắp xếp giảm dần theo tần suất xuất hiện.

Dòng 3–4: Dùng slice(1) để lấy thành phố có số lượng nhà nhiều nhất, sau đó pull(city) để trích tên thành phố đó lưu vào biến top_city.

1. head(tieuluan[tieuluan$acre_lot <= quantile(tieuluan$acre_lot, 0.05, na.rm = TRUE), ], 7)

Giải thích kỹ thuật: dùng để lấy các nhà diện tích thuộc top 5% nhỏ nhất và hiện 7 dòng đầu

1. head(tieuluan[tieuluan$bath >= 4 & tieuluan$price > 1600000, ], 5)

Giải thích kỹ thuật: dùng để lấy các nhà có từ 4 phòng tắm trở lên và giá > 1600000 và hiện 5 dòng đầu

1. head(tieuluan[tieuluan$price == 1680000, ], 14)

Giải thích kỹ thuật: dùng để Lấy các nhà giá = 1680000 và hiện 14 dòng đầu

1. head(tieuluan[tieuluan$acre_lot == max(tieuluan$acre_lot, na.rm = TRUE), ], 5)

Giải thích kỹ thuật: dùng để lấy các bất động sản có diện tích đất lớn nhất và hiện 5 dòng đầu

7.2 . Truy cập một giá trị cụ thể

Tác giả thực hiện một số lệnh sau đây để truy cập một giá trị cụ thể:

1. tieuluan[25555, 3]
## [1] 3

Giải thích kỹ thuật: dùng để lấy giá trị bath ở dòng thứ 25555, cột thứ 3

1. tieuluan$city[which.max(tieuluan$price)]
## [1] "Brooklyn"

Giải thích kỹ thuật: dùng để lấy giá trị city của dòng có price lớn nhất

1. tieuluan$city[1234]
## [1] "West Hartford"

Giải thích kỹ thuật: dùng để lấy giá trị city ở dòng thứ 12343

1. tieuluan$acre_lot[which.min(tieuluan$acre_lot)]
## [1] 0.01

Giải thích kỹ thuật: dùng để lấy giá trị acre_lot nhỏ nhất trong bộ dữ liệu

1. tieuluan[15000, 2]
## [1] 349900

Giải thích kỹ thuật: dùng để lấy giá trị price ở dòng thứ 15000, cột thứ 2

1. tieuluan$bath[10001]
## [1] 4

Giải thích kỹ thuật: dùng để lấy giá trị bath ở dòng thứ 10001

1. tieuluan$price[which.max(tieuluan$price)]
## [1] 1680000

Giải thích kỹ thuật: dùng để lấy giá trị price lớn nhất trong bộ dữ liệu

1. tieuluan$acre_lot[2025]
## [1] 0.31

Giải thích kỹ thuật: dùng để lấy giá trị acre_lot (diện tích đất) ở dòng thứ 2025

1. tieuluan[19000, "city"]
## [1] "Oakhurst"

Giải thích kỹ thuật: dùng để lấy giá trị city ở dòng 19000 truy cập theo tên cột

1. tieuluan$bath[which.max(tieuluan$bath)]
## [1] 6

Giải thích kỹ thuật: dùng để lấy giá trị bath lớn nhất trong bộ dữ liệu

7.3 . Thêm và sửa dữ liệu

Tác giả thực hiện các lệnh thêm và sửa dữ liệu dưới đây:

1. tieuluan$status[1005] <- "sold"

Giải thích kỹ thuật: dùng để chỉnh lại trạng thái ở dòng 1005 thành sold

1. tieuluan$city[5555] <- "Adams"

Giải thích kỹ thuật: dùng để cập nhật lại tên thành phố cho dòng thứ 5555

1. tieuluan$TransactionNo <- 1:nrow(tieuluan)

Giải thích kỹ thuật: dùng để thêm cột đánh số thứ tự giao dịch

1. tieuluan <- tieuluan[-3, ]

Giải thích kỹ thuật: dùng để xóa dòng thứ 3 khỏi dữ liệu

1. tieuluan$bath[10] <- 3

Giải thích kỹ thuật: dùng để gán lại số phòng tắm dòng thứ 10 thành 3

1. tieuluan$price[2] <- tieuluan$price[2] * 1.05

Giải thích kỹ thuật: dùng để sửa giá dòng thứ 2 của biến price tăng 5%ệ

1. tieuluan$price[nrow(tieuluan)] <- tieuluan$price[nrow(tieuluan)] * 1.05

Giải thích kỹ thuật: dùng để cập nhật price dòng cuối cùng tăng 5%

1. tieuluan$price[4] <- tieuluan$price[4] * 0.93

Giải thích kỹ thuật: dùng để sửa giá dòng thứ 4 giảm 7%

1. tieuluan$status[6789] <- "for_sale"

Giải thích kỹ thuật: dùng để sửa trạng thái dòng thứ 6789 thành for_sale

1. tieuluan$bath[1999] <- 3

Giải thích kỹ thuật: dùng để sửa số phòng tắm của dòng thứ 999 thành 3

1. tieuluan$price[nrow(tieuluan)] <- tieuluan$price[nrow(tieuluan)] * 1.05

Giải thích kỹ thuật: dùng để tăng giá dòng cuối cùng lên 5%

1. tieuluan$city[2004] <- "Vernon"

Giải thích kỹ thuật: dùng để chỉnh lại thành phố của dòng thứ 2004 thành “Vernon”

1. tieuluan$acre_lot[118] <- tieuluan$acre_lot[118] * 1.5

Giải thích kỹ thuật: dùng để tăng diện tích đất (acre_lot) của dòng 118 lên gấp rưỡi

1. tieuluan$bath[order(tieuluan$price, decreasing = TRUE)[1:3]] <- 5

Giải thích kỹ thuật: dùng để đặt lại số phòng tắm cho top 3 dòng giá cao nhất thành 5

1. tieuluan$acre_lot_m2 <- tieuluan$acre_lot * 4046.86

Giải thích kỹ thuật: dùng để tạo 1 biến mới tên acre_lot_m2 từ acre_lot sang mét vuông

7.4 . Phân tổ các biến

1. tieuluan <- tieuluan %>%                    
2.   mutate(                             
3.     prev_sold_date = as.Date(prev_sold_date),            
4.     prev_month_year = format(prev_sold_date, "%m-%Y"),   
5.     prev_year = year(prev_sold_date))

Giải thích kỹ thuật

Dòng 1: Gán lại dữ liệu cho tieuluan sau khi biến đổi.

Dòng 2: Dùng hàm mutate() để tạo hoặc chỉnh sửa cột trong bảng dữ liệu.

Dòng 3: Chuyển prev_sold_date về kiểu ngày chuẩn bằng as.Date().

Dòng 4: Tạo biến prev_month_year thể hiện tháng-năm theo định dạng “mm-YYYY”.

Dòng 5: Tạo biến prev_year lưu năm riêng biệt từ cột ngày gốc.

  • Nhận xét : Tác giả trích xuất năm từ biến prev_sold_date để tạo biến mới year, giúp thuận tiện cho việc phân tích và so sánh dữ liệu theo từng năm.

7.4.1 . Phân tổ biến price theo mức giá

1. tieuluan <- tieuluan %>%                
2.   mutate(                               
3.     mucgianha = case_when(             
4.       price < 100000 ~ "Rất rẻ",       
5.       price >= 100000 & price < 300000 ~ "Rẻ",        
6.       price >= 300000 & price < 600000 ~ "Trung bình",
7.       price >= 600000 & price < 1000000 ~ "Mắc",     
8.       price >= 1000000 ~ "Rất mắc"))

Giải thích kỹ thuật

Dòng 1: Sử dụng toán tử pipe %>% để liên kết các bước xử lý dữ liệu.

Dòng 2: Dùng hàm mutate() để tạo thêm biến mới trong bảng tieuluan.

Dòng 3: Hàm case_when() dùng để gán nhãn phân loại cho biến dựa trên điều kiện.

Dòng 4–8: Phân khúc price thành 5 mức: “Rất rẻ” (<100.000 USD), “Rẻ” (100.000–<300.000), “Trung bình” (300.000–<600.000), “Mắc” (600.000–<1.000.000), “Rất mắc” (≥1.000.000).

  • Nhận xét : Tác giả thực hiện phân loại “Price” thành biến “mucgianha” theo các mức từ “Rất rẻ” (giá dưới 100.000 USD ), “Rẻ” (giá từ 100.000 USD đến dưới 300.000 USD ), “Trung bình” (giá từ 300.000 USD đến dưới 600.000 USD), “Mắc” (giá từ 600.000 USD đến dưới 1.000.000 USD) “Rất mắc” (giá triệu USD trở lên). Kết quả nhận được là mỗi bất động sản được gán nhãn mức giá tương ứng, thuận tiện cho phân tích và thống kê theo nhóm.

7.4.2 . Phân tổ biến acre_lot theo diện tích đất

1. # Phân tổ biến acre_lot thành diện tích đất
2. tieuluan <- tieuluan %>%
3.   mutate(                             
4.     dientichdat = cut(
5.       acre_lot,                       
6.       breaks = c(0, 0.1, 0.2, 0.5, 1, Inf),  
7.       labels = c("Rất nhỏ", "Nhỏ", "Vừa", "Lớn", "Rất lớn"), 
8.       include.lowest = TRUE,      
9.       right = FALSE))
10. table(tieuluan$dientichdat)
## 
## Rất nhỏ     Nhỏ     Vừa     Lớn Rất lớn 
##  149461  366590  348537   86273   29215

Giải thích kỹ thuật

Dòng 1: Dùng toán tử pipe %>% để liên kết các bước xử lý dữ liệu.

Dòng 2: Hàm mutate() được dùng để tạo biến mới dientichdat từ biến acre_lot.

Dòng 3–8: Sử dụng hàm cut() để chia acre_lot thành 5 nhóm hợp lý theo khoảng: breaks = c(0, 0.1, 0.2, 0.5, 1, Inf) tương ứng với “Rất nhỏ”, “Nhỏ”, “Vừa”, “Lớn”, “Rất lớn”; include.lowest = TRUE giúp bao gồm giá trị nhỏ nhất, còn right = FALSE quy định khoảng [min, max).

Dòng 10: Dùng table(tieuluan$dientichdat) để đếm số lượng quan sát trong từng nhóm diện tích đất.

  • Nhận xét : Sử dụng lệnh cut() phân tổ biến acre_lot thành biến mới dientichdat với 5 nhóm: “Rất nhỏ” (diện tích từ 0 đến 0.1 acre), “Nhỏ” (từ 0.1 đến 0.2 acre), “Vừa” (từ 0.2 đến 0.5 acre), “Lớn” (từ 0.5 đến 1 acre) và “Rất lớn” (lớn hơn 1 acre). Việc phân loại này giúp dễ dàng phân tích phân phối diện tích đất của các bất động sản và so sánh giữa các nhóm khác nhau.

7.4.3 . Nhà có giá thuộc nhóm “Rẻ” hoặc “Rất rẻ” và đã bán

1. data1 <- subset(          
2.   tieuluan,                          
3.   mucgianha %in% c("Rẻ", "Rất rẻ") &    
4.     status == "sold" )                                   
5. head(data1)

Giải thích kỹ thuật

Dòng 1: Hàm subset() được dùng để lọc dữ liệu theo điều kiện cụ thể.

Dòng 2: Chỉ định bảng dữ liệu gốc là tieuluan.

Dòng 3–4: Điều kiện lọc: mucgianha nằm trong các nhóm “Rẻ” hoặc “Rất rẻ” và status bằng “sold”.

Dòng 5: Hàm head(data1) hiển thị 6 dòng đầu tiên của bảng dữ liệu data1.

  • Nhận xét : Nhóm bất động sản này gồm các nhà có giá thuộc mức “Rẻ” hoặc “Rất rẻ” và đã được bán (sold), với 221.695 quan sát, chiếm 22,62% trên tổng số 980.076 quan sát. Nhóm này đại diện cho phân khúc nhà ở giá thấp – trung bình, có diện tích đất nhỏ đến rất nhỏ (≈≤0,25 acre) và 1–3 phòng tắm, phù hợp với khách hàng trung lưu và thu nhập thấp đang tìm kiếm nhà ở vừa túi tiền. Phân khúc này phản ánh xu hướng mua để an cư hoặc đầu tư ngắn hạn, thể hiện nhu cầu ổn định của người dân đối với nhà ở cơ bản, chi phí thấp, đồng thời giúp doanh nghiệp định hướng chiến lược phát triển và tiếp thị phù hợp với thị trường đại chúng.

7.4.4 . Nhà có từ 3 phòng tắm trở lên và diện tích đất thuộc nhóm “Đất lớn” hoặc “Đất rất lớn”

1. data2 <- subset(                     
2.   tieuluan,                          
3.   bath >= 3 &                         
4.     dientichdat %in% c("Lớn", "Rất lớn"))
5. head(data2)

Giải thích kỹ thuật

Dòng 1-2: tương tự phân tổ Nhà có giá thuộc nhóm “Rẻ” hoặc “Rất rẻ” và đã bán

Dòng 3–4: Điều kiện lọc: bath >= 3 (nhà có từ 3 phòng tắm trở lên) và dientichdat diện tích đất “Lớn” hoặc “Rất lớn”.

Nhận xét : Nhóm bất động sản này gồm các nhà có từ 3 phòng tắm trở lên và diện tích đất thuộc nhóm “Lớn” hoặc “Rất lớn”, với 54.324 quan sát, chiếm 5,54% trên tổng số quan sát. Nhóm này đại diện cho phân khúc nhà ở trung – cao cấp, có không gian sống rộng rãi, tiện nghi hiện đại, hướng đến khách hàng có thu nhập khá và cao, đặc biệt là các hộ gia đình mong muốn nâng cấp chất lượng cuộc sống hoặc đầu tư lâu dài. Nhóm này phản ánh xu hướng mở rộng nhu cầu nhà ở diện tích lớn và đầy đủ tiện ích, đồng thời thể hiện sự quan tâm gia tăng của nhà đầu tư vào phân khúc bất động sản giá trị cao với tiềm năng sinh lời ổn định.

7.4.5 . Nhà có giá thuộc nhóm “Cao” hoặc “Rất cao” và đã bán

1. data3 <- subset(                         
2. tieuluan,                               
3. mucgianha %in% c("Cao", "Rất cao") &   
4. status == "sold")
5. head(data3)

Giải thích kỹ thuật

Dòng 1-2: tương tự phân tổ Nhà có giá thuộc nhóm “Rẻ” hoặc “Rất rẻ” và đã bán

Dòng 3–4: Điều kiện lọc: mucgianha giá nhà thuộc nhóm “Cao” hoặc “Rất cao” và status là đã bán.

Nhận xét: Nhóm bất động sản này gồm các nhà có giá thuộc mức “Mắc” hoặc “Rất mắc” và đã được bán (sold), nhưng không có quan sát nào trong bộ dữ liệu hiện tại. Điều này cho thấy phân khúc nhà cao cấp tuy tồn tại trên thị trường nhưng phần lớn vẫn đang trong trạng thái rao bán, chưa phát sinh nhiều giao dịch thực tế. Nguyên nhân có thể do giá trị tài sản lớn, tính thanh khoản thấp hoặc nhu cầu mua thực tế hạn chế so với các phân khúc giá thấp hơn. Kết quả này phản ánh xu hướng thị trường tập trung vào phân khúc trung bình – thấp.

7.4.6 . Nhà bán sau 2020 và có ít nhất 2 phòng tắm

1. data4 <- subset(           
2. tieuluan,                  
3. prev_sold_date >= 2020 &    
4. bath >= 2 &                 
5. status == "sold")           
6. head(data4)

Giải thích kỹ thuật

Dòng 1-2: tương tự phân tổ Nhà có giá thuộc nhóm “Rẻ” hoặc “Rất rẻ” và đã bán.

Dòng 3–5: Điều kiện lọc: năm bán trước từ 2020 trở đi, bath >= 2 có ít nhất 2 phòng tắm và status là đã bán.

Nhận xét : Nhóm bất động sản này gồm các nhà đã bán từ năm 2020 trở đi và có từ 2 phòng tắm trở lên, với 473.096 quan sát, chiếm 48,27% tổng dữ liệu. Nhóm này phản ánh phân khúc phổ thông–trung cấp, giá chủ yếu “Rẻ” đến “Trung bình”, diện tích nhỏ–vừa, phù hợp gia đình trẻ và người mua an cư sau đại dịch. Một phần nhỏ thuộc nhóm cao cấp ven biển, thể hiện xu hướng đầu tư dài hạn của khách hàng khá giả.

7.4.7 . Nhà giá thấp nhưng diện tích đất lớn

1. data5 <- subset(                        
2. tieuluan,                              
3. mucgianha == "Rẻ" &                     
4. dientichdat %in% c("Lớn", "Rất lớn"))
5. head(data5)

Giải thích kỹ thuật

Dòng 1-2: tương tự phân tổ Nhà có giá thuộc nhóm “Rẻ” hoặc “Rất rẻ” và đã bán..

Dòng 3–4: Điều kiện lọc: mucgianha là “Rẻ” và dientichdat là “Lớn” hoặc “Rất lớn”.

Nhận xét: Nhóm này gồm các nhà có giá “Rẻ” nhưng diện tích đất “Lớn” hoặc “Rất lớn”, với 39.450 quan sát, chiếm 4,03% tổng dữ liệu. Phần lớn đang rao bán (for_sale), có 1–3 phòng tắm và diện tích trung bình khoảng (2.000–5.000 m²). Nhóm này phản ánh phân khúc nhà giá thấp nhưng ưu tiên không gian rộng, phù hợp người mua ngân sách hạn chế muốn sở hữu nhiều đất hoặc nhà đầu tư tìm cơ hội tích lũy bất động sản dài hạn.

7.4.8 . Nhà giao dịch cũ (trước 2016) và giá thấp

1. data6 <- subset(                          
2. tieuluan,                                  
3. prev_sold_date < 2016 &                    
4. mucgianha %in% c("Rẻ", "Rất rẻ"))                     
5. head(data6)

Giải thích kỹ thuật

Dòng 1–2: Tương tự phân tổ “Nhà có giá thuộc nhóm ‘Rẻ’ hoặc ‘Rất rẻ’ và đã bán” (lọc dữ liệu từ tieuluan).

Dòng 3–4: Điều kiện lọc: nhà được giao dịch trước năm 2016 và mucgianha giá thuộc nhóm “Rẻ” hoặc “Rất rẻ”

Nhận xét : Nhóm này gồm các căn giao dịch (trước 2016) và giá “Rẻ/Rất rẻ”, có 517 quan sát với 12 biến, chiếm 0,05% tổng dữ liệu. Phần lớn đang rao bán (for_sale), 1–2 phòng tắm, đất nhỏ–vừa (ước khoảng (200–1.500 m²)). Nhóm này phản ánh nhu cầu của người mua ngân sách hạn chế và nhà đầu tư cải tạo/cho thuê, tập trung vào bất động sản cũ cần nâng cấp với giá vào thấp.

7.4.9 . Nhà ở thành phố Akron, giá thuộc nhóm “Rẻ”, và đã giao dịch bán

1. data7 <- subset(               
2. tieuluan,                      
3. city == "Akron" &              
4. mucgianha == "Rẻ" &          
5. status == "sold" )          
6. head(data7) 

Giải thích kỹ thuật

Dòng 1–2: Tương tự phân tổ “Nhà có giá thuộc nhóm ‘Rẻ’ hoặc ‘Rất rẻ’ và đã bán” .

Dòng 3–4: Điều kiện lọc: chỉ lấy các căn nhà ở thành phố Akro), mucgianha thuộc nhóm “Rẻ” và status là đã bán.

Nhận xét : Phân nhóm “giá Rẻ, đã bán” tại một địa bàn cụ thể có 681 quan sát, chiếm 0,07% tổng dữ liệu. Giao dịch tập trung giai đoạn 2021–2022; số phòng tắm phổ biến 1–3; diện tích đất chủ yếu mức Vừa–Lớn, vẫn hiện diện một số “Rất lớn”. Cấu hình này cho thấy nhu cầu mạnh của nhóm khách hàng nhạy giá, ưu tiên nhà ở tầm trung với quỹ đất đủ dùng, phù hợp mục tiêu an cư hoặc đầu tư ngắn hạn.

7.4.10 . Nhà ở thành phố Atlanta, có diện tích đất thuộc nhóm “Lớn” hoặc “Rất lớn” và đã bán

1. data8 <- subset(                    
2. tieuluan,                           
3. city == "Atlanta" &                  
4. dientichdat %in% c("Lớn", "Rất lớn") &      
5. status == "sold")
6. head(data8)

Giải thích kỹ thuật

Dòng 1–2: Tương tự phân tổ “Nhà có giá thuộc nhóm ‘Rẻ’ hoặc ‘Rất rẻ’ và đã bán”

Dòng 3–4: Điều kiện lọc: các căn ở thành phố Atlanta, dientichdat diện tích đất thuộc nhóm “Lớn” hoặc “Rất lớn” và status là đã bán.

Nhận xét : Phân nhóm nhà đã bán tại Atlanta có diện tích đất “Lớn/Rất lớn” gồm 222 quan sát, chiếm 0,02% tổng dữ liệu. Giao dịch tập trung giai đoạn 2021–2022, giá trải từ “Rẻ” đến “Rất mắc”, chủ yếu Trung bình–Mắc, với 2–4 phòng tắm phổ biến. Phân khúc này phản ánh nhu cầu cao về nhà có quỹ đất rộng, phục vụ khách hàng thu nhập khá–cao hướng đến không gian sống thoáng và đầu tư dài hạn.

7.5 Phân tổ 1 đến 3 biến

7.5.1 . Thống kê mô tả biến price

1. thongke1 <- tieuluan %>%   
2.   summarise(
3.     Sogiaodich = n(),      
4.     Giatritb = mean(price, na.rm = TRUE),   
5.     max = max(price, na.rm = TRUE),        
6.     min = min(price, na.rm = TRUE),         
7.     Trungvi = median(price, na.rm = TRUE),  
8.     Dolechchuan = sd(price, na.rm = TRUE),  
9.     Q1 = quantile(price, 0.25, na.rm = TRUE),
10.     Q3 = quantile(price, 0.75, na.rm = TRUE))
11. head(thongke1)

Giải thích kỹ thuật

Dòng 1–2: Sử dụng toán tử %>% để chuyển dữ liệu tieuluan vào hàm summarise() nhằm tính các chỉ số thống kê cho biến price.

Dòng 3–10: Tính các giá trị thống kê mô tả gồm số giao dịch,giá trung bình, giá cao nhất, giá thấp nhất, trung vị, độ lệch chuẩn và tính tứ phân vị thứ nhất Q1 và thứ ba Q3.

Dòng 11: head(thongke1) hiển thị kết quả thống kê mô tả vừa tính được.

Dựa vào bảng thông kê trên

  • Tổng giá trị giao dịch là 980.076 giao dịch

  • Giá trị trung bình của giá trị giao dịch là 435.034,3 USD.

  • Trung vị: 360.000 USD.

  • Giá trị tối thiểu và tối đa: 10.000 USD đến 1.680.000 USD → khoảng cách rất lớn, nhấn mạnh biến động giao dịch đa dạng.

  • Độ lệch chuẩn: 293.287,6 USD, cho thấy mức độ biến động cao giữa các giao dịch

  • Q1 và Q3: 233.000 USD và 550.000 USD, cho thấy phần lớn giao dịch tập trung ở mức giá trung bình – khá trong thị trường.

7.5.2 . Thống kê mô tả cho biến acre_lot_m2

1. ### . Thống kê mô tả cho biến acre_lot_m2
2. thongke2 <- tieuluan %>%                     #Dùng %>% để chuyển bảng dữ liệu tieuluan vào hàm summarise()
3.   summarise(                                 #Hàm summarise() để tính toán các thống kê mô tả
4.     Sogiaodich = n(),                        #Số lượng quan sát (tổng số căn nhà trong dữ liệu)
5.     Dientichtb = mean(acre_lot_m2, na.rm = TRUE),   #Giá trị trung bình của diện tích (bỏ qua NA)
6.     Max = max(acre_lot_m2, na.rm = TRUE),           #Giá trị diện tích lớn nhất
7.     Min = min(acre_lot_m2, na.rm = TRUE),           #Giá trị diện tích nhỏ nhất
8.     Trungvi = median(acre_lot_m2, na.rm = TRUE),    #Trung vị (median) – diện tích đại diện
9.     Dolechchuan = sd(acre_lot_m2, na.rm = TRUE),    #Độ lệch chuẩn – mức độ phân tán của diện tích
10.     Q1 = quantile(acre_lot_m2, 0.25, na.rm = TRUE), #Tứ phân vị thứ nhất (25% dữ liệu nhỏ hơn giá trị này)
11.     Q3 = quantile(acre_lot_m2, 0.75, na.rm = TRUE)  #Tứ phân vị thứ ba (75% dữ liệu nhỏ hơn giá trị này)
12.   )
13. head(thongke2)                                #Hiển thị kết quả thống kê ra màn hình

Giải thích kỹ thuật : tương tự như thông kê mô tả của biến price

Dựa trên bảng thống kê:

  • Tổng số giao dịch là 980.076 giao dịch.

  • Diện tích trung bình là 1.042,61m².

  • Trung vị: 768,9034 m².

  • Giá trị tối thiểu và tối đa: từ 40,4686 m² đến 7.775,295 m² → khoảng cách rất lớn, phản ánh sự đa dạng rõ rệt về quy mô đất.

  • Độ lệch chuẩn: 905,742 m², cho thấy mức biến động cao giữa các bất động sản.

  • Q1 và Q3: lần lượt là 526,0918 m² và 1.214,058 m², cho thấy phần lớn bất động sản tập trung ở nhóm diện tích trung bình – khá trong thị trường.

7.5.3 . Tính thống kê mô tả theo mucgianha và mucdientichdat

1. thongke3 <- tieuluan %>%                                
2.   group_by(mucgianha, dientichdat) %>%                   
3.   summarise(                                              
4.     Sogiaodich = n(),                                     
5.     Giatritb = mean(price, na.rm = TRUE),                 
6.     Trungvi = median(price, na.rm = TRUE),                
7.     Max = max(price, na.rm = TRUE),                       
8.     Min = min(price, na.rm = TRUE),                       
9.     Dolechchuan = sd(price, na.rm = TRUE),                
10.     Q1 = quantile(price, 0.25, na.rm = TRUE),             
11.     Q3 = quantile(price, 0.75, na.rm = TRUE)) %>%
12.   arrange(mucgianha, dientichdat)                       
13. head(thongke3)                                            

Giải thích kỹ thuật

Dòng 1–2: Sử dụng %>% để đưa bảng dữ liệu tieuluan vào hàm group_by(), nhóm theo hai biến phân loại là mucgianha và dientichdat.

Dòng 3–11: Dùng summarise() để tính các thống kê mô tả trong từng nhóm, gồm: số giao dịch , giá trung bình , trung vị , giá cao nhất , giá thấp nhất, độ lệch chuẩn, và hai tứ phân vị.

Dòng 12: arrange() sắp xếp kết quả theo thứ tự mucgianha và dientichdat.

Dòng 13: head(thongke3) hiển thị 6 dòng đầu tiên của bảng thống kê kết quả.

Dựa vào bảng thống kê trên:

  • Số lượng giao dịch giữa các nhóm giá và diện tích không đồng đều, trong đó các nhóm “Rẻ – Nhỏ/Vừa” và “Trung bình – Nhỏ/Vừa” chiếm tỷ trọng cao nhất, phản ánh phân khúc nhà ở tầm trung và giá thấp là phổ biến nhất trên thị trường.

  • Giá trị trung bình tăng dần theo phân khúc giá, thể hiện sự phân tầng rõ rệt giữa các mức giá:

    • Rất rẻ: khoảng 68.949 – 72.805 USD

    • Rẻ: khoảng 209.332 – 215.681 USD

    • Trung bình: khoảng 426.656 – 435.705 USD

    • Mắc: khoảng 760.660 – 771.369 USD

    • Rất mắc: khoảng 1.286.162 – 1.302.464 USD → Cho thấy mức giá được phân tầng hợp lý, phản ánh cấu trúc thị trường rõ ràng từ phổ thông đến cao cấp.

  • Độ lệch chuẩn (SD) tăng mạnh ở các phân khúc cao cấp, cho thấy mức biến động giá lớn do khác biệt về vị trí và tiện ích:

    • Rất rẻ: khoảng 20.156 – 22.636 USD

    • Rẻ: khoảng 54.485 – 56.311 USD

    • Trung bình: khoảng 83.515 – 85.174 USD

    • Mắc: khoảng 111.693 – 115.360 USD

    • Rất mắc: khoảng 172.444 – 177.751 USD

  • Khoảng giá Q1–Q3 cho thấy phần lớn giao dịch tập trung trong các mức:

    • Rất rẻ: 53.000 – 89.900 USD

    • Rẻ: 164.900 – 260.000 USD

    • Trung bình: 351.000 – 499.900 USD

    • Mắc: 665.000 – 859.000 USD

    • Rất mắc: 1.149.888 – 1.450.000 USD → Phản ánh mức giá phổ biến của từng phân khúc và ranh giới rõ ràng giữa các tầng thị trường.

  • Giá tối thiểu – tối đa trải rộng từ 10.000 USD đến 1.680.000 USD, cho thấy biên độ chênh lệch rất lớn, phản ánh thị trường đa dạng, bao gồm cả phân khúc nhà ở đại chúng và bất động sản cao cấp.

7.5.4 . Tính thống kê mô tả theo status và mucdientichdat

1. thongke4 <- tieuluan %>%                               
2.   group_by(status, dientichdat) %>%                     
3.   summarise(                                            
4.     Sogiaodich = n(),                                   
5.     Giatritb = mean(price, na.rm = TRUE),               
6.     Trungvi = median(price, na.rm = TRUE),              
7.     Max = max(price, na.rm = TRUE),                     
8.     Min = min(price, na.rm = TRUE),                     
9.     Dolechchuan = sd(price, na.rm = TRUE),              
10.     Q1 = quantile(price, 0.25, na.rm = TRUE),           
11.     Q3 = quantile(price, 0.75, na.rm = TRUE)) %>%
12.   arrange(status, dientichdat)                          
13. head(thongke4)                                          

Giải thích kỹ thuật

Dòng 1–2:tương tự như thống kê theo mucgianha và dientichdat nhưng nhóm dữ liệu theo hai biến: status và dientichdat.

Dòng 3–11: tương tự như thống kê theo mucgianha và dientichdat

Dòng 12: arrange() sắp xếp kết quả theo thứ tự status và dientichdat.

Dựa vào bảng thống kê trên:

  • Số lượng giao dịch giữa hai trạng thái “for_sale” và “sold” có sự chênh lệch rõ rệt, trong đó các nhóm “Nhỏ” và “Vừa” chiếm tỷ trọng lớn nhất ở cả hai trạng thái. Điều này phản ánh phân khúc nhà có diện tích trung bình được quan tâm và giao dịch nhiều nhất trên thị trường.

  • Giá trị trung bình tăng dần theo quy mô diện tích, thể hiện mối quan hệ hợp lý giữa diện tích và giá trị bất động sản:

    • For_sale: từ 424.604 USD (Rất nhỏ) đến 482.998 USD (Rất lớn)

    • Sold: từ 419.450 USD (Vừa) đến 439.769 USD (Lớn) → Cho thấy giá niêm yết thường cao hơn giá bán thực tế, phù hợp với thực tế thị trường có sự thương lượng trước khi giao dịch.

  • Độ lệch chuẩn (SD) dao động trong khoảng 275.000 – 322.000 USD, phản ánh mức biến động giá cao, đặc biệt ở những bất động sản có diện tích lớn và rất lớn, nơi giá trị chịu ảnh hưởng mạnh bởi vị trí, tiện ích và chất lượng tài sản.

  • Khoảng giá Q1–Q3 tập trung chủ yếu trong khoảng:

    • For_sale: 210.000 – 629.000 USD

    • Sold: 219.900 – 569.900 USD → Điều này cho thấy phần lớn giao dịch tập trung trong phân khúc trung bình – khá, là mức phổ biến và có tính thanh khoản cao nhất.

  • Giá tối thiểu – tối đa trải rộng từ 10.000 – 1.680.000 USD, khẳng định thị trường bất động sản đa dạng cả về quy mô lẫn giá trị, bao gồm từ nhà ở phổ thông đến phân khúc cao cấp.

7.5.5 . Tính thống kê mô tả theo mucgianha bath

1. thongke5 <- tieuluan %>%                          
2.   group_by(mucgianha, bath) %>%                     
3.   summarise(                                        
4.     Sogiaodich = n(),                               
5.     Giatritb = mean(price, na.rm = TRUE),           
6.     Trungvi = median(price, na.rm = TRUE),          
7.     Max = max(price, na.rm = TRUE),                 
8.     Min = min(price, na.rm = TRUE),                 
9.     Dolechchuan = sd(price, na.rm = TRUE),          
10.     Q1 = quantile(price, 0.25, na.rm = TRUE),       
11.     Q3 = quantile(price, 0.75, na.rm = TRUE)) %>%
12.   arrange(mucgianha, bath)                        
13. head(thongke5)                                      

Giải thích kỹ thuật

Dòng 1–2: tương tự như thống kê theo mucgianha và dientichdat nhưng nhóm theo hai biến mucgianha và bath.

Dòng 3–11: tương tự như thống kê theo mucgianha và dientichdat

Dòng 12: Sắp xếp kết quả theo thứ tự tăng dần của mucgianha và bath.

Dựa vào bảng thống kê trên:

  • Số lượng giao dịch giữa các nhóm giá và số phòng tắm (bath) có sự chênh lệch đáng kể, trong đó các nhóm “Rẻ – 2 phòng tắm” và “Trung bình – 2 hoặc 3 phòng tắm” chiếm tỷ trọng cao nhất, phản ánh phân khúc nhà tầm trung với 2–3 phòng tắm là lựa chọn phổ biến nhất của thị trường.

  • Giá trị trung bình tăng dần theo phân khúc giá, thể hiện quy luật hợp lý giữa giá trị và cấp độ nhà ở:

    • Rất rẻ: khoảng 58.570 – 74.954 USD

    • Rẻ: khoảng 183.218 – 241.996 USD

    • Trung bình: khoảng 413.664 – 493.703 USD

    • Mắc: khoảng 757.834 – 813.898 USD

    • Rất mắc: khoảng 1.252.930 – 1.344.547 USD → Cho thấy cấu trúc phân tầng giá rõ rệt, phản ánh sự đa dạng về thu nhập và nhu cầu của các nhóm người mua.

  • Độ lệch chuẩn (SD) tăng dần theo cấp độ giá, chứng tỏ phân khúc cao cấp có mức dao động giá lớn hơn do khác biệt về vị trí, thiết kế và tiện ích:

    • Rất rẻ: khoảng 19.153 – 31.456 USD

    • Rẻ: khoảng 46.652 – 57.820 USD

    • Trung bình: khoảng 77.652 – 85.337 USD

    • Mắc: khoảng 111.693 – 114.640 USD

    • Rất mắc: khoảng 172.434 – 181.988 USD

  • Khoảng giá Q1–Q3 thể hiện vùng tập trung chính của từng nhóm:

    • Rất rẻ: 41.526 – 91.225 USD

    • Rẻ: 139.000 – 280.000 USD

    • Trung bình: 349.000 – 557.695 USD

    • Mắc: 659.000 – 899.992 USD

    • Rất mắc: 1.099.980 – 1.499.000 USD → Cho thấy phần lớn giao dịch nằm trong khoảng trung – khá, phản ánh tính thanh khoản cao ở phân khúc tầm trung.

  • Giá tối thiểu – tối đa trải rộng từ 10.000 USD đến 1.680.000 USD, khẳng định thị trường có biên độ rất lớn, bao gồm từ nhà giá rẻ phổ thông đến bất động sản cao cấp, phù hợp với đặc trưng của thị trường bất động sản đa tầng và phân khúc rõ rệt.

7.5.6 . Tính thống kê mô tả theo status, mucgianha, và mucdientichdat

1. thongke6 <- tieuluan %>%                               
2.   group_by(status, mucgianha, dientichdat) %>%         
3.   summarise(                                           
4.     Sogiaodich = n(),                                  
5.     Giatritb = mean(price, na.rm = TRUE),              
6.     Trungvi = median(price, na.rm = TRUE),             
7.     Max = max(price, na.rm = TRUE),                    
8.     Min = min(price, na.rm = TRUE),                    
9.     Dolechchuan = sd(price, na.rm = TRUE),             
10.     Q1 = quantile(price, 0.25, na.rm = TRUE),          
11.     Q3 = quantile(price, 0.75, na.rm = TRUE)) %>%
12.   arrange(status, mucgianha, dientichdat)              
13. head(thongke6)                                         

Giải thích kỹ thuật

Dòng 1–2: tương tự như thống kê theo mucgianha và dientichdat nhưng nhóm theo ba biến phân loại: status, mucgianha, và dientichdat.

Dòng 3–11: tương tự như thống kê theo mucgianha và dientichdat.

Dòng 12: Sắp xếp kết quả theo thứ tự tăng dần của status, mucgianha, và dientichdat để dễ dàng đọc và phân tích.

Dựa vào bảng thống kê trên:

  • Số lượng giao dịch giữa hai trạng thái “for_sale” và “sold” có sự khác biệt đáng kể, trong đó các nhóm “Rẻ – Nhỏ/Vừa” và “Trung bình – Nhỏ/Vừa” chiếm tỷ trọng lớn nhất. Điều này cho thấy phân khúc tầm trung và giá thấp là khu vực hoạt động sôi động nhất của thị trường, phản ánh nhu cầu mạnh từ nhóm khách hàng trung lưu.

  • Giá trị trung bình (Giatritb) tăng đều theo cấp độ giá và gần như ổn định giữa hai trạng thái:

    • Rất rẻ: khoảng 68.910 – 74.685 USD

    • Rẻ: khoảng 208.318 – 216.791 USD

    -Trung bình: khoảng 425.387 – 437.371 USD

    • Mắc: khoảng 758.907 – 772.862 USD

    • Rất mắc: khoảng 1.282.518 – 1.309.947 USD → Điều này cho thấy sự phân tầng giá hợp lý và rõ ràng, đồng thời giá bán thực tế (sold) nhìn chung thấp hơn nhẹ so với giá niêm yết (for_sale), phù hợp với quy luật thương lượng trên thị trường.

  • Độ lệch chuẩn (SD) dao động từ 18.738 – 22.801 USD ở nhóm Rất rẻ, lên tới 171.170 – 178.022 USD ở nhóm Rất mắc, thể hiện mức biến động giá càng lớn ở các phân khúc cao cấp, do ảnh hưởng của vị trí, diện tích và tiện ích.

  • Khoảng giá Q1–Q3 phản ánh vùng tập trung của giao dịch theo nhóm:

    • Rất rẻ: 52.000 – 89.900 USD

    • Rẻ: 160.000 – 264.900 USD

    • Trung bình: 350.000 – 499.989 USD

    • Mắc: 665.000 – 859.900 USD

    • Rất mắc: 1.144.500 – 1.450.000 USD → Các khoảng giá này duy trì ổn định giữa hai trạng thái, cho thấy thị trường có tính thanh khoản cao ở vùng trung – khá.

  • Giá tối thiểu – tối đa trải rộng từ 10.000 – 1.680.000 USD, khẳng định biên độ giá rất lớn của thị trường, bao gồm từ nhà giá rẻ đại chúng đến bất động sản cao cấp, phản ánh cấu trúc thị trường đa tầng và đa nhu cầu.

8 . Trực quan hóa dữ liệu

8.1 . Vẽ đồ thị cơ bản với R

8.1.1 . Biểu đồ đường (Line Plot): Giá theo thứ tự quan sát

1. plot(tieuluan$price, type="l", col="darkred",
2.      main="Xu hướng giá", xlab="Thứ tự quan sát", ylab="Giá (USD)")

Giải thích kỹ thuật

Dòng 1: Sử dụng hàm plot() để vẽ biểu đồ đường (line plot), đặt màu sắc của đường là đỏ đậm, thiết lập tiêu đề chính, và nhãn cho trục X và trục Y.

Dòng 2: Đặt nhãn cho trục X là “Thứ tự quan sát” và trục Y là “Giá (USD)”.

  • Nhận xét : Biểu đồ thể hiện xu hướng giá nhà theo thứ tự quan sát. Dễ thấy rằng phần lớn các mức giá nằm ở khoảng thấp, chỉ có một số ít điểm có giá trị tăng vọt lên rất cao — đây có thể là những ngoại lệ (outliers) do giá nhà siêu đắt hoặc đặc biệt hiếm. Nhìn chung, dữ liệu giá có sự phân tán lớn, không ổn định và xuất hiện nhiều dao động mạnh, cho thấy thị trường nhà ở có sự chênh lệch đáng kể giữa các bất động sản.

8.1.2 . Biến động giá bán bất động sản theo năm

1. df_year_price <- tieuluan %>% 
2.   group_by(prev_year) %>% 
3.   summarise(price_tb = mean(price, na.rm = TRUE)) %>%
4.   arrange(prev_year)
5. plot(df_year_price$prev_year, df_year_price$price_tb, type="l", col="darkred", main="Biến động giá bán bất động sản theo năm",
6.      xlab="Năm", ylab="Giá bán trung bình (USD)")
7. points(df_year_price$prev_year, df_year_price$price_tb,
8.        pch=16, col="darkred")

Giải thích kỹ thuật

Dòng 2: group_by(prev_year) nhóm dữ liệu theo năm (prev_year).

Dòng 3: summarise(price_tb = mean(price, na.rm = TRUE)) tính giá trung bình (price_tb) mỗi năm, bỏ qua các giá trị NA.

Dòng 4: arrange(prev_year) sắp xếp kết quả theo năm tăng dần.

Dòng 5-7: Xác định loại biểu đồ tương tự biểu đồ đường (Line Plot): Giá theo thứ tự quan sát

Dòng 8: Sử dụng hàm points() để thêm các điểm tròn vào biểu đồ, với trục X là năm và trục Y là giá trung bình.

Dòng 9: pch = 16 thiết lập điểm tròn đặc.

Nhận xét : Biểu đồ cho thấy giá bán bất động sản biến động mạnh theo thời gian. Giai đoạn 1900–1940 giá giảm nhẹ, sau đó tăng vọt rõ rệt trong giai đoạn 1950–1970 và đạt mức cao nhất. Từ sau năm 1970, giá tăng dần và ổn định hơn trong khoảng 1980–2010. Đến sau năm 2020, giá có xu hướng giảm mạnh, cho thấy thị trường có dấu hiệu chững lại hoặc suy yếu do Covid.

8.1.3 . Biểu đồ cột (Bar Plot): Số lượng nhà theo trạng thái bán

1. status_count <- table(tieuluan$status)              
2. bp <- barplot(
3.   status_count,main = "Số lượng nhà theo trạng thái",           
4.   xlab = "Trạng thái",ylab = "Số lượng",                                
5.   col = c("darkolivegreen", "orange"),               
6.   ylim = c(0, max(status_count) * 1.3))
7. text(x = bp,y = status_count + max(status_count)*0.05,        
8.   labels = status_count,
9.   pos = 3,cex = 0.9,font = 2,col = "black")

Giải thích kỹ thuật

Dòng 1: status_count <- table(tieuluan$status) tạo bảng tần suất đếm số lượng các giá trị trong biến status của dữ liệu tieuluan.

Dòng 2: bp <- barplot(status_count, main = “Số lượng nhà theo trạng thái”, vẽ biểu đồ cột và lưu vị trí các cột vào biến bp. Thiết lập tiêu đề biểu đồ là “Số lượng nhà theo trạng thái”.

Dòng 3-4: thiết lập nhãn cho trục X là “Trạng thái”, thiết lập nhãn cho trục Y là “Số lượng

Dòng 5: thiết lập màu sắc cho các cột

Dòng 6: tăng thêm 30% giá trị lớn nhất trong bảng status_count để có khoảng trống phía trên các cột.

Dòng 7: thêm các nhãn (giá trị) lên trên các cột, với vị trí y cách giá trị của cột một khoảng nhỏ (5% của giá trị lớn nhất).

Dòng 8: in giá trị trong status_count lên trên mỗi cột.

Dòng 9: pos = 3, cex = 0.9, font = 2, col = “black” thiết lập vị trí nhãn trên cùng, kích thước chữ 90%,in độ đậm và chữ màu đen.

Nhận xét : Biểu đồ cho thấy số lượng nhà đã bán (sold) cao hơn đáng kể so với số nhà đang rao bán (for_sale). Cụ thể, số nhà bán được là 554.042, vượt khoảng 128.000 căn so với số nhà đang rao bán là 426.034. Điều này phản ánh thị trường bất động sản có tính thanh khoản khá tốt, nhu cầu mua cao hơn cung hiện có, cho thấy giao dịch diễn ra sôi động và thị trường đang phát triển tích cực.

8.1.4 . Biểu đồ tròn (Pie Chart): Tỷ lệ nhà theo trạng thái

1. status_count <- table(tieuluan$status)                
2. percent <- round(100 * status_count / sum(status_count), 1)
3. labels <- paste(names(status_count), "-", percent, "%")
4. pie(
5.   status_count,labels = labels,                               
6.   main = "Tỷ lệ nhà theo trạng thái",            
7.   col = c("forestgreen", "goldenrod"),border = "white")

Giải thích kỹ thuật

Dòng 1: tạo bảng tần suất đếm số lượng các giá trị trong biến status.

Dòng 2: tính tỷ lệ phần trăm cho mỗi giá trị trong status_count, làm tròn đến một chữ số thập phân.

Dòng 3: tạo nhãn cho biểu đồ, kết hợp tên trạng thái với tỷ lệ phần trăm.

Dòng 4–7: Sử dụng hàm pie() để vẽ biểu đồ tròn, với các tham số:

Dòng 4: status_count là dữ liệu cần biểu diễn và gắn nhãn vào từng phần của biểu đồ.

Dòng 5: thiết lập tiêu đề cho biểu đồ.

Dòng 6: chọn màu sắc cho các phần của biểu đồ, đặt màu viền của các phần trong biểu đồ là trắn

  • Nhận xét : Biểu đồ cho thấy nhà đã bán (sold) chiếm 56,5%, trong khi nhà đang rao bán (for_sale) chiếm 43,5% tổng số lượng. Tỷ lệ này cho thấy thị trường bất động sản có tính thanh khoản khá cao, phần lớn các bất động sản được giao dịch thành công. Tuy nhiên, tỷ lệ nhà còn rao bán cũng tương đối lớn, phản ánh nguồn cung vẫn dồi dào và thị trường duy trì trạng thái cân bằng giữa cung và cầu.

8.1.5 . Biểu đồ hộp (Box Plot): Phân phối số phòng tắm

1. boxplot(tieuluan$bath,                               
2.         main = "Phân phối số phòng tắm",ylab = "Số lượng phòng tắm",
3.         col = "#9D0",border = "#3E065F") 

Giải thích kỹ thuật

Dòng 1:vẽ biểu đồ hộp(boxplot)cho biến bath, thể hiện phân phối số phòng tắm.

Dòng 2-4: xác định các chỉ số trong biểu đồ tương tự như Biểu đồ cột (Bar Plot): Số lượng nhà theo trạng thái bán.

  • Nhận xét: Biểu đồ hộp cho thấy số phòng tắm chủ yếu dao động từ 2 đến 3 phòng, trung vị rơi vào khoảng 2 phòng tắm. Một số bất động sản có từ 5–6 phòng tắm được xem là giá trị ngoại lai, xuất hiện ít. Nhìn chung, phần lớn nhà có số phòng tắm ở mức trung bình, phản ánh phân khúc nhà phổ thông chiếm ưu thế trên thị trường.

8.1.6 . Biểu đồ hộp (Box Plot): Phân phối số lượng phòng tắm của các bất động sản có ≥ 3 phòng tắm

1. boxplot(tieuluan$bath[tieuluan$bath >= 3],                 
2.   main = "Phân phối số phòng tắm (≥ 3)",             
3.   ylab = "Số lượng phòng tắm",col = "yellow",border = "#3E065F")

Giải thích Kỹ thuật: các bước tương tự như Biểu đồ hộp (Box Plot): Phân phối số phòng tắm

  • Nhận xét : Biểu đồ cho thấy các bất động sản có từ 3 phòng tắm trở lên chủ yếu tập trung ở mức 3–4 phòng, trong đó trung vị là 3 phòng tắm. Một số ít căn có 5–6 phòng tắm được xem là ngoại lệ (outlier). Điều này cho thấy phân khúc nhà cao cấp (nhiều phòng tắm) chiếm tỷ lệ nhỏ, phần lớn vẫn là nhà ở quy mô vừa phải, phù hợp với nhu cầu gia đình tiêu chuẩn.

8.1.7 . Biểu đồ cột (Bar Plot): Thể hiện tần suất số phòng tắm

1. bathroom_freq <- table(tieuluan$bath)
2. bp <- barplot(bathroom_freq,main = "Tần suất số phòng tắm",             
3.               xlab = "Số phòng tắm",ylab = "Số lượng nhà",                     
4.               col = "lightcoral",ylim = c(0, max(bathroom_freq) * 1.2))      
5. text(x = bp,y = bathroom_freq + max(bathroom_freq)*0.05,         
6.      labels = bathroom_freq,cex = 0.8,font = 2,col = "black")                 

Giải thích kỹ thuật

Dòng 1: tạo bảng tần suất để đếm số lượng các giá trị trong biến bath

Dòng 2:vẽ biểu đồ cột (barplot()) cho tần suất các giá trị trong bathroom_freq và lưu vị trí của các cột vào biến bp.

Dòng 4: thiết lập màu sắc cho các cột và điều chỉnh giới hạn trục Y để có thêm khoảng trống phía trên các cột.

Dòng 5: 0.05 là hệ số tạo khoảng cách 5% so với giá trị lớn nhất trong bathroom_freq, giúp nhãn cách đỉnh cột một khoảng.

Dòng 6: thiết lập nhãn điều chỉnh kích thước chữ (cex = 0.8), làm chữ đậm (font = 2) và màu chữ là đen.

  • Nhận xét : Biểu đồ cho thấy đa số các căn nhà có từ 2 đến 3 phòng tắm, trong đó 2 phòng tắm là phổ biến nhất. Khi số phòng tắm tăng lên, tần suất giảm rõ rệt, hầu như rất ít căn có trên 10 phòng tắm. Điều này phản ánh rằng phần lớn bất động sản có quy mô sinh hoạt trung bình, phù hợp với nhu cầu hộ gia đình thông thường. Nhìn chung, phân bố lệch phải, tức là tập trung chủ yếu ở nhóm ít phòng tắm và giảm dần khi số phòng tăng.

8.1.8 . Biểu đồ cột (Bar Plot): 10 thành phố có nhiều nhà nhất

1. top_cities <- sort(table(tieuluan$city), decreasing = TRUE)[1:10]  
2. bp <- barplot(top_cities,las = 2,                                              
3.   col = "turquoise",main = "Top 10 thành phố có nhiều nhà nhất",    
4.   ylab = "Số lượng nhà",cex.names = 0.8,ylim = c(0, max(top_cities) * 1.25))
5. text(x = bp, y = top_cities + max(top_cities) * 0.03,                       
6.      labels = top_cities, pos = 3, cex = 0.8,font = 2,col = "black")

Giải thích kỹ thuật

Dòng 1: tạo bảng tần suất cho biến city và sắp xếp theo thứ tự giảm dần, chỉ lấy 10 thành phố có nhiều nhà nhất.

Dòng 3: thiết lập màu sắc các cột và tiêu đề cho biểu đồ.

Dòng 4: thiết lập nhãn trục Y, giảm kích thước tên các thành phố xuống 80% (cex.names = 0.8) và trục Y để có khoảng trống phía trên các cột.

Dòng 5: thêm nhãn lên trên các cột, cách đỉnh cột một khoảng 3%.

Dòng 6: tương tự Biểu đồ cột (Bar Plot): Thể hiện tần suất số phòng tắm

  • Nhận xét: Biểu đồ cho thấy Houston là thành phố có số lượng nhà nhiều nhất với 14.184 căn, vượt xa các thành phố khác. Theo sau là Tucson, Phoenix và Chicago với khoảng 6.000–7.000 căn mỗi nơi. Các thành phố còn lại như Philadelphia, Dallas hay Orlando có số lượng tương đối đồng đều và thấp hơn đáng kể. Điều này phản ánh Houston là trung tâm bất động sản sôi động nhất, có quy mô giao dịch lớn và sức hút thị trường cao hơn so với các khu vực khác.

8.1.9 . Biểu đồ tròn (Pie Chart): Tỷ lệ % của top 10 thành phố có nhiều nhà nhất

1. top_cities <- sort(table(tieuluan$city), decreasing = TRUE)[1:10]   
2. pct <- round(top_cities / sum(top_cities) * 100, 1)               
3. labels <- paste(names(top_cities), "(", pct, "%)", sep = "")        
4. pie(top_cities,labels = labels,                         
5.   main = "Tỷ lệ % của Top 10 thành phố có nhiều nhà nhất",
6.   col = rainbow(10), border = "white")

Giải thích kỹ thuật

Dòng 1: tương tự đồ thị trên

Dòng 2: tính tỷ lệ phần trăm của mỗi thành phố trong top_cities và làm tròn kết quả đến một chữ số thập phân.

Dòng 3:tạo nhãn cho biểu đồ, kết hợp tên thành phố với tỷ lệ phần trăm.

Dòng 4: vẽ biểu đồ tròn cho top_cities với nhãn đã có labels

  • Nhận xét : Biểu đồ cho thấy Houston chiếm tỷ lệ lớn nhất với 20.9% tổng số nhà trong top 10 thành phố, cao gấp đôi so với các khu vực còn lại. Theo sau là Tucson (10.6%) và Phoenix (10.3%), trong khi các thành phố như Richmond, Orlando và Saint Louis dao động quanh mức 8%. Điều này chứng tỏ Houston là thị trường bất động sản nổi bật và tập trung cao nhất, còn các thành phố khác có mức độ phân bổ tương đối đồng đều, thể hiện sự đa dạng khu vực trong hoạt động giao dịch nhà ở.

8.1.10 . Biểu đồ cột (Bar Plot): 10 thành phố có ít nhà nhất

1. bottom_cities <- sort(table(tieuluan$city), decreasing = FALSE)[1:10] 
2. bp <- barplot(bottom_cities,las = 2,col = "pink",   
3.   main = "Top 10 thành phố có ít nhà nhất",  
4.   ylab = "Số lượng nhà",cex.names = 0.8,ylim = c(0, max(bottom_cities) * 1.25))
5. text(x = bp,y = bottom_cities + max(bottom_cities) * 0.03,  
6.   labels = bottom_cities,pos = 3,cex = 0.8,font = 2,col = "darkred")

Giải thích kỹ thuật

Dòng 1:tạo bảng tần suất cho biến city, sắp xếp theo thứ tự tăng dần và chỉ lấy 10 thành phố có ít nhà nhất.

Dòng 2:las = 2 xoay nhãn trục X thành dọc,col = “pink” chọn màu hồng cho các cột.

Dòng 4: thiết lập nhãn trục Y”, giảm kích thước tên các thành phố xuống 80% và điều chỉnh giới hạn trục Y để có thêm khoảng trống phía trên các cột.

Dòng 5:thêm nhãn (giá trị) lên trên các cột, cách đỉnh cột một khoảng 3%.

Dòng 6: thiết lập nhãn, in đậm, căn chỉnh chữ, màu chữ.

  • Nhận xét : Biểu đồ cho thấy 10 thành phố có ít nhà nhất đều chỉ có 1 căn nhà được ghi nhận, bao gồm Aaronsburg, Abbott, Abbyville, Abell, Abrams,…. Điều này phản ánh rằng dữ liệu về các khu vực này còn rất hạn chế hoặc thị trường bất động sản tại đây kém sôi động, hầu như không có hoạt động giao dịch đáng kể so với các trung tâm lớn như Houston hay Phoenix.

8.2 . Trực quan hóa bằng ggplot2

8.2.1 . Số lượng nhà theo diện tích đất & trạng thái bán

1. ggplot(tieuluan, aes(x = dientichdat, fill = status)) +   
2.   geom_bar(position = "dodge") +                         
3.   geom_text(stat = "count", aes(label = ..count..),       
4.             position = position_dodge(width = 0.9),        
5.             vjust = -0.3, size = 3) + 
6.   scale_fill_manual(values = c("deepskyblue", "gold")) +
7.   labs(title = "Trạng thái bán theo mức diện tích đất",    
8.        x = "Mức diện tích đất",                           
9.        y = "Số lượng nhà") +                              
10.   theme_minimal()                                          

Giải thích kỹ thuật

Dòng 1: khởi tạo biểu đồ ggplot() với biến dientichdat trên trục X và màu sắc phân loại theo biến status.

Dòng 2: vẽ biểu đồ cột với các cột được đặt cạnh nhau (dodge) cho từng trạng thái trong biến status.

Dòng 3: thêm nhãn số lượng lên các cột, sử dụng ..count.. để lấy giá trị đếm cho mỗi nhóm.

Dòng 4: điều chỉnh vị trí nhãn sao cho không bị chồng lên các cột.

Dòng 5: điều chỉnh vị trí của nhãn lên trên cao hơn các cột (vjust = -0.3) và thiết lập kích thước chữ cho nhãn.

Dòng 6: thiết lập màu sắc thủ công cho các cột, với màu xanh dương và vàng cho các trạng thái.

Dòng 7: thiết lập tiêu đề, nhãn trục X và nhãn trục Y “.

Dòng 8: theme_minimal() áp dụng theme đơn giản cho biểu đồ.

  • Nhận xét : Biểu đồ cho thấy các bất động sản có diện tích đất nhỏ và vừa chiếm tỷ trọng cao nhất trong cả hai nhóm trạng thái. Cụ thể, nhóm “Nhỏ” và “Vừa” có tổng số lượng nhà bán và đang rao bán vượt trội, trong đó số nhà đã bán (sold) luôn cao hơn đang rao bán (for_sale). Ngược lại, nhóm “Lớn” và “Rất lớn” chiếm tỷ lệ thấp, thể hiện rằng các bất động sản quy mô lớn ít phổ biến và khó giao dịch hơn. Điều này phản ánh nhu cầu thị trường tập trung mạnh vào các loại nhà có diện tích vừa và nhỏ, phù hợp với khả năng tài chính và nhu cầu ở thực tế của đa số người mua.

8.2.2 . Biểu đồ cột ngang: Số lượng nhà đã bán theo từng mức giá

1. ggplot(tieuluan %>% filter(status == "sold"),           
2.        aes(x = mucgianha, fill = mucgianha)) +
3.   geom_bar() + geom_text(stat = "count", aes(label = ..count..),
4.                          hjust = -0.1, size = 2) + coord_flip() +
5.   labs(title = "Số lượng nhà đã bán theo mức giá",       
6.     x = "Mức giá", y = "Số lượng nhà") +
7.   scale_fill_manual(values = c("pink", "mediumpurple", "orange", "khaki", "tomato")) +theme_minimal(base_size = 13) +                       
8.   theme(plot.title = element_text(hjust = 0.5, face = "bold"),
9.     legend.position = "none")

Giáỉ thích kỹ thuật

Dòng 1: trục X là mucgianha và màu sắc phân loại theo mucgianha.

Dòng 2: Vẽ biểu đồ cột (geom_bar()) cho các giá trị của mucgianha trong nhóm nhà đã bán.

Dòng 3: Thêm nhãn số lượng vào biểu đồ cột, tính số lượng cho mỗi nhóm và hiển thị nhãn số lượng lên trên các cột.

Dòng 4: hjust = -0.1 điều chỉnh vị trí nhãn, đẩy chúng ra ngoài cột và size = 2 điều chỉnh kích thước chữ của nhãn.

Dòng 5: chuyển trục X thành trục Y và ngược lại để các nhãn dễ đọc hơn.

Dòng 6: Thiết lập tiêu đề của biểu đồ”, nhãn trục X”, và nhãn trục Y.

Dòng 7: dùng để chọn màu sắc cho các cột trong biểu đồ

Dòng 8: làm cho biểu đồ gọn gàng và dễ nhìn hơn.

Dòng 9: Điều chỉnh tiêu đề để căn giữa tiêu đề và làm chữ đậm, ẩn phần chú giải (legend).

  • Nhận xét : Biểu đồ cho thấy phần lớn các căn nhà đã bán thuộc nhóm giá “trung bình” và “rẻ”, lần lượt 219.907 và 195.482 căn, chiếm tỷ trọng lớn nhất. Trong khi đó, nhóm “mắc” có 85.198 căn, còn “rất rẻ” và “rất mắc” chỉ đạt 26.213 và 27.244 căn. Điều này cho thấy phân khúc nhà giá trung bình và rẻ có sức mua mạnh nhất, phản ánh nhu cầu thị trường tập trung chủ yếu vào các loại nhà có giá phù hợp với thu nhập của đa số người dân, trong khi phân khúc cao cấp ít được mua hơn.

8.2.3 . Biểu đồ cột ngang: Số lượng nhà đang rao bán theo từng mức giá

1. ggplot(tieuluan %>% filter(status == "for_sale"),       
2.        aes(x = mucgianha, fill = mucgianha)) + geom_bar() +
3.   geom_text(stat = "count", aes(label = ..count..),       
4.             hjust = -0.1, size = 2) + coord_flip() +                                    labs(title = "Số lượng nhà đang rao bán theo mức giá",     
5.     x = "Mức giá",y = "Số lượng nhà" ) +
6.   scale_fill_manual(values = c("dodgerblue", "yellowgreen", "goldenrod", "coral", "brown")) +  # Màu mới hoàn toàn cho từng mức giá
7.   theme_minimal(base_size = 13) +                         
8.   theme(plot.title = element_text(hjust = 0.5, face = "bold"),    
9.     legend.position = "none")

Giải thích kỹ thuật: tương tự Biểu đồ cột ngang: Số lượng nhà đã bán theo từng mức giá

  • Nhận xét : Biểu đồ cho thấy các căn nhà đang rao bán chủ yếu thuộc nhóm giá “trung bình”, chiếm số lượng lớn nhất với 171.645 căn, tiếp theo là nhóm “rẻ” với 140.661 căn. Nhóm “mắc” có 69.660 căn, trong khi “rất rẻ” và “rất mắc” chỉ đạt 20.703 và 23.365 căn. Điều này phản ánh thị trường tập trung mạnh vào phân khúc giá trung bình và rẻ, phù hợp với nhu cầu và khả năng chi trả của phần lớn người mua, còn các phân khúc cao hơn có lượng rao bán ít hơn do kén khách và tính thanh khoản thấp.

8.2.4 . Biểu đồ tròn: Tỷ lệ nhà đã bán theo diện tích đất

1. sold_data <- tieuluan %>%
2.   filter(status == "sold")                  
3. data_pie <- sold_data %>%
4.   count(dientichdat) %>%                      
5.   mutate(tyle = round(n / sum(n) * 100, 2), 
6.          label = paste0(dientichdat, " - ", tyle, "%"))
7. ggplot(data_pie, aes(x = "", y = n, fill = dientichdat)) +  
8.   geom_bar(stat = "identity", width = 1) + coord_polar("y") +                  geom_text( aes(label = label),                        
9.               position = position_stack(vjust = 0.5),size = 3 ) +               scale_fill_manual(
10.     values = c("orangered", "aquamarine4", "wheat", "plum", "dodgerblue4")) +
11.   labs( title = "Tỷ lệ nhà đã bán theo diện tích đất" ) +     
12.  theme_void() +                                               
13.  theme(plot.title = element_text(hjust = 0.5, face = "bold")) 

Giải thích kỹ thuật

Dòng 1: lấy các nhà có trạng thái “sold” (đã bán), lưu vào biến sold_data.

Dòng 2: Đếm số lượng nhà bán theo nhóm dientichdat

Dòng 3: mutate(tyle = round(n / sum(n) * 100, 2), label = paste0(dientichdat, ” - “, tyle,”%“)) Tạo cột mới tyle tính tỷ lệ phần trăm của từng diện tích đất (dientichdat), làm tròn kết quả đến 2 chữ số, và tạo nhãn (label) kết hợp diện tích đất và tỷ lệ phần trăm.

Dòng 4: vẽ biểu đồ tròn, trục X rỗng, trục Y là số lượng nhà và fill = dientichdat.

Dòng 5: Vẽ biểu đồ cột với các cột có chiều rộng bằng 1 (width = 1) và chuyển biểu đồ thành hình tròn bằng coord_polar(“y”).

Dòng 6: Thêm nhãn tỷ lệ phần trăm vào các phần trong biểu đồ tròn, căn chỉnh nhãn theo chiều dọc và điều chỉnh kích thước chữ là 3.

Dòng 7: Sử dụng màu sắc thủ công cho các phần của biểu đồ tròn, với màu sắc.

Dòng 9: để loại bỏ các trục, nhãn và lưới, giúp biểu đồ trở nên đơn giản.

Dòng 10: Căn giữa tiêu đề với hjust = 0.5 và làm chữ đậm.

Nhận xét: Biểu đồ cho thấy phần lớn các căn nhà đã bán tập trung ở nhóm “Nhỏ” (38,87%) và “Vừa” (34,46%), chiếm hơn 70% tổng số giao dịch. Trong khi đó, nhóm “Rất nhỏ” chiếm khoảng 15,68%, còn “Lớn” và “Rất lớn” lần lượt chỉ chiếm 8,24% và 2,74%. Điều này cho thấy nhà có diện tích trung bình và nhỏ vẫn là phân khúc được giao dịch phổ biến nhất, phù hợp với khả năng chi trả và nhu cầu thực tế của phần lớn người mua trên thị trường.

8.2.5 . Biểu đồ tròn: Tỷ lệ nhà đang cho thuê theo diện tích đất

1. rent_data <- tieuluan %>%
2.   filter(status == "for_sale")                            
3. data_pie_rent <- rent_data %>%
4.   count(dientichdat) %>%                                    
5.   mutate(tyle = round(n / sum(n) * 100, 2),                      
6.     label = paste0(dientichdat, " - ", tyle, "%"))           
7. ggplot(data_pie_rent, aes(x = "", y = n, fill = dientichdat)) +   
8.   geom_bar(stat = "identity", width = 1) +                        
9.   coord_polar("y") + geom_text(aes(label = label),                            
10.             position = position_stack(vjust = 0.5), size = 3) +                         scale_fill_manual(values = c(                                   
11.     "seagreen", "deeppink", "goldenrod1", "cornflowerblue", "tan" )) +
12.   labs(title = "Tỷ lệ nhà đang cho thuê theo diện tích đất") +   
13.   theme_void() +                                                  
14.   theme(plot.title = element_text(hjust = 0.5, face = "bold"))    

Giải thích kỹ thuật: biểu đồ vẽ tương tự biểu đồ tròn: Tỷ lệ nhà đã bán theo diện tích đất

  • Nhận xét: Biểu đồ cho thấy các căn nhà đang cho thuê chủ yếu thuộc nhóm diện tích “Vừa” (36,99%) và “Nhỏ” (35,49%), chiếm hơn 70% tổng số bất động sản rao bán. Trong khi đó, nhóm “Rất nhỏ” chiếm khoảng 14,69%, còn “Lớn” và “Rất lớn” chỉ lần lượt đạt 9,53% và 3,3%. Điều này phản ánh thị trường cho thuê tập trung chủ yếu vào các căn có diện tích vừa và nhỏ, phù hợp với nhu cầu thuê nhà phổ thông và khả năng tài chính trung bình của khách hàng.

8.2.6 . Biểu đồ đường: Xu hướng giá bán trung bình của nhà “for_sale” từ 2018 đến 2020

1. forsale_2018_2020 <- tieuluan %>%
2.   filter(status == "for_sale" & prev_year >= 2018 & prev_year <= 2020)
3. price_month_fs <- forsale_2018_2020 %>%
4.   group_by(prev_month_year) %>%                   
5.   summarise(price_tb = mean(price, na.rm = TRUE))  
6. ggplot(price_month_fs, aes(x = prev_month_year,     
7.                            y = price_tb,           
8.                            group = 1)) +          
9.   geom_line(color = "deeppink", size = 1.2) +      
10.   geom_point(color = "deeppink", size = 2) +       
11.   labs(title = "Xu hướng giá bán trung bình nhà đang rao bán (2018–2020)",  
12.     x = "Tháng-Năm",                                                    
13.     y = "Giá bán trung bình (USD)") +
14.   theme_minimal() +                                       
15.   theme(axis.text.x = element_text(angle = 60, hjust = 0.5))  

Giải thích kỹ thuật

Dòng 1:lấy các bản ghi có trạng thái là “for_sale” và năm từ 2018 đến 2020.

Dòng 2: Nhóm dữ liệu theo tháng và năm (prev_month_year) và tính giá bán trung bình (price_tb) cho mỗi tháng, bỏ qua giá trị NA.

Dòng 3: vẽ biểu đồ ggplot() sử dụng prev_month_year làm trục X (tháng-năm) và price_tb làm trục Y (giá bán trung bình), group = 1 đảm bảo tất cả các điểm được nối thành một đường duy nhất, không phân nhóm theo các giá trị khác.

Dòng 4:Vẽ đường cho giá bán trung bình có độ dày đường là 1.2.

Dòng 5: Thêm các điểm tròn vào biểu đồ đường kích thước điểm là 2.

Dòng 8: Căn chỉnh văn bản của trục X theo góc 60 độ và căn giữa các nhãn với hjust = 0.5.

  • Nhận xét: Biểu đồ cho thấy giá bán trung bình của bất động sản có biến động khá mạnh theo thời gian. Giá nhà for_sale (đang rao bán) dao động liên tục, có một số giai đoạn giảm sâu (như giữa năm 2021 và 2023) rồi tăng vọt vào cuối giai đoạn. Trong khi đó, giá sold (đã bán) có xu hướng tăng từ năm 2020 đến giữa 2021, sau đó giảm dần rồi ổn định hơn so với giá rao bán. Nhìn chung, giá rao bán thường cao hơn giá bán thực tế, phản ánh chênh lệch giữa kỳ vọng của người bán và mức giá giao dịch thành công trên thị trường.

8.2.7 . Biểu đồ bản đồ nhiệt (Heatmap): Mối quan hệ giữa diện tích nhà và mức giá nhà

1. freq_table <- tieuluan %>%
2.   group_by(dientichdat, mucgianha) %>%           
3.   summarise(count = n()) %>%                    
4.   ungroup()                                      
5. ggplot(freq_table, aes(x = dientichdat, y = mucgianha, fill = count)) + 
6.   geom_tile(color = "white") +                   
7.   scale_fill_gradient(low = "thistle",           
8.                       high = "seagreen") +       
9.   theme_minimal() +                              
10.   labs(x = "Diện tích đất",y = "Mức giá nhà",fill = "Số lượng")

Giải thích kỹ thuật

Dòng 1: freq_table <- tieuluan %>% group_by(dientichdat, mucgianha) %>% summarise(count = n()) %>% ungroup() Nhóm dữ liệu theo dientichdat (diện tích đất) và mucgianha (mức giá nhà), đếm số lượng bản ghi trong mỗi nhóm và lưu kết quả vào cột count, sau đó hủy nhóm (ungroup()).

Dòng 2:vẽ biểu đồ ggplot() trục X là diện tích đất, trục Y là mức giá nhà và fill = count

Dòng 3: Vẽ các ô với viền màu trắng.

Dòng 4:Thiết lập màu sắc cho các ô, với màu nhẹ cho các giá trị nhỏ và màu đậm cho các giá trị lớn.

  • Nhận xét : Biểu đồ heatmap cho thấy những căn nhà có diện tích “Nhỏ” và “Vừa” tập trung nhiều nhất ở các mức giá “Rẻ” và “Trung bình”, được thể hiện bằng các ô màu xanh đậm. Trong khi đó, các nhóm nhà có diện tích “Lớn” và “Rất lớn” xuất hiện ít hơn, đặc biệt ở mức giá “Rất mắc” hay “Rất rẻ”. Điều này chứng tỏ phần lớn giao dịch bất động sản tập trung vào phân khúc tầm trung, với diện tích vừa phải và giá cả hợp lý, phù hợp với nhu cầu phổ biến của người mua nhà để ở.

8.2.8 . Biểu đồ phân tán (Scatter Plot): Mối quan hệ giữa log(Diện tích đất m²) và log(Giá nhà)

1. ggplot(tieuluan, aes(x = log(acre_lot_m2 + 1),          
2.                      y = log(price + 1),                
3.                      color = mucgianha)) +              
4.   geom_point(alpha = 0.2) +                           
5.   scale_color_manual(values = c(                        
6.     "goldenrod", "slateblue", "brown3", "palegreen", "coral"
7.   )) +
8.    theme_minimal() +                                     
9.   labs(x = "log(Diện tích đất m²)",y = "log(Giá nhà)",color = "Mức giá")

Giải thích kỹ thuật

Dòng 1: vẽ biểu đồ ggplot() với acre_lot_m2 và price được chuyển đổi sang logarit (thêm 1 để tránh log(0)).

Dòng 2: Vẽ các điểm trên biểu đồ, với độ trong suốt (alpha = 0.2).

Dòng 3: Chỉ định màu sắc thủ công cho các điểm.

  • Nhận xét : Biểu đồ cho thấy mối quan hệ giữa log(Diện tích đất) và log(Giá nhà) có xu hướng tăng nhẹ, tức là diện tích đất lớn hơn thường đi kèm giá bán cao hơn, nhưng không tỷ lệ thuận tuyệt đối. Các nhóm mức giá “Trung bình” và “Rẻ” chiếm phần lớn, tập trung ở vùng diện tích trung bình đến nhỏ, trong khi nhóm “Mắc” và “Rất mắc” chủ yếu nằm ở vùng diện tích lớn hơn. Điều này cho thấy diện tích là yếu tố ảnh hưởng đến giá, song mức giá còn chịu tác động mạnh của vị trí, chất lượng và tiện ích bất động sản.

8.2.9 . Biểu đồ Histogram: Phân phối diện tích nhà theo từng mức diện tích

1. ggplot(tieuluan, aes(x = acre_lot_m2)) +                        
2.   geom_histogram(binwidth = 500, fill = 'plum', color = 'forestgreen') + 
3.   facet_wrap(~ dientichdat) +                                   
4.   labs(title = 'Phân phối diện tích đất theo từng mức diện tích đất',
5.     x = 'Diện tích đất (m²)',y = 'Số lượng') +
6.   theme_minimal()                                               

Giải thích kỹ thuật

Dòng 1: sử dụng biến acre_lot_m2 làm trục X

Dòng 2: vẽ biểu đồ histogram, chia diện tích đất thành các khoảng 500 m², tô màu cột và viền cột.

Dòng 3: chia biểu đồ thành nhiều ô nhỏ theo nhóm dientichdat

Dòng 4: thêm tiêu đề , nhãn trục X và trục Y .

Dòng 5: tạo biểu đồ gọn gàng, đơn giản

  • Nhận xét : Biểu đồ histogram cho thấy phần lớn các bất động sản tập trung ở nhóm diện tích “Rất nhỏ”, “Nhỏ” và “Vừa”, với mật độ dày đặc ở vùng dưới 2.000 m². Trong khi đó, nhóm “Lớn” và “Rất lớn” có số lượng ít và phân bố rải rác, thể hiện tính hiếm của các lô đất quy mô lớn. Nhìn chung, phân phối diện tích đất bị lệch phải (right-skewed), tức phần lớn nhà có diện tích nhỏ, phản ánh xu hướng đô thị hóa và nhu cầu cao ở phân khúc đất nhỏ – trung bình.

8.2.10 . Biểu đồ Histogram: Phân phối giá bất động sản theo từng mức giá nhà

1. ggplot(tieuluan, aes(x = price)) +                                   
2.   geom_histogram(binwidth = 100000, fill = 'mediumseagreen', color = 'magenta') +  
3.   facet_wrap(~ mucgianha) +                                          
4.   labs(title = 'Phân phối giá bất động sản theo mức giá nhà',           
5.     x = 'Giá bất động sản (USD)', y = 'Số lượng') +
6.   theme_minimal()                                                    

Giải thích kỹ thuật : vẽ biểu đồ tương tự Biểu đồ Histogram: Phân phối giá bất động sản theo từng mức giá nhà

  • Nhận xét : Biểu đồ cho thấy phân phối giá bất động sản trong từng nhóm mức giá khá tập trung và rõ rệt. Các nhóm “Rẻ” và “Trung bình” có số lượng lớn nhất, giá tập trung quanh 300.000–700.000 USD, trong khi “Mắc” và “Rất mắc” trải rộng ở mức giá cao hơn nhưng ít xuất hiện hơn. Nhóm “Rất rẻ” có biên độ giá nhỏ và tập trung sát ngưỡng thấp. Nhìn chung, thị trường bất động sản thiên về phân khúc giá tầm trung và bình dân, phản ánh nhu cầu ở thực tế cao hơn so với đầu tư cao cấp.

8.2.11 . Biểu đồ Histogram: Phân phối giá bất động sản theo từng năm (2020–2022)

1. tieuluan_2018_2024 <- tieuluan %>% filter(prev_year %in% 2018:2024)      
2. ggplot(tieuluan_2018_2024, aes(x = price)) +                        
3.   geom_histogram(binwidth = 100000, fill = "purple", color = "deepskyblue") +
4.   facet_wrap(~ prev_year) +                                         
5.   labs(title = "Histogram phân phối giá theo từng năm (2018–2024)",   
6.     x = "Giá bất động sản (USD)",y = "Số lượng") +
7.   theme_minimal(base_size = 13) +                                   
8.   theme(
9.     plot.title = element_text(hjust = 0.5, face = "bold"),
10.     axis.text.x = element_text(size = 10))     

Giải thích kỹ thuật :

Dòng 1: chỉ lấy các bản ghi có năm (prev_year) từ 2018 đến 2024.

Dòng 2: sử dụng price làm trục X để hiển thị phân phối giá.

Dòng 3: vẽ biểu đồ histogram với mỗi cột có chiều rộng 100.000 USD, tô màu cột và viền cột

Dòng 4: chia biểu đồ thành các phần nhỏ theo từng năm (prev_year)

Dòng 5: thiết lập tiêu đề cho biểu đồ, nhãn trục X và trục Y .

Dòng 6: làm biểu đồ trở nên sạch sẽ và dễ nhìn với kích thước chữ cơ bản.

Dòng 7: căn giữa tiêu đề (0.5x) của biểu đồ và làm chữ đậm

Dòng 8: cỡ chữ cột X là 10

  • Nhận xét : Biểu đồ histogram cho thấy phân phối giá bất động sản từ năm 2018–2024 có dạng lệch phải rõ rệt, nghĩa là đa số nhà tập trung ở mức giá thấp, trong khi một số ít bất động sản có giá rất cao kéo dài phần đuôi phải. Giai đoạn 2020–2022 xuất hiện sự tăng nhẹ ở nhóm giá trung bình, phản ánh thị trường khởi sắc sau thời kỳ dịch Covid-19. Tuy nhiên, nhìn chung giá vẫn tập trung chủ yếu trong khoảng dưới 500.000 USD, cho thấy phân khúc bình dân – trung cấp vẫn chiếm ưu thế trên thị trường.

8.2.12 . Biểu đồ mật độ (Density plot): Phân bố số phòng tắm theo diện tích đất

1. ggplot(tieuluan, aes(x = bath)) +                   
2.   geom_density(fill = "darkmagenta") +                    
3.   facet_wrap(~ dientichdat) +                         
4.   labs(title = "Density plot số phòng tắm theo nhóm diện tích đất", 
5.     x = "Số phòng tắm",  y = "Mật độ") +
6.   theme_minimal(base_size = 13) +             
7.   theme(plot.title = element_text(hjust = 0.5, face = "bold"))

Giải thích kỹ thuật

Dòng 1:Khởi tạo biểu đồ ggplot(), sử dụng biến bath làm trục X.

Dòng 2: Vẽ đồ thị mật độ (density plot) cho bath, geom_density() tạo ra một đồ thị mật độ cho biến bath.

Dòng 3: Tạo các phần (facets) cho biểu đồ dựa trên biến dientichdat.

Dòng 4: Thiết lập tiêu đề cho biểu đồ và đặt nhãn cho trục X và trục Y.

Dòng 5: giúp biểu đồ trông gọn gàng hơn, base_size = 13 chỉ định kích thước chữ cơ bản cho các phần tử trên biểu đồ.

Dòng 6: căn giữa tiêu đề (hjust = 0.5) và làm chữ đậm.

  • Nhận xét : Biểu đồ mật độ cho thấy phân bố số phòng tắm tương đối giống nhau giữa các nhóm diện tích đất. Trong mọi nhóm, các đỉnh mật độ tập trung mạnh ở 2 và 3 phòng tắm, phản ánh đây là cấu hình phổ biến nhất của nhà ở. Những giá trị có từ 4 phòng tắm trở lên xuất hiện rất ít, chủ yếu ở các nhóm diện tích “Lớn” và “Rất lớn”. Nhìn chung, quy mô phòng tắm tăng nhẹ theo diện tích đất, nhưng phần lớn bất động sản vẫn thuộc phân khúc tầm trung – nhà từ 2 đến 3 phòng tắm.

9 . Kết luận

  • Phân tích cho thấy thị trường bất động sản Hoa Kỳ tập trung chủ yếu ở phân khúc giá “Rẻ – Trung bình” và diện tích “Nhỏ – Vừa”. Các giao dịch đã bán chiếm ưu thế hơn đang rao bán, phản ánh thanh khoản tốt và nhu cầu ở thực cao. Phân phối giá và diện tích đều lệch phải, cho thấy sự chênh lệch lớn giữa các nhóm nhà, đặc biệt ở khu vực giá cao.

  • Giá nhà trung bình duy trì quanh mức dưới 500.000 USD, trong đó nhóm giá “Rẻ” và “Trung bình” chiếm đa số. Những căn có 2–3 phòng tắm, diện tích vừa phải được giao dịch nhiều nhất, phản ánh xu hướng đô thị hóa và ưu tiên nhà ở phù hợp khả năng chi trả. Mối quan hệ giữa diện tích và giá có xu hướng tăng cùng nhau nhưng không mạnh, cho thấy các yếu tố như vị trí và chất lượng vẫn đóng vai trò quan trọng hơn.

  • Nhìn chung, thị trường nhà ở Hoa Kỳ có tính ổn định và đa tầng, với tâm điểm là phân khúc phổ thông. Kết quả này là cơ sở để liên hệ sang phân tích BIDV, khi xu hướng giá và cầu nhà ở có thể tác động đến tín dụng bán lẻ, biên lợi nhuận (NIM) và hiệu quả sinh lời (NPM) của ngân hàng giai đoạn 2010–2024.

10 . CHƯƠNG II: PHÂN TÍCH CÁC YẾU TỐ TÀI CHÍNH CỦA NGÂN HÀNG BIDV GIAI ĐOẠN 2010-2024

11 . Giới thiệu về bộ dữ liệu

11.1 . Giới thiệu dữ liệu

Bộ dữ liệu Báo cáo tài chính BIDV được nhóm tác giả thu thập từ trang web “BIDV.com.vn” bao gồm các biến tài chính quan trọng của Ngân hàng TMCP Đầu tư và Phát triển Việt Nam (BIDV) được thu thập trong giai đoạn \(\text{15}\) năm, từ năm \(\text{2010}\) đến \(\text{2024}\). Các biến được chia thành nhiều nhóm: Quy mô (như Tổng tài sản, Dư nợ cho vay), Hiệu suất (như ROA, ROE, Lợi nhuận trước/sau thuế), Cơ cấu vốn (Vốn chủ sở hữu, Tổng nợ), Dòng tiền và Các khoản mục thu chi cốt lõi (như Doanh thu lãi thuần, Chi phí hoạt động, Chi phí tín dụng). Đây là cơ sở dữ liệu toàn diện giúp phân tích xu hướng tăng trưởng, đo lường khả năng sinh lời, đánh giá hiệu quả quản lý rủi ro và nhận diện các chiến lược tài chính của BIDV trong một chu kỳ kinh tế dài.

11.2 . Đọc dữ liệu

Ta giả tiến hành đọc từng sheet của file excel Báo cáo tài chính của BIDV giai đoạn 2010-2024 và gán cho từng sheet “Cân đối kế toán”, “Hoạt động kinh doanh”, “Lưu chuyển tiền tệ” tương ứng với các object “CDKT”, “HDKD” và “LCTT”.

1. # Đọc từng sheet vào các dataframe riêng biệt và gán bào từng object mới 
2. CDKT <- read_excel("D:/TMT_R/BCTC_BID_Final.xlsx", sheet = "CDKT")
3. HDKD <- read_excel("D:/TMT_R/BCTC_BID_Final.xlsx", sheet = "HDKD")
4. LCTT <- read_excel("D:/TMT_R/BCTC_BID_Final.xlsx", sheet = "LCTT")
5. head(CDKT)
1. head(HDKD)
1. head(LCTT)

Giải thích kỹ thuật

Dòng 1-3: Đọc từng sheet vào các dataframe riêng biệt

Dòng 4-6: xem 6 dòng đầu của từng dataframe

11.3 . Tạo dataframne mới phù hợp cho việc phân tích

Tiếp theo tác giả lọc 14 biến phù hợp với nhu cầu phân tích và gán vào một object mới tên là “BIDV”

1. # Lọc biến tại từng bảng
2. CDKT_sel <- CDKT %>%
3.   select(nam  = Năm,tong_tai_san       = `TỔNG TÀI SẢN`,
4.     tien_mat_vangbac_daquy           = `Tiền mặt, vàng bạc, đá quý`,
5.     tong_no_phai_tra   = `Tổng nợ phải trả`,
6.     von_chu_so_huu     = `Vốn chủ sở hữu`)
7. HDKD_sel <- HDKD %>%
8.   select(nam                       = Năm,
9.     thu_nhap_lai_va_cac_khoan_tuong_tu        = `Thu nhập lãi và các khoản thu nhập tương tự`,
10.     chi_phi_lai_va_cac_chi_phi_tuong_tu       = `Chi phí lãi và các chi phí tương tự`,
11.     thu_nhap_lai_thuan                        = `Thu nhập lãi thuần`,
12.     loi_nhuan_sau_thue                        = `Lợi nhuận sau thuế`,
13.     lai_lo_thuan_hd_ngoai_hoi_va_vang         = `Lãi/(lỗ) thuần từ hoạy động kinh doanh ngoại hối và vàng`,
14.     tong_thu_nhap_hoat_dong                   = `Tổng thu nhập hoạt động`)
15. LCTT_sel <- LCTT %>%
16.   select(nam                             = Năm,
17.     thanh_toan_nv_ncc               = `Thanh toán cho nhân viên và nhà cung cấp`,
18.     chi_thue_tndn                   = `Tiền chi nộp thuế thu nhập doanh nghiệp`,
19.     tien_thu_thanh_ly_ts_co_dinh    = `Tiền thu được từ thanh lý tài sản cố định`)
20. BIDV <- CDKT_sel %>%
21.   left_join(HDKD_sel, by = "nam") %>%
22.   left_join(LCTT_sel, by = "nam")
23. colnames(BIDV) <- gsub("\\s+", "_", tolower(
24.   stringi::stri_trans_general(colnames(BIDV), "Latin-ASCII")))
25. # Xem 6 dòng đầu tiên và cuối cùng của bảng kết quả
26. head(BIDV)
1. tail(BIDV)

Giải thích kỹ thuật

Dòng 1: lọc và chọn các cộ từ bảng dữ liệu CDKT

Dòng 2-4: đổi tên các biến ứng với các biến trong CDKT

Dòng 5-18: làm tương tự dòng 1-4 cho 2 bảng HDKD và LCTT

Dòng 19: Thực hiện phép left_join giữa bảng CDKT_sel và bảng HDKD_sel dựa trên cột nam. Điều này kết hợp thông tin từ hai bảng dựa trên năm (nam), giữ tất cả các dòng từ CDKT_sel và bổ sung các giá trị tương ứng từ HDKD_sel. Nếu không có kết quả tương ứng trong HDKD_sel, các giá trị từ bảng đó sẽ là NA.

Dòng 20:thực hiện phép left_join với bảng LCTT_sel, cũng dựa trên cột nam. Điều này kết hợp thông tin từ bảng LCTT_sel với bảng kết quả của phép left_join trước đó (giữa CDKT_sel và HDKD_sel), giữ lại tất cả dữ liệu từ bảng hiện tại và bổ sung dữ liệu từ LCTT_sel theo năm (nam).

Dòng 21 :gsub(“\s+”, “_“, …) Thay thế tất cả khoảng trắng trong tên cột bằng dấu gạch dưới, tolower: chuyển thành chữ thường.

Dòng 22: Chuyển đổi tên các cột sang dạng ASCII chuẩn, loại bỏ dấu tiếng Việt và các ký tự đặc biệt.

11.4 . Xem thông tin chung của BIDV

Ta sử dụng sử dụng một số lệnh bên dưới để xem thông tin chung của BIDV.

1. dim(BIDV)
## [1] 15 14

Giải thích kỹ thuật : Kiểm tra kích thước bộ dữ liệu BIDV

-Nhận xét : Sử dụng lệnh dim() kết quả trả về cho thấy bộ dữ liệu BIDV có 15 hàng (quan sát) và 14 cột (biến), cho thấy số quan sát còn ít nhưng số lượng biến khá đầy đủ để phân tích nhiều khía cạnh tài chính và hoạt động của BIDV.

1. names(BIDV)
##  [1] "nam"                                 "tong_tai_san"                       
##  [3] "tien_mat_vangbac_daquy"              "tong_no_phai_tra"                   
##  [5] "von_chu_so_huu"                      "thu_nhap_lai_va_cac_khoan_tuong_tu" 
##  [7] "chi_phi_lai_va_cac_chi_phi_tuong_tu" "thu_nhap_lai_thuan"                 
##  [9] "loi_nhuan_sau_thue"                  "lai_lo_thuan_hd_ngoai_hoi_va_vang"  
## [11] "tong_thu_nhap_hoat_dong"             "thanh_toan_nv_ncc"                  
## [13] "chi_thue_tndn"                       "tien_thu_thanh_ly_ts_co_dinh"

Giải thích kỹ thuật :Xem tên các biến trong BIDV

  • Nhận xét: Sử dụng lệnh names() trả về danh sách các biến của bộ dữ liệu BIDV gồm: “nam”, “tong_tai_san”, “tien_mat_vangbac_daquy”, “tong_no_phai_tra”, “von_chu_so_huu”, “thu_nhap_lai_va_cac_khoan_tuong_tu”, “chi_phi_lai_va_cac_chi_phi_tuong_tu”,“thu_nhap_lai_thuan”,“loi_nhuan_sau_thue”,“lai_lo_thuan_hd_ngoai_hoi_va_vang”, “tong_thu_nhap_hoat_dong”, “thanh_toan_nv_ncc”, “chi_thue_tndn”, “tien_thu_thanh_ly_ts_co_dinh”, phản ánh đầy đủ các thông tin tài chính và hoạt động của BIDV, bao gồm quy mô tài sản, hiệu quả sinh lời và dòng tiền.

Dữ liệu bao gồm các biến sau, được tổng hợp chi tiết trong bảng dưới đây nhằm phục vụ cho quá trình phân tích.

Bảng 1. Danh sách các biến trong dữ liệu tài chính BIDV
STT Tên biến Mô tả
1 nam Năm báo cáo tài chính
2 tong_tai_san Tổng tài sản hợp nhất tại thời điểm báo cáo
3 tien_mat_vangbac_daquy Tiền mặt, vàng bạc, đá quý của doanh nghiệp
4 tong_no_phai_tra Tổng nợ phải trả vào cuối kỳ báo cáo
5 von_chu_so_huu Vốn chủ sở hữu của BIDV tại thời điểm báo cáo
6 thu_nhap_lai_va_cac_khoan_tuong_tu Thu nhập lãi cùng các khoản tương tự do ngân hàng tạo ra
7 chi_phi_lai_va_cac_chi_phi_tuong_tu Chi phí lãi cùng các chi phí tương tự phải trả trong kỳ
8 thu_nhap_lai_thuan Thu nhập lãi thuần từ hoạt động tài chính
9 loi_nhuan_sau_thue Lợi nhuận ròng sau thuế thu nhập doanh nghiệp
10 lai_lo_thuan_hd_ngoai_hoi_va_vang Lãi hoặc lỗ thuần từ hoạt động kinh doanh ngoại hối và vàng
11 tong_thu_nhap_hoat_dong Tổng thu nhập hoạt động phát sinh trong kỳ
12 thanh_toan_nv_ncc Chi phí thanh toán cho nhân viên và nhà cung cấp
13 chi_thue_tndn Tiền chi trả thuế thu nhập doanh nghiệp
14 tien_thu_thanh_ly_ts_co_dinh Tiền thu được từ việc thanh lý tài sản cố định

Giải thích kỹ thuật

Dòng 1: Dùng để tạo một bảng dữ liệu mới tên des_bidv bằng hàm data.frame().

Dòng 2: Dùng để tạo cột STT, chứa các số thứ tự từ 1 đến 14.

Dòng 3-4: Dùng để tạo cột Ten_bien, chứa danh sách tên các biến trong bộ dữ liệu tài chính BIDV.

Dòng 5-11: Dùng để tạo cột Mo_ta, mô tả chi tiết cho các biến trong bộ dữ liệu tài chính.

Dòng 12: Dùng để gọi bảng dữ liệu des_bidv và truyền qua các hàm tiếp theo bằng toán tử %>%.

Dòng 13: Dùng hàm kable() để chuyển bảng des_bidv thành bảng HTML, với tham số align = “c” để căn giữa tất cả các cột.

Dòng 14: Dùng col.names để đặt tiêu đề các cột là “STT”, “Tên biến”, và “Mô tả” (các tên này được in đậm).

Dòng 15: Dùng caption để thêm tiêu đề cho bảng, căn giữa và in đậm dòng chữ “Bảng 1. Danh sách các biến trong dữ liệu tài chính BIDV”.

Dòng 16: Dùng hàm kable_styling() để chỉnh giao diện bảng HTML.

Dòng 17: Các tùy chọn striped, hover, condensed, responsive giúp bảng có hiệu ứng xen kẽ màu sắc, đổi màu khi rê chuột, gọn gàng hơn và tự động điều chỉnh kích thước; full_width = FALSE giúp bảng không chiếm toàn bộ chiều rộng, position = “center” căn giữa bảng, và font_size = 14 thay đổi cỡ chữ.

Dòng 18: Dùng row_spec(0, bold = TRUE, background = “#6495ED”) để định dạng hàng tiêu đề, làm chữ đậm và có nền màu xanh dương đậm (#6495ED).

Dòng 19: Dùng column_spec(1:3, border_right = TRUE) để thêm viền phải cho cả ba cột trong bảng.

1. str(BIDV)
## tibble [15 × 14] (S3: tbl_df/tbl/data.frame)
##  $ nam                                : chr [1:15] "2010" "2011" "2012" "2013" ...
##  $ tong_tai_san                       : num [1:15] 3.66e+14 4.06e+14 4.85e+14 5.48e+14 6.50e+14 ...
##  $ tien_mat_vangbac_daquy             : num [1:15] 3.25e+12 3.63e+12 3.30e+12 3.86e+12 5.39e+12 ...
##  $ tong_no_phai_tra                   : num [1:15] 3.42e+14 3.81e+14 4.58e+14 5.16e+14 6.17e+14 ...
##  $ von_chu_so_huu                     : num [1:15] 2.42e+13 2.44e+13 2.65e+13 3.20e+13 3.36e+13 ...
##  $ thu_nhap_lai_va_cac_khoan_tuong_tu : num [1:15] 2.98e+13 4.46e+13 3.05e+13 4.38e+13 4.40e+13 ...
##  $ chi_phi_lai_va_cac_chi_phi_tuong_tu: num [1:15] -2.06e+13 -3.19e+13 -2.13e+13 -2.90e+13 -2.71e+13 ...
##  $ thu_nhap_lai_thuan                 : num [1:15] 9.19e+12 1.26e+13 9.21e+12 1.48e+13 1.68e+13 ...
##  $ loi_nhuan_sau_thue                 : num [1:15] 3.76e+12 3.20e+12 2.57e+12 4.05e+12 4.99e+12 ...
##  $ lai_lo_thuan_hd_ngoai_hoi_va_vang  : num [1:15] 2.89e+11 3.14e+11 2.47e+11 1.62e+11 2.65e+11 ...
##  $ tong_thu_nhap_hoat_dong            : num [1:15] 1.15e+13 1.54e+13 1.15e+13 1.92e+13 2.19e+13 ...
##  $ thanh_toan_nv_ncc                  : num [1:15] -5.01e+12 -6.33e+12 -4.53e+12 -6.58e+12 -7.96e+12 ...
##  $ chi_thue_tndn                      : num [1:15] -7.14e+11 -1.20e+12 -9.69e+11 -1.09e+12 -1.51e+12 ...
##  $ tien_thu_thanh_ly_ts_co_dinh       : num [1:15] 5.99e+09 2.91e+09 3.32e+09 4.08e+09 1.67e+09 ...

Giải thích kỹ thuật : Xem cấu trúc tổng quát của dữ liệu BID

  • Nhận xét: Sử dụng lệnh str() cho thấy cấu trúc tổng quát của bộ dữ liệu BIDV gồm 15 quan sát và 14 biến. Trong đó, biến “nam” có kiểu ký tự (chr) đại diện cho năm, các biến còn lại đều là kiểu số (num) phản ánh các chỉ số tài chính và dòng tiền của BIDV, giúp kiểm tra nhanh kiểu dữ liệu và phạm vi giá trị của từng biến trước khi phân tích.
1. sapply(BIDV, class)
##                                 nam                        tong_tai_san 
##                         "character"                           "numeric" 
##              tien_mat_vangbac_daquy                    tong_no_phai_tra 
##                           "numeric"                           "numeric" 
##                      von_chu_so_huu  thu_nhap_lai_va_cac_khoan_tuong_tu 
##                           "numeric"                           "numeric" 
## chi_phi_lai_va_cac_chi_phi_tuong_tu                  thu_nhap_lai_thuan 
##                           "numeric"                           "numeric" 
##                  loi_nhuan_sau_thue   lai_lo_thuan_hd_ngoai_hoi_va_vang 
##                           "numeric"                           "numeric" 
##             tong_thu_nhap_hoat_dong                   thanh_toan_nv_ncc 
##                           "numeric"                           "numeric" 
##                       chi_thue_tndn        tien_thu_thanh_ly_ts_co_dinh 
##                           "numeric"                           "numeric"

Giải thích kỹ thuật: Xem kiểu dữ liệu theo từng cột của BIDV

  • Nhận xét: Sử dụng lệnh sapply() với class trả về kiểu dữ liệu của từng cột trong bộ dữ liệu BIDV. Kết quả cho thấy biến “nam” có kiểu ký tự (character) trong khi 13 biến còn lại đều có kiểu số (numeric), phản ánh rằng các chỉ số tài chính và dòng tiền được lưu dưới dạng số để thuận tiện cho phân tích định lượng.
1. skim(BIDV)
Data summary
Name BIDV
Number of rows 15
Number of columns 14
_______________________
Column type frequency:
character 1
numeric 13
________________________
Group variables None

Variable type: character

skim_variable n_missing complete_rate min max empty n_unique whitespace
nam 0 1 4 4 0 15 0

Variable type: numeric

skim_variable n_missing complete_rate mean sd p0 p25 p50 p75 p100 hist
tong_tai_san 0 1 1.251883e+15 7.412196e+14 3.662678e+14 5.993632e+14 1.202284e+15 1.639191e+15 2.760792e+15 ▇▆▅▂▃
tien_mat_vangbac_daquy 0 1 8.430533e+12 3.977379e+12 3.253384e+12 4.628074e+12 8.203016e+12 1.166170e+13 1.411672e+13 ▇▃▂▅▆
tong_no_phai_tra 0 1 1.188759e+15 7.037727e+14 3.418986e+14 5.664138e+14 1.153450e+15 1.556203e+15 2.615881e+15 ▇▅▆▂▃
von_chu_so_huu 0 1 6.306981e+13 3.801020e+13 2.421973e+13 3.282309e+13 4.883401e+13 8.298782e+13 1.449111e+14 ▇▂▃▁▂
thu_nhap_lai_va_cac_khoan_tuong_tu 0 1 7.914638e+13 3.951223e+13 2.978186e+13 4.427068e+13 7.862851e+13 1.008776e+14 1.527613e+14 ▇▂▅▁▂
chi_phi_lai_va_cac_chi_phi_tuong_tu 0 1 -4.849219e+13 2.280513e+13 -9.662575e+13 -6.483006e+13 -4.767318e+13 -2.933516e+13 -2.059048e+13 ▁▁▇▂▇
thu_nhap_lai_thuan 0 1 3.065420e+13 1.739830e+13 9.191386e+12 1.584445e+13 3.095533e+13 4.140056e+13 5.800758e+13 ▇▃▆▂▅
loi_nhuan_sau_thue 0 1 9.207143e+12 7.080721e+12 2.571943e+12 4.518338e+12 6.945586e+12 9.694514e+12 2.560404e+13 ▇▃▁▁▂
lai_lo_thuan_hd_ngoai_hoi_va_vang 0 1 1.476188e+12 1.671746e+12 1.622780e+11 2.913230e+11 6.681280e+11 1.814239e+12 5.361499e+12 ▇▂▁▁▂
tong_thu_nhap_hoat_dong 0 1 4.013631e+13 2.338242e+13 1.148508e+13 2.053524e+13 3.901672e+13 5.626547e+13 8.106087e+13 ▇▂▃▁▃
thanh_toan_nv_ncc 0 1 -1.363652e+13 6.859184e+12 -2.580315e+13 -1.836830e+13 -1.379649e+13 -7.267992e+12 -4.525990e+12 ▃▅▅▃▇
chi_thue_tndn 0 1 -2.203221e+12 1.593351e+12 -6.884931e+12 -2.362017e+12 -1.732575e+12 -1.355578e+12 -7.138120e+11 ▁▁▁▂▇
tien_thu_thanh_ly_ts_co_dinh 0 1 9.257067e+09 5.983982e+09 1.671000e+09 4.689000e+09 8.545000e+09 1.144800e+10 2.238700e+10 ▇▆▆▁▃
Nhận xét thống kê các biến BIDV
Biến Nhận_xét
nam Biến ký tự, không thiếu giá trị, gồm 15 quan sát thể hiện các năm trong giai đoạn 2010–2024.
tong_tai_san Biến số, không thiếu giá trị, trung bình ~1.25e+15, dao động từ 3.66e+14 đến 2.76e+15; tổng tài sản BIDV tăng liên tục qua các năm, thể hiện quy mô mở rộng mạnh mẽ.
tien_mat_vangbac_daquy Biến số, không thiếu giá trị, trung bình ~8.43e+12, dao động từ 3.25e+12 đến 1.41e+13; lượng tiền mặt, vàng bạc, đá quý tăng dần nhưng biến động nhẹ qua các năm.
tong_no_phai_tra Biến số, không thiếu giá trị, trung bình ~1.19e+15, dao động từ 3.42e+14 đến 2.62e+15; tổng nợ phải trả tăng theo quy mô hoạt động, chiếm tỷ trọng lớn trong tổng tài sản.
von_chu_so_huu Biến số, không thiếu giá trị, trung bình ~6.31e+13, dao động từ 2.42e+13 đến 1.45e+14; vốn chủ sở hữu tăng ổn định, phản ánh khả năng tích lũy vốn tốt.
thu_nhap_lai_va_cac_khoan_tuong_tu Biến số, không thiếu giá trị, trung bình ~7.91e+13, dao động từ 2.98e+13 đến 1.53e+14; thu nhập lãi và các khoản tương tự tăng theo thời gian, là nguồn thu chính của ngân hàng.
chi_phi_lai_va_cac_chi_phi_tuong_tu Biến số, không thiếu giá trị, trung bình ~-4.85e+13, dao động từ -9.66e+13 đến -2.06e+13; chi phí lãi mang giá trị âm, phản ánh chi phí vốn của ngân hàng, biến động mạnh giữa các năm.
thu_nhap_lai_thuan Biến số, không thiếu giá trị, trung bình ~3.07e+13, dao động từ 9.19e+12 đến 5.80e+13; thu nhập lãi thuần tăng qua các năm, cho thấy hiệu quả kinh doanh cốt lõi được duy trì.
loi_nhuan_sau_thue Biến số, không thiếu giá trị, trung bình ~9.21e+12, dao động từ 2.57e+12 đến 2.56e+13; lợi nhuận sau thuế tăng trưởng dần, nhưng độ lệch chuẩn cao phản ánh biến động lợi nhuận lớn.
lai_lo_thuan_hd_ngoai_hoi_va_vang Biến số, không thiếu giá trị, trung bình ~1.48e+12, dao động từ 1.62e+11 đến 5.36e+12; lãi/lỗ thuần từ hoạt động ngoại hối và vàng có biến động mạnh do ảnh hưởng tỷ giá và giá vàng.
tong_thu_nhap_hoat_dong Biến số, không thiếu giá trị, trung bình ~4.01e+13, dao động từ 1.15e+13 đến 8.11e+13; tổng thu nhập hoạt động tăng đáng kể, phản ánh tăng trưởng ổn định của BIDV.
thanh_toan_nv_ncc Biến số, không thiếu giá trị, trung bình ~-1.36e+13, dao động từ -2.58e+13 đến -4.53e+12; dòng tiền thanh toán cho nhân viên và nhà cung cấp âm, thể hiện chi ra trong hoạt động thường xuyên.
chi_thue_tndn Biến số, không thiếu giá trị, trung bình ~-2.20e+12, dao động từ -6.88e+12 đến -7.14e+11; chi thuế thu nhập doanh nghiệp phản ánh nghĩa vụ thuế tăng theo lợi nhuận.
tien_thu_thanh_ly_ts_co_dinh Biến số, không thiếu giá trị, trung bình ~9.26e+09, dao động từ 1.67e+09 đến 2.24e+10; tiền thu từ thanh lý tài sản cố định nhỏ, ít ảnh hưởng đến tổng lưu chuyển tiền.

Giải thích kỹ thuật:

Dòng 1-30: Tạo hai vector var và nhan_xet chứa tên các biến và các nhận xét về các biến đó, ứng với 14 biến tài chính trong dữ liệu BIDV.

Dòng 31 : Dùng data.frame() để kết hợp hai vector var và nhan_xet thành một bảng dữ liệu có hai cột: Biến và Nhận_xét

Dòng 32: Sử dụng kable() để chuyển bảng dữ liệu thành một bảng HTML với tiêu đề là “Nhận xét thống kê các biến BIDV”.

Dòng 33: sử dụng kable_styling() để làm đẹp bảng HTML với các tùy chọn: không chiếm toàn bộ chiều rộng (full_width = F), căn giữa bảng trong trang (position = “center”), và áp dụng hiệu ứng Bootstrap như gạch sọc (striped), đổi màu khi rê chuột (hover), và làm bảng gọn hơn (condensed).

12 . Xử lý dữ liệu thô

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

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

Giải thích kỹ thuật: Kiểm tra xem dữ liệu BIDV có bất kỳ giá trị thiếu (NA) nào hay không

  • Nhận xét : Sử dụng lệnh any(is.na()) kết quả trả về là FALSE, cho thấy bộ dữ liệu BIDV không có giá trị NA nào, tức tất cả 15 quan sát và 14 biến đều đầy đủ, không thiếu dữ liệu.
1. sum(is.na(BIDV))
## [1] 0

Giải thích kỹ thuật : Đếm tổng số giá trị thiếu (NA) trong toàn bộ bộ dữ liệu BIDV

  • Nhận xét: Sử dụng lệnh sum(is.na()) kết quả trả về là 0, cho thấy toàn bộ dữ liệu BIDV không có giá trị thiếu. Điều này xác nhận dữ liệu đầy đủ, không cần xử lý NA trước khi phân tích.
1. colSums(is.na(BIDV))
##                                 nam                        tong_tai_san 
##                                   0                                   0 
##              tien_mat_vangbac_daquy                    tong_no_phai_tra 
##                                   0                                   0 
##                      von_chu_so_huu  thu_nhap_lai_va_cac_khoan_tuong_tu 
##                                   0                                   0 
## chi_phi_lai_va_cac_chi_phi_tuong_tu                  thu_nhap_lai_thuan 
##                                   0                                   0 
##                  loi_nhuan_sau_thue   lai_lo_thuan_hd_ngoai_hoi_va_vang 
##                                   0                                   0 
##             tong_thu_nhap_hoat_dong                   thanh_toan_nv_ncc 
##                                   0                                   0 
##                       chi_thue_tndn        tien_thu_thanh_ly_ts_co_dinh 
##                                   0                                   0

Giải thích kỹ thuật : Đếm số lượng giá trị thiếu (NA) trong từng cột của dữ liệu BIDV

  • Nhận xét : Sử dụng lệnh colSums(is.na()) kết quả trả về 0 cho tất cả các cột, cho thấy không có cột nào chứa giá trị NA. Điều này xác nhận dữ liệu BIDV hoàn chỉnh, tất cả 14 biến đều đầy đủ 15 quan sát, thuận tiện cho việc phân tích thống kê tiếp theo.
1. names(BIDV)[colSums(is.na(BIDV)) > 0]
## character(0)

Giải thích kỹ thuật: Liệt kê tên các cột trong BIDV có chứa giá trị thiếu (NA)

  • Nhận xét : Sử dụng lệnh names()[colSums(is.na()) > 0] kết quả trả về là character(0), nghĩa là không có cột nào chứa giá trị NA. Điều này xác nhận dữ liệu BIDV hoàn toàn đầy đủ, không thiếu quan sát hay biến nào.

12.2 . Xác định và loại bỏ dữ liệu trùng lặp

1. duplicated(BIDV)
##  [1] FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE
## [13] FALSE FALSE FALSE

Giải thích kỹ thuật : Kiểm tra các dòng trùng lặp trong dữ liệu BIDV

  • Nhận xét : Sử dụng lệnh duplicated() kết quả trả về toàn FALSE, cho thấy không có dòng nào bị trùng lặp trong bộ dữ liệu BIDV. Điều này đảm bảo rằng tất cả 15 quan sát đều duy nhất, không có bản ghi bị lặp lại.
1. sum(duplicated(BIDV))
## [1] 0

Giải thích kỹ thuật:Đếm tổng số dòng trùng lặp trong dữ liệu BIDV

  • Nhận xét: Sử dụng lệnh sum(duplicated()) kết quả trả về là 0, nghĩa là không có dòng nào bị trùng lặp. Điều này xác nhận dữ liệu BIDV toàn bộ các quan sát đều duy nhất, không cần loại bỏ bản ghi trùng lặp.

12.3 . Phát hiện & sửa chữa giá trị bất thường

1. BIDV[BIDV$tong_no_phai_tra < 0, ]

Giải thích kỹ thuật: Kiểm tra các giá trị âm bất hợp lý trong cột ‘tong_no_phai_tra’ của dữ liệu BIDV

  • Nhận xét: Sử dụng lệnh BIDV[BIDV$tong_no_phai_tra < 0, ] kết quả trả về 0 dòng, nghĩa là không có giá trị âm nào trong cột tong_no_phai_tra. Điều này xác nhận tổng nợ phải trả BIDV đều hợp lý và không có dữ liệu bất thường.
1. BIDV[BIDV$thu_nhap_lai_va_cac_khoan_tuong_tu < 0, ]

Giải thích kỹ thuật : Kiểm tra các giá trị âm trong cột ‘thu_nhap_lai_va_cac_khoan_tuong_tu’ của dữ liệu BIDV

  • Nhận xét: Sử dụng lệnh BIDV[BIDV$thu_nhap_lai_va_cac_khoan_tuong_tu < 0, ] kết quả trả về 0 dòng, nghĩa là không có giá trị âm nào trong biến thu_nhap_lai_va_cac_khoan_tuong_tu. Điều này chứng tỏ hu nhập lãi cùng các khoản tương tự do ngân hàng tạo ra của BIDV trong dữ liệu đều hợp lý và không bất thường.
1. BIDV[BIDV$thu_nhap_lai_thuan < 0, c("nam", "thu_nhap_lai_thuan")]

Giải thích kỹ thuật: Kiểm tra các giá trị âm trong cột ‘thu_nhap_lai_thuan’ của dữ liệu BIDV

  • Nhận xét : Sử dụng lệnh BIDV[BIDV$thu_nhap_lai_thuan < 0, c(“nam”, “thu_nhap_lai_thuan”)] kết quả trả về 0 dòng, nghĩa là không có giá trị âm nào trong biến thu_nhap_lai_thuan. Điều này xác nhận thu nhập lãi thuần của BIDV trong tất cả các năm đều hợp lý và dương, không có giá trị bất thường.
1. BIDV[BIDV$tong_thu_nhap_hoat_dong < 0, c("nam", "tong_thu_nhap_hoat_dong")]

Giải thích kỹ thuật : Kiểm tra các giá trị âm trong cột ‘tong_thu_nhap_hoat_dong’ của dữ liệu BIDV

  • Nhận xét : Sử dụng lệnh BIDV[BIDV$tong_thu_nhap_hoat_dong < 0, c(“nam”, “tong_thu_nhap_hoat_dong”)] kết quả trả về 0 dòng, nghĩa là không có giá trị âm nào trong biến tong_thu_nhap_hoat_dong. Điều này chứng tỏ tổng thu nhập hoạt động của BIDV đều hợp lý, không bất thường.

12.4 . Chuyển đổi kiểu dữ liệu

1. BIDV$nam <- as.integer(BIDV$nam)   
2. str(BIDV$nam)                        
##  int [1:15] 2010 2011 2012 2013 2014 2015 2016 2017 2018 2019 ...

Giải thích kỹ thuật:

Dòng 1: chuyển nam thành dạng số

Dòng 2: xem cấu trúc biến nam

  • Nhận xét : Sử dụng lệnh as.integer(BIDV$nam) chuyển biến nam từ kiểu ký tự sang kiểu số nguyên. Kết quả trả về là int [1:15] 2010 2011 2012 …2024, nghĩa là 15 quan sát của năm đã được chuyển thành số, thuận tiện cho các phép tính, vẽ biểu đồ hoặc phân tích theo thời gian.
1. sapply(BIDV, class)
##                                 nam                        tong_tai_san 
##                           "integer"                           "numeric" 
##              tien_mat_vangbac_daquy                    tong_no_phai_tra 
##                           "numeric"                           "numeric" 
##                      von_chu_so_huu  thu_nhap_lai_va_cac_khoan_tuong_tu 
##                           "numeric"                           "numeric" 
## chi_phi_lai_va_cac_chi_phi_tuong_tu                  thu_nhap_lai_thuan 
##                           "numeric"                           "numeric" 
##                  loi_nhuan_sau_thue   lai_lo_thuan_hd_ngoai_hoi_va_vang 
##                           "numeric"                           "numeric" 
##             tong_thu_nhap_hoat_dong                   thanh_toan_nv_ncc 
##                           "numeric"                           "numeric" 
##                       chi_thue_tndn        tien_thu_thanh_ly_ts_co_dinh 
##                           "numeric"                           "numeric"

Giải thích kỹ thuật: Kiểm tra kiểu dữ liệu của tất cả các cột trong dữ liệu BIDV, sapply() áp dụng hàm class() cho từng cột, trả về kiểu dữ liệu của từng biến

Nhận xét chi tiết: Sử dụng lệnh sapply(BIDV, class) cho thấy:

  • Biến nam hiện ở dạng integer, rất phù hợp để thực hiện các phân tích chuỗi thời gian hoặc vẽ biểu đồ theo năm.

  • Các biến còn lại gồm: tong_tai_san, tien_mat_vangbac_daquy, tong_no_phai_tra, von_chu_so_huu,thu_nhap_lai_va_cac_khoan_tuong_tu, chi_phi_lai_va_cac_chi_phi_tuong_tu,thu_nhap_lai_thuan, loi_nhuan_sau_thue, lai_lo_thuan_hd_ngoai_hoi_va_vang,tong_thu_nhap_hoat_dong, thanh_toan_nv_ncc, chi_thue_tndn, và tien_thu_thanh_ly_ts_co_dinh đều có kiểu numeric, đảm bảo có thể sử dụng cho các phép toán tài chính, ước lượng mô hình, và vẽ biểu đồ.

13 . Thống kê cơ bản

13.1 . Truy cập dữ liệu

1. head(BIDV$von_chu_so_huu, 5)
## [1] 2.421973e+13 2.439045e+13 2.649445e+13 3.203998e+13 3.360620e+13
1. tail(BIDV$tong_no_phai_tra, 8)
## [1] 1.153450e+15 1.258377e+15 1.412304e+15 1.437039e+15 1.675367e+15
## [6] 2.016558e+15 2.178002e+15 2.615881e+15
1. BIDV[BIDV$tien_mat_vangbac_daquy > 4e+12, ]
1. head(BIDV[, c("nam", "tong_thu_nhap_hoat_dong")], 7)
1. tail(BIDV[, c("nam", "loi_nhuan_sau_thue")], 3)
1. BIDV[(BIDV$von_chu_so_huu / BIDV$tong_tai_san) > 0.07, ]
1. head(BIDV$tien_thu_thanh_ly_ts_co_dinh, 4)
## [1] 5.992e+09 2.910e+09 3.323e+09 4.079e+09
1. tail(BIDV$chi_thue_tndn, 2)
## [1] -4.551443e+12 -6.884931e+12
1. BIDV[BIDV$thu_nhap_lai_thuan > 0, ]
1. head(BIDV[, c("nam", "tong_tai_san", "von_chu_so_huu")], 6)

Giải thích kỹ thuật

Dòng 1:Lấy 5 giá trị đầu tiên của cột von_chu_so_huu từ bảng BIDV.

Dòng 2: Lấy 8 giá trị cuối cùng của cột tong_no_phai_tra từ bảng BIDV.

Dòng 3:Lọc ra các dòng trong bảng BIDV có giá trị của cột tien_mat_vangbac_daquy lớn hơn 4 tỷ (4e+12).

Dòng 4:Lấy 7 dòng đầu tiên của bảng BIDV chỉ với hai cột nam và tong_thu_nhap_hoat_dong.

Dòng 5:Lấy 3 dòng cuối cùng của bảng BIDV chỉ với hai cột nam và loi_nhuan_sau_thue.

Dòng 6:Lọc ra các dòng trong bảng BIDV có tỷ lệ von_chu_so_huu trên tong_tai_san lớn hơn 7%.

Dòng 7:Lấy 4 giá trị đầu tiên của cột tien_thu_thanh_ly_ts_co_dinh từ bảng BIDV.

Dòng 8:Lấy 2 giá trị cuối cùng của cột chi_thue_tndn từ bảng BIDV.

Dòng 9:Lọc ra các dòng trong bảng BIDV có giá trị của cột thu_nhap_lai_thuan lớn hơn 0.

Dòng 10:Lấy 6 dòng đầu tiên của bảng BIDV chỉ với ba cột nam, tong_tai_san, và von_chu_so_huu.

13.2 . Truy cập giá trị cụ thể

1. BIDV[nrow(BIDV), "tong_tai_san"]
1. BIDV[1, "von_chu_so_huu"]
1. BIDV[7, "loi_nhuan_sau_thue"]
1. BIDV[3, "nam"]
1. BIDV$tong_no_phai_tra[9]
## [1] 1.258377e+15
1. median_tts <- median(BIDV$tong_tai_san)
2. BIDV[which.min(abs(BIDV$tong_tai_san - median_tts)), "nam"]
1. BIDV[which.max(BIDV$tien_mat_vangbac_daquy), "nam"]
1. min(BIDV$thu_nhap_lai_thuan)
## [1] 9.191386e+12
1. mean(BIDV$loi_nhuan_sau_thue)
## [1] 9.207143e+12
1. BIDV[which.max(BIDV$chi_thue_tndn / BIDV$tong_thu_nhap_hoat_dong), "nam"]
1. BIDV$lai_lo_thuan_hd_ngoai_hoi_va_vang[BIDV$lai_lo_thuan_hd_ngoai_hoi_va_vang > 1e+12]
## [1] 1.039685e+12 1.494696e+12 1.732324e+12 1.896154e+12 3.136613e+12
## [6] 4.707371e+12 5.361499e+12
1. BIDV[which.max(BIDV$tien_thu_thanh_ly_ts_co_dinh), ]
1. BIDV[which.max(BIDV$tien_mat_vangbac_daquy / BIDV$tong_tai_san), ]
1. BIDV[which.min(BIDV$thanh_toan_nv_ncc / BIDV$tong_tai_san), ]

Giải thích kỹ thuật

Dòng 1:Lấy giá trị của cột tong_tai_san ở dòng cuối cùng của bảng BIDV, sử dụng nrow(BIDV) để xác định số dòng cuối cùng.

Dòng 2: Lấy giá trị của cột von_chu_so_huu ở dòng đầu tiên của bảng BIDV.

Dòng 3:Lấy giá trị của cột loi_nhuan_sau_thue ở dòng thứ 7 của bảng BIDV.

Dòng 4:Lấy giá trị của cột nam ở dòng thứ 3 của bảng BIDV.

Dòng 5: Lấy giá trị của cột tong_no_phai_tra ở dòng thứ 9 của bảng BIDV.

Dòng 6:Tính giá trị trung vị (median) của cột tong_tai_san trong bảng BIDV và lưu kết quả vào biến median_tts.

Dòng 7:Lấy giá trị của cột nam ở dòng có giá trị tong_tai_san gần với giá trị trung vị (median_tts), bằng cách tìm chỉ số dòng có sự chênh lệch nhỏ nhất giữa giá trị của tong_tai_san và trung vị.

Dòng 8:Lấy giá trị của cột nam ở dòng có giá trị tien_mat_vangbac_daquy lớn nhất.

Dòng 9:Lấy giá trị nhỏ nhất trong cột thu_nhap_lai_thuan của bảng BIDV.

Dòng 10:Tính giá trị trung bình của cột loi_nhuan_sau_thue trong bảng BIDV.

Dòng 11:Lấy giá trị của cột nam ở dòng có tỷ lệ chi_thue_tndn trên tong_thu_nhap_hoat_dong lớn nhất.

Dòng 12:Lọc ra các giá trị trong cột lai_lo_thuan_hd_ngoai_hoi_va_vang có giá trị lớn hơn 1 tỷ (1e+12).

Dòng 13:Lấy toàn bộ dòng có giá trị tien_thu_thanh_ly_ts_co_dinh lớn nhất.

Dòng 14:Lấy toàn bộ dòng có tỷ lệ tien_mat_vangbac_daquy trên tong_tai_san lớn nhất.

Dòng 15:Lấy toàn bộ dòng có tỷ lệ thanh_toan_nv_ncc trên tong_tai_san nhỏ nhất.

13.3 . Thêm và chỉnh sửa dữ liệu

1. BIDV$tong_tai_san[nrow(BIDV)] <- BIDV$tong_tai_san[nrow(BIDV)] * 0.93
2. BIDV$von_chu_so_huu[2] <- BIDV$von_chu_so_huu[2] * 1.05
3. BIDV$tien_mat_vangbac_daquy[3] <- BIDV$tien_mat_vangbac_daquy[3] * 0.99
4. BIDV$tong_no_phai_tra[1] <- BIDV$tong_no_phai_tra[1] * 1.08
5. BIDV$thu_nhap_lai_va_cac_khoan_tuong_tu[BIDV$nam == "2021"] <- BIDV$thu_nhap_lai_va_cac_khoan_tuong_tu[BIDV$nam == "2021"] * 1.02
6. BIDV$NIM <- BIDV$thu_nhap_lai_thuan / BIDV$tong_tai_san
7. BIDV$NPM <- BIDV$loi_nhuan_sau_thue / BIDV$tong_thu_nhap_hoat_dong
8. BIDV$chi_phi_lai_va_cac_chi_phi_tuong_tu[1] <- BIDV$chi_phi_lai_va_cac_chi_phi_tuong_tu[1] * 0.98
9. BIDV$chi_thue_tndn[nrow(BIDV)] <- BIDV$chi_thue_tndn[nrow(BIDV)] * 1.05
10. BIDV$ty_le_tienmat_ts <- BIDV$tien_mat_vangbac_daquy / BIDV$tong_tai_san
11. BIDV$hieuqua_NIM <- ifelse(BIDV$NIM > 0.025, "Tốt",
12.                  ifelse(BIDV$NIM >= 0.015 & BIDV$NIM <= 0.025, "Trung bình", "Thấp"))
13. BIDV$hieuqua_NPM <- ifelse(BIDV$NPM > 0.20, "Rất tốt",
14.                  ifelse(BIDV$NPM >= 0.10 & BIDV$NPM <= 0.20, "Tốt", "Thấp"))
15. BIDV$index <- seq_along(BIDV$nam)
16. BIDV$index <- NULL

Giải thích kỹ thuật:

Dòng 1:Điều chỉnh giá trị của cột tong_tai_san ở dòng cuối cùng bằng cách giảm nó đi 7% (nhân với 0.93).

Dòng 2: Tăng giá trị của cột von_chu_so_huu ở dòng thứ 2 lên 5% (nhân với 1.05).

Dòng 3:Giảm giá trị của cột tien_mat_vangbac_daquy ở dòng thứ 3 xuống 1% (nhân với 0.99).

Dòng 4: Tăng giá trị của cột tong_no_phai_tra ở dòng đầu tiên lên 8% (nhân với 1.08).

Dòng 5: Tăng giá trị của cột thu_nhap_lai_va_cac_khoan_tuong_tu cho năm 2021 lên 2% (nhân với 1.02).

Dòng 6: BIDV\(NIM <- BIDV\)thu_nhap_lai_thuan / BIDV$tong_tai_san Tạo cột mới NIM (Biên lợi nhuận lãi ròng) bằng cách chia thu_nhap_lai_thuan cho tong_tai_san.

Dòng 7: Tạo cột mới NPM (Biên lợi nhuận sau thuế) bằng cách chia loi_nhuan_sau_thue cho tong_thu_nhap_hoat_dong.

Dòng 8:Giảm giá trị của cột chi_phi_lai_va_cac_chi_phi_tuong_tu ở dòng đầu tiên đi 2% (nhân với 0.98).

Dòng 9: Tăng giá trị của cột chi_thue_tndn ở dòng cuối cùng lên 5% (nhân với 1.05).

Dòng 10:Tạo cột mới ty_le_tienmat_ts tính tỷ lệ tiền mặt, vàng bạc, đá quý trên tổng tài sản (tien_mat_vangbac_daquy / tong_tai_san).

Dòng 11: Tạo cột hieuqua_NIM để phân loại hiệu quả NIM:“Tốt” nếu NIM > 0.025,“Trung bình” nếu NIM từ 0.015 đến 0.025,“Thấp” nếu NIM < 0.015.

Dòng 12:Tạo cột hieuqua_NPM để phân loại hiệu quả NPM:“Rất tốt” nếu NPM > 0.20,“Tốt” nếu NPM từ 0.10 đến 0.20,“Thấp” nếu NPM < 0.10.

Dòng 13:Tạo cột index, lưu trữ số thứ tự cho từng dòng trong bảng dữ liệu BIDV theo cột nam.

Dòng 14:Xóa cột index khỏi bảng BIDV sau khi không còn cần thiết nữa.

13.4 . Phân tổ dữ liệu theo điều kiện cụ thể

13.4.1 . Giai đoạn 2015–2020 với NIM > 2%

1. d1 <- subset(BIDV,                             
2.   nam >= 2015 & nam <= 2020 &        
3.     NIM > 0.02)
4. head(d1)                          

Giải thích kỹ thuật:

Dòng 1: Hàm subset() được sử dụng để lọc dữ liệu theo điều kiện cụ thể.

Dòng 2–3: Điều kiện lọc: nam trong khoảng từ 2015 đến 2020 và NIM lớn hơn 2% (0.02).

Dòng : Hàm head(d1) hiển thị 6 dòng đầu tiên

  • Nhận xét : Nhóm dữ liệu này gồm giai đoạn 2015–2020, với 6 quan sát, chiếm 40% trên tổng 15 quan sát của bộ dữ liệu, đại diện cho thời kỳ tăng trưởng ổn định của ngân hàng. Trong giai đoạn này, NIM > 2,3% và NPM đạt 14–26%, phản ánh hiệu quả sinh lời tốt. Tổng tài sản và lợi nhuận sau thuế đều tăng qua các năm, cho thấy xu hướng mở rộng quy mô và hoạt động tài chính hiệu quả.

13.4.2 . NPM cao và có lãi ròng dương

1. d2 <- subset(BIDV,
2.   NPM > 0.15 &                       
3.     loi_nhuan_sau_thue > 0)
4. head(d2)

Giải thích kỹ thuật : thực hiện tương tự giống phân tổ Giai đoạn 2015–2020 với NIM > 2%

  • Nhận xét : Nhóm dữ liệu này gồm các năm có NPM > 15% và lợi nhuận sau thuế dương, với 14 quan sát, chiếm 93,3% tổng bộ dữ liệu. Giai đoạn này phản ánh hiệu quả sinh lời cao và ổn định, khi NPM dao động từ 17%–32%, duy trì mức lợi nhuận ròng tích cực qua các năm. Tổng tài sản và vốn chủ sở hữu tăng mạnh, cho thấy ngân hàng hoạt động hiệu quả và mở rộng quy mô bền vững. Nhìn chung, nhóm này đại diện cho giai đoạn tăng trưởng ổn định, với năng lực sinh lời và hiệu suất tài chính ở mức tốt – rất tốt.

13.4.3 . Biên lãi thuần dương và có phát sinh thu lãi

1. d3 <- subset(BIDV,
2.   NIM > 0.03 &                          
3.     thu_nhap_lai_va_cac_khoan_tuong_tu > 0 ) 
4. head(d3)

Giải thích kỹ thuật : thực hiện tương tự giống phân tổ Giai đoạn 2015–2020 với NIM > 2%

  • Nhận xét: Nhóm dữ liệu này gồm năm 2011, với 1 quan sát, chiếm 6,7% tổng bộ dữ liệu. Năm này có biên lãi thuần (NIM) đạt 3,11% và có phát sinh thu nhập lãi dương, phản ánh khả năng sinh lời tốt từ hoạt động tín dụng. Đây là giai đoạn ngân hàng duy trì hiệu quả hoạt động cao, với NPM 20,76% và hiệu quả tài chính được xếp loại “Rất tốt”.

13.4.4 . Dòng tiền chi trả cho NV/NCC âm (chi ra), nhưng vẫn có lãi và nộp thuế

1. d4 <- subset(BIDV,
2.   thanh_toan_nv_ncc < 0 &            
3.     loi_nhuan_sau_thue > 0 &         
4.     chi_thue_tndn > -1e12)
5. head(d4)

Giải thích kỹ thuật : thực hiện tương tự giống phân tổ Giai đoạn 2015–2020 với NIM > 2%

  • Nhận xét : Nhóm dữ liệu này gồm năm 2010 và 2012, với 2 quan sát, chiếm 13,3% tổng bộ dữ liệu. Cả hai năm đều có dòng tiền chi trả cho nhân viên và nhà cung cấp âm (chi ra), nhưng vẫn đạt lợi nhuận sau thuế dương và phát sinh chi thuế TNDN, cho thấy khả năng tạo dòng tiền tốt từ hoạt động kinh doanh chính. Nhóm này phản ánh doanh nghiệp duy trì hiệu quả tài chính ổn định, dù vẫn trong giai đoạn đầu tư mở rộng và chi phí vận hành cao.

13.4.5 . Tăng trưởng tài sản lớn, NIM ổn định

1. d5 <- subset(BIDV,                                      
2.   tong_tai_san >= 1.5e15 &                  
3.     NIM >= 0.024)                           
4. head(d5)

Giải thích kỹ thuật : thực hiện tương tự giống phân tổ Giai đoạn 2015–2020 với NIM > 2%

  • Nhận xét : Nhóm dữ liệu này gồm các năm 2021–2023, với 3 quan sát, chiếm 20% tổng bộ dữ liệu. Đây là giai đoạn ngân hàng có quy mô tài sản lớn (≥1,5 triệu tỷ đồng) và NIM duy trì ổn định quanh mức 2,4–2,6%, thể hiện hiệu quả sinh lời bền vững dù mở rộng quy mô mạnh. Lợi nhuận sau thuế và NPM tăng dần (từ 17,3% lên 30,1%), cho thấy hiệu quả quản lý chi phí và tăng trưởng lợi nhuận cao, phản ánh giai đoạn phát triển vững chắc và tối ưu hiệu suất hoạt động.

13.4.6 . Hiệu quả NIM “Rất tốt” và lợi nhuận sau thuế lớn hơn hoặc bằng 3.2e+12

1. d6 <- subset(                                 
2.   BIDV,                                          
3.   hieuqua_NPM == "Rất tốt" &                      
4.     loi_nhuan_sau_thue >= 3.2e+12)
5. head(d6)                          

Giải thích kỹ thuật : thực hiện tương tự giống phân tổ Giai đoạn 2015–2020 với NIM > 2%

  • Nhận xét : Nhóm dữ liệu này gồm giai đoạn 2015–2020, với 6 quan sát, chiếm 40% tổng bộ dữ liệu. Tất cả các năm trong nhóm đều có hiệu quả NPM đạt mức “Rất tốt” và lợi nhuận sau thuế ≥ 3.200 tỷ đồng, phản ánh khả năng sinh lời cao và ổn định. NIM duy trì quanh 2,3–2,6%, cho thấy biên lợi nhuận ổn định, trong khi tổng tài sản tăng mạnh qua các năm, khẳng định hiệu quả vận hành và sức tăng trưởng bền vững của ngân hàng.

13.5 . Phân tích 1 đến 3 biến

13.5.1 . Thống kê mô tả biến loi_nhuan_sau_thue

1. tk1 <- BIDV %>%                              
2.   summarise(
3.     Solieu = n(),                                   
4.     Trungbinh = mean(loi_nhuan_sau_thue, na.rm = TRUE), 
5.     max = max(loi_nhuan_sau_thue, na.rm = TRUE),    
6.     min = min(loi_nhuan_sau_thue, na.rm = TRUE),    
7.     Trungvi = median(loi_nhuan_sau_thue, na.rm = TRUE), 
8.     Dolechchuan = sd(loi_nhuan_sau_thue, na.rm = TRUE), 
9.     Q1 = quantile(loi_nhuan_sau_thue, 0.25, na.rm = TRUE), 
10.     Q3 = quantile(loi_nhuan_sau_thue, 0.75, na.rm = TRUE)) 
11. head(tk1)

Giải thích kỹ thuật

Dòng 1: Dùng toán tử %>% để chuyển dữ liệu từ bảng BIDV vào hàm summarise() để tính các chỉ số thống kê cho cột loi_nhuan_sau_thue.

Dòng 2–9: Tính các chỉ số thống kê mô tả cho cột loi_nhuan_sau_thue, bao gồm số lượng bản ghi (n()), giá trị trung bình (mean()), giá trị lớn nhất (max()), giá trị nhỏ nhất (min()), trung vị (median()), độ lệch chuẩn (sd()), tứ phân vị thứ nhất (quantile(…, 0.25)) và tứ phân vị thứ ba (quantile(…, 0.75)), bỏ qua các giá trị NA.

Dòng 10: head(tk1) hiển thị 6 dòng đầu tiên

Dựa vào bảng thống kê trên:

  • Tổng số năm quan sát: 15 năm.

  • Giá trị trung bình của lợi nhuận sau thuế: 9.207143 × 10¹² đồng.

  • Trung vị: 6.945586 × 10¹² đồng.

  • Giá trị nhỏ nhất và lớn nhất: từ 2.571943 × 10¹² đồng đến 2.560404 × 10¹³ đồng, cho thấy khoảng cách rất lớn, phản ánh sự chênh lệch đáng kể về lợi nhuận giữa các năm.

  • Độ lệch chuẩn: 7.080721 × 10¹² đồng, khá cao so với giá trị trung bình, chứng tỏ lợi nhuận sau thuế của ngân hàng biến động mạnh qua thời gian.

  • Q1 và Q3: lần lượt là 7.080721 × 10¹² đồng và 7.080721 × 10¹² đồng (thiếu Q3 trong dữ liệu, có thể cần bổ sung), tuy nhiên giá trị hiện có cho thấy lợi nhuận tập trung quanh mức trung bình, phản ánh hiệu quả hoạt động tương đối ổn định trong giai đoạn phân tích.

13.5.2 . Thống kê mô tả biến thu_nhap_lai_thuan

1. tk2 <- BIDV %>%                             
2.   summarise(
3.     Solieu = n(),                                   
4.     Trungbinh = mean(thu_nhap_lai_thuan, na.rm = TRUE),
5.     max = max(thu_nhap_lai_thuan, na.rm = TRUE),     
6.     min = min(thu_nhap_lai_thuan, na.rm = TRUE),     
7.     Trungvi = median(thu_nhap_lai_thuan, na.rm = TRUE),
8.     Dolechchuan = sd(thu_nhap_lai_thuan, na.rm = TRUE),
9.     Q1 = quantile(thu_nhap_lai_thuan, 0.25, na.rm = TRUE),
10.     Q3 = quantile(thu_nhap_lai_thuan, 0.75, na.rm = TRUE))
11. head(tk2)

Giải thích kỹ thuật: thực hiện tương tự giống Thống kê mô tả biến loi_nhuan_sau_thue

Dựa vào bảng thống kê trên:

  • Tổng số năm quan sát: 15 năm.

  • Giá trị trung bình của thu nhập lãi thuần: 3.065420 × 10¹³ đồng.

  • Trung vị: 3.095533 × 10¹³ đồng.

  • Giá trị nhỏ nhất và lớn nhất: từ 9.191386 × 10¹² đồng đến 5.800758 × 10¹³ đồng, cho thấy khoảng cách khá lớn, phản ánh sự khác biệt đáng kể về khả năng sinh lãi thuần giữa các năm.

  • Độ lệch chuẩn: 1.739830 × 10¹³ đồng, ở mức cao so với trung bình, chứng tỏ thu nhập lãi thuần của ngân hàng biến động mạnh qua các năm.

  • Q1 và Q3: lần lượt là 1.739830 × 10¹³ đồng và 1.584445 × 10¹³ đồng (giá trị Q3 có thể cần kiểm tra lại do dữ liệu chưa khớp), tuy nhiên nhìn chung các giá trị cho thấy phần lớn các năm có thu nhập lãi thuần ở mức trung bình – khá, phản ánh hiệu quả sinh lãi ổn định của ngân hàng qua thời gian.

13.5.3 . Thống kê mô tả Tổng thu nhập hoạt động theo nam và hieuqua_NPM

1. tk3 <- BIDV %>%                      
2.   group_by(nam, hieuqua_NPM) %>%                      
3.   summarise(                                          
4.     Sogiaodich = n(),                                 
5.     Trungbinh  = mean(tong_thu_nhap_hoat_dong, na.rm = TRUE), 
6.     Trungvi    = median(tong_thu_nhap_hoat_dong, na.rm = TRUE),
7.     Max        = max(tong_thu_nhap_hoat_dong, na.rm = TRUE),   
8.     Min        = min(tong_thu_nhap_hoat_dong, na.rm = TRUE),  
9.     Q1         = quantile(tong_thu_nhap_hoat_dong, 0.25, na.rm = TRUE), 
10.     Q3         = quantile(tong_thu_nhap_hoat_dong, 0.75, na.rm = TRUE)) %>%
11.   arrange(nam, hieuqua_NPM)                           
12. head(tk3)                            

Giải thích kỹ thuật: thực hiện tương tự giống Thống kê mô tả biến loi_nhuan_sau_thue

Dựa vào bảng thống kê trên:

  • Tổng số năm quan sát: 15 năm, phản ánh liên tục quá trình thay đổi hiệu quả hoạt động của ngân hàng.

  • Nhóm “Rất tốt” gồm các năm 2010–2016, 2022–2024 (tổng 9 năm, chiếm 60% bộ dữ liệu). Trong giai đoạn này, tổng thu nhập hoạt động tăng mạnh từ 1,15 × 10¹³ lên 8,11 × 10¹³ đồng, cho thấy hiệu suất sinh lời vượt trội, khả năng kiểm soát chi phí tốt và duy trì biên lợi nhuận cao.

  • Nhóm “Tốt” gồm các năm 2017–2021 (6 năm, chiếm 40% bộ dữ liệu). Thu nhập hoạt động tiếp tục tăng từ 3,90 × 10¹³ đến 6,25 × 10¹³ đồng, phản ánh giai đoạn tăng trưởng ổn định, dù biên lợi nhuận có phần giảm nhẹ do chi phí và quy mô mở rộng nhanh.

  • Giá trị nhỏ nhất – lớn nhất: từ 1,15 × 10¹³ đến 8,11 × 10¹³ đồng, cho thấy biên độ tăng trưởng mạnh và năng lực sinh lời ngày càng cao.

→ Nhìn chung, ngân hàng duy trì hiệu quả NPM ở mức tốt trở lên trong toàn bộ giai đoạn, với xu hướng tăng trưởng bền vững và hiệu suất tài chính ngày càng được cải thiện.

13.5.4 . Thống kê mô tả Lợi nhuận sau thuế theo hieuqua_NIM và hieuqua_NPM

1. tk4 <- BIDV %>%                     
2.   group_by(hieuqua_NIM, hieuqua_NPM) %>%              
3.   summarise(                                          
4.     Sogiaodich = n(),                                 
5.     Trungbinh  = mean(loi_nhuan_sau_thue, na.rm = TRUE), 
6.     Trungvi    = median(loi_nhuan_sau_thue, na.rm = TRUE),
7.     Max        = max(loi_nhuan_sau_thue, na.rm = TRUE),   
8.     Min        = min(loi_nhuan_sau_thue, na.rm = TRUE),   
9.     Dolechchuan= sd(loi_nhuan_sau_thue, na.rm = TRUE),    
10.     Q1         = quantile(loi_nhuan_sau_thue, 0.25, na.rm = TRUE), 
11.     Q3         = quantile(loi_nhuan_sau_thue, 0.75, na.rm = TRUE)) %>%
12.   arrange(hieuqua_NIM, hieuqua_NPM)         
13. head(tk4)                            

Giải thích kỹ thuật: thực hiện tương tự giống Thống kê mô tả biến loi_nhuan_sau_thue

Dựa vào bảng thống kê trên:

  • Tổng cộng 4 nhóm kết hợp giữa hiệu quả NIM và NPM, phản ánh rõ mối quan hệ giữa biên lãi và hiệu suất sinh lời ròng của ngân hàng.

  • Nhóm “Trung bình – Rất tốt” có 5 quan sát, lợi nhuận sau thuế trung bình đạt 1,25 × 10¹³ đồng, cao nhất trong các nhóm, cho thấy dù biên lãi ở mức trung bình nhưng khả năng kiểm soát chi phí và sinh lời ròng rất tốt.

  • Nhóm “Trung bình – Tốt” gồm 2 quan sát, lợi nhuận trung bình 7,89 × 10¹² đồng, phản ánh hiệu quả ổn định nhưng thấp hơn nhóm “Rất tốt” do biên lãi và quy mô lợi nhuận cùng ở mức vừa phải.

  • Nhóm “Tốt – Rất tốt” có 5 quan sát, lợi nhuận trung bình 6,87 × 10¹² đồng, cho thấy ngân hàng đạt hiệu suất sinh lời cao khi đồng thời duy trì biên lãi tốt và kiểm soát chi phí hiệu quả.

  • Nhóm “Tốt – Tốt” gồm 3 quan sát, lợi nhuận trung bình 8,42 × 10¹² đồng, thể hiện hiệu quả tài chính cân bằng và ổn định, với mức biến động thấp.

→ Nhìn chung, các nhóm có NPM “Rất tốt” đạt lợi nhuận cao hơn rõ rệt, dù NIM chỉ ở mức “Trung bình” hoặc “Tốt”, cho thấy khả năng quản lý chi phí và tối ưu lợi nhuận ròng là yếu tố then chốt giúp ngân hàng duy trì hiệu quả tài chính vượt trội.

14 . Trực quan hóa dữ liệu

14.1 . Vẽ biểu dồ cơ bản với R

14.1.1 . Scatter Plot: Quan hệ tổng tài sản vs lợi nhuận sau thuế

1. plot(BIDV$tong_tai_san,              
2.      BIDV$loi_nhuan_sau_thue,       
3.      pch = 19,col = "blue",cex = 1.2,                     
4.      xlab = "Tổng tài sản (VND)",ylab = "LN sau thuế (VND)",    
5.      main = "Scatter Plot: Tài sản vs LNST") 

Giải thích kỹ thuật

Dòng 1-2: Sử dụng hàm plot() để vẽ biểu đồ phân tán (scatter plot), hình dạng điểm là hình tròn đặc

Dòng 3: pch = 19: Đặt kiểu điểm là hình tròn đặc, col = “blue”: Màu điểm là xanh dương, cex = 1.2: Kích thước điểm lớn hơn 20% so với mặc định.

Dòng 4: Đặt nhãn cho trục X và trục Y và nhãn biểu đồ

  • Nhận xét : Biểu đồ thể hiện mối quan hệ cùng chiều rõ rệt giữa tổng tài sản và lợi nhuận sau thuế – khi tổng tài sản tăng, lợi nhuận cũng tăng mạnh. Các điểm dữ liệu phân bố khá đều, hình thành đường xu hướng dốc lên, chứng tỏ quy mô tài sản có ảnh hưởng tích cực đến hiệu quả sinh lời của ngân hàng. Điều này phản ánh ngân hàng quản lý vốn hiệu quả, mở rộng tài sản đi kèm tăng trưởng lợi nhuận bền vững.

14.1.2 . Line Plot: Diễn biến NIM

1. plot(BIDV$nam,BIDV$NIM,                       
2.      type = "b",col = "red", lwd = 2,pch = 17,                       
3.      xlab = "Năm",ylab = "NIM",main = "Line Plot: NIM theo năm")

Giải thích kỹ thuật:

Dòng 1-2: Sử dụng hàm plot() để vẽ biểu đồ đường (line plot) cho biến nam và NIM

Dòng 3: với các điểm vẽ là hình tam giác (pch = 17), màu đường là đỏ (col = “red”), độ dày đường là 2 (lwd = 2), kết hợp giữa đường và điểm (type = “b”).

Dòng 4: Đặt nhãn cho trục X là “Năm”, trục Y là “NIM” và tiêu đề biểu đồ là “Line Plot: NIM theo năm”.

  • Nhận xét : Biểu đồ cho thấy biên lãi ròng (NIM) của BIDV biến động khá mạnh trong giai đoạn 2010–2024. Sau khi đạt đỉnh cao vào năm 2011, NIM giảm sâu vào năm 2012, phản ánh giai đoạn khó khăn của thị trường tín dụng. Từ 2013 trở đi, NIM duy trì dao động quanh mức 2,3–2,7%, với một số chu kỳ tăng nhẹ (2017–2018, 2021–2022) nhưng xu hướng chung là ổn định và hơi giảm nhẹ về cuối kỳ (2024). Điều này cho thấy khả năng sinh lời từ hoạt động cho vay của ngân hàng được duy trì ổn định nhưng chưa có sự bứt phá rõ rệt.

14.1.3 . Bar Plot: Tiền mặt, vàng bạc, đá quý từng năm

1. y_max <- max(BIDV$tien_mat_vangbac_daquy) * 1.15  
2. bp <- barplot(BIDV$tien_mat_vangbac_daquy,         
3.               names.arg = BIDV$nam, col = "orange",                     
4.               space = 1.1,width = 0.7,                        
5.               ylim = c(0, y_max),main = "Bar Plot: Tiền mặt, vàng bạc, đá quý",
6.               xlab = "Năm",ylab = "Tổng giá trị (VND)")         
7. grid()                                             
8. text(bp, BIDV$tien_mat_vangbac_daquy,              
9.      labels = formatC(BIDV$tien_mat_vangbac_daquy, format = "e", digits = 2), 
10.      pos = 3, offset = 0.2, cex = 0.55, font = 2)   

Giải thích kỹ thuật

Dòng 1:Tính giá trị lớn nhất trong cột tien_mat_vangbac_daquy của bảng BIDV và nhân với 1.15 để tạo giới hạn tối đa cho trục Y của biểu đồ.

Dòng 2-7:Vẽ biểu đồ cột với các tham số:Giá trị của cột tien_mat_vangbac_daquy cho chiều cao các cột

Dòng 3: đặt tên các cột theo giá trị của năm (nam),col = “orange”: Màu sắc của các cột là cam

Dòng 4 :space = 1.1: Khoảng cách giữa các cột, width = 0.7: Độ rộng của các cột.

Dòng 5: ylim = c(0, y_max): Giới hạn trục Y từ 0 đến giá trị tối đa y_max, main = “Bar Plot: Tiền mặt, vàng bạc, đá quý”: Tiêu đề của biểu đồ.

Dòng 6: xlab = “Năm”: Nhãn trục X là “Năm”, ylab = “Tổng giá trị (VND)”: Nhãn trục Y là “Tổng giá trị (VND)”.

Dòng 7: grid() Thêm lưới vào biểu đồ để làm cho biểu đồ dễ đọc hơn.

Dòng 8: Thêm nhãn số vào các cột của biểu đồ:

Dòng 9: Chuyển giá trị trong tien_mat_vangbac_daquy thành định dạng khoa học với 2 chữ số thập phân.

Dòng 10:pos = 3: Đặt nhãn phía trên các cột, offset = 0.2: Đẩy nhãn lên phía trên một chút để tránh trùng với các cột, cex = 0.55: Kích thước chữ là 55% so với mặc định, font = 2: Làm chữ đậm (bold).

-Nhận xét : Biểu đồ cho thấy giá trị tiền mặt, vàng bạc, đá quý của BIDV tăng mạnh và ổn định trong giai đoạn 2010–2018, đặc biệt năm 2018 đạt mức cao đột biến (~1,41×10¹³ VND). Giai đoạn 2019–2022 duy trì quanh mức cao, phản ánh chính sách dự trữ tiền mặt và tài sản có tính thanh khoản cao. Tuy nhiên, từ 2023 giá trị này giảm nhẹ, cho thấy xu hướng tối ưu hóa tài sản ngắn hạn hoặc chuyển dịch cơ cấu đầu tư sang tài sản sinh lời cao hơn.

14.1.4 . Box Plot: Thu nhập lãi thuần

1. boxplot(BIDV$thu_nhap_lai_thuan,                   
2.         col = "green",border = "darkgreen",                      
3.         horizontal = TRUE, notch = TRUE,                              
4.         main = "Box Plot: Thu nhập lãi thuần",     
5.         xlab = "Thu nhập lãi thuần (VND)")         
6. grid()

Giải thích kỹ thuật

Dòng 1: Sử dụng hàm boxplot() để vẽ biểu đồ hộp (box plot) cho biến thu_nhap_lai_thuan.

Dòng 2: Đặt màu cho các hộp là xanh lá cây (col = “green”), viền hộp là xanh đậm (border = “darkgreen”),

Dòng 3: vẽ hộp theo chiều ngang (horizontal = TRUE), và tạo notch (lỗ hổng) trên biểu đồ (notch = TRUE).

Dòng 4: Đặt tiêu đề biểu đồ và nhãn trục X

Dòng 5: Thêm lưới vào biểu đồ bằng hàm grid().

  • Nhận xét: Biểu đồ hộp cho thấy thu nhập lãi thuần của BIDV phân bố khá rộng, với trung vị khoảng 3×10¹³ VND, chứng tỏ ngân hàng duy trì mức thu nhập ổn định. Khoảng tứ phân vị (IQR) lớn, phản ánh dao động thu nhập qua các năm đáng kể, có thể do thay đổi lãi suất thị trường hoặc quy mô tín dụng. Các điểm biên xa (whiskers) cho thấy một số năm có giá trị thu nhập vượt trội, minh chứng cho giai đoạn tăng trưởng mạnh mẽ trong hoạt động cho vay sinh lời.

14.1.5 . Biểu đồ tròn phân loại hiệu quả NIM

1. nim_counts <- table(BIDV$hieuqua_NIM)                        
2. percents <- round(100 * nim_counts / sum(nim_counts), 1) 
3. labels_pie <- paste0(names(nim_counts), "\n(", percents, "%)") 
4. pie(nim_counts,                                           
5.     labels = labels_pie,                                  
6.     col = c("forestgreen", "gold", "tomato"),             
7.     main = "Pie Chart: Phân loại NIM",clockwise = TRUE,                            cex = 1.2,init.angle = 90)                                      

Giải thích kỹ thuật

Dòng 1-2: Sử dụng hàm table() để đếm số lượng các giá trị trong cột hieuqua_NIM của bảng BIDV, và tính tỷ lệ phần trăm của mỗi giá trị.

Dòng 3: Tạo nhãn cho biểu đồ tròn (labels_pie) bằng cách kết hợp tên các nhóm và tỷ lệ phần trăm.

Dòng 4: Sử dụng hàm pie() để vẽ biểu đồ tròn, với các nhãn được tạo từ labels_pie, màu sắc cho các phần của biểu đồ, thêm tiêu đề, xoay biểu đồ theo chiều kim đồng hồ (clockwise = TRUE) và điều chỉnh kích thước chữ cho nhãn là 1.2 (cex = 1.2), bắt đầu góc từ 90 độ (init.angle = 90).

  • Nhận xét: Biểu đồ tròn cho thấy hơn một nửa số năm (53,3%) BIDV đạt mức NIM được xếp loại “Tốt”, trong khi 46,7% còn lại thuộc nhóm “Trung bình”. Điều này chứng tỏ khả năng sinh lời từ lãi vay của ngân hàng nhìn chung ổn định và duy trì ở mức khá, tuy nhiên vẫn có một số năm hiệu quả thấp hơn trung bình, phản ánh ảnh hưởng của biến động thị trường lãi suất và cấu trúc tài sản sinh lời.

14.1.6 . Histogram phân phối lãi/lỗ thuần hoạt động ngoại hối & vàng

1. hist(BIDV$lai_lo_thuan_hd_ngoai_hoi_va_vang,   
2.      col = "orchid",breaks = 6,                              
3.      border = "gray30",xlab = "Lãi/lỗ thuần ngoại hối & vàng (VND)", 
4.      ylab = "Tần suất",                       
5.      main = "Histogram: Phân phối lãi/lỗ hoạt động ngoại hối & vàng BIDV",
6.      freq = TRUE)                             
7. rug(BIDV$lai_lo_thuan_hd_ngoai_hoi_va_vang, col = "navy") 

Giải thích kỹ thuật

Dòng 1: Vẽ biểu đồ tần suất (histogram) cho cột lai_lo_thuan_hd_ngoai_hoi_va_vang từ bảng BIDV

Dòng 2: col = “orchid”: Màu của các cột,breaks = 6: Chia biểu đồ thành 6 nhóm.

Dòng 3: Màu viền của các cột là màu xám đậm, nhãn cột x

Dòng 4: nhãn cột y

Dòng 5: nhãn biểu đồ

Dòng 7: vẽ một dãi dưới trục x để hiển thị các giá trị

  • Nhận xét : Biểu đồ cho thấy phần lớn các năm BIDV có lãi thuần từ hoạt động ngoại hối và vàng ở mức thấp (dưới 2×10¹² VND), chỉ có một vài năm đạt giá trị cao vượt trội trên 4×10¹² VND. Phân phối lệch phải rõ rệt, phản ánh rằng đa số kết quả kinh doanh ngoại hối ổn định nhưng khi có biến động thị trường thuận lợi, lợi nhuận có thể tăng mạnh đột biến. Điều này cho thấy hoạt động ngoại hối và vàng của BIDV mang tính chu kỳ và phụ thuộc nhiều vào biến động tỷ giá quốc tế.

14.1.7 . So sánh 2 histogram: Tiền thu thanh lý tài sản cố định & Chi phí thuế TNDN

1. par(mfrow = c(1,2))                               
2. hist(BIDV$tien_thu_thanh_ly_ts_co_dinh,
3.      col = "#40E",breaks = 5,                                  
4.      border = "black", main = "Histogram: Tiền thu thanh lý TS",    
5.      xlab = "Tiền thu (VND)", ylab = "Tần suất")  
6. rug(BIDV$tien_thu_thanh_ly_ts_co_dinh, col = "#40E")  
7. hist(BIDV$chi_thue_tndn,                          
8.      col = "#FF10F0",breaks = 5,                                  
9.      border = "black",main = "Histogram: Chi phí thuế TNDN",      
10.      xlab = "Chi phí thuế (VND)", ylab = "Tần suất") 
11. rug(BIDV$chi_thue_tndn, col = "#FF10F0")          

r 1. par(mfrow = c(1,1))

Giải thích kỹ thuật: thực hiện tương tự giống Histogram phân phối lãi/lỗ thuần hoạt động ngoại hối & vàng

Dòng 11: chỉ hiển thị 1 biểu đồ trong một cửa sổ

  • Nhận xét : Hai biểu đồ histogram cho thấy tiền thu thanh lý tài sản cố định của BIDV chủ yếu tập trung ở mức dưới 1×10¹⁰ VND, thể hiện hoạt động thanh lý tài sản không thường xuyên và giá trị nhỏ. Ngược lại, chi phí thuế TNDN phân bố lệch trái mạnh, với phần lớn giá trị âm (do hoàn thuế hoặc điều chỉnh thuế), cho thấy biến động lớn giữa các năm. Tổng thể, dữ liệu phản ánh nguồn thu từ thanh lý ổn định ở mức thấp, trong khi chi phí thuế có tính bất thường và phụ thuộc vào chính sách tài chính từng giai đoạn.

14.1.8 . Biểu đồ cột chồng hai lớp: Thanh toán NV-NCC & Chi phí thuế TNDN

1. values_stack_paytax <- rbind(
2.   abs(BIDV$thanh_toan_nv_ncc),    
3.   abs(BIDV$chi_thue_tndn))
4. barplot(values_stack_paytax,                         
5.         beside = FALSE,                              
6.         names.arg = BIDV$nam,                        
7.         col = c("#39F", "#FF1"),                     
8.         main = "Cột chồng 2 lớp: Thanh toán NV-NCC & Chi thuế TNDN",
9.         xlab = "Năm",                                
10.         ylab = "Giá trị (VND)")                      
11. legend("topright", legend = c("Thanh toán NV-NCC", "Chi phí thuế TNDN"), 
12.        fill = c("#39F", "#FF1"),  bty = "n", cex = 0.9)

Giải thích kỹ thuật

Dòng 1: Kết hợp hai cột thanh_toan_nv_ncc (chi trả cho nhân viên và nhà cung cấp) và chi_thue_tndn (chi phí thuế thu nhập doanh nghiệp) thành một bảng dữ liệu mới values_stack_paytax, chuyển cả hai cột này thành giá trị tuyệt đối

Dòng 2: Vẽ biểu đồ cột chồng (stacked bar plot) với các thông số

Dòng 11: Thêm chú giải (legend) vào góc trên bên phải của biểu đồ, với các nhãn, bty = “n”: Loại bỏ viền của chú giải, cex = 0.9: Đặt kích thước chữ cho chú giải là 0.9 lần kích thước mặc định.

  • Nhận xét : Biểu đồ thể hiện tổng chi thanh toán cho nhân viên – nhà cung cấp (NV-NCC) và chi phí thuế TNDN của BIDV đều có xu hướng tăng ổn định qua các năm 2010–2024. Trong đó, khoản thanh toán NV-NCC chiếm tỷ trọng lớn nhất, phản ánh gánh nặng chi phí hoạt động thường xuyên. Chi phí thuế TNDN tuy nhỏ hơn nhưng cũng tăng dần song song, cho thấy lợi nhuận trước thuế tăng và BIDV đóng góp ngân sách ngày càng cao. Tổng thể, biểu đồ thể hiện hiệu quả hoạt động ổn định, song chi phí vận hành tăng đều theo quy mô.

14.1.9 . Biểu đồ cột ba giá trị: Vốn chủ sở hữu, Tổng nợ phải trả, Tổng tài sản BIDV

1. values_triple <- rbind(BIDV$von_chu_so_huu, BIDV$tong_no_phai_tra, BIDV$tong_tai_san)          
2. barplot(values_triple,                                             
3.         beside = TRUE,                                              
4.         names.arg = BIDV$nam,                                       
5.         col = c("blue", "red", "green"),                            
6.         main = "Biểu đồ cột ba giá trị:\n Vốn chủ sở hữu, Tổng nợ phải trả, Tổng tài sản BIDV ",                         
7.         xlab = "Năm", ylab = "Giá trị (VND)")                     
8. legend("topleft", legend = c("Vốn chủ sở hữu", "Tổng nợ phải trả", "Tổng tài sản"), fill = c("blue", "red", "green"))         

Giải thích kỹ thuật :

Dòng 1: Dùng hàm rbind() để kết hợp ba cột

Dòng 2: Vẽ biểu đồ cột cho ba giá trị và tương tự các chỉ tiêu đã đề cập ở các biểu đồ trước đó

Dòng 8: Thêm chú giải vào góc trên bên trái

  • Nhận xét : Biểu đồ thể hiện rõ quy mô tài chính BIDV tăng trưởng mạnh mẽ trong giai đoạn 2010–2024. Cả tổng tài sản và tổng nợ phải trả đều tăng đều qua các năm, với tốc độ gần song song, cho thấy nguồn vốn vay vẫn chiếm tỷ trọng chủ đạo trong cấu trúc tài chính. Trong khi đó, vốn chủ sở hữu tăng chậm hơn nhưng ổn định, phản ánh mức độ an toàn vốn được cải thiện dần theo thời gian. Nhìn chung, BIDV mở rộng quy mô tổng tài sản nhờ tăng trưởng tín dụng và huy động vốn, song vẫn cần tăng tỷ trọng vốn chủ sở hữu để củng cố năng lực tài chính bền vững.

14.1.10 . Biểu đồ boxplot ba biến: Thu nhập lãi thuần, Lợi nhuận sau thuế, Tổng thu nhập hoạt động

1. boxplot(BIDV$thu_nhap_lai_thuan, BIDV$loi_nhuan_sau_thue, BIDV$tong_thu_nhap_hoat_dong,          
2.         names = c("Thu nhập lãi thuần", "LN sau thuế", "Tổng thu nhập HĐ"), 
3.         col = c("orange", "skyblue", "pink"), 
4.         main = "Boxplot ba biến: 3 chỉ tiêu lợi nhuận BIDV",
5.         ylab = "Giá trị (VND)")

Giải thích kỹ thuật:

Dòng 1: Vẽ biểu đồ hộp (box plot) cho ba biến và tương tự các chỉ tiêu đã đề cập ở các biểu đồ trước đó

  • Nhận xét : Biểu đồ cho thấy tổng thu nhập hoạt động và thu nhập lãi thuần của BIDV có giá trị trung vị cao, phân bố rộng, thể hiện hiệu quả tăng trưởng ổn định của nguồn thu chính. Trong khi đó, lợi nhuận sau thuế thấp hơn đáng kể và có các điểm ngoại lệ, cho thấy sự biến động do chi phí hoạt động và trích lập dự phòng rủi ro ảnh hưởng đến khả năng sinh lời thực tế của ngân hàng.

14.2 . Vẽ biểu đồ bằng ggplot2

14.2.1 . Biểu đồ đường: Tổng tài sản từng năm

1. ggplot(BIDV, aes(x = nam, y = tong_tai_san)) +                    
2.   geom_line(color = "#39FF14", size = 1.5) +                      
3.   geom_point(color = "#39FF14", size = 3) +                      
4.   geom_text(aes(label = formatC(tong_tai_san, format = "e", digits = 2)), 
5.             vjust = -1, color = "black", size = 2.5) +            
6.   labs(title = "Đường đơn: Tổng tài sản theo năm", x = "Năm", y = "Tổng tài sản (VND)") +
7.   theme_minimal()

Giải thích kỹ thuật

Dòng 1:Sử dụng ggplot() để tạo biểu đồ với dữ liệu

Dòng 2: Vẽ đường nối các điểm với màu sắc có độ dày 1.5

Dòng 3: Vẽ các điểm tại các giá trị dữ liệu và kích thước điểm là 3.

Dòng 4: Thêm nhãn cho các điểm,hiển thị giá trị tong_tai_san dưới dạng số khoa học (format = “e”), với 2 chữ số thập phân (digits = 2),vị trí nhãn hơi lệch lên .

Dòng 6: giao diện tối giản cho biểu đồ

  • Nhận xét : Biểu đồ thể hiện tổng tài sản của BIDV tăng liên tục qua các năm, đặc biệt tăng mạnh từ sau năm 2016 và vượt mốc 2,5 triệu tỷ đồng vào năm 2024. Đường xu hướng tăng ổn định cho thấy quy mô hoạt động của ngân hàng mở rộng đều đặn, phản ánh năng lực tăng trưởng vững vàng và khả năng quản lý tài sản hiệu quả trong giai đoạn 2010–2024.

###. Biểu đồ đường: Tổng nợ phải trả từng năm

1. ggplot(BIDV, aes(x = nam, y = tong_no_phai_tra)) +               
2.   geom_line(color = "#FF10F0", size = 1.5) +                      
3.   geom_point(color = "#FF10F0", size = 3) +                       
4.   geom_text(aes(label = formatC(tong_no_phai_tra, format = "e", digits = 2)), 
5.             vjust = -1, color = "darkred", size = 2.5) +            
6.   labs(title = "Đường đơn: Tổng nợ phải trả theo năm", x = "Năm", y = "Tổng nợ phải trả (VND)") +
7.   theme_minimal()

Giải thích kỹ thuật : thực hiện tương tự giống với Biểu đồ đường: Tổng tài sản từng năm

  • Nhận xét: Biểu đồ cho thấy tổng nợ phải trả của BIDV tăng liên tục qua các năm 2010–2024, với độ dốc tăng mạnh rõ rệt từ sau năm 2016, đặc biệt bứt phá giai đoạn 2020–2024. Xu hướng này phản ánh quy mô hoạt động và huy động vốn mở rộng mạnh, song cũng cho thấy áp lực nghĩa vụ tài chính ngày càng lớn, đòi hỏi kiểm soát rủi ro nợ hợp lý để duy trì an toàn vốn.

14.2.2 . Biểu đồ cột nhóm so sánh thu nhập lãi thuần, tổng thu nhập hoạt động, lợi nhuận sau thuế theo năm

1. df_triple_mean <- BIDV[, c("nam", "thu_nhap_lai_thuan", "tong_thu_nhap_hoat_dong", "loi_nhuan_sau_thue")]   
2. df_triple_mean_long <- pivot_longer(df_triple_mean,
3.                                     cols = c("thu_nhap_lai_thuan", "tong_thu_nhap_hoat_dong", "loi_nhuan_sau_thue"),
4.                                     names_to = "variable", values_to = "value")
5. ggplot(df_triple_mean_long, aes(x = factor(nam), y = value, fill = variable)) +
6.   geom_bar(stat = "identity", position = position_dodge(width = 0.7), width = 0.55) + 
7.   geom_text(aes(label = signif(value, 2)), color = "#00F", size = 1.6,
8.             fontface = "bold", position = position_dodge(width = 0.7), vjust = -0.55) +
9.   scale_fill_manual(
10.     values = c("#FFD700", "#39FF14", "#FF1463"), 
11.     labels = c("Lợi nhuận sau thuế", "Thu nhập lãi thuần", "Tổng thu nhập hoạt động")  
12.   ) +labs(title = "Biểu đồ so sánh Thu nhập lãi thuần, Tổng thu nhập hoạt động, Lợi nhuận sau thuế",
13.     x = "Năm", y = "Giá trị (VND)", fill = "Chỉ tiêu") +
14.   theme_minimal() +                                                         
15.   theme(axis.text.x = element_text(color = "#FF00EA", size = 9, angle = 20))  

Giải thích kỹ thuật:

Dòng 1: tạo bảng con df_triple_mean

Dòng 2-3: Chuyển dữ liệu từ dạng rộng sang dạng dàiác cột thu_nhap_lai_thuan, tong_thu_nhap_hoat_dong, và loi_nhuan_sau_thue được chuyển thành hai cột mới: variable: Chứa tên cột gốc (các chỉ tiêu),value: Chứa giá trị của các chỉ tiêu.

Dòng 4-5: vẽ biểu đồ bar theo các chỉ tiêu tương tự các biểu đồ trên đã đề cập

Dòng 6: vẽ biểu đồ cột, cho dùng giá trị thực tế của cột value cho chiều cao các cột, đặt các cột cạnh nhau

Dòng 7: Thêm các nhãn cho biểu đồ, và cột

Dòng 9: chỉnh màu sắc cho các cột và nhãn

  • Nhận xét: Ba chỉ tiêu đều tăng mạnh và ổn định theo thời gian, thể hiện sự mở rộng quy mô hoạt động và hiệu quả tài chính của BIDV. Trong đó, thu nhập lãi thuần luôn chiếm tỷ trọng cao nhất và tăng đều qua các năm; tổng thu nhập hoạt động duy trì xu hướng tăng song song, phản ánh hiệu quả khai thác các nguồn thu ngoài lãi; còn lợi nhuận sau thuế tuy thấp hơn nhưng tăng nhanh rõ rệt từ năm 2021, cho thấy hiệu suất sinh lời được cải thiện nhờ kiểm soát chi phí và tăng trưởng doanh thu ổn định.

14.2.3 . Biểu đồ scatter phân tán: Tổng nợ phải trả vs Tiền thu thanh lý tài sản cố định, màu năm

1. ggplot(BIDV, aes(x = tong_no_phai_tra, y = tien_thu_thanh_ly_ts_co_dinh, color = nam)) +         
2.   geom_point(size = 4.2, alpha = 0.85) + 
3.   geom_text(aes(label = formatC(tien_thu_thanh_ly_ts_co_dinh, format = "e", digits = 1)),
4.             vjust = -1.06, color = "black", size = 2.7, fontface = "bold") + 
5.   scale_color_gradient(low = "#FFD700", high = "#FF00EA") + 
6.   labs(title = "BIỂU ĐỒ PHÂN TÁN:\n Tổng nợ phải trả & Tiền thu thanh lý TS cố định",                
7.     x = "Tổng nợ phải trả (VND)", 
8.     y = "Tiền thu thanh lý tài sản cố định (VND)", 
9.     color = "Năm") +
10.   theme_minimal() +
11.   theme(plot.title = element_text(hjust = 0.5, size =14 , face = "bold", color = "black"),        
12.     axis.text = element_text(color = "#FFD700"),
13.     axis.title = element_text(size = 13, face = "bold") )

Giải thích kỹ thuật

Dòng 1 :Khởi tạo biểu đồ phân tán (ggplot)

Dòng 2: Vẽ các điểm phân tán với các thông số tương tự như các biểu đồ trước đã đề cập

Dòng 3 : Thêm nhãn cho biểu đồ với các thông số tương tự như các biểu đồ trước đã đề cập

Dòng 5: Thiết lập màu sắc cho các điểm

  • Nhận xét: Biểu đồ thể hiện mối tương quan thuận nhẹ giữa tổng nợ phải trả và tiền thu thanh lý TSCĐ — khi nợ tăng, giá trị thanh lý cũng có xu hướng cao hơn. Các điểm năm gần đây (màu hồng neon) tập trung ở vùng giá trị cao, cho thấy quy mô tài sản và nghĩa vụ nợ đều mở rộng. Trong khi đó, các năm cũ (vàng) nằm ở vùng thấp, phản ánh quá trình tăng trưởng dần của BIDV theo thời gian.

14.2.4 . Biểu đồ tròn tỉ lệ nhóm hiệu quả NPM của BIDV

1. npm_counts <- as.data.frame(table(BIDV$hieuqua_NPM)) 
2. colnames(npm_counts) <- c("Hiệu quả NPM", "Số lượng")              
3. npm_counts$y <- round(100 * npm_counts$`Số lượng` / sum(npm_counts$`Số lượng`), 1)    
4. ggplot(npm_counts, aes(x = "", y = y, fill = `Hiệu quả NPM`)) + 
5.   geom_bar(stat = "identity", width = 1, color = "white") + 
6.   coord_polar("y", start = 0) +    
7.   scale_fill_manual(
8.     values = c("#FFD700", "#39FF14", "#FF00EA"),  
9.     labels = c("Hiệu quả cao", "Hiệu quả trung bình", "Hiệu quả thấp") ) +
10.   geom_text( 
11.     aes(label = paste0(y, "%")), 
12.     position = position_stack(vjust = 0.5), color = "#00F", size = 5, fontface = "bold" ) +
13.   labs(title = "BIỂU ĐỒ TRÒN TỈ LỆ HIỆU QUẢ NPM", 
14.     fill = "Nhóm hiệu quả"   ) +
15.   theme_minimal() +
16.   theme(
17.     plot.title = element_text(hjust = 0.5, size = 15, face = "bold", color = "black"),
18.     legend.text = element_text(size = 11))

Giải thích kỹ thuật :

Dòng 1: Tạo một bảng dữ liệu npm_counts

Dòng 2:Đặt lại tên cột cho bảng npm_counts, đổi tên các cột thành “Hiệu quả NPM” và “Số lượng” ’

Dòng 3: Tính tỷ lệ % của mỗi nhóm hiẹue quả NPM

Dòng 4-5: vẽ biểu đồ tròn với các thông số tương tự như các biểu đồ trước đã đề cập

Dòng 6: vẽ biểu đồ bar với các thông số tương tự như các biểu đồ trước đã đề cập

Dòng 7: thiết lập màu sắc cho các phần của biểu đồ tròn

Dòng 8: thêm nhãn cho biểu đồ tròn

Dòng 9: thêm tiêu đề cho biểu đồ chính

  • Nhận xét: Biểu đồ cho thấy nhóm NPM hiệu quả cao chiếm ưu thế (≈67%), trong khi nhóm trung bình chỉ khoảng 33%, và không có nhóm hiệu quả thấp. Điều này phản ánh hiệu suất sinh lời của BIDV khá tốt, biên lợi nhuận ròng được duy trì ở mức ổn định cao, cho thấy khả năng kiểm soát chi phí và tối ưu hóa hoạt động kinh doanh hiệu quả trong giai đoạn phân tích.

14.2.5 . Biểu đồ histogram phân phối thu nhập lãi và các khoản tương tự BIDV

1. ggplot(BIDV, aes(x = thu_nhap_lai_va_cac_khoan_tuong_tu)) +
2.   geom_histogram(fill = "#39FF14", color = "white", alpha = 0.72, bins = 12) +
3.   labs(title = "PHÂN PHỐI THU NHẬP LÃI VÀ CÁC KHOẢN TƯƠNG TỰ", 
4.     x = "Thu nhập lãi và các khoản tương tự (VND)",
5.     y = "Tần suất"  ) +
6.   theme_minimal() + 
7.   theme(
8.     plot.title = element_text(hjust = 0.5, size = 15, face = "bold", color = "black"), 
9.     axis.text.x = element_text(color = "#FF1463", size = 11) )

Giải thích kỹ thuật

Dòng 1: vẽ biểu đồ với gglot(), trục X là cột thu_nhap_lai_va_cac_khoan_tuong_tu

Dòng 2: vẽ biểu đồ tần suất histogram với các tham số tương tự đã đề cập ở các đồ thị trước đó

Dong 3: thêm nhãn cho biểu đồ chính

Dòng 4: đơn giản hoá giao diện biểu đồ

  • Nhận xét : Biểu đồ cho thấy phân phối thu nhập lãi và các khoản tương tự của BIDV lệch phải rõ rệt, tập trung nhiều ở mức 4×10¹³ VND, còn các giá trị cao hơn thưa dần. Điều này cho thấy phần lớn các năm có doanh thu lãi ở mức trung bình, chỉ một vài năm đạt mức cao vượt trội, phản ánh xu hướng tăng trưởng nhưng không đồng đều trong nguồn thu từ hoạt động tín dụng.

14.2.6 . Biểu đồ histogram phân phối 3 chỉ tiêu BIDV (Tổng thu nhập, Thanh toán NV-NCC, Thuế TNDN)

1. df3 <- BIDV[, c("tong_thu_nhap_hoat_dong", "thanh_toan_nv_ncc", "chi_thue_tndn")]  
2. df3_long <- pivot_longer(df3, cols = everything(), names_to = "Chỉ tiêu", values_to = "Giá trị") 
3. ggplot(df3_long, aes(x = `Giá trị`, fill = `Chỉ tiêu`)) + 
4.   geom_histogram(position = "identity", alpha = 0.62, bins = 13, color = "white") +              
5.   scale_fill_manual(values = c("#FFD700", "#00FFF0", "#FF00EA"),
6.                     labels = c("Tổng thu nhập hoạt động", "Thanh toán NV-NCC", "Chi phí thuế TNDN")) + 
7.   labs(title = "PHÂN PHỐI 3 CHỈ TIÊU BIDV", x = "Giá trị (VND)", y = "Tần suất", fill = "Chỉ tiêu") +  
8.   theme_minimal() + 
9.   theme(plot.title = element_text(hjust = 0.5, size = 15, face = "bold", color = "black"))  

Giải thích kỹ thuật: thực hiện tương tự giống Biểu đồ histogram phân phối thu nhập lãi và các khoản tương tự BIDV

  • Nhận xét: Biểu đồ cho thấy phân phối ba chỉ tiêu tài chính của BIDV có đặc điểm khác biệt rõ rệt — trong đó tổng thu nhập hoạt động tập trung quanh giá trị dương thấp, thanh toán NV–NCC trải rộng về phía giá trị cao hơn, còn chi phí thuế TNDN chủ yếu nằm ở vùng âm, thể hiện đặc trưng chi phí. Sự khác biệt này phản ánh cấu trúc dòng tiền hai chiều (thu – chi) trong hoạt động của ngân hàng, với xu hướng doanh thu ổn định nhưng chi phí biến động mạnh qua các năm.

14.2.7 . Biểu đồ đường 4 biến tài chính BIDV theo năm

1. df <- BIDV[, c("nam", "tong_tai_san", "tong_no_phai_tra", "von_chu_so_huu", "tong_thu_nhap_hoat_dong")]                       
2. df_long <- pivot_longer(df, 
3.                         cols = c("tong_tai_san", "tong_no_phai_tra", "von_chu_so_huu", "tong_thu_nhap_hoat_dong"),
4.                         names_to = "Chỉ tiêu", values_to = "Giá trị") 
5. max_value <- max(df_long$`Giá trị`, na.rm = TRUE)  
6. y_breaks <- seq(0, max_value, by = 5e13)      
7. label_scientific <- function(x) format(x, scientific = TRUE, digits = 2) 
8. ggplot(df_long, aes(x = nam, y = `Giá trị`, color = `Chỉ tiêu`, group = `Chỉ tiêu`)) + 
9.   geom_line(size = 1.2) +  
10.   geom_point(size = 2.7) + 
11.   scale_color_manual(
12.     values = c("#FFD700", "#39FF14", "#FF00EA", "#00FFF0"),  
13.     labels = c("Tổng tài sản", "Tổng nợ phải trả", "Vốn chủ sở hữu", "Tổng thu nhập hoạt động")) +
14.   scale_y_continuous(
15.     breaks = y_breaks,
16.     labels = label_scientific) +
17.   labs(title = "BIỂU ĐỒ ĐƯỜNG 4 BIẾN: Tổng tài sản, Tổng nợ phải trả, Vốn chủ sở hữu, Tổng thu nhập hoạt động",     
18.     x = "Năm", y = "Giá trị (VND)",color = "Chỉ tiêu") +
19.   theme_minimal() + 
20.   theme(
21.     plot.title = element_text(hjust = 0.5, size = 8, face = "bold", color = "black"),  
22.     axis.text.x = element_text(color = "black", size = 10),
23.     axis.text.y = element_text(color = "black", size = 5))

Giải thích kỹ thuật: Giải thích kỹ thuật : thực hiện tương tự giống với Biểu đồ đường: Tổng tài sản từng năm

  • Nhận xét: Biểu đồ thể hiện xu hướng tăng trưởng mạnh mẽ của BIDV giai đoạn 2010–2024, trong đó tổng tài sản và tổng nợ phải trả tăng song song với mức độ gần như tương đương, cho thấy mức mở rộng quy mô chủ yếu dựa trên nguồn vốn huy động. Trong khi đó, vốn chủ sở hữu và tổng thu nhập hoạt động cũng tăng nhưng với tốc độ chậm hơn, phản ánh mức độ an toàn vốn ổn định và khả năng sinh lời đang được củng cố dần theo quy mô phát triển.

14.2.8 . Biểu đồ heatmap giá trị tài sản tiền mặt, vàng bạc, đá quý qua từng năm

1. scale_fill_gradientn(
2.   colors = c("#39FF14", "#0099FF", "#8000FF"),       
3.   name = "Tiền mặt, vàng bạc, đá quý")
## <ScaleContinuous>
##  Range:  
##  Limits:    0 --    1
1. df_heat1 <- BIDV[, c("nam", "tien_mat_vangbac_daquy")]
2. ggplot(df_heat1, aes(x = factor(nam), y = "Tiền mặt, vàng bạc, đá quý")) +   
3.   geom_tile(aes(fill = tien_mat_vangbac_daquy), color = "white", linewidth = 0.5) +  
4.   scale_fill_gradientn(
5.     colors = c("#39FF14", "#0099FF", "#8000FF"),      
6.     name = "Tiền mặt, vàng bạc, đá quý"               ) +
7.   labs(title = "HEATMAP: Tiền mặt, vàng bạc, đá quý qua các năm", x = "Năm", y = "") + 
8.   theme_minimal() +                                                         
9.   theme(
10.     plot.title = element_text(hjust = 0.5, color = "#0099FF", size = 15, face = "bold"), 
11.     axis.text.x = element_text(color = "black", size = 6) )

Giải thích kỹ thuật

Dòng 1-3: Thiết lập một gradient màu cho biểu đồ:

Dòng 4: Tạo bảng con df_heat1

Dòng 5: vẽ biểu đồ với ggplot() với các tiêu chí tương tự với các biểu đồ đã đề cập ở trên

Dòng 6: vẽ biểu đồ hình vuông cho biến tien_mat_vangbac_daquy với các tiêu chí tương tự với các biểu đồ đã đề cập ở trên

Dòng 7: áp dụng gradien màu cho các hình vuông

Dòng 10: thêm nhãn cho biểu đồ chính

Dòng 11-14: giao diện tối giản và kiểu chữ màu sắc cho biểu đồ

  • Nhận xét: Biểu đồ heatmap cho thấy giá trị tiền mặt, vàng bạc và đá quý của BIDV tăng dần qua các năm, thể hiện qua gam màu chuyển từ xanh lá sáng sang tím đậm. Giai đoạn 2010–2015 duy trì ổn định ở mức trung bình, trong khi từ 2018 trở đi màu sắc đậm hơn rõ rệt, phản ánh xu hướng gia tăng nắm giữ tài sản thanh khoản và dự trữ giá trị. Điều này cho thấy ngân hàng duy trì tốt khả năng thanh khoản và củng cố cấu trúc tài sản an toàn theo thời gian.

14.2.9 . Biểu đồ phân phối lợi nhuận theo biến NIM

1. ggplot(BIDV, aes(x = loi_nhuan_sau_thue)) +     
2.   geom_histogram(binwidth = 5e12, fill = "#2196F3", color = "#FF00EA", alpha = 0.8) +
3.   facet_wrap(~hieuqua_NIM) + 
4.   labs(                                                                      
5.     x = "Lợi nhuận sau thuế (VND)",                                       
6.     y = "Số lần xuất hiện",                                                  
7.     title = "Phân phối lợi nhuận sau thuế theo nhóm hiệu quả NIM") +
8.   theme_minimal() +                                                         
9.   theme(
10.     plot.title = element_text(hjust = 0.5, color = "#2196F3", size = 15, face = "bold"), 
11.     axis.text.x = element_text(color = "#FF00EA", size = 11) )

Giải thích kỹ thuật : thực hiện tương tự giống với Biểu đồ histogram phân phối thu nhập lãi và các khoản tương tự BIDV

  • Nhận xét: Biểu đồ thể hiện phân phối lợi nhuận sau thuế của BIDV theo nhóm hiệu quả NIM. Nhóm “Tốt” có lợi nhuận tập trung chủ yếu ở mức thấp–trung bình, phản ánh sự ổn định và ít biến động. Trong khi đó, nhóm “Trung bình” trải rộng hơn và có vài năm đạt lợi nhuận cao, cho thấy hiệu quả NIM chưa ổn định nhưng tiềm năng cải thiện lớn. Điều này cho thấy mối liên hệ giữa biên lãi ròng (NIM) và khả năng sinh lợi ròng của ngân hàng.

14.2.10 . Biểu đồ mật độ thu nhập lãi và các khoản tương tự theo hiệu quả NIM

1. ggplot(BIDV, aes(x = thu_nhap_lai_va_cac_khoan_tuong_tu)) +      
2.   geom_density(fill = "#39FF14", color = "black", alpha = 0.8) +  
3.   facet_wrap(~hieuqua_NIM) +                                     
4.   labs(x = "Thu nhập lãi và các khoản tương tự (VND)",              
5.     y = "Mật độ (density)",                                       
6.     title = "Biểu đồ mật độ thu nhập lãi và các khoản tương tự theo hiệu quả NIM" ) +
7.   theme_minimal() +                                               
8.   theme(plot.title = element_text(hjust = 0.5, color = "black", size = 12, face = "bold"), 
9.     axis.text.x = element_text(color = "#00AEA5", size = 11))

Giải thích kỹ thuật

Dòng 1: vẽ biểu đồ với ggplot() trục X là cột thu_nhap_lai_va_cac_khoan_tuong_tu

Dòng 2: Vẽ biểu đồ mật độ (density plot) với các tiêu chí tương tự với các biểu đồ đã đề cập ở trên

Dòng 3: chia biẻu đồ thành các nhóm con dựa trên hieuqua_nim

Dòng 4: thêm nhãn cho biểu đồ chính

Dòng 7-9: tối giản giao diện biểu đồ và điều chỉnh kiểu chữ, màu sắc của biểu đồ

-Nhận xét: Biểu đồ cho thấy phân bố thu nhập lãi và các khoản tương tự có sự khác biệt giữa hai nhóm hiệu quả NIM. Nhóm “Tốt” tập trung ở mức thu nhập trung bình–cao, thể hiện khả năng sinh lời ổn định từ hoạt động cho vay. Ngược lại, nhóm “Trung bình” có phân bố dàn trải hơn, phản ánh hiệu quả sử dụng tài sản kém ổn định, cho thấy biên lợi nhuận lãi của nhóm này chưa được tối ưu hóa.

15 . Kết luận

  • Phân tích cho thấy quy mô hoạt động của BIDV tăng mạnh và ổn định trong giai đoạn 2010–2024. Tổng tài sản, nợ phải trả và vốn chủ sở hữu đều tăng qua các năm, trong đó nguồn vốn huy động vẫn chiếm tỷ trọng lớn. Doanh thu từ hoạt động cốt lõi và lợi nhuận sau thuế đều tăng, đặc biệt sau năm 2021, phản ánh khả năng mở rộng quy mô và hiệu quả kinh doanh ngày càng được cải thiện.

  • Về biên lợi nhuận, chỉ số NIM duy trì ở mức ổn định quanh 2,3–2,7% nhưng có thời điểm chịu áp lực do chi phí vốn tăng nhanh, trong khi NPM cải thiện rõ rệt nhờ kiểm soát chi phí tốt hơn. Các khoản mục thanh khoản như tiền mặt, vàng bạc, đá quý tăng theo chu kỳ, còn lợi nhuận ngoại hối – vàng biến động, cho thấy mức nhạy cảm nhất định với điều kiện thị trường tài chính.

  • Tổng thể, BIDV giữ được đà tăng trưởng bền vững và duy trì biên lợi nhuận dương. Tuy nhiên, ngân hàng cần tiếp tục giảm chi phí vốn, mở rộng thu nhập ngoài lãi và nâng cao hiệu quả sử dụng tài sản. Trọng tâm đề xuất là tăng tỷ lệ tiền gửi không kỳ hạn (CASA) để giảm chi phí huy động, phát triển dịch vụ và ngân hàng số nhằm đa dạng nguồn thu, đồng thời kiểm soát chặt chi phí và rủi ro để bảo vệ NIM, NPM và duy trì tăng trưởng lợi nhuận ổn định trong các năm tới.

16 Tài liệu tham khảo

  • Trần Mạnh Tường(2025). Data manipulation và Data Visualization

  • Nghĩa, H. P. TPP & NHỮNG TÁC ĐỘNG ĐẾN THỊ TRƯỜNG BẤT ĐỘNG SẢN VIỆT NAM.

  • Vương, Q. H., Nguyễn, H. S., & Trần, T. D. (2008). Hậu quả của tín dụng bất động sản ở Mỹ và nghĩ về các biện pháp phòng ngừa ở Việt Nam.

  • CHÍNH, T. PHÂN TÍCH HIỆU QUẢ HOẠT ĐỘNG CÙA CÁC NGÂN HÀNG THƯƠNG MẠI có PHÁN TẠI VIỆT NAM.

  • Ha Nam Khanh, G., & Chau, T. K. (2020). Nhân tố ảnh hưởng đến quyết định sử dụng dịch vụ smartbanking-Nghiên cứu thực nghiệm tại BIDV-Chi nhánh Bắc Sài gòn (The Factors Affect on the Decision of Using Smart Banking Service at Bank of Investment and Development of Viet Nam-North Saigon Branch). Tạp chí Khoa học & Đào tạo Ngân hàng-Số.