CHƯƠNG I. PHÂN TÍCH DỮ LIỆU Ô TÔ BẰNG NGÔN NGỮ R

1. PHẦN MỞ ĐẦU

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

Trong thời đại công nghiệp 4.0 và chuyển đổi số, dữ liệu trở thành nguồn tài nguyên chiến lược quan trọng đối với mọi lĩnh vực của nền kinh tế. Việc thu thập, phân tích và khai thác dữ liệu giúp các tổ chức, doanh nghiệp và cá nhân đưa ra quyết định dựa trên bằng chứng (data-driven decisions) thay vì cảm tính.

Một trong những lĩnh vực chịu tác động mạnh mẽ của làn sóng dữ liệu đó là ngành công nghiệp ô tô – nơi mà mỗi chiếc xe không chỉ đại diện cho phương tiện di chuyển mà còn phản ánh xu hướng tiêu dùng, hành vi thị trường, và năng lực cạnh tranh của doanh nghiệp.

Giá xe là một yếu tố kinh tế quan trọng, chịu ảnh hưởng bởi nhiều khía cạnh như:

  • Đặc điểm kỹ thuật: hãng sản xuất, công suất động cơ, năm sản xuất, loại nhiên liệu, hệ dẫn động, kiểu hộp số,…

  • Yếu tố sử dụng: số km đã đi, số chủ sở hữu, tình trạng xe,…

  • Yếu tố thị trường: độ phổ biến thương hiệu, loại người bán, màu sắc xe, và tình trạng khấu hao.

Trong bối cảnh dữ liệu về thị trường ô tô ngày càng đa dạng và phong phú, việc phân tích dữ liệu giá xe bằng các công cụ khoa học dữ liệu trở nên cần thiết, giúp:

Hiểu rõ quy luật hình thành giá bán của xe,

Xác định yếu tố nào tác động mạnh nhất đến giá,

Và cung cấp thông tin hỗ trợ ra quyết định cho người tiêu dùng, nhà sản xuất và nhà quản lý.

Ngôn ngữ R — một công cụ mạnh mẽ trong lĩnh vực phân tích thống kê và trực quan hóa dữ liệu — cho phép thực hiện các phép tính, kiểm định, và biểu diễn dữ liệu một cách khoa học, sinh động và dễ hiểu. Việc vận dụng R để phân tích dữ liệu thực tế về giá xe không chỉ giúp người học rèn luyện kỹ năng lập trình và tư duy dữ liệu, mà còn minh chứng cho khả năng ứng dụng của khoa học dữ liệu trong kinh tế và kỹ thuật.

Chính vì vậy, đề tài “Phân tích dữ liệu giá xe bằng ngôn ngữ R” được lựa chọn với mong muốn:

  • Ứng dụng kiến thức về xử lý dữ liệu, thống kê và trực quan hóa,

  • Hiểu sâu hơn bản chất của các yếu tố tác động đến giá xe,

  • Và khẳng định vai trò của R trong việc giải quyết các bài toán phân tích dữ liệu thực tế.

Nghiên cứu này không chỉ mang ý nghĩa học thuật, mà còn có giá trị thực tiễn cao trong việc:

  • Hỗ trợ người tiêu dùng đưa ra quyết định mua xe hợp lý,

  • Giúp các doanh nghiệp hiểu rõ xu hướng định giá thị trường,

  • Và góp phần thúc đẩy tư duy khoa học dữ liệu trong lĩnh vực kinh tế – kỹ thuật..

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

Mục tiêu của đề tài là tiến hành phân tích toàn diện dữ liệu giá xe ô tô nhằm khám phá, mô tả và làm sáng tỏ mối quan hệ giữa các yếu tố kỹ thuật, đặc tính sử dụng và giá trị thị trường của xe. Thông qua việc khai thác bộ dữ liệu lớn và đa dạng về thông tin như hãng xe, mẫu xe, năm sản xuất, loại nhiên liệu, hệ dẫn động, số km đã đi, tình trạng xe và giá bán, nghiên cứu hướng đến việc hiểu sâu cấu trúc dữ liệu, đồng thời xác định các yếu tố có ảnh hưởng đáng kể đến giá xe.

Cụ thể hơn, nghiên cứu tập trung vào việc làm sạch, xử lý và chuẩn hóa dữ liệu để đảm bảo độ tin cậy cho các phép phân tích thống kê. Sau đó, đề tài tiến hành phân tích mô tả thống kê nhằm xác định xu hướng trung tâm, độ phân tán và hình dạng phân phối của các biến liên quan đến giá bán. Việc khám phá mối tương quan giữa các yếu tố định lượng như công suất động cơ, quãng đường đã sử dụng hay tuổi xe với giá bán sẽ giúp nhận diện những mối quan hệ tiềm ẩn mà dữ liệu có thể tiết lộ.

Song song với đó, đề tài sử dụng các kỹ thuật trực quan hóa dữ liệu hiện đại trong ngôn ngữ R, như biểu đồ phân phối (histogram), biểu đồ hộp (boxplot), biểu đồ mật độ (density plot), biểu đồ tán xạ (scatter plot) hay biểu đồ tương quan (correlation heatmap). Những hình thức biểu diễn này không chỉ giúp người đọc dễ dàng nhận thấy các xu hướng và mẫu hình (patterns) trong dữ liệu, mà còn hỗ trợ diễn giải các kết quả thống kê một cách trực quan, sinh động và khoa học.

Bên cạnh khía cạnh kỹ thuật, nghiên cứu còn hướng đến việc đưa ra các nhận định có giá trị thực tiễn. Qua quá trình phân tích, đề tài làm rõ những yếu tố có khả năng tác động mạnh đến giá bán — chẳng hạn như loại nhiên liệu, hệ truyền động, hay loại người bán — và xem xét cách các yếu tố này góp phần hình thành nên giá trị thị trường của xe ô tô cũ. Điều này không chỉ giúp người tiêu dùng hiểu rõ hơn về giá trị thực của xe khi mua bán, mà còn cung cấp thông tin hữu ích cho các đại lý, nhà sản xuất hoặc nhà phân tích thị trường trong việc xây dựng chiến lược định giá phù hợp.

Về mặt học thuật, đề tài góp phần ứng dụng ngôn ngữ R trong phân tích dữ liệu thực tiễn, giúp người học củng cố kỹ năng xử lý, thống kê và trực quan hóa dữ liệu. Việc triển khai đề tài trên một bộ dữ liệu lớn, thực tế và có tính đa chiều như vehicle_price_prediction.csv cũng là minh chứng cho khả năng của R trong việc xử lý dữ liệu phức tạp, khẳng định vai trò của khoa học dữ liệu trong việc biến dữ liệu thô thành thông tin có ý nghĩa phục vụ cho việc ra quyết định.

1.3. Phương pháp nghiên cứu

Đề tài được thực hiện dựa trên phương pháp nghiên cứu định lượng, kết hợp với phân tích thống kê mô tả và khai phá dữ liệu (exploratory data analysis). Trọng tâm của phương pháp nghiên cứu là phân tích, trực quan hóa và diễn giải dữ liệu nhằm làm sáng tỏ mối quan hệ giữa các yếu tố đặc trưng của xe và giá bán trên thị trường.

Quá trình nghiên cứu bắt đầu bằng việc thu thập và nhập dữ liệu từ tệp vehicle_price_prediction.csv, một bộ dữ liệu lớn với một triệu quan sát và hai mươi biến, phản ánh thông tin về đặc tính kỹ thuật, tình trạng và yếu tố giao dịch của xe ô tô. Sau khi dữ liệu được nhập, bước tiếp theo là làm sạch và chuẩn hóa, bao gồm kiểm tra giá trị thiếu, loại bỏ dữ liệu trùng lặp, chuyển đổi kiểu dữ liệu, và mã hóa các biến định tính về dạng thích hợp để phục vụ cho phân tích thống kê.

Khi dữ liệu đã sẵn sàng, đề tài tiến hành phân tích thống kê mô tả nhằm nhận diện các đặc điểm tổng quát của tập dữ liệu. Các chỉ số trung tâm (mean, median), độ phân tán (variance, standard deviation), và hình dạng phân phối (skewness, kurtosis) được sử dụng để đánh giá cấu trúc và xu hướng biến thiên của dữ liệu. Đồng thời, ma trận tương quan được xây dựng để đo lường mức độ quan hệ tuyến tính giữa các biến định lượng như công suất động cơ, số km đã đi và giá bán.

Một phần quan trọng khác trong phương pháp nghiên cứu là trực quan hóa dữ liệu bằng công cụ đồ họa trong ngôn ngữ R, đặc biệt là gói ggplot2. Các loại biểu đồ như histogram, boxplot, scatter plot, violin plot, và biểu đồ mật độ được triển khai để minh họa xu hướng, sự khác biệt và tương quan giữa các biến. Trực quan hóa giúp không chỉ phát hiện các mẫu hình dữ liệu mà còn hỗ trợ diễn giải kết quả một cách sinh động, trực quan và dễ hiểu.

Bên cạnh đó, nghiên cứu còn vận dụng các phép kiểm định thống kê cơ bản nhằm củng cố các kết luận mô tả. Các thao tác được thực hiện một cách có hệ thống và minh bạch trong môi trường R, giúp đảm bảo tính chính xác, khả năng tái lập và độ tin cậy của kết quả. Như vậy, phương pháp nghiên cứu của đề tài không chỉ tập trung vào kết quả số học, mà còn chú trọng đến quy trình khoa học và cách thức diễn giải, nhằm thể hiện tư duy phân tích dữ liệu một cách toàn diện.

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

Đối tượng nghiên cứu của đề tài là tập dữ liệu về giá xe ô tô chứa trong tệp vehicle_price_prediction.csv. Bộ dữ liệu bao gồm các thông tin đa dạng phản ánh đặc điểm kỹ thuật, yếu tố sử dụng và thông tin giao dịch của từng xe. Cụ thể, các biến trong dữ liệu thể hiện các khía cạnh như hãng xe (make), mẫu xe (model), năm sản xuất (year), công suất động cơ (engine_hp), quãng đường đã sử dụng (mileage), loại nhiên liệu (fuel_type), loại hộp số (transmission), tình trạng xe (condition), số chủ sở hữu (owner_count), loại người bán (seller_type) và giá bán (price).

Phạm vi nghiên cứu của đề tài giới hạn trong việc phân tích và mô tả dữ liệu, không bao gồm mô hình hóa hoặc dự báo giá xe bằng thuật toán học máy. Nghiên cứu chỉ tập trung vào các yếu tố nội tại của xe có trong dữ liệu, không xét đến các yếu tố kinh tế vĩ mô hoặc thị trường bên ngoài như thuế, khu vực địa lý hay thời điểm bán. Bằng cách giới hạn phạm vi như vậy, nghiên cứu đảm bảo tính tập trung, giúp khai thác triệt để giá trị thông tin sẵn có trong dữ liệu, đồng thời mang lại cái nhìn rõ ràng về các yếu tố ảnh hưởng trực tiếp đến giá xe.

Bên cạnh đó, dữ liệu được giả định là đã được thu thập và xử lý sơ bộ ở mức đảm bảo chất lượng, do đó nghiên cứu không đi sâu vào quy trình thu thập mà tập trung vào khai thác, phân tích và trình bày dữ liệu một cách khoa học. Tất cả các phép phân tích đều được thực hiện trong môi trường RStudio, sử dụng các gói công cụ hiện đại như tidyverse, dplyr, ggplot2, skimr, và psych để đảm bảo tính chính xác và hiệu quả.

1.5. Kết cấu đề tài

Đề tài được bố cục thành hai phần chính, bao gồm Phần Mở đầu và Phần Nội dung, nhằm đảm bảo tính logic và thống nhất trong quá trình trình bày.

Phần Mở đầu trình bày cơ sở lý luận và định hướng nghiên cứu của đề tài, bao gồm các nội dung: lý do chọn đề tài, mục tiêu nghiên cứu, phương pháp nghiên cứu, đối tượng và phạm vi nghiên cứu. Cụ thể, phần này giải thích lý do lựa chọn chủ đề phân tích dữ liệu ô tô, nêu rõ mục tiêu chính là làm sạch, xử lý và trực quan hóa dữ liệu nhằm khám phá mối quan hệ giữa các biến như giá xe (Price), hãng xe (Make), năm sản xuất (Year), quãng đường đã đi (Mileage), công suất (Horsepower), v.v. Đồng thời, phần này cũng trình bày phương pháp nghiên cứu được áp dụng – sử dụng ngôn ngữ R cùng các thư viện phổ biến như dplyr, tidyr và ggplot2 – để tiến hành tiền xử lý dữ liệu, mã hóa biến, phân tích thống kê và trực quan hóa kết quả.

Phần Nội dung là trọng tâm của đề tài, tập trung vào quá trình xử lý, phân tích và biểu diễn dữ liệu, được chia thành bốn chương chính như sau:

Chương 1: Giới thiệu tổng quan về bộ dữ liệu. Chương này trình bày các bước nạp thư viện cần thiết, giới thiệu cấu trúc bộ dữ liệu, khám phá các biến, kiểm tra giá trị thiếu và dữ liệu trùng lặp, đồng thời mô tả thống kê sơ bộ các biến định lượng và định tính.

Chương 2: Xử lý dữ liệu và mã hóa biến. Phần này tập trung vào việc làm sạch dữ liệu, chuẩn hóa đơn vị đo lường, mã hóa biến định tính, tạo biến mới (như biến hiệu suất hp_per_dollar), nhóm lại các giá trị, sắp xếp và lọc dữ liệu để phục vụ cho các bước phân tích tiếp theo.

Chương 3: Phân tích thống kê cơ bản. Chương này tiến hành phân tích mô tả các biến quan trọng như Price, Make, Mileage và Year thông qua các chỉ số trung bình, phương sai, độ lệch chuẩn và tần suất. Ngoài ra, chương còn phân tích mối tương quan giữa các biến và thực hiện so sánh theo nhóm (ví dụ: so sánh giá trung bình giữa các hãng xe hoặc giữa các năm sản xuất).

Chương 4: Trực quan hóa dữ liệu. Phần cuối cùng trình bày các dạng biểu đồ minh họa kết quả phân tích như biểu đồ phân phối, biểu đồ hộp (boxplot), biểu đồ tán xạ (scatter plot), biểu đồ tương quan (correlation plot) và biểu đồ so sánh nhóm. Thông qua đó, người đọc có thể dễ dàng quan sát xu hướng, mối liên hệ giữa các yếu tố và các nhân tố ảnh hưởng đến giá xe.

Cuối cùng, phần Kết luận tổng hợp toàn bộ kết quả đã đạt được, đánh giá hiệu quả của quá trình xử lý và phân tích dữ liệu, đồng thời nêu ra những hạn chế còn tồn tại và đề xuất hướng phát triển cho các nghiên cứu tiếp theo.

2. PHÂN TÍCH BỘ DỮ LIỆU GIÁ XE HƠI

2.1. Giới thiệu tổng quan về bộ dữ liệu

2.1.1. Nạp thư viện cần thiết

library(dplyr) 
## Warning: package 'dplyr' was built under R version 4.5.1
## 
## Attaching package: 'dplyr'
## The following objects are masked from 'package:stats':
## 
##     filter, lag
## The following objects are masked from 'package:base':
## 
##     intersect, setdiff, setequal, union
library(readr) 
## Warning: package 'readr' was built under R version 4.5.1
library(psych)
## Warning: package 'psych' was built under R version 4.5.1
library(ggplot2) 
## Warning: package 'ggplot2' was built under R version 4.5.1
## 
## Attaching package: 'ggplot2'
## The following objects are masked from 'package:psych':
## 
##     %+%, alpha

Đoạn mã được sử dụng nhằm cài đặt, nạp và đọc dữ liệu phục vụ cho việc phân tích bộ dữ liệu vehicle_price_prediction.csv trong R. Đây là bước đầu tiên trong quy trình xử lý dữ liệu, giúp thiết lập môi trường làm việc và đưa bộ dữ liệu gốc vào hệ thống để chuẩn bị cho các thao tác phân tích thống kê và trực quan hóa.

Đầu tiên là nạp các thư viện đã cài bằng lệnh library(). Khi nạp thành công, R sẽ kích hoạt toàn bộ các hàm có trong từng gói, cho phép người dùng sử dụng trực tiếp mà không cần khai báo đường dẫn. Cụ thể, library(dplyr) nạp gói hỗ trợ thao tác dữ liệu như lọc (filter()), nhóm (group_by()), và tóm tắt (summarise()). Gói readr được gọi để sử dụng hàm read_csv() – hàm chính để đọc tệp dữ liệu dạng văn bản phân tách bằng dấu phẩy. Cuối cùng, gói psych được kích hoạt nhằm chuẩn bị cho phần phân tích thống kê mô tả chi tiết trong các bước sau. Ba lệnh này không tạo ra kết quả hiển thị cụ thể nhưng là nền tảng kỹ thuật quan trọng giúp R hiểu và sử dụng đúng các hàm trong quá trình xử lý dữ liệu.

vehicle_data <- read_csv("C:/Users/HONG GAM/Downloads/vehicle_price_prediction.csv")
## Rows: 1000000 Columns: 20
## ── Column specification ────────────────────────────────────────────────────────
## Delimiter: ","
## chr (12): make, model, transmission, fuel_type, drivetrain, body_type, exter...
## dbl  (8): year, mileage, engine_hp, owner_count, vehicle_age, mileage_per_ye...
## 
## ℹ Use `spec()` to retrieve the full column specification for this data.
## ℹ Specify the column types or set `show_col_types = FALSE` to quiet this message.
View(vehicle_data)

Hàm read_csv() thuộc gói readr có nhiệm vụ đọc tệp dữ liệu vehicle_price_prediction.csv từ đường dẫn chỉ định trên máy tính. Tên tệp nằm trong dấu ngoặc kép và đi kèm với đường dẫn tuyệt đối để R có thể truy cập đúng vị trí của tệp. Ký hiệu <- là toán tử gán trong R, được hiểu là “gán kết quả của hàm bên phải cho đối tượng bên trái”. Như vậy, toàn bộ dữ liệu được đọc từ tệp sẽ được lưu vào một đối tượng mới có tên là vehicle_data. Đây là một data frame – dạng cấu trúc dữ liệu bảng trong R, gồm các hàng (quan sát) và cột (biến).

Khi lệnh này được thực thi, R sẽ tự động nhận dạng kiểu dữ liệu của từng cột trong tệp. Những cột chứa chữ (ví dụ: make, model, fuel_type) sẽ được xác định là kiểu character, còn các cột chứa số (như year, mileage, price) sẽ được đọc dưới dạng numeric hoặc double. Sau khi đọc xong, R sẽ hiển thị một phần thông tin mô tả gồm số lượng cột và kiểu dữ liệu tương ứng. Đây là một đặc điểm đặc trưng của hàm read_csv() giúp người dùng kiểm tra nhanh xem dữ liệu đã được đọc đúng định dạng hay chưa.

2.1.2. Giới thiệu bộ dữ liệu

nrow(vehicle_data) 
## [1] 1000000
ncol(vehicle_data) 
## [1] 20
dim(vehicle_data)
## [1] 1000000      20

Về mặt kỹ thuật, hàm nrow() trong R có chức năng đếm số hàng (rows) trong một đối tượng dữ liệu kiểu data frame, tức là số lượng quan sát hoặc bản ghi trong tập dữ liệu. Kết quả [1] 1000000 cho biết bộ dữ liệu đang phân tích có tổng cộng 1.000.000 quan sát, nghĩa là có một triệu dòng dữ liệu, mỗi dòng tương ứng với thông tin của một chiếc xe cụ thể. Tương tự, hàm ncol() dùng để đếm số cột (columns) của bộ dữ liệu, tức là số lượng biến (variables) hoặc đặc trưng được ghi nhận cho mỗi quan sát. Kết quả [1] 20 cho thấy mỗi xe được mô tả bởi 20 biến khác nhau, phản ánh nhiều khía cạnh từ đặc tính kỹ thuật, tình trạng sử dụng cho đến yếu tố kinh tế và thị trường. dim() là thao tác kiểm tra kích thước ban đầu, giúp xác nhận rằng dữ liệu đã được đọc đầy đủ vào bộ nhớ. Nếu kết quả của hàm này trùng khớp với kích thước mong đợi (ở đây là 1.000.000 dòng và 20 cột), điều đó chứng tỏ rằng quá trình nạp dữ liệu từ tệp CSV đã thành công và không xảy ra lỗi mất mát thông tin trong quá trình nhập.

Những hàm này là những thao tác cơ bản nhưng đóng vai trò cực kỳ quan trọng trong khâu kiểm tra dữ liệu ban đầu. Về kỹ thuật, việc xác định đúng số hàng và số cột giúp đảm bảo rằng dữ liệu đã được đọc đầy đủ và không bị lỗi nhập liệu trong quá trình nạp từ file CSV. Nếu số hàng hoặc số cột trả về thấp hơn so với kỳ vọng, điều đó có thể báo hiệu dữ liệu bị thiếu dòng, cột hoặc lỗi tách giá trị khi đọc tệp. Ngược lại, khi kết quả hiển thị đúng 1.000.000 hàng và 20 cột, ta có thể khẳng định rằng toàn bộ dữ liệu đã được nhập chính xác và đầy đủ vào môi trường làm việc của R.

Về mặt ý nghĩa thống kê, kết quả này cung cấp cái nhìn định lượng đầu tiên về kích thước mẫu (sample size) và độ phức tạp của bộ dữ liệu. Số lượng 1.000.000 quan sát thể hiện một quy mô dữ liệu rất lớn, đủ để tiến hành các phân tích thống kê mô tả và kiểm định có ý nghĩa thực tiễn cao. Với quy mô mẫu lớn như vậy, các chỉ số thống kê như trung bình, trung vị, độ lệch chuẩn… có độ ổn định cao và ít chịu ảnh hưởng của sai số ngẫu nhiên. Số lượng 20 biến cũng cho thấy dữ liệu có tính đa chiều (multivariate), tức là mỗi xe được mô tả bởi nhiều đặc tính khác nhau. Điều này giúp cho việc phân tích có chiều sâu hơn, vì ta có thể xem xét đồng thời ảnh hưởng của nhiều yếu tố — chẳng hạn, mối quan hệ giữa giá xe và các biến như year, mileage, fuel_type, hoặc brand_popularity.

2.1.3. Mô tả các biến trong bộ dữ liệu

variable_description <- data.frame(
  Variable = c(
    "make", "model", "year", "mileage", "engine_hp",
    "transmission", "fuel_type", "drivetrain", "body_type",
    "exterior_color", "interior_color", "owner_count",
    "accident_history", "seller_type", "condition",
    "trim", "vehicle_age", "mileage_per_year",
    "brand_popularity", "price"
  ),
  
  Description = c(
    "Hãng sản xuất của xe (ví dụ: Toyota, Honda, Ford...).",
    "Mẫu xe cụ thể của hãng (ví dụ: Civic, Corolla, Focus...).",
    "Năm sản xuất của xe, được sử dụng để tính tuổi xe và giá trị khấu hao.",
    "Số km xe đã đi được kể từ khi mua, thể hiện mức độ sử dụng.",
    "Công suất động cơ (mã lực), phản ánh khả năng vận hành của xe.",
    "Loại hộp số (tự động, sàn, bán tự động...).",
    "Loại nhiên liệu sử dụng (xăng, dầu diesel, điện, hybrid...).",
    "Hệ dẫn động của xe (FWD, RWD, AWD...).",
    "Kiểu thân xe (sedan, SUV, hatchback, coupe...).",
    "Màu sơn bên ngoài của xe.",
    "Màu nội thất bên trong của xe.",
    "Số lượng chủ sở hữu trước đó, phản ánh lịch sử sử dụng.",
    "Thông tin về tình trạng tai nạn của xe (đã từng bị tai nạn hay chưa).",
    "Loại người bán (chính chủ, đại lý, bên thứ ba...).",
    "Tình trạng hiện tại của xe (Excellent, Good, Fair, Poor...).",
    "Phiên bản hoặc cấp độ trang bị của xe (Base, LX, Sport...).",
    "Tuổi xe tính theo năm hiện tại trừ năm sản xuất.",
    "Quãng đường xe đi trung bình mỗi năm (mileage / vehicle_age).",
    "Mức độ phổ biến thương hiệu trên thị trường (giá trị chuẩn hóa).",
    "Giá bán xe (đơn vị tiền tệ, thường là USD)."
  )
)
print(variable_description)
##            Variable
## 1              make
## 2             model
## 3              year
## 4           mileage
## 5         engine_hp
## 6      transmission
## 7         fuel_type
## 8        drivetrain
## 9         body_type
## 10   exterior_color
## 11   interior_color
## 12      owner_count
## 13 accident_history
## 14      seller_type
## 15        condition
## 16             trim
## 17      vehicle_age
## 18 mileage_per_year
## 19 brand_popularity
## 20            price
##                                                               Description
## 1                   Hãng sản xuất của xe (ví dụ: Toyota, Honda, Ford...).
## 2               Mẫu xe cụ thể của hãng (ví dụ: Civic, Corolla, Focus...).
## 3  Năm sản xuất của xe, được sử dụng để tính tuổi xe và giá trị khấu hao.
## 4             Số km xe đã đi được kể từ khi mua, thể hiện mức độ sử dụng.
## 5          Công suất động cơ (mã lực), phản ánh khả năng vận hành của xe.
## 6                             Loại hộp số (tự động, sàn, bán tự động...).
## 7            Loại nhiên liệu sử dụng (xăng, dầu diesel, điện, hybrid...).
## 8                                  Hệ dẫn động của xe (FWD, RWD, AWD...).
## 9                         Kiểu thân xe (sedan, SUV, hatchback, coupe...).
## 10                                              Màu sơn bên ngoài của xe.
## 11                                         Màu nội thất bên trong của xe.
## 12                Số lượng chủ sở hữu trước đó, phản ánh lịch sử sử dụng.
## 13  Thông tin về tình trạng tai nạn của xe (đã từng bị tai nạn hay chưa).
## 14                     Loại người bán (chính chủ, đại lý, bên thứ ba...).
## 15           Tình trạng hiện tại của xe (Excellent, Good, Fair, Poor...).
## 16            Phiên bản hoặc cấp độ trang bị của xe (Base, LX, Sport...).
## 17                       Tuổi xe tính theo năm hiện tại trừ năm sản xuất.
## 18          Quãng đường xe đi trung bình mỗi năm (mileage / vehicle_age).
## 19       Mức độ phổ biến thương hiệu trên thị trường (giá trị chuẩn hóa).
## 20                            Giá bán xe (đơn vị tiền tệ, thường là USD).
library(knitr)
kable(variable_description, caption = "Bảng mô tả các biến trong dữ liệu giá xe")
Bảng mô tả các biến trong dữ liệu giá xe
Variable Description
make Hãng sản xuất của xe (ví dụ: Toyota, Honda, Ford…).
model Mẫu xe cụ thể của hãng (ví dụ: Civic, Corolla, Focus…).
year Năm sản xuất của xe, được sử dụng để tính tuổi xe và giá trị khấu hao.
mileage Số km xe đã đi được kể từ khi mua, thể hiện mức độ sử dụng.
engine_hp Công suất động cơ (mã lực), phản ánh khả năng vận hành của xe.
transmission Loại hộp số (tự động, sàn, bán tự động…).
fuel_type Loại nhiên liệu sử dụng (xăng, dầu diesel, điện, hybrid…).
drivetrain Hệ dẫn động của xe (FWD, RWD, AWD…).
body_type Kiểu thân xe (sedan, SUV, hatchback, coupe…).
exterior_color Màu sơn bên ngoài của xe.
interior_color Màu nội thất bên trong của xe.
owner_count Số lượng chủ sở hữu trước đó, phản ánh lịch sử sử dụng.
accident_history Thông tin về tình trạng tai nạn của xe (đã từng bị tai nạn hay chưa).
seller_type Loại người bán (chính chủ, đại lý, bên thứ ba…).
condition Tình trạng hiện tại của xe (Excellent, Good, Fair, Poor…).
trim Phiên bản hoặc cấp độ trang bị của xe (Base, LX, Sport…).
vehicle_age Tuổi xe tính theo năm hiện tại trừ năm sản xuất.
mileage_per_year Quãng đường xe đi trung bình mỗi năm (mileage / vehicle_age).
brand_popularity Mức độ phổ biến thương hiệu trên thị trường (giá trị chuẩn hóa).
price Giá bán xe (đơn vị tiền tệ, thường là USD).

Bảng trên mô tả chi tiết các biến trong bộ dữ liệu giá xe, cung cấp thông tin nền tảng giúp hiểu rõ cấu trúc và ý nghĩa của từng biến trước khi tiến hành phân tích thống kê. Về mặt kỹ thuật, bảng được tạo bằng hàm data.frame() trong R với hai cột chính: “Variable” chứa tên biến và “Description” mô tả nội dung, phạm vi hoặc đơn vị đo lường của từng biến. Sau đó, bảng được hiển thị bằng hàm kable() thuộc gói knitr, giúp trình bày kết quả ở định dạng đẹp và dễ đọc trong báo cáo. Cấu trúc này được gọi là bảng metadata (siêu dữ liệu), có vai trò quan trọng trong việc xác định chức năng và vai trò của từng biến trong các bước xử lý, phân tích hoặc xây dựng mô hình dự đoán.

Về nội dung, bảng gồm 20 biến chính, được chia thành bốn nhóm thông tin cơ bản. Nhóm thứ nhất là đặc điểm nhận dạng của xe, bao gồm các biến như make (hãng xe), model (mẫu xe), year (năm sản xuất) và body_type (kiểu dáng thân xe), giúp phân biệt và phân loại các dòng xe khác nhau. Nhóm thứ hai là đặc điểm kỹ thuật, gồm các biến như engine_hp (công suất động cơ), transmission (hộp số), drivetrain (hệ dẫn động) và fuel_type (loại nhiên liệu) – đây là những yếu tố có ảnh hưởng trực tiếp đến hiệu năng, chi phí vận hành và giá trị của xe. Nhóm thứ ba phản ánh tình trạng và lịch sử sử dụng xe, bao gồm mileage (số km đã đi), owner_count (số chủ sở hữu), accident_history (lịch sử tai nạn) và condition (tình trạng hiện tại của xe). Các biến này là cơ sở để đánh giá mức độ hao mòn, rủi ro và tuổi thọ thực tế của phương tiện. Cuối cùng, nhóm thứ tư là biến kinh tế và chỉ số phụ trợ, như brand_popularity (độ phổ biến thương hiệu), vehicle_age (tuổi xe), mileage_per_year (số dặm trung bình mỗi năm) và price (giá bán xe). Các biến này thường được tính toán hoặc chuẩn hóa để phục vụ cho mô hình định giá và phân tích xu hướng thị trường.

2.1.4. Khám phá sơ bộ cấu trúc dữ liệu

head(vehicle_data)
## # A tibble: 6 × 20
##   make       model      year mileage engine_hp transmission fuel_type drivetrain
##   <chr>      <chr>     <dbl>   <dbl>     <dbl> <chr>        <chr>     <chr>     
## 1 Volkswagen Jetta      2016  183903       173 Manual       Electric  RWD       
## 2 Lexus      RX         2010  236643       352 Manual       Gasoline  FWD       
## 3 Subaru     Crosstrek  2016  103199       188 Automatic    Diesel    AWD       
## 4 Cadillac   Lyriq      2016  118889       338 Manual       Gasoline  AWD       
## 5 Toyota     Highland…  2018  204170       196 Manual       Diesel    FWD       
## 6 Land Rover Defender   2021   44907       479 Manual       Diesel    RWD       
## # ℹ 12 more variables: body_type <chr>, exterior_color <chr>,
## #   interior_color <chr>, owner_count <dbl>, accident_history <chr>,
## #   seller_type <chr>, condition <chr>, trim <chr>, vehicle_age <dbl>,
## #   mileage_per_year <dbl>, brand_popularity <dbl>, price <dbl>

Lệnh head(vehicle_data) được sử dụng để hiển thị 6 dòng đầu tiên của bộ dữ liệu, giúp người phân tích xem nhanh nội dung thực tế sau khi dữ liệu được nạp vào R. Về mặt kỹ thuật, đây là thao tác quan trọng để kiểm tra dữ liệu có được đọc đúng định dạng hay không, chẳng hạn như xác nhận xem các cột chữ (make, model, fuel_type) được nhận dạng là dạng ký tự, còn các cột số (year, mileage, price) là dạng số. Nếu dữ liệu hiển thị đúng và không bị lỗi mã hóa hoặc giá trị rỗng, điều đó chứng tỏ quá trình nhập liệu từ tệp CSV đã thành công.

head() cho phép người nghiên cứu quan sát sơ bộ đặc điểm và tính hợp lý của dữ liệu. Từ những dòng đầu tiên, ta có thể nhận thấy mỗi quan sát đại diện cho một chiếc xe cùng các biến mô tả về kỹ thuật, tình trạng và giá bán. Điều này giúp hình thành cái nhìn tổng quát ban đầu về bộ dữ liệu, xác định loại biến, và chuẩn bị cho các bước thống kê mô tả, làm sạch, hoặc trực quan hóa trong các phần sau.

str(vehicle_data)
## spc_tbl_ [1,000,000 × 20] (S3: spec_tbl_df/tbl_df/tbl/data.frame)
##  $ make            : chr [1:1000000] "Volkswagen" "Lexus" "Subaru" "Cadillac" ...
##  $ model           : chr [1:1000000] "Jetta" "RX" "Crosstrek" "Lyriq" ...
##  $ year            : num [1:1000000] 2016 2010 2016 2016 2018 ...
##  $ mileage         : num [1:1000000] 183903 236643 103199 118889 204170 ...
##  $ engine_hp       : num [1:1000000] 173 352 188 338 196 479 160 172 197 198 ...
##  $ transmission    : chr [1:1000000] "Manual" "Manual" "Automatic" "Manual" ...
##  $ fuel_type       : chr [1:1000000] "Electric" "Gasoline" "Diesel" "Gasoline" ...
##  $ drivetrain      : chr [1:1000000] "RWD" "FWD" "AWD" "AWD" ...
##  $ body_type       : chr [1:1000000] "Sedan" "Sedan" "Sedan" "SUV" ...
##  $ exterior_color  : chr [1:1000000] "Blue" "Silver" "Silver" "Black" ...
##  $ interior_color  : chr [1:1000000] "Brown" "Beige" "Beige" "Gray" ...
##  $ owner_count     : num [1:1000000] 5 5 5 3 5 5 1 5 3 1 ...
##  $ accident_history: chr [1:1000000] "None" "Minor" "None" "None" ...
##  $ seller_type     : chr [1:1000000] "Dealer" "Dealer" "Dealer" "Private" ...
##  $ condition       : chr [1:1000000] "Excellent" "Good" "Excellent" "Good" ...
##  $ trim            : chr [1:1000000] "EX" "LX" "Touring" "Base" ...
##  $ vehicle_age     : num [1:1000000] 9 15 9 9 7 4 7 3 10 1 ...
##  $ mileage_per_year: num [1:1000000] 20434 15776 11467 13210 29167 ...
##  $ brand_popularity: num [1:1000000] 0.0401 0.0399 0.0402 0.0398 0.0396 ...
##  $ price           : num [1:1000000] 7209 6912 11916 25985 8151 ...
##  - attr(*, "spec")=
##   .. cols(
##   ..   make = col_character(),
##   ..   model = col_character(),
##   ..   year = col_double(),
##   ..   mileage = col_double(),
##   ..   engine_hp = col_double(),
##   ..   transmission = col_character(),
##   ..   fuel_type = col_character(),
##   ..   drivetrain = col_character(),
##   ..   body_type = col_character(),
##   ..   exterior_color = col_character(),
##   ..   interior_color = col_character(),
##   ..   owner_count = col_double(),
##   ..   accident_history = col_character(),
##   ..   seller_type = col_character(),
##   ..   condition = col_character(),
##   ..   trim = col_character(),
##   ..   vehicle_age = col_double(),
##   ..   mileage_per_year = col_double(),
##   ..   brand_popularity = col_double(),
##   ..   price = col_double()
##   .. )
##  - attr(*, "problems")=<externalptr>

Lệnh str(vehicle_data) được dùng để xem cấu trúc tổng quát của bộ dữ liệu. Kết quả hiển thị cho biết đối tượng vehicle_data là một bảng dữ liệu (data frame) có 1.000.000 quan sát và 20 biến. Mỗi biến (cột) được liệt kê kèm theo kiểu dữ liệu và một vài giá trị mẫu.

Trong kết quả trên, ta thấy rằng phần lớn các biến như make, model, transmission, fuel_type, drivetrain, body_type, condition, seller_type… có kiểu ký tự (chr), tức là các biến định tính mô tả đặc điểm phân loại của xe. Các biến còn lại như year, mileage, engine_hp, owner_count, vehicle_age, mileage_per_year, brand_popularity, và price có kiểu số thực (num), đại diện cho dữ liệu định lượng có thể dùng cho các phép tính thống kê.

Về mặt kỹ thuật, str() là công cụ giúp người phân tích xác định đúng kiểu dữ liệu của từng cột, một bước cực kỳ quan trọng để tránh lỗi trong quá trình xử lý sau này. Ví dụ, nếu một biến số bị đọc nhầm thành dạng ký tự (do có ký hiệu đặc biệt như “–” hoặc “N/A”), các phép tính như trung bình hoặc độ lệch chuẩn sẽ không thể thực hiện được. Nhờ str(), ta có thể kiểm tra và phát hiện sớm những lỗi kiểu dữ liệu này.

Về mặt thống kê, kết quả str() giúp người phân tích nhận diện cấu trúc dữ liệu đa dạng của bộ giá xe: gồm cả biến định tính (dùng để nhóm, phân loại, hoặc vẽ biểu đồ tần suất) và biến định lượng (dùng để tính toán, so sánh, và mô hình hóa).

class(vehicle_data)
## [1] "spec_tbl_df" "tbl_df"      "tbl"         "data.frame"

Lệnh class() được dùng để kiểm tra kiểu (class) của đối tượng trong R. Kết quả trả về là “spec_tbl_df”, “tbl_df”, “tbl”, “data.frame”, cho biết vehicle_data là một bảng dữ liệu dạng tibble – kiểu dữ liệu mở rộng của data.frame trong R, được tối ưu bởi gói readr hoặc dplyr.

Về mặt kỹ thuật, điều này có nghĩa rằng dữ liệu có thể được thao tác dễ dàng bằng các hàm của tidyverse. Về mặt học thuật, việc xác định đúng kiểu dữ liệu giúp chọn công cụ phân tích phù hợp, đồng thời đảm bảo tính tương thích giữa các bước xử lý (như lọc, nhóm, hay thống kê mô tả).

names(vehicle_data)
##  [1] "make"             "model"            "year"             "mileage"         
##  [5] "engine_hp"        "transmission"     "fuel_type"        "drivetrain"      
##  [9] "body_type"        "exterior_color"   "interior_color"   "owner_count"     
## [13] "accident_history" "seller_type"      "condition"        "trim"            
## [17] "vehicle_age"      "mileage_per_year" "brand_popularity" "price"

Lệnh names(vehicle_data) được sử dụng để liệt kê toàn bộ tên các biến (cột) có trong bộ dữ liệu. Kết quả hiển thị cho thấy tập dữ liệu có 20 biến, bao gồm các thông tin như hãng xe (make), mẫu xe (model), năm sản xuất (year), số km đã đi (mileage), công suất động cơ (engine_hp), loại nhiên liệu (fuel_type), tình trạng xe (condition), và giá bán (price).

Về mặt kỹ thuật, đây là bước giúp kiểm tra cấu trúc dữ liệu và xác nhận rằng các tên biến đã được đọc đúng, không bị lỗi ký tự hoặc ký hiệu đặc biệt. Về mặt thống kê, việc hiểu rõ ý nghĩa của từng biến là cơ sở để xây dựng các chỉ tiêu mô tả và lựa chọn biến phù hợp cho phân tích trong các phần sau.

cat("Số dòng:", nrow(vehicle_data), "\n")
## Số dòng: 1000000
cat("Số cột:", ncol(vehicle_data), "\n")
## Số cột: 20

Đoạn mã trên được sử dụng để xác định kích thước của bộ dữ liệu vehicle_data, bao gồm số lượng quan sát (dòng) và số lượng biến (cột). Cụ thể, hai hàm nrow() và ncol() lần lượt trả về số dòng – tương ứng với số lượng mẫu xe được ghi nhận, và số cột – tương ứng với số lượng đặc tính mô tả cho mỗi chiếc xe trong tập dữ liệu. Hàm cat() được dùng để in kết quả ra màn hình một cách rõ ràng, kèm theo chú thích bằng tiếng Việt. Kết quả cho thấy bộ dữ liệu có 1.000.000 dòng và 20 cột, nghĩa là có một triệu mẫu xe, mỗi mẫu chứa thông tin của 20 biến khác nhau.

Về mặt kỹ thuật, đây là một thao tác cơ bản nhưng rất quan trọng trong bước đầu khám phá dữ liệu (data inspection). Việc xác định đúng số lượng dòng và cột giúp người phân tích hiểu rõ quy mô, cấu trúc và khối lượng thông tin cần xử lý. Với quy mô 1 triệu quan sát, tập dữ liệu này có thể được xem là một tập dữ liệu lớn (large dataset), đòi hỏi quá trình xử lý và phân tích phải được tối ưu để đảm bảo hiệu suất.

Về mặt ý nghĩa thống kê, việc biết rằng dữ liệu bao gồm 1 triệu xe và 20 biến cho thấy đây là một tập dữ liệu phong phú và đại diện tốt cho thị trường ô tô. Mỗi chiếc xe được mô tả bởi 20 đặc điểm như: hãng sản xuất, năm sản xuất, giá bán, công suất, loại hộp số, nhiên liệu, quãng đường đã đi, tình trạng, số chủ sở hữu, v.v. Điều này giúp nhà phân tích có nhiều hướng khai thác khác nhau, từ việc so sánh giá theo thương hiệu, loại nhiên liệu, năm sản xuất, cho đến phân tích xu hướng tiêu dùng và dự báo giá bán. Như vậy, kết quả này không chỉ cung cấp cái nhìn sơ bộ về cấu trúc dữ liệu, mà còn khẳng định tiềm năng của tập dữ liệu trong việc phân tích, trực quan hóa và mô hình hóa thống kê nâng cao.

sample_n(vehicle_data, 5)
## # A tibble: 5 × 20
##   make       model      year mileage engine_hp transmission fuel_type drivetrain
##   <chr>      <chr>     <dbl>   <dbl>     <dbl> <chr>        <chr>     <chr>     
## 1 Land Rover Defender   2013  161414       352 Automatic    Gasoline  RWD       
## 2 BMW        3 Series   2017  173020       284 Manual       Gasoline  FWD       
## 3 Subaru     Crosstrek  2012  300000       221 Manual       Gasoline  AWD       
## 4 Jeep       Grand Ch…  2017  214780       148 Automatic    Electric  RWD       
## 5 Porsche    Macan      2016  207033       473 Manual       Electric  FWD       
## # ℹ 12 more variables: body_type <chr>, exterior_color <chr>,
## #   interior_color <chr>, owner_count <dbl>, accident_history <chr>,
## #   seller_type <chr>, condition <chr>, trim <chr>, vehicle_age <dbl>,
## #   mileage_per_year <dbl>, brand_popularity <dbl>, price <dbl>

Lệnh sample_n(vehicle_data, 5) được dùng để lấy ngẫu nhiên 5 dòng từ tập dữ liệu vehicle_data. Về mặt kỹ thuật, đây là hàm trong gói dplyr, giúp chọn mẫu ngẫu nhiên để xem nhanh cấu trúc và giá trị dữ liệu mà không cần hiển thị toàn bộ. Kết quả cho thấy dữ liệu chứa thông tin chi tiết về các xe như hãng, mẫu, năm sản xuất, số dặm, công suất, loại hộp số, nhiên liệu và hệ dẫn động.

Về ý nghĩa thống kê, việc lấy mẫu ngẫu nhiên giúp kiểm tra tính hợp lệ và đa dạng của dữ liệu, đảm bảo các giá trị hợp lý và đại diện cho toàn bộ tập dữ liệu. Đây là bước quan trọng trước khi phân tích sâu để xác định xu hướng, mối quan hệ hoặc mô hình hóa dữ liệu.

tail(vehicle_data, 5)
## # A tibble: 5 × 20
##   make          model   year mileage engine_hp transmission fuel_type drivetrain
##   <chr>         <chr>  <dbl>   <dbl>     <dbl> <chr>        <chr>     <chr>     
## 1 Jeep          Chero…  2015  130407       176 Manual       Electric  FWD       
## 2 Dodge         Chall…  2013  276316       211 Manual       Gasoline  RWD       
## 3 Mercedes-Benz E-Cla…  2023    3964       339 Automatic    Electric  AWD       
## 4 Volvo         XC90    2019   83674       311 Automatic    Gasoline  AWD       
## 5 Ram           1500    2022   44863       240 Automatic    Diesel    FWD       
## # ℹ 12 more variables: body_type <chr>, exterior_color <chr>,
## #   interior_color <chr>, owner_count <dbl>, accident_history <chr>,
## #   seller_type <chr>, condition <chr>, trim <chr>, vehicle_age <dbl>,
## #   mileage_per_year <dbl>, brand_popularity <dbl>, price <dbl>

Về mặt kỹ thuật, hàm tail() là một hàm cơ bản trong R, cho phép xem nhanh các quan sát cuối cùng của một khung dữ liệu (data frame hoặc tibble). Tham số đầu tiên là tên tập dữ liệu (vehicle_data), còn tham số thứ hai (5) quy định số dòng cuối được hiển thị.

Về mặt ý nghĩa thống kê, việc xem các dòng cuối cùng của tập dữ liệu giúp đảm bảo rằng các biến có giá trị hợp lệ và được nhập đúng định dạng, tránh lỗi như giá trị bị thiếu (NA), kiểu dữ liệu sai (ví dụ số thành ký tự), hay sự xuất hiện của các giá trị bất thường (outliers

sapply(vehicle_data, class)
##             make            model             year          mileage 
##      "character"      "character"        "numeric"        "numeric" 
##        engine_hp     transmission        fuel_type       drivetrain 
##        "numeric"      "character"      "character"      "character" 
##        body_type   exterior_color   interior_color      owner_count 
##      "character"      "character"      "character"        "numeric" 
## accident_history      seller_type        condition             trim 
##      "character"      "character"      "character"      "character" 
##      vehicle_age mileage_per_year brand_popularity            price 
##        "numeric"        "numeric"        "numeric"        "numeric"

Lệnh sapply(vehicle_data, class) trong R được dùng để kiểm tra kiểu dữ liệu (data type) của từng cột trong bảng vehicle_data. Về mặt kỹ thuật, hàm sapply() áp dụng hàm class cho mỗi cột và trả về kết quả là một vector liệt kê kiểu dữ liệu tương ứng của từng biến.

Kết quả cho thấy dữ liệu gồm hai loại chính:

Biến định tính (character): như make, model, transmission, fuel_type, drivetrain, body_type, exterior_color, seller_type, condition… thể hiện thông tin mô tả hoặc phân loại.

Biến định lượng (numeric): như year, mileage, engine_hp, owner_count, vehicle_age, price… thể hiện các giá trị số có thể tính toán, trung bình hoặc mô hình hóa.

Về mặt ý nghĩa thống kê, việc xác định kiểu dữ liệu giúp người phân tích lựa chọn đúng phương pháp xử lý và trực quan hóa. Các biến định tính phù hợp với biểu đồ cột, biểu đồ tròn hoặc phân nhóm; trong khi các biến định lượng có thể dùng để tính trung bình, phương sai, tương quan hoặc hồi quy. Đây là bước tiền xử lý quan trọng đảm bảo việc phân tích sau này chính xác và hợp lý.

cat("TÓM TẮT DỮ LIỆU\n")
## TÓM TẮT DỮ LIỆU
cat("=================\n")
## =================
cat("Số dòng:", nrow(vehicle_data), "\n")
## Số dòng: 1000000
cat("Số cột:", ncol(vehicle_data), "\n")
## Số cột: 20
cat("Các biến bao gồm:\n")
## Các biến bao gồm:
cat(paste("-", names(vehicle_data), collapse = "\n"), "\n")
## - make
## - model
## - year
## - mileage
## - engine_hp
## - transmission
## - fuel_type
## - drivetrain
## - body_type
## - exterior_color
## - interior_color
## - owner_count
## - accident_history
## - seller_type
## - condition
## - trim
## - vehicle_age
## - mileage_per_year
## - brand_popularity
## - price

Đoạn mã R trên có chức năng hiển thị thông tin tổng quan về bộ dữ liệu vehicle_data, bao gồm số lượng dòng, số lượng cột và danh sách các biến có trong tập dữ liệu. Về mặt kỹ thuật, đây là bước kiểm tra cần thiết nhằm đảm bảo dữ liệu đã được nạp đúng cách và sẵn sàng cho quá trình phân tích tiếp theo. Việc in ra cấu trúc dữ liệu giúp người phân tích nắm rõ phạm vi và thành phần của bộ dữ liệu, đặc biệt hữu ích khi làm việc với tập dữ liệu lớn hoặc phức tạp.

Về mặt thống kê, phần tóm tắt dữ liệu cung cấp cái nhìn khái quát về quy mô và đặc điểm của mẫu nghiên cứu. Với 1.000.000 dòng và 20 biến, tập dữ liệu thể hiện quy mô quan sát lớn và độ đa dạng thông tin cao, giúp tăng độ tin cậy cho các ước lượng thống kê và mô hình dự đoán sau này. Các biến như thương hiệu, năm sản xuất, quãng đường đã đi, công suất động cơ hay tình trạng xe đều là những yếu tố quan trọng có thể ảnh hưởng đến giá xe. Như vậy, phần tóm tắt dữ liệu không chỉ mang ý nghĩa kỹ thuật trong việc kiểm tra dữ liệu mà còn mang ý nghĩa thống kê khi giúp hiểu rõ cấu trúc và tiềm năng phân tích của tập dữ liệu.

2.1.5. Chọn các cột cốt lõi cho phân tích

Trong giai đoạn khám phá và xử lý dữ liệu, không phải lúc nào ta cũng cần toàn bộ các biến có trong tập dữ liệu gốc. Việc tập trung vào những biến cốt lõi (core variables) giúp quá trình phân tích trở nên rõ ràng hơn, giảm tải bộ nhớ và tránh nhiễu thông tin không cần thiết. Với tập dữ liệu về xe ô tô, bốn biến cơ bản nhất thường được sử dụng để mô tả đặc trưng của một chiếc xe là hãng sản xuất (make), mẫu xe (model), năm sản xuất (year), và giá bán (price).

Để chỉ làm việc với các biến này, ta sử dụng hàm select() từ gói dplyr để chọn bốn cột nói trên và lưu vào một data frame mới có tên là df_core.

df_core <- vehicle_data %>%
  select(make, mileage, year, price)

head(df_core)
## # A tibble: 6 × 4
##   make       mileage  year  price
##   <chr>        <dbl> <dbl>  <dbl>
## 1 Volkswagen  183903  2016  7209.
## 2 Lexus       236643  2010  6912.
## 3 Subaru      103199  2016 11916.
## 4 Cadillac    118889  2016 25985.
## 5 Toyota      204170  2018  8151.
## 6 Land Rover   44907  2021 59491.

Về mặt kỹ thuật, hàm select() được sử dụng để lựa chọn các cột cụ thể từ một bảng dữ liệu mà không làm thay đổi nội dung các giá trị bên trong. Khi kết hợp với toán tử %>%, câu lệnh trở nên dễ đọc, giúp mô tả rõ ràng quá trình lọc biến. Việc lưu kết quả vào một biến mới (df_core) đảm bảo rằng dữ liệu gốc vehicle_data vẫn được giữ nguyên, tránh mất mát thông tin ban đầu trong trường hợp cần quay lại để xử lý hoặc đối chiếu. Ngoài ra, việc chỉ chọn các biến cần thiết còn giúp tăng hiệu suất xử lý, đặc biệt khi làm việc với tập dữ liệu lớn.

Về ý nghĩa thống kê, việc chỉ giữ lại các biến make, model, year, và price giúp ta tập trung vào những yếu tố chính ảnh hưởng trực tiếp đến giá trị của xe. Cụ thể, make và model phản ánh thương hiệu và dòng xe, year đại diện cho yếu tố thời gian hay tuổi đời xe, còn price là biến phụ thuộc quan trọng nhất trong các bài toán định giá hoặc dự đoán giá bán. Việc tách dữ liệu cốt lõi này giúp các bước phân tích tiếp theo — như thống kê mô tả, so sánh giá theo năm, hay xây dựng mô hình hồi quy — được thực hiện nhanh chóng và chính xác hơn, mà không bị ảnh hưởng bởi các biến phụ không cần thiết.

2.2. Xử lý dữ liệu thô và mã hóa dữ liệu

2.2.1. Kiểm tra các giá trị thiếu và trùng lặp

2.2.1.1. Kiểm tra giá trị thiếu

colSums(is.na(vehicle_data))
##             make            model             year          mileage 
##                0                0                0                0 
##        engine_hp     transmission        fuel_type       drivetrain 
##                0                0                0                0 
##        body_type   exterior_color   interior_color      owner_count 
##                0                0                0                0 
## accident_history      seller_type        condition             trim 
##                0                0                0                0 
##      vehicle_age mileage_per_year brand_popularity            price 
##                0                0                0                0

Lệnh này được dùng để kiểm tra số lượng giá trị thiếu (NA) trong từng biến của bộ dữ liệu. Hàm is.na() xác định vị trí các ô bị thiếu, sau đó colSums() cộng tổng số giá trị thiếu theo từng cột. Kết quả trả về toàn bộ bằng 0, chứng tỏ không có biến nào chứa dữ liệu bị thiếu.

Về mặt kỹ thuật, điều này cho thấy dữ liệu đã được thu thập và làm sạch tốt, đảm bảo tính toàn vẹn. Về mặt thống kê, việc không có giá trị thiếu giúp giảm sai lệch mẫu và tăng độ tin cậy của các phép phân tích mô tả, bởi tất cả các biến đều có số lượng quan sát đầy đủ.

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

Câu lệnh any(is.na(vehicle_data)) trong R được dùng để kiểm tra xem dữ liệu có chứa giá trị bị thiếu (NA) hay không.

  • is.na(vehicle_data) trả về một ma trận các giá trị TRUE/FALSE tương ứng với từng ô dữ liệu (TRUE nếu là NA, FALSE nếu không).

  • any() kiểm tra xem có ít nhất một giá trị TRUE trong toàn bộ dữ liệu không.

Kết quả này cho thấy dữ liệu hoàn chỉnh 100%, không bị thiếu thông tin ở bất kỳ biến nào.

2.2.1.2. Kiểm tra giá trị trùng lặp

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

Lệnh sum(duplicated(vehicle_data)) được sử dụng để kiểm tra xem trong bộ dữ liệu có bản ghi nào bị trùng lặp hay không. Hàm duplicated() trả về giá trị TRUE cho những hàng trùng, và sum() cộng tổng số đó. Kết quả trả về bằng 0, nghĩa là không có quan sát nào bị lặp lại.

Về mặt kỹ thuật, điều này chứng tỏ rằng mỗi dòng trong dữ liệu là một bản ghi duy nhất, không bị sao chép hoặc lặp. Về mặt thống kê, dữ liệu không trùng lặp giúp đảm bảo tính độc lập giữa các quan sát, một giả định quan trọng khi thực hiện phân tích thống kê và mô hình hóa sau này.

2.2.2. Mã hóa và tạo cột mới có điều kiện

2.2.2.1. Mã hóa biến định tính thành biến nhị phân

vehicle_data %>% mutate(is_automatic = ifelse(transmission == "Automatic", 1, 0)) %>% select(transmission, is_automatic)
## # A tibble: 1,000,000 × 2
##    transmission is_automatic
##    <chr>               <dbl>
##  1 Manual                  0
##  2 Manual                  0
##  3 Automatic               1
##  4 Manual                  0
##  5 Manual                  0
##  6 Manual                  0
##  7 Automatic               1
##  8 Automatic               1
##  9 Automatic               1
## 10 Automatic               1
## # ℹ 999,990 more rows

Đoạn mã này sử dụng hàm mutate() trong gói dplyr để tạo thêm một cột mới có tên là is_automatic, được mã hóa dựa trên giá trị của biến transmission. Cụ thể, hàm ifelse() kiểm tra từng dòng dữ liệu: nếu giá trị trong cột transmission là “Automatic” thì gán giá trị 1, còn nếu là “Manual” thì gán 0. Sau đó, select(transmission, is_automatic) được dùng để chỉ hiển thị hai cột này — giúp ta dễ dàng đối chiếu kết quả giữa biến gốc và biến mới vừa tạo.

Về mặt dữ liệu, bước này chuyển đổi biến định tính “transmission” thành một biến nhị phân (binary variable), cho phép máy tính hoặc các mô hình thống kê hiểu và xử lý dễ dàng hơn.

Giá trị 1 đại diện cho xe sử dụng hộp số tự động,

Giá trị 0 đại diện cho xe hộp số sàn (Manual).

Việc mã hóa như vậy là cần thiết khi muốn thực hiện các phân tích như hồi quy tuyến tính, hồi quy logistic hoặc phân tích nhân tố, vốn yêu cầu các biến đầu vào là dạng số. Ngoài ra, bước này cũng giúp dễ dàng tính toán tỷ lệ xe tự động trong toàn bộ dữ liệu, hoặc so sánh giá trung bình giữa hai nhóm xe (tự động và số sàn) trong các bước thống kê tiếp theo.

2.2.2.2. Tạo biến “tuổi xe”

Trong quá trình xử lý dữ liệu, để phục vụ cho việc phân loại và phân tích đặc điểm của các xe trong tập dữ liệu, ta cần xác định tình trạng “xe mới” hay “xe cũ” dựa trên năm sản xuất (year). Bởi vì tập dữ liệu không có biến thể hiện trực tiếp tuổi của xe, ta có thể tính toán thông qua năm hiện tại. Cụ thể, ta tạo một biến mới có tên age, được tính bằng hiệu giữa năm hiện tại (2025) và năm sản xuất của xe. Công thức thực hiện trong R như sau:

vehicle_data <- vehicle_data %>% mutate(age = 2025 - year)
vehicle_data %>%  select(year, age) %>% head(10)
## # A tibble: 10 × 2
##     year   age
##    <dbl> <dbl>
##  1  2016     9
##  2  2010    15
##  3  2016     9
##  4  2016     9
##  5  2018     7
##  6  2021     4
##  7  2018     7
##  8  2022     3
##  9  2015    10
## 10  2025     0

Về mặt kỹ thuật, đoạn mã trên sử dụng hàm mutate() trong gói dplyr để tạo thêm một biến mới có tên age trong bảng dữ liệu vehicle_data. Bên trong hàm mutate(), phép tính 2025 - year được thực hiện theo cơ chế vector hóa (vectorized operation) của R, nghĩa là phép trừ này được áp dụng đồng thời cho toàn bộ các hàng trong biến year mà không cần sử dụng vòng lặp. Kết quả thu được là một cột mới age thể hiện số năm tuổi của từng chiếc xe, trong đó các giá trị dương cho biết thời gian sử dụng kể từ năm sản xuất đến năm hiện tại (2025). Cách viết này giúp mã ngắn gọn, dễ đọc và đảm bảo hiệu suất xử lý cao ngay cả khi làm việc với tập dữ liệu lớn. Cuối cùng, hàm select() được dùng để hiển thị hai cột year và age giúp người phân tích dễ dàng kiểm tra kết quả tạo biến trước khi tiếp tục các bước phân tích thống kê tiếp theo.

Về ý nghĩa thống kê và thực tiễn, việc tạo biến age mang lại thông tin quan trọng về mức độ hao mòn và giá trị sử dụng của xe, yếu tố có ảnh hưởng mạnh đến giá bán và hành vi người tiêu dùng. Biến này giúp phân tích dễ dàng hơn các đặc trưng theo độ tuổi xe, chẳng hạn như xu hướng giảm giá theo thời gian, chi phí bảo trì hoặc sự thay đổi trong nhu cầu mua xe mới so với xe cũ. Ngoài ra, dựa trên biến age, có thể phân loại các xe thành nhóm “xe mới” (tuổi ≤ 3 năm), “xe trung bình” (4–7 năm) và “xe cũ” (≥ 8 năm), từ đó phục vụ hiệu quả cho các phép thống kê mô tả, so sánh nhóm hoặc mô hình hồi quy nhằm dự đoán giá trị xe. Về mặt thực tế, việc tính toán tuổi xe còn giúp xác định tốc độ khấu hao tài sản và xu hướng tiêu thụ xe qua thời gian, góp phần hỗ trợ các nhà phân tích hoặc doanh nghiệp ra quyết định chính xác hơn trong định giá và hoạch định chiến lược thị trường.

2.2.2.3. Phân loại xe mới/cũ

Phân loại xe theo đời sản xuất để phục vụ các phân tích thống kê mô tả và so sánh giữa các nhóm. Dựa trên biến year (năm sản xuất), ta có thể xác định được tình trạng của xe — “mới” hay “cũ” — bằng cách tạo một biến mới có tên car_status. Theo tiêu chí phân loại, những xe có năm sản xuất từ 2020 trở lên được xem là xe mới (NEW), trong khi các xe sản xuất trước năm 2020 được xem là xe cũ (OLD). Câu lệnh R để thực hiện thao tác này như sau:

vehicle_data <- vehicle_data %>%
  mutate(car_status = ifelse(year >= 2020, "NEW", "OLD"))
vehicle_data %>%
  select(year, car_status) %>%
  head(10)
## # A tibble: 10 × 2
##     year car_status
##    <dbl> <chr>     
##  1  2016 OLD       
##  2  2010 OLD       
##  3  2016 OLD       
##  4  2016 OLD       
##  5  2018 OLD       
##  6  2021 NEW       
##  7  2018 OLD       
##  8  2022 NEW       
##  9  2015 OLD       
## 10  2025 NEW

Về mặt kỹ thuật, đoạn mã trên sử dụng hàm mutate() trong gói dplyr để tạo thêm một biến mới có tên car_status trong bảng dữ liệu vehicle_data. Bên trong hàm mutate(), ta sử dụng hàm ifelse() để thiết lập điều kiện logic cho từng hàng dữ liệu. Cụ thể, ifelse(year >= 2020, “NEW”, “OLD”) kiểm tra giá trị của biến year (năm sản xuất): nếu năm sản xuất lớn hơn hoặc bằng 2020, biến car_status sẽ được gán giá trị “NEW”, ngược lại nhận giá trị “OLD”. Toàn bộ quá trình được thực hiện đồng thời cho tất cả các hàng trong tập dữ liệu, nhờ khả năng xử lý vector hóa (vectorized processing) của R, giúp thao tác diễn ra nhanh chóng và hiệu quả ngay cả với các bộ dữ liệu lớn. Việc kết hợp toán tử pipe %>% giúp mã lệnh trở nên mạch lạc và dễ hiểu, mô tả rõ ràng luồng xử lý dữ liệu từ đầu vào (vehicle_data) đến khi tạo ra biến mới. Cuối cùng, hàm select() được dùng để hiển thị các cột year và car_status, giúp người phân tích kiểm tra trực tiếp kết quả mã hóa trước khi sử dụng biến này trong các phân tích thống kê hoặc mô hình hóa tiếp theo.

Về ý nghĩa thống kê và thực tiễn, việc mã hóa biến car_status giúp phân tách dữ liệu thành hai nhóm rõ ràng là xe mới và xe cũ, từ đó cho phép thực hiện các phân tích so sánh giữa các phân khúc sản phẩm theo thời gian sản xuất. Biến này đặc biệt hữu ích trong các phép thống kê mô tả như so sánh giá trung bình, mức độ hao mòn, hoặc công suất động cơ giữa hai nhóm, cũng như trong các mô hình hồi quy, nơi car_status có thể được sử dụng như một biến độc lập định tính phản ánh mức độ hiện đại của xe. Ngoài ra, từ góc nhìn kinh tế – thị trường, việc phân loại này giúp nhà phân tích dễ dàng theo dõi xu hướng tiêu thụ xe mới qua các năm, đánh giá mức độ ảnh hưởng của công nghệ và năm sản xuất đến giá bán, hoặc nhận diện chu kỳ thay thế phương tiện trên thị trường. Như vậy, biến car_status vừa có giá trị kỹ thuật trong xử lý dữ liệu, vừa mang ý nghĩa phân tích quan trọng, góp phần hỗ trợ việc hiểu sâu hơn về cấu trúc và xu hướng của thị trường xe ô tô.

2.2.2.4. Phân khúc giá bán (price_segment)

Trong phân tích dữ liệu về thị trường ô tô, phân khúc giá (price segmentation) là một bước quan trọng giúp hiểu rõ hơn về cấu trúc giá và hành vi tiêu dùng của từng nhóm khách hàng. Thay vì sử dụng giá bán dưới dạng biến liên tục (price), ta có thể chia giá thành các nhóm giá trị (price categories) để dễ dàng so sánh và trực quan hóa xu hướng giữa các phân khúc.

Dựa trên phân bố giá trong dữ liệu, ta chia thị trường thành ba nhóm:

  • Low: xe có giá dưới 25.000 USD — thường là các dòng xe phổ thông, phù hợp với nhu cầu sử dụng cơ bản.

  • Mid: xe có giá từ 25.000 đến dưới 50.000 USD — nhóm trung cấp, phổ biến nhất trên thị trường.

  • High: xe có giá từ 50.000 USD trở lên — thường là xe hạng sang hoặc xe hiệu năng cao.

vehicle_data <- vehicle_data %>%
  mutate(
    price_segment = case_when(
      price < 25000 ~ "Low",
      price >= 25000 & price < 50000 ~ "Mid",
      price >= 50000 ~ "High"
    )
  )

vehicle_data %>%
  select(price, price_segment)
## # A tibble: 1,000,000 × 2
##     price price_segment
##     <dbl> <chr>        
##  1  7209. Low          
##  2  6912. Low          
##  3 11916. Low          
##  4 25985. Mid          
##  5  8151. Low          
##  6 59491. High         
##  7 10823. Low          
##  8 26935. Mid          
##  9 11431. Low          
## 10 30577. Mid          
## # ℹ 999,990 more rows

Về mặt kỹ thuật, hàm mutate() được sử dụng để tạo thêm biến mới price_segment trong bảng dữ liệu vehicle_data. Bên trong, hàm case_when() cho phép thiết lập các điều kiện logic phân loại giá trị của biến price thành ba nhóm. Điều kiện price < 25000 gán nhãn “Low”, price >= 25000 & price < 50000 gán nhãn “Mid”, và price >= 50000 gán nhãn “High”. Cấu trúc case_when() rất linh hoạt, giúp mã dễ đọc, dễ mở rộng nếu sau này muốn điều chỉnh ngưỡng giá hoặc thêm nhóm mới.

Về ý nghĩa thống kê, việc phân khúc giá giúp chuyển đổi biến liên tục thành biến phân loại, từ đó cho phép phân tích so sánh giữa các nhóm dễ dàng hơn. Chẳng hạn, ta có thể đánh giá tỷ lệ xe trong từng phân khúc, so sánh đặc điểm trung bình của mỗi nhóm (như công suất, năm sản xuất, hoặc thương hiệu), hoặc trực quan hóa dữ liệu bằng biểu đồ thanh (bar chart) để thấy rõ sự phân bố giá trên thị trường. Ngoài ra, việc nhóm giá thành các phân khúc còn giúp giảm ảnh hưởng của các giá trị ngoại lai (outliers), làm cho các mô hình thống kê trở nên ổn định hơn.

2.2.2.5. Phân loại thương hiệu (brand_type)

Trong phân tích thị trường ô tô, thương hiệu (make) đóng vai trò rất quan trọng vì nó phản ánh đẳng cấp, chất lượng và định vị sản phẩm trên thị trường. Để phục vụ cho việc phân tích so sánh và mô hình hóa, ta cần nhóm các hãng xe thành những phân khúc thương hiệu lớn. Cụ thể, các hãng cao cấp như Lexus, Cadillac, BMW, và Audi thường được xếp vào nhóm Luxury (xe sang), trong khi các thương hiệu còn lại được xếp vào nhóm Standard (xe phổ thông).

vehicle_data <- vehicle_data %>%
  mutate(
    brand_type = ifelse(
      make %in% c("Lexus", "Cadillac", "BMW", "Audi"),
      "Luxury",
      "Standard"
    )
  )
vehicle_data %>% count(make, brand_type)
## # A tibble: 25 × 3
##    make      brand_type     n
##    <chr>     <chr>      <int>
##  1 Acura     Standard   40147
##  2 Audi      Luxury     40022
##  3 BMW       Luxury     39840
##  4 Cadillac  Luxury     39847
##  5 Chevrolet Standard   39982
##  6 Chrysler  Standard   40059
##  7 Dodge     Standard   40035
##  8 Ford      Standard   39842
##  9 GMC       Standard   39754
## 10 Honda     Standard   40015
## # ℹ 15 more rows

Về mặt kỹ thuật, hàm mutate() trong gói dplyr được sử dụng để tạo thêm một biến mới có tên brand_type, trong đó hàm ifelse() đóng vai trò kiểm tra điều kiện logic: nếu giá trị của biến make thuộc danh sách các hãng xe cao cấp như Lexus, Cadillac, BMW hoặc Audi, biến brand_type sẽ được gán giá trị “Luxury”, ngược lại là “Standard”. Cấu trúc %in% được dùng để kiểm tra xem giá trị có nằm trong một tập hợp nhất định hay không, nhờ đó câu lệnh trở nên ngắn gọn, rõ ràng và dễ mở rộng khi cần bổ sung thêm thương hiệu khác. Việc kết hợp các hàm này trong một dòng mã duy nhất giúp quy trình xử lý dữ liệu trở nên linh hoạt và hiệu quả hơn, đặc biệt khi làm việc với tập dữ liệu có quy mô lớn hoặc cần phân loại tự động theo tiêu chí định sẵn.

Về ý nghĩa thống kê và thực tiễn, việc phân loại thương hiệu thành hai nhóm “Luxury” và “Standard” giúp chuẩn hóa biến phân loại và tăng khả năng phân tích so sánh giữa các phân khúc thị trường. Thay vì làm việc với hàng chục thương hiệu riêng lẻ, việc gom nhóm giúp giảm độ phức tạp của dữ liệu, đồng thời làm nổi bật các khác biệt có ý nghĩa giữa hai phân khúc chính. Trong thực tế, nhóm “Luxury” thường đại diện cho các xe có giá trị thương hiệu cao, chất lượng vượt trội và được định vị ở phân khúc cao cấp, trong khi nhóm “Standard” phản ánh các dòng xe phổ thông, hướng đến đại đa số người tiêu dùng. Việc đưa biến brand_type vào phân tích cho phép so sánh các chỉ số quan trọng như giá trung bình, công suất động cơ, hoặc mức độ phổ biến thương hiệu giữa hai nhóm, từ đó rút ra những kết luận có ý nghĩa về chiến lược định giá, xu hướng tiêu dùng và cấu trúc thị trường. Như vậy, biến brand_type vừa mang giá trị kỹ thuật trong việc đơn giản hóa dữ liệu, vừa có ý nghĩa thống kê – kinh tế sâu sắc, giúp mô hình phân tích phản ánh chính xác hơn sự khác biệt giữa các phân khúc xe trên thị trường.

2.2.2.6. Phân Nhóm Theo Số Km

vehicle_data <- vehicle_data %>% mutate(mileage_group = case_when(mileage < 50000 ~ "Low", 
mileage <= 150000 ~ "Mid", TRUE ~ "High"))
vehicle_data %>%
  select(mileage, mileage_group) %>%
  head(10)
## # A tibble: 10 × 2
##    mileage mileage_group
##      <dbl> <chr>        
##  1  183903 High         
##  2  236643 High         
##  3  103199 Mid          
##  4  118889 Mid          
##  5  204170 High         
##  6   44907 Low          
##  7  129770 Mid          
##  8   29146 Low          
##  9  169165 High         
## 10    5081 Low

Về ý nghĩa kỹ thuật, đoạn mã này giúp chuyển đổi biến định lượng (mileage) thành biến phân loại (mileage_group), từ đó dễ dàng hơn trong việc thống kê, vẽ biểu đồ và mô hình hóa (ví dụ: so sánh giá xe trung bình giữa các nhóm sử dụng). Đây là bước tiền xử lý phổ biến trong phân tích dữ liệu, đặc biệt khi muốn phát hiện xu hướng hoặc sự khác biệt giữa các nhóm giá trị.

Về ý nghĩa thống kê, việc phân nhóm quãng đường đi cho phép hiểu rõ hơn mối quan hệ giữa mức độ sử dụng xe và giá trị còn lại của xe. Thông thường, xe thuộc nhóm “Low” sẽ có giá cao hơn do ít hao mòn, trong khi nhóm “High” có xu hướng giảm giá do quãng đường sử dụng nhiều hơn. Như vậy, việc tạo biến phân loại không chỉ giúp đơn giản hóa việc diễn giải mà còn hỗ trợ trực quan hóa dữ liệu và phát hiện các mẫu thống kê tiềm ẩn trong tập dữ liệu.

2.2.2.7. Gom nhóm màu nội thất

Nhóm lại các biến phân loại có quá nhiều mức giá trị (levels) để giúp mô hình dự đoán hoạt động ổn định hơn và tăng tính khái quát trong phân tích. Biến interior_color (màu nội thất xe) trong tập dữ liệu ban đầu có rất nhiều giá trị khác nhau như Black, Gray, Brown, Beige, White, Red, v.v. Số lượng mức giá trị lớn này có thể gây ra phân tán dữ liệu và tăng độ phức tạp của mô hình, đặc biệt khi mô hình cần mã hóa các biến dạng nhân tố (factor variables).

Để đơn giản hóa và vẫn giữ được đặc trưng thẩm mỹ cơ bản của xe, ta tiến hành nhóm lại các màu nội thất thành hai nhóm chính dựa trên tông màu:

Dark: bao gồm các màu tối như Black và Gray.

Light/Other: bao gồm các màu sáng hoặc khác như Brown, Beige, White, Red, v.v

vehicle_data <- vehicle_data %>%
  mutate(
    interior_group = case_when(
      interior_color %in% c("Black", "Gray") ~ "Dark",
      TRUE ~ "Light/Other" # Bao gồm Brown, Beige, v.v.
    )
  )
vehicle_data %>%
  select(interior_color, interior_group) %>%
  head(10)
## # A tibble: 10 × 2
##    interior_color interior_group
##    <chr>          <chr>         
##  1 Brown          Light/Other   
##  2 Beige          Light/Other   
##  3 Beige          Light/Other   
##  4 Gray           Dark          
##  5 Brown          Light/Other   
##  6 Black          Dark          
##  7 Beige          Light/Other   
##  8 Black          Dark          
##  9 Black          Dark          
## 10 Beige          Light/Other

Về mặt kỹ thuật, hàm mutate() (thuộc gói dplyr) được sử dụng để tạo thêm một biến mới trong tập dữ liệu, còn hàm case_when() cho phép thiết lập các điều kiện gán giá trị tương tự như cấu trúc if…else if…else. Cụ thể, nếu biến interior_color thuộc một trong các giá trị “Black” hoặc “Gray”, biến mới interior_group sẽ nhận giá trị “Dark”. Trong các trường hợp khác, giá trị mặc định sẽ là “Light/Other”. Cú pháp %in% giúp kiểm tra nhanh xem một giá trị có nằm trong một danh sách được định nghĩa sẵn hay không, nhờ đó làm cho mã lệnh ngắn gọn, dễ hiểu và dễ mở rộng trong tương lai.

Về ý nghĩa thống kê, việc nhóm lại biến interior_color thành hai nhóm lớn có vai trò quan trọng trong việc giảm số lượng mức giá trị của biến phân loại, giúp mô hình hồi quy hoặc máy học ổn định hơn và tránh hiện tượng “nhiễu” do số lượng nhóm quá nhỏ. Ngoài ra, từ góc độ thị trường, tông màu tối (“Dark”) thường gắn liền với các dòng xe cao cấp, mang lại cảm giác sang trọng và trung tính, trong khi tông màu sáng hoặc khác (“Light/Other”) phản ánh sự đa dạng và xu hướng thẩm mỹ cá nhân của người tiêu dùng.

Do đó, việc mã hóa lại biến này không chỉ mang tính kỹ thuật trong xử lý dữ liệu mà còn có ý nghĩa thực tiễn trong phân tích hành vi người mua và xu hướng giá bán — chẳng hạn, xe có nội thất màu tối có thể được ưa chuộng hơn ở phân khúc cao cấp, trong khi các màu sáng phổ biến ở phân khúc xe gia đình hoặc xe phổ thông.

2.2.2.8. Tạo biến “in hoa”

vehicle_data %>% mutate(make_upper = toupper(make)) %>% select(make, make_upper) %>% print()
## # A tibble: 1,000,000 × 2
##    make       make_upper
##    <chr>      <chr>     
##  1 Volkswagen VOLKSWAGEN
##  2 Lexus      LEXUS     
##  3 Subaru     SUBARU    
##  4 Cadillac   CADILLAC  
##  5 Toyota     TOYOTA    
##  6 Land Rover LAND ROVER
##  7 Mazda      MAZDA     
##  8 Volkswagen VOLKSWAGEN
##  9 Ram        RAM       
## 10 Chrysler   CHRYSLER  
## # ℹ 999,990 more rows

Về mặt kỹ thuật:

Toán tử %>% giúp truyền kết quả của từng bước sang bước tiếp theo một cách trực quan.

mutate(make_upper = toupper(make)) tạo một biến mới make_upper là phiên bản viết hoa hoàn toàn của cột make.

Hàm toupper() trong R chuyển tất cả các ký tự chữ thường thành chữ in hoa.

Việc này rất quan trọng khi xử lý dữ liệu chứa ký tự vì R phân biệt chữ hoa – chữ thường, ví dụ “toyota” ≠ “Toyota”.

select(make, make_upper) chỉ hiển thị hai cột này để dễ so sánh trước và sau biến đổi.

print() dùng để hiển thị kết quả ngay trong bảng.

Về ý nghĩa thống kê / dữ liệu: Về mặt thống kê, việc chuẩn hóa này giúp tránh trùng lặp dữ liệu khi cùng một hãng xe có nhiều cách ghi khác nhau (ví dụ “Toyota”, “toyota”, “TOYOTA”), đảm bảo tính nhất quán khi thực hiện các phép nhóm (grouping) hoặc phân tích tần suất theo thương hiệu. Đây là bước làm sạch dữ liệu (data cleaning) quan trọng, giúp tăng độ chính xác cho các phân tích mô tả và mô hình thống kê sau này.

2.2.2.9. Tạo biến chỉ mục định danh (car_id)

Trong nhiều tập dữ liệu, đặc biệt là khi dữ liệu được tổng hợp hoặc kết hợp từ nhiều nguồn khác nhau, việc thiếu mã định danh duy nhất (unique identifier) cho từng quan sát có thể gây khó khăn trong việc truy xuất, đối chiếu hoặc xử lý dữ liệu. Để khắc phục điều này, ta cần tạo một biến chỉ mục (index variable) giúp đánh dấu thứ tự của từng hàng trong bảng dữ liệu.

Ở đây, ta tạo thêm cột car_id đại diện cho số thứ tự của mỗi xe, bắt đầu từ 1 đến hết, nhằm đảm bảo mỗi quan sát có thể được nhận diện duy nhất.

vehicle_data <- vehicle_data %>%
  mutate(car_id = row_number())

vehicle_data %>%
  select(car_id, make, model)
## # A tibble: 1,000,000 × 3
##    car_id make       model     
##     <int> <chr>      <chr>     
##  1      1 Volkswagen Jetta     
##  2      2 Lexus      RX        
##  3      3 Subaru     Crosstrek 
##  4      4 Cadillac   Lyriq     
##  5      5 Toyota     Highlander
##  6      6 Land Rover Defender  
##  7      7 Mazda      Mazda3    
##  8      8 Volkswagen Atlas     
##  9      9 Ram        2500      
## 10     10 Chrysler   300       
## # ℹ 999,990 more rows

Về mặt kỹ thuật, hàm mutate() trong gói dplyr được dùng để tạo thêm một biến mới trong tập dữ liệu, trong khi hàm row_number() tự động gán chỉ số thứ tự (index) cho từng hàng, dựa trên vị trí thực tế của quan sát trong bảng. Khi kết hợp với toán tử %>%, thao tác này trở nên mạch lạc, giúp ta dễ dàng thêm chỉ mục mà không làm thay đổi cấu trúc hay giá trị các biến còn lại. Cột car_id được tạo ra sẽ có giá trị tăng dần từ 1 đến số lượng bản ghi, đảm bảo rằng mỗi dòng dữ liệu đều có một mã định danh riêng biệt.

Về ý nghĩa thống kê, việc thêm cột car_id tuy không ảnh hưởng trực tiếp đến nội dung phân tích, nhưng đóng vai trò quan trọng trong quản lý, truy xuất và thao tác dữ liệu. Biến này giúp dễ dàng thực hiện các thao tác như lọc, gộp, kiểm tra trùng lặp, hoặc đối chiếu kết quả giữa các bảng dữ liệu khác nhau. Trong các mô hình phân tích hoặc quy trình xử lý dữ liệu lớn, mã định danh duy nhất như car_id giúp đảm bảo toàn vẹn dữ liệu (data integrity), hạn chế lỗi trùng lặp và hỗ trợ tái lập quy trình phân tích một cách chính xác. Như vậy, việc tạo thêm biến chỉ mục là một bước nhỏ nhưng có ý nghĩa lớn về tổ chức và quản lý dữ liệu, giúp quá trình phân tích sau này trở nên rõ ràng, chặt chẽ và đáng tin cậy hơn.

2.2.3. Chuẩn hóa và biến đổi

2.2.3.1. Chuẩn hóa Min-Max: Chuẩn hóa cột mileage về phạm vi 0 đến 1.

vehicle_data <- vehicle_data %>% mutate(mileage_norm = (mileage - min(mileage)) / (max(mileage) - min(mileage)))
vehicle_data %>%
  select(mileage, mileage_norm) %>%
  arrange(mileage) %>% 
  head(10)
## # A tibble: 10 × 2
##    mileage mileage_norm
##      <dbl>        <dbl>
##  1     500            0
##  2     500            0
##  3     500            0
##  4     500            0
##  5     500            0
##  6     500            0
##  7     500            0
##  8     500            0
##  9     500            0
## 10     500            0

Đoạn mã trên thực hiện việc chuẩn hóa biến mileage – quãng đường xe đã đi – thành biến mới mileage_norm bằng cách đưa toàn bộ giá trị của biến này về khoảng [0, 1]. Trong đó, giá trị nhỏ nhất của mileage được gán bằng 0 và giá trị lớn nhất được gán bằng 1. Về mặt kỹ thuật, đây là bước chuẩn hóa dữ liệu giúp các biến có đơn vị đo lường khác nhau trở nên đồng nhất về thang đo. Điều này đặc biệt quan trọng trong các thuật toán học máy và mô hình thống kê, vì nếu không chuẩn hóa, các biến có giá trị lớn sẽ chi phối kết quả phân tích và làm sai lệch trọng số trong mô hình.

Về mặt thống kê, việc chuẩn hóa không làm thay đổi bản chất hay mối tương quan giữa các biến, mà chỉ thay đổi phạm vi giá trị để giúp việc so sánh và diễn giải trở nên dễ dàng hơn. Trong kết quả hiển thị, các giá trị mileage bằng 500 có mileage_norm bằng 0, cho thấy đây là những xe có quãng đường sử dụng thấp nhất trong toàn bộ dữ liệu. Như vậy, bước chuẩn hóa này giúp dữ liệu được biểu diễn trên cùng một thang đo, tạo điều kiện thuận lợi cho các bước phân tích, mô hình hóa và dự đoán giá xe ở giai đoạn sau.

2.2.3.2. Đổi tên biến cho thống nhất

names(vehicle_data) <- make.names(names(vehicle_data))

Lệnh này được sử dụng để chuẩn hóa lại tên các biến trong dữ liệu, trong trường hợp tên biến có ký tự đặc biệt, dấu cách hoặc ký hiệu không hợp lệ trong R. Hàm make.names() sẽ tự động thay thế các ký tự không phù hợp bằng dấu chấm “.”, giúp đảm bảo tất cả tên biến đều hợp lệ và dễ sử dụng trong các thao tác lập trình sau này.

Về mặt kỹ thuật, điều này giúp tránh lỗi khi gọi biến hoặc khi viết các hàm xử lý dữ liệu phức tạp. Về mặt học thuật, đây là bước chuẩn hóa cấu trúc dữ liệu (data normalization) nhằm tăng tính ổn định và nhất quán cho tập dữ liệu trong toàn bộ quá trình phân tích.

2.2.3.3. Chuẩn hóa đơn vị đo

Biến mileage thể hiện tổng quãng đường xe đã di chuyển kể từ khi xuất xưởng nhưng được đo bằng đơn vị dặm (mile), trong khi trong hệ đo lường quốc tế và các nghiên cứu kỹ thuật, đơn vị thường được sử dụng là kilômét (km). Để đảm bảo tính thống nhất trong phân tích và dễ dàng so sánh giữa các biến, biến này được chuyển đổi sang đơn vị km bằng công thức quy đổi chuẩn là 1 mile = 1.60934 km. Quá trình chuyển đổi được thực hiện bằng lệnh:

vehicle_data <- vehicle_data %>% mutate(mileage_km = mileage / 1.60934)
vehicle_data %>%
  select(mileage, mileage_km) %>%
  head(10)
## # A tibble: 10 × 2
##    mileage mileage_km
##      <dbl>      <dbl>
##  1  183903    114272.
##  2  236643    147044.
##  3  103199     64125.
##  4  118889     73874.
##  5  204170    126866.
##  6   44907     27904.
##  7  129770     80636.
##  8   29146     18111.
##  9  169165    105115.
## 10    5081      3157.

Về mặt kỹ thuật, đoạn mã trên sử dụng hàm mutate() trong gói dplyr để tạo thêm một biến mới có tên mileage_km trong bảng dữ liệu vehicle_data. Bên trong hàm mutate(), phép chia mileage / 1.60934 được áp dụng cho toàn bộ các hàng của biến mileage theo cơ chế vector hóa (vectorized operation) của R, nghĩa là toàn bộ giá trị trong cột được tính toán cùng lúc mà không cần sử dụng vòng lặp thủ công. Phép chia này thực hiện việc chuyển đổi đơn vị đo từ dặm (mile) sang kilômét (km) dựa trên công thức quy đổi tiêu chuẩn 1 mile = 1.60934 km. Kết quả thu được là một cột mới mileage_km được thêm vào cuối bảng dữ liệu, trong khi dữ liệu gốc vẫn được giữ nguyên để phục vụ đối chiếu khi cần. Cuối cùng, hàm select() được dùng để hiển thị hai biến mileage và mileage_km, cho phép người phân tích kiểm tra nhanh kết quả chuyển đổi và đảm bảo độ chính xác của phép tính trước khi tiếp tục các bước xử lý tiếp theo.

Về ý nghĩa thống kê và thực tiễn, việc chuyển đổi đơn vị đo lường từ dặm sang kilômét giúp chuẩn hóa dữ liệu theo hệ đo lường quốc tế (SI), đảm bảo tính thống nhất và dễ so sánh khi thực hiện các phân tích mô tả hoặc mô hình hóa. Điều này đặc biệt quan trọng khi kết hợp dữ liệu từ nhiều nguồn khác nhau, bởi sự không đồng nhất trong đơn vị đo có thể dẫn đến sai lệch nghiêm trọng trong kết quả phân tích. Biến mileage_km phản ánh chính xác quãng đường xe đã di chuyển theo chuẩn quốc tế, giúp các phép phân tích như tương quan giữa quãng đường sử dụng và giá bán (price), hoặc mô hình hồi quy dự đoán giá trị xe theo mức độ hao mòn trở nên chính xác và có ý nghĩa hơn. Từ góc độ thực tiễn, việc chuẩn hóa này không chỉ đảm bảo tính khoa học trong nghiên cứu mà còn hỗ trợ các doanh nghiệp, nhà phân tích hoặc nhà đầu tư có thể đánh giá, so sánh và ra quyết định chính xác dựa trên dữ liệu được thống nhất về mặt đơn vị đo lường.

2.2.3.4.Chuẩn hóa tên biến và thêm chỉ mục xe

Trong quá trình tiền xử lý dữ liệu, một bước quan trọng để đảm bảo tính thống nhất và dễ sử dụng là làm sạch tên biến (tên cột). Dữ liệu thu thập từ nhiều nguồn khác nhau thường có tên cột không đồng nhất về cách viết (chữ hoa, chữ thường, ký tự đặc biệt hoặc dấu cách), điều này có thể gây lỗi hoặc nhầm lẫn trong các bước phân tích sau. Để chuẩn hóa và tăng tính nhất quán, ta tiến hành chuyển toàn bộ tên cột trong tập dữ liệu vehicle_data sang chữ thường. Việc này giúp đảm bảo mọi biến đều có định dạng thống nhất, thuận tiện khi gọi trong các thao tác xử lý, trực quan hóa hoặc xây dựng mô hình.

vehicle_data <- vehicle_data %>%
  rename_with(tolower)

names(vehicle_data)
##  [1] "make"             "model"            "year"             "mileage"         
##  [5] "engine_hp"        "transmission"     "fuel_type"        "drivetrain"      
##  [9] "body_type"        "exterior_color"   "interior_color"   "owner_count"     
## [13] "accident_history" "seller_type"      "condition"        "trim"            
## [17] "vehicle_age"      "mileage_per_year" "brand_popularity" "price"           
## [21] "age"              "car_status"       "price_segment"    "brand_type"      
## [25] "mileage_group"    "interior_group"   "car_id"           "mileage_norm"    
## [29] "mileage_km"

Về mặt kỹ thuật, hàm rename_with() trong gói dplyr được sử dụng để đổi tên toàn bộ hoặc một nhóm cột trong bảng dữ liệu dựa trên một hàm chuyển đổi nhất định. Trong trường hợp này, việc áp dụng hàm tolower() giúp chuyển toàn bộ tên cột sang chữ thường, tạo ra sự thống nhất về định dạng và giúp R xử lý dữ liệu ổn định hơn vì R phân biệt chữ hoa và chữ thường. Khi kết hợp với toán tử %>%, thao tác này trở nên rõ ràng, mạch lạc và dễ tích hợp vào quy trình tiền xử lý dữ liệu phức tạp.

Về ý nghĩa thống kê, việc chuẩn hóa tên cột không ảnh hưởng trực tiếp đến kết quả tính toán nhưng lại đóng vai trò quan trọng trong việc đảm bảo tính toàn vẹn, nhất quán và dễ tái lập của quy trình phân tích. Dữ liệu có tên biến đồng nhất giúp người phân tích tránh sai sót khi gọi biến, dễ dàng hợp nhất nhiều nguồn dữ liệu khác nhau, đồng thời tăng khả năng tự động hóa trong lập trình, chẳng hạn khi chạy các hàm lặp hoặc xây dựng pipeline xử lý. Như vậy, thao tác làm sạch tên cột tuy đơn giản nhưng mang ý nghĩa kỹ thuật và thống kê quan trọng, giúp toàn bộ quá trình phân tích diễn ra trơn tru, chính xác và chuyên nghiệp hơn.

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

Trong quá trình phân tích dữ liệu, việc xác định đúng kiểu dữ liệu (data type) của từng biến là rất quan trọng vì nó ảnh hưởng trực tiếp đến cách R xử lý và hiển thị thông tin. Các biến phân loại, chẳng hạn như loại người bán (seller_type), không nên được lưu dưới dạng ký tự (character) mà cần được chuyển sang dạng factor để có thể sử dụng trong các phép phân tích thống kê, mô hình hồi quy, hoặc trực quan hóa dữ liệu.

Để thực hiện việc này, ta sử dụng hàm mutate() kết hợp với hàm as.factor() để chuyển đổi cột seller_type sang dạng factor như sau:

vehicle_data <- vehicle_data %>%
  mutate(seller_type = as.factor(seller_type))

class(vehicle_data$seller_type)
## [1] "factor"

Về mặt kỹ thuật, hàm mutate() được sử dụng để tạo hoặc cập nhật một biến trong bảng dữ liệu, trong khi hàm as.factor() có chức năng chuyển đổi kiểu dữ liệu ký tự sang dạng phân loại (factor). Khi một biến được lưu dưới dạng factor, R sẽ tự động gán các “mức” (levels) tương ứng với từng giá trị duy nhất, giúp tiết kiệm bộ nhớ và tối ưu hóa quá trình tính toán trong các mô hình thống kê. Việc chuyển đổi này đặc biệt quan trọng khi làm việc với các biến mô tả thuộc tính định tính như “Private”, “Dealer”, hoặc “Certified Dealer” trong seller_type, vì các giá trị này không có ý nghĩa số học mà chỉ mang tính phân biệt nhóm.

Về ý nghĩa thống kê và thực tiễn, việc chuyển đổi biến seller_type sang dạng factor giúp R hiểu đúng bản chất phân loại của dữ liệu, cho phép thực hiện các phép so sánh, thống kê tần suất, hoặc ước lượng trung bình theo nhóm một cách chính xác. Trong các mô hình hồi quy, R sẽ tự động mã hóa các mức của factor thành biến giả (dummy variables), nhờ đó mô hình có thể định lượng được ảnh hưởng của từng loại người bán đến giá xe hoặc các biến kết quả khác. Ngoài ra, từ góc độ thực tế thị trường, phân loại kiểu người bán giúp phân tích hành vi giao dịch, ví dụ: xe bán bởi đại lý chính hãng thường có giá cao hơn nhưng độ tin cậy lớn hơn so với xe do cá nhân bán lại. Do đó, việc chuyển đổi seller_type thành factor không chỉ mang ý nghĩa kỹ thuật trong xử lý dữ liệu mà còn có giá trị thống kê – kinh tế rõ ràng, giúp tăng độ chính xác và khả năng diễn giải trong các phân tích tiếp theo.

2.3. Các thống kê cơ bản

2.3.1. Thống kê mô tả cho biến định lượng

summary(vehicle_data$year)
##    Min. 1st Qu.  Median    Mean 3rd Qu.    Max. 
##    2000    2015    2018    2017    2020    2025

Về mặt kỹ thuật, biến year biểu thị năm sản xuất của xe, được lưu dưới dạng số nguyên và thường dùng để xác định tuổi xe hoặc làm biến đầu vào cho các phép tính như vehicle_age. Kết quả thống kê cho thấy các xe trong dữ liệu được sản xuất trong giai đoạn từ năm 2000 đến 2025, với trung vị là 2018. Điều này cho thấy phần lớn xe trong tập dữ liệu là các mẫu tương đối mới, chủ yếu được sản xuất sau năm 2015. Về mặt thống kê, đây là biến có tính thời gian quan trọng, ảnh hưởng trực tiếp đến giá trị còn lại của xe, vì xe càng mới thì giá trị thường càng cao.

summary(vehicle_data$mileage)
##    Min. 1st Qu.  Median    Mean 3rd Qu.    Max. 
##     500   57654  103331  112660  157865  300000

Về mặt kỹ thuật, biến mileage đo tổng quãng đường mà xe đã di chuyển (tính bằng km). Đây là một biến định lượng liên tục và thường được sử dụng để phản ánh mức độ hao mòn và tình trạng sử dụng của xe. Thống kê cho thấy giá trị mileage dao động từ 500 km đến 300.000 km, với trung vị là khoảng 103.000 km. Về mặt thống kê, phạm vi rộng này cho thấy dữ liệu bao gồm cả xe gần như mới và xe đã sử dụng lâu dài, giúp việc phân tích giá xe theo mức độ sử dụng trở nên đa dạng và đáng tin cậy.

summary(vehicle_data$engine_hp)
##    Min. 1st Qu.  Median    Mean 3rd Qu.    Max. 
##    90.0   162.0   215.0   235.7   300.0   581.0

Về mặt kỹ thuật, biến engine_hp đại diện cho công suất động cơ của xe (tính bằng mã lực – horsepower). Đây là biến định lượng quan trọng, thường được sử dụng để đánh giá hiệu năng của xe. Thống kê cho thấy giá trị dao động từ 90 đến 581 mã lực, với trung vị 215 mã lực, phản ánh sự đa dạng về phân khúc xe từ xe phổ thông đến xe thể thao cao cấp. Về mặt thống kê, công suất động cơ là yếu tố có thể ảnh hưởng trực tiếp đến giá xe và khả năng tiêu thụ nhiên liệu, do đó nó đóng vai trò quan trọng trong các mô hình dự đoán giá.

summary(vehicle_data$owner_count)
##    Min. 1st Qu.  Median    Mean 3rd Qu.    Max. 
##   1.000   2.000   4.000   3.478   5.000   5.000

Về mặt kỹ thuật, biến owner_count cho biết số lượng chủ sở hữu mà xe đã từng có, là một biến rời rạc (integer). Thống kê cho thấy giá trị dao động từ 1 đến 5, trung vị là 4, cho thấy phần lớn xe đã qua nhiều chủ sở hữu. Về mặt thống kê, số lượng chủ xe phản ánh mức độ luân chuyển của xe trên thị trường — xe qua càng nhiều chủ thường có giá trị thấp hơn do khả năng bảo dưỡng không đồng nhất và rủi ro lịch sử sử dụng cao hơn.

summary(vehicle_data$vehicle_age)
##    Min. 1st Qu.  Median    Mean 3rd Qu.    Max. 
##   1.000   5.000   7.000   7.586  10.000  25.000

Về mặt kỹ thuật, biến vehicle_age được tính toán từ năm hiện tại trừ đi năm sản xuất, thể hiện tuổi của xe. Kết quả cho thấy tuổi xe trong tập dữ liệu dao động từ 1 đến 25 năm, với trung vị 7 năm. Về mặt thống kê, biến này là một trong những yếu tố chính quyết định giá trị còn lại của xe, vì tuổi xe càng cao thì giá trị thị trường thường giảm dần. Sự phân bố này cũng gợi ý rằng dữ liệu bao gồm nhiều xe đã qua sử dụng, phản ánh tốt thị trường xe cũ.

summary(vehicle_data$mileage_per_year)
##     Min.  1st Qu.   Median     Mean  3rd Qu.     Max. 
##    33.33 10487.63 14688.12 14540.67 18685.94 55391.00

Về mặt kỹ thuật, biến mileage_per_year thể hiện quãng đường trung bình mà xe di chuyển mỗi năm, được tính bằng tổng mileage chia cho vehicle_age. Kết quả cho thấy giá trị dao động từ 33 km/năm đến hơn 55.000 km/năm, với trung vị khoảng 14.600 km/năm. Về mặt thống kê, biến này giúp đánh giá mức độ sử dụng xe theo thời gian, loại bỏ ảnh hưởng của tuổi xe. Các giá trị cực đại cho thấy có một số xe được sử dụng với tần suất cao, có thể là xe dịch vụ hoặc xe thương mại.

summary(vehicle_data$brand_popularity)
##    Min. 1st Qu.  Median    Mean 3rd Qu.    Max. 
## 0.03932 0.03984 0.04002 0.04000 0.04015 0.04048

Về mặt kỹ thuật, biến brand_popularity phản ánh mức độ phổ biến hoặc thị phần tương đối của thương hiệu xe, được biểu diễn bằng một giá trị số nhỏ (dao động từ 0.0393 đến 0.0405). Đây có thể là chỉ số tính toán dựa trên tần suất xuất hiện của thương hiệu trong tập dữ liệu. Về mặt thống kê, phạm vi hẹp của biến này cho thấy các thương hiệu trong dữ liệu có mức phổ biến khá cân bằng, không có thương hiệu nào chiếm ưu thế tuyệt đối. Biến này có thể được sử dụng như một yếu tố bổ sung trong mô hình dự đoán giá để xem xét tác động của thương hiệu đến giá trị xe.

summary(vehicle_data$price)
##    Min. 1st Qu.  Median    Mean 3rd Qu.    Max. 
##    1500   10325   17865   20329   27601   93422

Biến price thể hiện giá bán của xe (tính bằng đơn vị tiền tệ, có thể là USD hoặc tương đương), và đây là biến mục tiêu quan trọng nhất trong bài toán phân tích và dự đoán giá ô tô. Về mặt kỹ thuật, đây là biến định lượng liên tục, được sử dụng làm đầu ra (output variable) trong các mô hình hồi quy hoặc dự đoán. Việc sử dụng hàm summary() giúp mô tả đặc trưng thống kê cơ bản của biến, bao gồm giá trị nhỏ nhất, lớn nhất, trung bình, trung vị và các tứ phân vị, qua đó đánh giá sơ bộ sự phân bố và độ biến thiên của giá xe trong tập dữ liệu.

Về mặt thống kê, kết quả cho thấy giá xe dao động từ 1.500 đến 93.422, với trung vị là 17.865 và trung bình là 20.329. Sự chênh lệch khá lớn giữa giá trị trung bình và giá trị cực đại cho thấy phân phối giá bị lệch phải (right-skewed) — tức là có một số ít xe có giá rất cao kéo trung bình tăng lên. Khoảng giá rộng này phản ánh sự đa dạng trong dữ liệu, bao gồm cả xe phổ thông giá thấp và xe hạng sang giá cao. Nhìn chung, biến price không chỉ phản ánh giá trị thị trường của từng xe mà còn là thước đo tổng hợp ảnh hưởng của nhiều yếu tố khác nhau, như thương hiệu, năm sản xuất, quãng đường đi, công suất động cơ và tình trạng xe, nên việc hiểu rõ đặc trưng của biến này là nền tảng cho mọi phân tích tiếp theo trong mô hình định giá.

2.3.2. Thống kê mô tả cho biến định tính

table(vehicle_data$make)
## 
##         Acura          Audi           BMW      Cadillac     Chevrolet 
##         40147         40022         39840         39847         39982 
##      Chrysler         Dodge          Ford           GMC         Honda 
##         40059         40035         39842         39754         40015 
##       Hyundai          Jeep           Kia    Land Rover         Lexus 
##         39318         40006         40484         40133         39921 
##         Mazda Mercedes-Benz        Nissan       Porsche           Ram 
##         40247         39794         40217         40210         40148 
##        Subaru         Tesla        Toyota    Volkswagen         Volvo 
##         40230         40226         39627         40054         39842

Về mặt kỹ thuật, biến make biểu thị hãng sản xuất của xe và được lưu dưới dạng biến phân loại (categorical variable). Kết quả thống kê cho thấy có hơn 20 thương hiệu khác nhau trong tập dữ liệu, mỗi hãng có số lượng mẫu tương đối đồng đều, dao động khoảng 39.000–40.000 xe mỗi hãng. Điều này cho thấy dữ liệu được phân bố khá cân bằng giữa các thương hiệu, giúp đảm bảo tính đại diện khi so sánh giá hoặc phân tích đặc trưng theo hãng. Về mặt thống kê, biến make là yếu tố quan trọng trong việc đánh giá ảnh hưởng của thương hiệu đến giá bán, bởi các hãng xe cao cấp như BMW, Mercedes-Benz hay Porsche thường có giá trung bình cao hơn đáng kể so với các hãng phổ thông như Ford hay Hyundai.

table(vehicle_data$model)
## 
##           1500           2500       3 Series            300           3500 
##          13145          13539           7871          20202          13464 
##       5 Series            911             A4             A6         Acadia 
##           8079          10016           7931           7893           9860 
##         Accord         Altima          Atlas        C-Class         Camaro 
##           8100           8025           8079           9959           7901 
##          Camry        Cayenne     Challenger        Charger       Cherokee 
##           8030          10070          13239          13457          10067 
##          Civic        Compass        Corolla           CR-V      Crosstrek 
##           7949          10061           7837           7967          10147 
##            CT5           CX-5           CX-9       Defender      Discovery 
##          10010          10014          10122          13423          13321 
##        Durango        E-Class        Elantra        Equinox             ES 
##          13339           9999           9707           8026           7990 
##       Escalade         Escape       Explorer          F-150          Focus 
##           9890           7879           7979           7961           8004 
##       Forester          Forte            GLE           Golf Grand Cherokee 
##          10038           8196          10072           8012           9968 
##             GX     Highlander        Impreza        Integra             IS 
##           7930           7943          10083          10089           7904 
##          Jetta          Lyriq             M3          Macan         Malibu 
##           7931          10055           8071          10034           8170 
##         Mazda3         Mazda6            MDX        Model 3        Model S 
##          10017          10094           9976          10107          10040 
##        Model X        Model Y        Mustang             NX        Odyssey 
##          10046          10033           8019           8032           7996 
##         Optima        Outback       Pacifica       Panamera         Passat 
##           7965           9962          19857          10090           8058 
##     Pathfinder          Pilot             Q5             Q7             R8 
##           7988           8003           7988           8165           8045 
##    Range Rover           RAV4            RDX          Rogue             RX 
##          13389           7880          10111           8086           8065 
##        S-Class            S60       Santa Fe         Sentra         Sierra 
##           9764           9964           9874           7994          10029 
##      Silverado         Sonata        Sorento       Sportage         Tacoma 
##           7894           9877           8097           8103           7937 
##          Tahoe      Telluride        Terrain         Tiguan          Titan 
##           7991           8123          10031           7974           8124 
##            TLX         Tucson            V60       Wrangler             X3 
##           9971           9860           9837           9910           7996 
##             X5           XC60           XC90            XT5          Yukon 
##           7823          10008          10033           9892           9834

Về mặt kỹ thuật, biến model biểu thị dòng xe cụ thể của từng hãng, chẳng hạn như “Camry”, “Civic” hay “Model 3”. Đây là biến phân loại có số lượng mức (levels) rất lớn, cho thấy tính đa dạng cao trong dữ liệu. Mỗi mẫu xe có số lượng bản ghi dao động quanh 10.000 xe, giúp đảm bảo đủ dữ liệu cho việc phân tích so sánh giữa các dòng. Về mặt thống kê, biến model cho phép phân tích chi tiết hơn trong nội bộ từng hãng, ví dụ để xác định dòng xe nào giữ giá tốt nhất hoặc được ưa chuộng nhất. Nó cũng là yếu tố quan trọng trong mô hình dự đoán giá, phản ánh phân khúc và đặc điểm kỹ thuật riêng của từng dòng xe

table(vehicle_data$transmission)
## 
## Automatic    Manual 
##    500263    499737

Về mặt kỹ thuật, biến transmission thể hiện loại hộp số của xe, gồm hai nhóm chính: “Automatic” (tự động) và “Manual” (số tay), với tần suất gần như tương đương (500.263 xe số tự động và 499.737 xe số tay). Đây là biến phân loại nhị phân, thường được dùng để xem xét sự khác biệt về giá hoặc thị hiếu người tiêu dùng. Về mặt thống kê, sự cân bằng giữa hai loại hộp số cho thấy dữ liệu phản ánh được thị trường đa dạng, nơi người dùng có nhu cầu cả về xe tiện lợi (tự động) và xe thể thao hoặc tiết kiệm nhiên liệu (số tay).

table(vehicle_data$fuel_type)
## 
##   Diesel Electric Gasoline 
##   320453   359597   319950

Về mặt kỹ thuật, biến fuel_type mô tả loại nhiên liệu mà xe sử dụng, bao gồm “Diesel”, “Electric” và “Gasoline”. Dữ liệu cho thấy ba loại nhiên liệu có phân bố tương đối đồng đều, trong đó “Electric” chiếm ưu thế nhẹ với khoảng 359.597 xe, tiếp theo là “Diesel” và “Gasoline”. Về mặt thống kê, biến này rất quan trọng trong việc phân tích xu hướng thị trường xe xanh, khi các mẫu xe điện ngày càng gia tăng. Ngoài ra, loại nhiên liệu còn ảnh hưởng trực tiếp đến chi phí vận hành và giá trị thị trường của xe.

table(vehicle_data$drivetrain)
## 
##    AWD    FWD    RWD 
## 361110 320142 318748

Về mặt kỹ thuật, biến drivetrain phản ánh hệ dẫn động của xe, gồm ba loại phổ biến: “AWD” (dẫn động bốn bánh), “FWD” (dẫn động cầu trước) và “RWD” (dẫn động cầu sau). Dữ liệu cho thấy ba loại có tần suất tương đối cân bằng, với AWD chiếm cao nhất – khoảng 361.110 xe. Về mặt thống kê, loại dẫn động ảnh hưởng mạnh đến khả năng vận hành và giá bán. Xe AWD thường có giá cao hơn do công nghệ phức tạp và hiệu năng vượt trội, trong khi FWD phổ biến ở xe gia đình do tiết kiệm nhiên liệu hơn.

table(vehicle_data$body_type)
## 
##        Coupe    Hatchback      Minivan Pickup Truck        Sedan          SUV 
##        86302        26930        33259       106773       326683       406693 
##        Wagon 
##        13360

Về mặt kỹ thuật, biến body_type mô tả kiểu dáng thân xe, gồm các loại như “SUV”, “Sedan”, “Pickup Truck”, “Coupe”, “Hatchback”, “Minivan” và “Wagon”. Trong đó, SUV chiếm tỷ trọng lớn nhất (406.693 xe), cho thấy xu hướng tiêu dùng hiện nay ưa chuộng các dòng xe gầm cao, đa dụng. Về mặt thống kê, biến này giúp phân tích sở thích của người tiêu dùng và mối quan hệ giữa kiểu dáng và giá bán. Các dòng SUV và Sedan thường có giá trung bình cao hơn do nhu cầu lớn và tính tiện dụng.

table(vehicle_data$exterior_color)
## 
##  Black   Blue   Gray    Red Silver  White 
## 166176 166609 166668 166793 166820 166934

Về mặt kỹ thuật, biến exterior_color thể hiện màu sơn bên ngoài của xe, được lưu dưới dạng biến phân loại (categorical variable). Dữ liệu cho thấy sáu màu chủ đạo gồm Black, Blue, Gray, Red, Silver và White, với số lượng mẫu khá cân bằng, dao động quanh 166.000 xe cho mỗi màu. Điều này giúp đảm bảo tính đa dạng và đại diện của dữ liệu. Về mặt thống kê, biến này phản ánh xu hướng lựa chọn màu sắc phổ biến trên thị trường xe ô tô, trong đó các màu trung tính như đen, bạc và trắng thường chiếm ưu thế do dễ bán lại và phù hợp với nhiều đối tượng khách hàng.

table(vehicle_data$interior_color)
## 
##  Beige  Black  Brown   Gray 
## 250570 249862 249414 250154

Về mặt kỹ thuật, biến interior_color mô tả màu nội thất của xe, cũng là biến phân loại với bốn giá trị chính: Beige, Black, Brown và Gray. Mỗi nhóm màu có tần suất gần như bằng nhau (khoảng 250.000 xe), cho thấy dữ liệu được phân bố đồng đều. Về mặt thống kê, màu nội thất là yếu tố có thể ảnh hưởng đến giá trị thẩm mỹ và cảm nhận chất lượng của xe, tuy không ảnh hưởng mạnh đến giá bán như các yếu tố kỹ thuật khác nhưng vẫn đóng vai trò trong việc đánh giá độ sang trọng và mức độ ưa chuộng của xe trên thị trường.

table(vehicle_data$accident_history)
## 
##  Major  Minor   None 
##  49886 199981 750133

Về mặt kỹ thuật, biến accident_history phản ánh tình trạng tai nạn của xe trong quá khứ, gồm ba mức: None, Minor và Major. Dữ liệu cho thấy phần lớn xe không có lịch sử tai nạn (750.133 xe), trong khi số xe từng gặp tai nạn nhỏ và lớn lần lượt là 199.981 và 49.886. Về mặt thống kê, biến này rất quan trọng trong đánh giá giá trị còn lại và độ tin cậy của xe đã qua sử dụng, vì xe từng gặp tai nạn thường có giá bán thấp hơn đáng kể, đặc biệt nếu mức độ hư hỏng là nghiêm trọng (Major).

table(vehicle_data$seller_type)
## 
##  Dealer Private 
##  699710  300290

Về mặt kỹ thuật, biến seller_type cho biết loại người bán xe, gồm hai nhóm chính: Dealer (đại lý) và Private (cá nhân). Trong dữ liệu, 69,9% xe được bán qua đại lý và 30,1% qua cá nhân. Về mặt thống kê, điều này phản ánh cấu trúc thị trường ô tô thứ cấp, trong đó phần lớn giao dịch diễn ra thông qua đại lý do tính đảm bảo và uy tín cao hơn. Biến này cũng hữu ích trong phân tích giá, vì xe bán từ đại lý thường có giá cao hơn do chi phí bảo hành, kiểm định và lợi nhuận thương mại.

table(vehicle_data$condition)
## 
## Excellent      Fair      Good 
##    400373     99944    499683

Về mặt kỹ thuật, biến condition mô tả tình trạng tổng thể của xe, gồm ba mức: Excellent, Good và Fair. Kết quả cho thấy đa số xe được đánh giá ở mức Good (499.683 xe), tiếp theo là Excellent (400.373 xe), và chỉ 99.944 xe ở mức Fair. Về mặt thống kê, biến này phản ánh chất lượng bảo dưỡng và tuổi thọ của xe, là yếu tố trực tiếp ảnh hưởng đến giá trị bán lại. Xe có tình trạng “Excellent” thường được định giá cao hơn đáng kể, trong khi nhóm “Fair” có thể cần chi phí sửa chữa lớn hơn.

table(vehicle_data$trim)
## 
##    Base      EX Limited      LX   Sport Touring 
##  166750  166209  167294  167013  166280  166454

Về mặt kỹ thuật, biến trim cho biết phiên bản hoặc cấp độ trang bị của xe, chẳng hạn như “Base”, “EX”, “Limited”, “LX” hay “Sport Touring”. Đây là biến phân loại thể hiện sự khác biệt về tính năng, tiện nghi hoặc động cơ giữa các phiên bản trong cùng một dòng xe. Số lượng xe ở các nhóm khá cân bằng, dao động quanh 166.000–167.000 xe mỗi loại. Về mặt thống kê, biến trim giúp phân tích sự chênh lệch giá giữa các cấp độ trang bị, cho phép xác định liệu phiên bản cao cấp có giữ giá tốt hơn so với bản tiêu chuẩn hay không, từ đó hỗ trợ trong việc dự báo giá trị xe theo cấu hình.

2.3.3. Phân tích biến Price

2.3.3.1. Thống kê mô tả

Phần này nhằm mô tả đặc điểm tổng quát của biến Price trong bộ dữ liệu ô tô sau khi đã được làm sạch. Cụ thể, mục tiêu là:

Xác định các chỉ số thống kê cơ bản như giá trị trung bình, trung vị, độ lệch chuẩn, min, max và các tứ phân vị.

Đánh giá mức độ phân tán và hình dạng phân phối của giá xe.

Nhận biết khoảng giá tập trung và sự chênh lệch giữa các nhóm xe trong dữ liệu. Thông qua thống kê mô tả, phần này giúp nắm bắt được bức tranh tổng thể về mức giá và mức độ biến động của thị trường xe trong tập dữ liệu.

mean(vehicle_data$price, na.rm = TRUE)
## [1] 20329.3

Ý nghĩa kỹ thuật: Lệnh này tính giá trị trung bình (mean) của biến price, bỏ qua các giá trị bị thiếu (NA). Kết quả là 20.329,3, thể hiện mức giá trung bình của toàn bộ các xe trong tập dữ liệu. Đây là một phép đo xu hướng trung tâm, được dùng phổ biến trong phân tích mô tả để xác định giá trị “đại diện” của biến liên tục.

Ý nghĩa thống kê: Giá trung bình cho thấy mức giá phổ biến nhất trên thị trường, nhưng có thể bị ảnh hưởng bởi các xe giá cực cao. Việc giá trung bình (20.329,3) cao hơn trung vị cho thấy phân phối lệch phải (right-skewed) – nghĩa là phần lớn xe có giá thấp hơn mức trung bình, và một số ít xe cao cấp có giá rất cao đã kéo trung bình lên.

median(vehicle_data$price, na.rm = TRUE)
## [1] 17864.74

Ý nghĩa kỹ thuật: Lệnh này tính trung vị (median) của biến price, là giá trị nằm chính giữa tập dữ liệu khi sắp xếp theo thứ tự tăng dần. Kết quả thu được là 17.864,74. Trung vị ít bị ảnh hưởng bởi các giá trị cực đoan, do đó phản ánh tốt giá trị trung tâm thực tế.

Ý nghĩa thống kê: Trung vị cho thấy một nửa số xe có giá thấp hơn 17.864,74 và nửa còn lại cao hơn giá này. Khi so sánh với trung bình, có thể thấy trung vị nhỏ hơn trung bình, điều này củng cố nhận định rằng phân phối giá xe bị lệch phải. Trung vị là một thước đo ổn định hơn khi phân tích các biến có độ lệch cao hoặc chứa giá trị ngoại lai.

sd(vehicle_data$price, na.rm = TRUE)
## [1] 13644.47

Ý nghĩa kỹ thuật: Hàm sd() tính độ lệch chuẩn (standard deviation) của biến price, kết quả là 13.644,47. Đây là thước đo mức độ phân tán của dữ liệu xung quanh giá trị trung bình. Độ lệch chuẩn càng lớn thì các giá trị càng phân tán rộng.

Ý nghĩa thống kê: Giá trị độ lệch chuẩn cao cho thấy giá xe có sự biến động lớn, phản ánh thị trường xe gồm nhiều phân khúc khác nhau, từ giá thấp đến rất cao. Điều này cũng cho thấy dữ liệu có thể chứa các giá trị ngoại lai (outliers) – đặc trưng của dữ liệu giá sản phẩm thực tế.

var(vehicle_data$price, na.rm = TRUE)
## [1] 186171485

Ý nghĩa kỹ thuật: Lệnh này tính phương sai (variance) của biến price, là bình phương của độ lệch chuẩn. Kết quả là 18.617.1485, cho thấy mức độ phân tán lớn của dữ liệu quanh giá trị trung bình.

Ý nghĩa thống kê: Phương sai cung cấp cùng thông tin với độ lệch chuẩn, nhưng ở dạng bình phương đơn vị. Giá trị phương sai cao xác nhận rằng sự chênh lệch giữa giá các xe là rất lớn, đặc biệt giữa các dòng xe phổ thông và xe cao cấp.

min(vehicle_data$price, na.rm = TRUE)
## [1] 1500
max(vehicle_data$price, na.rm = TRUE)
## [1] 93422.09

Ý nghĩa kỹ thuật: Hai hàm này lần lượt trả về giá nhỏ nhất và lớn nhất trong biến price. Kết quả là 1.500 (thấp nhất) và 93.422,09 (cao nhất). Đây là các giá trị biên giúp xác định phạm vi giá của toàn bộ tập dữ liệu.

Ý nghĩa thống kê: Khoảng giá rất rộng cho thấy thị trường ô tô trong dữ liệu trải dài từ xe giá rẻ đến xe sang trọng, minh chứng cho sự đa dạng trong mẫu nghiên cứu. Tuy nhiên, chênh lệch lớn này cũng cảnh báo khả năng tồn tại outlier (giá trị cực đoan) có thể ảnh hưởng đến các thống kê trung bình.

range(vehicle_data$price, na.rm = TRUE)
## [1]  1500.00 93422.09

Ý nghĩa kỹ thuật: Lệnh range() trả về khoảng giá trị nhỏ nhất và lớn nhất cùng lúc, tương đương với hai hàm min() và max(). Kết quả là [1500; 93422.09], giúp xác định phạm vi giá trị mà biến có thể nhận.

Ý nghĩa thống kê: Khoảng giá trị này minh họa rõ độ phân tán rộng của dữ liệu, thể hiện sự khác biệt lớn giữa các dòng xe. Đây là chỉ báo quan trọng khi quyết định có nên chuẩn hóa dữ liệu (normalization) trước khi phân tích mô hình hồi quy hoặc dự đoán hay không.

quantile(vehicle_data$price, probs = c(0.25, 0.75), na.rm = TRUE)
##      25%      75% 
## 10324.53 27601.40

Ý nghĩa kỹ thuật: Lệnh này tính các tứ phân vị thứ nhất (Q1 = 10.324,53) và thứ ba (Q3 = 27.601,40), tương ứng với 25% và 75% dữ liệu. Khoảng giữa hai giá trị này gọi là IQR – Interquartile Range.

Ý nghĩa thống kê: Kết quả cho thấy 50% số xe có giá nằm trong khoảng từ 10.324 đến 27.601, nghĩa là phần lớn xe thuộc nhóm tầm trung.

describe(vehicle_data$price)
##    vars     n    mean       sd   median  trimmed      mad  min      max
## X1    1 1e+06 20329.3 13644.47 17864.74 18940.12 12447.98 1500 93422.09
##       range skew kurtosis    se
## X1 91922.09 1.03     1.21 13.64

Ý nghĩa kỹ thuật: Hàm describe() (thuộc gói psych) tạo bảng tóm tắt thống kê đầy đủ gồm trung bình, trung vị, độ lệch chuẩn, phương sai, độ lệch tuyệt đối trung bình (mad), giá trị cắt tỉa (trimmed mean), min, max và số lượng quan sát (n). Đây là công cụ giúp nhìn tổng thể các đặc trưng thống kê của biến một cách trực quan và nhanh chóng.

Ý nghĩa thống kê: Bảng kết quả xác nhận lại toàn bộ các chỉ số đã tính trước, đồng thời cung cấp thêm mean trimmed (18.940,12) — tức là giá trung bình sau khi loại bỏ các giá trị cực đoan. Việc giá trị này thấp hơn mean ban đầu cho thấy ảnh hưởng đáng kể của các xe có giá rất cao trong dữ liệu. Tóm lại, describe() là công cụ tổng hợp hữu ích giúp hiểu sâu hơn về phân phối và mức độ biến thiên của biến giá.

# Tính phương sai và độ lệch chuẩn của giá xe (price) để đo mức độ biến động.

vehicle_data %>% summarise(var_price = var(price, na.rm = TRUE),
                           sd_price = sd(price, na.rm = TRUE))
## # A tibble: 1 × 2
##    var_price sd_price
##        <dbl>    <dbl>
## 1 186171485.   13644.

tính phương sai (variance) và độ lệch chuẩn (standard deviation) của biến price trong bộ dữ liệu vehicle_data. Về mặt kỹ thuật, đoạn mã sử dụng hàm summarise() của gói dplyr để tổng hợp hai chỉ số: var(price, na.rm = TRUE) tính phương sai của giá xe, còn sd(price, na.rm = TRUE) tính độ lệch chuẩn — cả hai đều loại bỏ các giá trị bị thiếu (NA). Bảng kết quả hiển thị hai cột: var_price = 186171485 và sd_price = 13644.47.

Về mặt thống kê, phương sai đo lường mức độ phân tán của các giá trị giá xe so với trung bình — giá trị phương sai càng lớn cho thấy các mức giá càng đa dạng và phân tán mạnh quanh trung bình. Tuy nhiên, do phương sai được tính theo đơn vị bình phương của biến gốc (ở đây là đơn vị “giá tiền bình phương”), nên nó thường khó diễn giải trực tiếp. Vì vậy, độ lệch chuẩn được sử dụng như một thước đo tương đương nhưng dễ hiểu hơn, vì nó có cùng đơn vị với giá trị gốc (đơn vị giá). Kết quả cho thấy độ lệch chuẩn 13,644.47 là khá cao so với giá trung bình (khoảng 20,329.3), điều này chứng tỏ giá xe trong bộ dữ liệu có mức độ biến động lớn — tức là có sự chênh lệch đáng kể giữa các mức giá, phản ánh sự đa dạng của các loại xe trong mẫu nghiên cứu (về thương hiệu, đời xe, hoặc chất lượng).

# Tính giá trị trung bình và trung vị của biến giá (price).
vehicle_data %>% summarise(mean_price = mean(price, na.rm = TRUE),
                           median_price = median(price, na.rm = TRUE))
## # A tibble: 1 × 2
##   mean_price median_price
##        <dbl>        <dbl>
## 1     20329.       17865.

Kết quả trong hình thể hiện việc tính giá trị trung bình (mean) và giá trị trung vị (median) của biến price trong bộ dữ liệu vehicle_data. Về mặt kỹ thuật, đoạn mã R sử dụng hàm summarise() trong gói dplyr để tổng hợp dữ liệu. Cụ thể, mean(price, na.rm = TRUE) tính trung bình của biến giá price sau khi loại bỏ các giá trị bị thiếu (NA), còn median(price, na.rm = TRUE) tính trung vị của cùng biến này cũng với điều kiện loại bỏ các giá trị thiếu. Kết quả trả về là một bảng tóm tắt (tibble) gồm hai cột: mean_price và median_price, lần lượt thể hiện giá trị trung bình và trung vị của giá xe.

Về mặt thống kê, giá trị trung bình (mean_price = 20329.3) đại diện cho mức giá trung tâm của toàn bộ các xe trong dữ liệu — nó bị ảnh hưởng bởi các giá trị ngoại lai (ví dụ các xe có giá rất cao hoặc rất thấp). Trong khi đó, giá trị trung vị (median_price = 17864.74) thể hiện giá trị mà tại đó 50% số xe có giá thấp hơn và 50% số xe có giá cao hơn. Việc trung bình lớn hơn trung vị cho thấy phân phối giá xe có xu hướng lệch phải (right-skewed), tức là tồn tại một số ít xe có giá rất cao kéo giá trị trung bình lên. Do đó, trung vị là thước đo đại diện tốt hơn cho “mức giá điển hình” của xe trong mẫu dữ liệu này, trong khi trung bình phản ánh xu hướng tổng quát có tính đến ảnh hưởng của các giá trị cực đoan.

# Xác định giá thấp nhất và cao nhất trong tập dữ liệu.

vehicle_data %>% summarise(min_price = min(price, na.rm = TRUE),
                           max_price = max(price, na.rm = TRUE))
## # A tibble: 1 × 2
##   min_price max_price
##       <dbl>     <dbl>
## 1      1500    93422.

Về mặt kỹ thuật, đoạn mã sử dụng hàm summarise() của gói dplyr để tổng hợp hai chỉ số: min(price, na.rm = TRUE) tìm giá trị thấp nhất của biến price, và max(price, na.rm = TRUE) tìm giá trị cao nhất, đồng thời loại bỏ các giá trị thiếu (NA) để đảm bảo tính chính xác. Bảng kết quả trả về cho thấy min_price = 1500 và max_price = 93422.09.

Về mặt thống kê, giá trị nhỏ nhất (1,500) đại diện cho chiếc xe có giá thấp nhất trong toàn bộ dữ liệu, còn giá trị lớn nhất (93,422.09) biểu thị chiếc xe đắt nhất. Khoảng chênh lệch lớn giữa hai giá trị này cho thấy dữ liệu có phạm vi biến thiên (range) rất rộng, phản ánh sự đa dạng đáng kể về giá cả trong thị trường xe — có thể bao gồm cả xe phổ thông giá rẻ lẫn xe cao cấp. Sự chênh lệch này cũng gợi ý khả năng tồn tại giá trị ngoại lai (outliers) ở nhóm giá cao, điều này phù hợp với nhận định trước đó rằng phân phối giá xe có xu hướng lệch phải. Việc nhận biết khoảng biến thiên như vậy giúp nhà phân tích hiểu rõ hơn về độ phân tán và cấu trúc của dữ liệu, đồng thời hỗ trợ việc lựa chọn các phương pháp mô hình hóa phù hợp hơn trong các phân tích thống kê tiếp theo.

2.3.3.2. Phân tích tương tác & phân khúc

Phần này nhằm tìm hiểu sự khác biệt và mối quan hệ giữa giá xe với các yếu tố khác trong bộ dữ liệu. Cụ thể:

Phân tích tương tác giữa Price với Make, Year, và Mileage để xác định yếu tố ảnh hưởng mạnh đến giá.

Phân khúc dữ liệu thành các nhóm giá (thấp, trung bình, cao) nhằm đánh giá sự khác biệt trong đặc điểm kỹ thuật giữa các phân khúc.

So sánh xu hướng giá giữa các hãng, năm sản xuất và mức sử dụng. Mục tiêu cuối cùng là phát hiện các mô hình giá đặc trưng và nhóm đối tượng xe có giá trị tương đồng.

Giá TB theo Nhiên liệu & Hộp số: Tính Giá bán trung vị theo sự kết hợp của 2 yếu tố.

vehicle_data %>% group_by(fuel_type, transmission) %>% summarise(median_price = median(price), .groups = 'drop')
## # A tibble: 6 × 3
##   fuel_type transmission median_price
##   <chr>     <chr>               <dbl>
## 1 Diesel    Automatic          17391.
## 2 Diesel    Manual             17395.
## 3 Electric  Automatic          18765.
## 4 Electric  Manual             18811.
## 5 Gasoline  Automatic          17295.
## 6 Gasoline  Manual             17416.

Đoạn code này nhóm dữ liệu đồng thời theo hai biến phân loại fuel_type (loại nhiên liệu: Diesel, Electric, Gasoline) và transmission (hộp số: Automatic, Manual), sau đó tính giá trung vị (median) của biến price cho từng tổ hợp nhóm. Việc sử dụng trung vị thay vì trung bình giúp giảm ảnh hưởng của các giá trị ngoại lai trong dữ liệu giá — vốn thường có sự chênh lệch lớn giữa các dòng xe. Tham số .groups = ‘drop’ đảm bảo dữ liệu sau khi tóm tắt sẽ được “phẳng hóa”, thuận tiện cho việc xuất bảng hoặc vẽ biểu đồ.

Ý nghĩa thống kê: Kết quả cho thấy giá trung vị của xe điện cao nhất (khoảng 18.800), tiếp đến là xe chạy dầu và xăng (khoảng 17.300–17.400). Điều này phản ánh xu hướng giá trị cao của xe điện do công nghệ mới, chi phí pin cao và nhu cầu thị trường tăng. Ngoài ra, hộp số tự động có giá trung vị nhỉnh hơn số tay, phù hợp với thực tế rằng hộp số tự động thường được trang bị trên các mẫu xe cao cấp hoặc đời mới hơn. Như vậy, sự kết hợp giữa fuel_type và transmission giúp làm rõ tác động tương hỗ của hai yếu tố kỹ thuật đến giá bán, cung cấp góc nhìn đa chiều hơn so với khi phân tích riêng từng biến.

Giá TB theo Tình trạng & Nguồn bán: Tính Giá bán trung vị theo condition và seller_type.

vehicle_data %>% group_by(condition, seller_type) %>% summarise(median_price = median(price), .groups = 'drop')
## # A tibble: 6 × 3
##   condition seller_type median_price
##   <chr>     <fct>              <dbl>
## 1 Excellent Dealer            18889.
## 2 Excellent Private           17927.
## 3 Fair      Dealer            16226.
## 4 Fair      Private           15317.
## 5 Good      Dealer            17977.
## 6 Good      Private           17132.

Lệnh này thực hiện nhóm dữ liệu theo hai biến condition (tình trạng xe: Excellent, Good, Fair) và seller_type (loại người bán: Dealer hoặc Private), sau đó tính giá trung vị cho từng nhóm. Việc nhóm theo hai yếu tố cùng lúc giúp đánh giá ảnh hưởng kết hợp giữa chất lượng vật lý và kênh bán hàng đến giá trị xe.

Ý nghĩa thống kê: Kết quả chỉ ra rằng xe trong tình trạng “Excellent” và được bán qua đại lý (Dealer) có giá trung vị cao nhất (~18.889), trong khi xe “Fair” do cá nhân bán có giá thấp nhất (~15.317). Sự khác biệt này phản ánh niềm tin và kỳ vọng của người mua: đại lý thường cung cấp xe đã kiểm định, bảo hành và uy tín hơn, trong khi xe cá nhân có thể thiếu bảo dưỡng đồng nhất. Về mặt thống kê, điều này cho thấy tình trạng xe và nguồn bán có ảnh hưởng mang tính nhân tố (factorial interaction), có thể được đưa vào các mô hình hồi quy tương tác để dự đoán giá một cách chính xác hơn.

Giá TB theo Tuổi xe: Phân nhóm year thành Cũ/Mới (>= 2018) và tính Giá TB của mỗi nhóm.

vehicle_data %>% mutate(age_group = ifelse(year >= 2018, "Mới", "Cũ")) %>% group_by(age_group) %>% summarise(mean_price = mean(price), .groups = 'drop')
## # A tibble: 2 × 2
##   age_group mean_price
##   <chr>          <dbl>
## 1 Cũ            12788.
## 2 Mới           27870.

Đoạn code sử dụng mutate() để tạo biến mới age_group nhằm phân loại xe thành hai nhóm tuổi: “Mới” (năm ≥ 2018) và “Cũ” (năm < 2018). Sau đó, group_by() và summarise() được dùng để tính giá trung bình (mean) cho từng nhóm. Đây là một kỹ thuật tiền xử lý phổ biến nhằm đơn giản hóa dữ liệu liên tục (năm sản xuất) thành các nhóm rời rạc dễ phân tích.

Ý nghĩa thống kê: Kết quả cho thấy xe mới có giá trung bình 27.870,46, cao gấp đôi xe cũ (12.787,78). Điều này phản ánh hiện tượng khấu hao giá trị (depreciation) – một quy luật phổ biến trong kinh tế học ô tô: giá trị xe giảm mạnh trong những năm đầu sử dụng. Việc chia nhóm như vậy giúp định lượng mức độ chênh lệch giá giữa hai phân khúc chính của thị trường và chứng minh rằng năm sản xuất là biến có sức ảnh hưởng mạnh nhất đến giá bán.

Giá TB theo Nhóm HP (Tertiles): Phân nhóm engine_hp thành 3 nhóm và tính Giá TB của mỗi nhóm.

vehicle_data %>% mutate(hp_group = ntile(engine_hp, 3)) %>% group_by(hp_group) %>% summarise(mean_price = mean(price), .groups = 'drop')
## # A tibble: 3 × 2
##   hp_group mean_price
##      <int>      <dbl>
## 1        1     11862.
## 2        2     17831.
## 3        3     31295.

Hàm ntile(engine_hp, 3) chia toàn bộ biến engine_hp (công suất động cơ) thành 3 nhóm bằng nhau theo số lượng mẫu (tertiles). Mỗi nhóm đại diện cho mức công suất thấp, trung bình và cao. Sau đó, tính giá trung bình của xe trong từng nhóm. Cách phân nhóm này cho phép so sánh xu hướng giá theo thứ bậc công suất, đồng thời loại bỏ sự ảnh hưởng của phân phối không đều.

Ý nghĩa thống kê: Giá trung bình tăng theo cấp độ công suất: nhóm 1 (~11.862), nhóm 2 (~17.830), nhóm 3 (~31.295). Mối quan hệ này thể hiện tương quan dương mạnh giữa công suất động cơ và giá xe, điều này hoàn toàn hợp lý vì công suất cao thường đi kèm với hiệu năng, vật liệu và công nghệ tốt hơn. Về mặt thống kê, điều này chứng minh rằng engine_hp là một biến độc lập có ảnh hưởng trực tiếp và tuyến tính đến giá, có thể đóng vai trò quan trọng trong mô hình hồi quy giá ô tô.

Giá TB theo Lưới Make & Condition: Tính Giá TB cho mỗi ô trong lưới kết hợp Top 5 make và condition.

vehicle_data %>% filter(make %in% (vehicle_data %>% count(make) %>% arrange(desc(n)) %>% head(5) %>% pull(make))) %>% group_by(make, condition) %>% summarise(mean_price = mean(price), .groups = 'drop')
## # A tibble: 15 × 3
##    make   condition mean_price
##    <chr>  <chr>          <dbl>
##  1 Kia    Excellent     10568.
##  2 Kia    Fair           9331.
##  3 Kia    Good          10163.
##  4 Mazda  Excellent     11922.
##  5 Mazda  Fair          10199.
##  6 Mazda  Good          11444.
##  7 Nissan Excellent     10930.
##  8 Nissan Fair           9423.
##  9 Nissan Good          10431.
## 10 Subaru Excellent     13694.
## 11 Subaru Fair          11758.
## 12 Subaru Good          12955.
## 13 Tesla  Excellent     33658.
## 14 Tesla  Fair          29059.
## 15 Tesla  Good          32090.

Đoạn mã này lọc ra Top 5 hãng xe có số lượng mẫu lớn nhất trong dữ liệu (make) bằng chuỗi lệnh lồng count() → arrange() → head() → pull(). Sau đó nhóm dữ liệu theo make (hãng xe) và condition (tình trạng), rồi tính giá trung bình. Đây là cách tập trung phân tích vào các thương hiệu phổ biến nhất, giúp kết quả có tính khái quát cao.

Ý nghĩa thống kê: Bảng kết quả cho thấy xe trong tình trạng Excellent luôn có giá trung bình cao hơn so với Good hoặc Fair, bất kể hãng nào. Ví dụ: Mazda (11.921 vs 10.199), Nissan (10.929 vs 9.422). Điều này chứng minh rằng tác động của tình trạng xe là nhất quán giữa các hãng, phản ánh quy luật định giá chung của thị trường. Đồng thời, mức giá trung bình khác nhau giữa các hãng (Mazda cao hơn Kia, Nissan) cho thấy định vị thương hiệu có ảnh hưởng đáng kể đến giá bán. Đây là kết quả có giá trị để phân tích thị phần và chính sách giá của từng hãng.

Tương quan theo HP: Tính Tương quan giữa price và mileage riêng cho 2 nhóm Công suất (High/Low).

vehicle_data %>% mutate(hp_group = ifelse(engine_hp > 300, "HP_Cao", "HP_Thường")) %>% group_by(hp_group) %>% summarise(corr_val = cor(price, mileage), .groups = 'drop')
## # A tibble: 2 × 2
##   hp_group  corr_val
##   <chr>        <dbl>
## 1 HP_Cao      -0.768
## 2 HP_Thường   -0.736

Về kỹ thuật, đoạn mã tạo biến phân loại mới hp_level chia xe thành hai nhóm:

“HP_Cao”: công suất động cơ trên 300 mã lực,

“HP_Thường”: công suất bằng hoặc dưới 300 mã lực. Sau đó, chương trình tính hệ số tương quan (correlation) giữa giá (price) và quãng đường đi (mileage) cho từng nhóm.

Về ý nghĩa thống kê, cả hai nhóm đều có hệ số tương quan âm mạnh (khoảng -0.76 và -0.74), nghĩa là khi quãng đường tăng thì giá xe giảm đáng kể, bất kể công suất cao hay thấp. Tuy nhiên, nhóm HP_Cao có giá trị âm lớn hơn, cho thấy xe công suất mạnh mất giá nhanh hơn khi sử dụng nhiều, có thể do chi phí vận hành cao và tốc độ hao mòn linh kiện lớn hơn.

Giá TB theo Mốc Số dặm: Phân tổ mileage thành các mốc (\(0-50k\), \(50k-100k\), \(>100k\)) và tính Giá TB cho mỗi mốc.

vehicle_data %>% mutate(mile_bins = cut(mileage, breaks = c(0, 50000, 100000, Inf), labels = c("0-50K", "50K-100K", ">100K"))) %>% group_by(mile_bins) %>% summarise(mean_price = mean(price), .groups = 'drop')
## # A tibble: 3 × 2
##   mile_bins mean_price
##   <fct>          <dbl>
## 1 0-50K         32811.
## 2 50K-100K      23628.
## 3 >100K         13511.

Hàm cut() được dùng để chia biến liên tục mileage thành ba nhóm rời rạc theo khoảng giá trị. Đây là cách phân tầng dữ liệu (binning) giúp làm rõ xu hướng biến động của giá theo quãng đường đã sử dụng. Sau đó, tính giá trung bình cho từng nhóm bằng summarise().

Ý nghĩa thống kê: Giá trung bình giảm mạnh khi số dặm tăng:

Dưới 50.000 km: ~32.811

50.000–100.000 km: ~23.627

Trên 100.000 km: ~13.510 Xu hướng này khẳng định rõ ràng quy luật khấu hao theo quãng đường sử dụng, tức là giá trị xe giảm gần tuyến tính theo mức độ vận hành. Về mặt thống kê, đây là mối quan hệ nghịch biến mạnh giữa mileage và price, đồng thời chỉ ra rằng mức độ sử dụng là một trong những yếu tố dự báo quan trọng nhất cho giá xe.

Tương quan Giá & Khấu hao: Tính Tương quan giữa price và mileage riêng cho từng năm sản xuất (year).

vehicle_data %>% group_by(year) %>% summarise(corr_price_mileage = cor(price, mileage), .groups = 'drop')
## # A tibble: 26 × 2
##     year corr_price_mileage
##    <dbl>              <dbl>
##  1  2000             -0.908
##  2  2001             -0.388
##  3  2002             -0.642
##  4  2003             -0.448
##  5  2004             -0.485
##  6  2005             -0.506
##  7  2006             -0.515
##  8  2007             -0.476
##  9  2008             -0.475
## 10  2009             -0.460
## # ℹ 16 more rows

Đoạn mã này tính hệ số tương quan Pearson giữa price và mileage trong từng nhóm năm sản xuất (year). Việc sử dụng group_by(year) cho phép đánh giá mối quan hệ giá – quãng đường một cách riêng biệt theo từng lứa xe, giúp kiểm tra xem mức độ ảnh hưởng của quãng đường đến giá có thay đổi theo thời gian hay không.

Ý nghĩa thống kê: Hầu hết các hệ số tương quan có giá trị âm mạnh (-0.4 đến -0.9), chứng minh mối quan hệ nghịch tuyến tính giữa số dặm và giá xe. Ở các năm cũ (2000–2003), hệ số tương quan rất cao (-0.9), nghĩa là số dặm đã đi ảnh hưởng cực mạnh đến giá trị còn lại. Trong khi đó, ở các năm mới hơn, giá trị tương quan có xu hướng giảm nhẹ, do xe đời mới chưa sử dụng đủ lâu để thể hiện mức khấu hao rõ rệt. Đây là kết quả có ý nghĩa thống kê sâu sắc, thể hiện mối quan hệ thời gian – hao mòn – giá trị trong thị trường xe ô tô đã qua sử dụng.

Tương quan theo Nguồn Bán: Tính Tương quan giữa price và engine_hp riêng cho nhóm Dealer và Private.

vehicle_data %>% group_by(seller_type) %>% summarise(corr_price_hp = cor(price, engine_hp), .groups = 'drop')
## # A tibble: 2 × 2
##   seller_type corr_price_hp
##   <fct>               <dbl>
## 1 Dealer              0.654
## 2 Private             0.655

2.3.3.3. Phân tích giá trị tương đối

Tạo biến hiệu suất: công suất trên giá (hp_per_dollar)

Trong quá trình phân tích dữ liệu, một trong những bước quan trọng là tạo biến mới (feature engineering) nhằm làm nổi bật các đặc trưng giúp mô hình hoặc phân tích thống kê phản ánh chính xác hơn bản chất của dữ liệu. Trong tập dữ liệu về xe, ngoài công suất động cơ (engine_hp) và giá bán (price), ta có thể tạo ra một chỉ số thể hiện hiệu suất công suất trên mỗi đơn vị giá trị – tức là số mã lực trên mỗi đô la mà người mua phải trả.

vehicle_data <- vehicle_data %>%
  mutate(hp_per_dollar = engine_hp / price)

vehicle_data %>%
  select(make, engine_hp, price, hp_per_dollar) %>%
  head(5)
## # A tibble: 5 × 4
##   make       engine_hp  price hp_per_dollar
##   <chr>          <dbl>  <dbl>         <dbl>
## 1 Volkswagen       173  7209.        0.0240
## 2 Lexus            352  6912.        0.0509
## 3 Subaru           188 11916.        0.0158
## 4 Cadillac         338 25985.        0.0130
## 5 Toyota           196  8151.        0.0240

Về mặt kỹ thuật, hàm mutate() trong gói dplyr được sử dụng để tạo thêm cột mới hoặc thay đổi giá trị của cột hiện có trong bảng dữ liệu. Biểu thức hp_per_dollar = engine_hp / price định nghĩa cách tính toán cho biến mới, trong đó phép chia được áp dụng tương ứng theo từng hàng dữ liệu. Việc đặt thao tác này trong chuỗi %>% giúp kết nối trực tiếp với các bước xử lý khác như select() hoặc filter(), tạo nên quy trình xử lý dữ liệu rõ ràng, linh hoạt và dễ mở rộng.

Về ý nghĩa thống kê và phân tích, biến hp_per_dollar là một thước đo phản ánh hiệu suất giá trị của xe, thể hiện lượng công suất động cơ mà người mua nhận được trên mỗi đô la chi trả. Chỉ số này giúp so sánh trực tiếp giữa các dòng xe có đặc điểm kỹ thuật và phân khúc khác nhau. Một giá trị hp_per_dollar cao cho thấy xe mang lại nhiều công suất hơn trên mỗi đơn vị chi phí, nghĩa là người tiêu dùng nhận được hiệu năng tốt hơn với cùng số tiền bỏ ra. Ngược lại, các xe có chỉ số thấp thường thuộc nhóm xe sang, nơi giá bán chịu ảnh hưởng bởi thương hiệu, thiết kế và tiện nghi hơn là sức mạnh động cơ.

Từ góc độ thống kê, việc tạo ra biến hp_per_dollar giúp chuẩn hóa mối quan hệ giữa công suất và giá, cho phép mô hình dự đoán hoặc phân tích hồi quy nhận diện rõ hơn sự khác biệt tương đối giữa các dòng xe. Bên cạnh đó, chỉ số này còn hỗ trợ trong phân khúc thị trường và đánh giá chiến lược giá, ví dụ xác định xe thể thao có hiệu suất cao so với giá bán, hoặc xe hạng sang có hiệu suất thấp nhưng giá trị thương hiệu lớn. Nhờ vậy, hp_per_dollar không chỉ là một biến kỹ thuật mới mà còn là một thước đo kinh tế có ý nghĩa thực tiễn, giúp làm rõ mối quan hệ giữa hiệu năng và giá trị của sản phẩm trên thị trường ô tô

Tỷ lệ Giá/Dặm: Tạo cột price_per_mile để đánh giá giá trị còn lại trên mỗi đơn vị khấu hao

vehicle_data <- vehicle_data %>% mutate(price_per_mile = price / mileage)
vehicle_data %>%
  select(make, model, price, mileage, price_per_mile) %>%
  arrange(desc(price_per_mile)) %>% 
  head(10)
## # A tibble: 10 × 5
##    make    model     price mileage price_per_mile
##    <chr>   <chr>     <dbl>   <dbl>          <dbl>
##  1 Porsche Panamera 93422.     500           187.
##  2 Porsche Cayenne  88450.     500           177.
##  3 Porsche Macan    87281.     500           175.
##  4 Porsche Macan    86114.     500           172.
##  5 Porsche 911      86100.     500           172.
##  6 Porsche Cayenne  85926.     500           172.
##  7 Porsche Macan    85734.     500           171.
##  8 Porsche Panamera 85107.     500           170.
##  9 Porsche Macan    84649.     500           169.
## 10 Porsche Cayenne  84371.     500           169.

Đoạn mã trên thực hiện việc tạo ra một biến mới có tên là price_per_mile, được tính bằng công thức price / mileage, tức là giá xe chia cho quãng đường xe đã đi. Biến này phản ánh giá trị trung bình mà mỗi km sử dụng của xe tương ứng với bao nhiêu đơn vị tiền, qua đó giúp đánh giá hiệu quả sử dụng và mức độ khấu hao của từng dòng xe. Sau khi tạo biến, dữ liệu được sắp xếp theo thứ tự giảm dần của price_per_mile để xác định những mẫu xe có giá trị sử dụng cao nhất, nghĩa là xe vẫn giữ được giá cao dù đã di chuyển một quãng đường nhất định.

Về mặt kỹ thuật, việc tạo ra biến price_per_mile giúp chuẩn hóa giá trị của xe theo mức độ sử dụng, từ đó có thể so sánh công bằng giữa các xe có quãng đường sử dụng khác nhau. Biến này đóng vai trò quan trọng trong các phân tích định giá, vì nó kết hợp hai yếu tố cơ bản ảnh hưởng đến giá ô tô là giá bán và mức độ sử dụng.

Về mặt thống kê, price_per_mile là một chỉ tiêu phản ánh tỷ lệ giá trị còn lại trên mỗi đơn vị sử dụng, giúp nhận diện các thương hiệu hoặc mẫu xe có khả năng giữ giá tốt hơn so với mức trung bình thị trường. Kết quả cho thấy các dòng xe của thương hiệu Porsche như Panamera, Cayenne hay Macan có giá trị price_per_mile cao nhất, điều này hàm ý rằng những mẫu xe này có độ khấu hao thấp và giữ giá tốt hơn so với nhiều dòng xe khác. Như vậy, chỉ số price_per_mile vừa mang ý nghĩa kinh tế thực tiễn, vừa có giá trị thống kê trong việc so sánh và phân tích giá trị tương đối giữa các dòng xe.

Phần trăm chênh lệch TB Hãng: Tính cột price_pct_diff là % chênh lệch giữa giá thực tế so với giá trung bình của hãng đó.

vehicle_data <- vehicle_data %>% group_by(make) %>% mutate(price_pct_diff = (price - mean(price)) / mean(price) * 100) %>% ungroup()
vehicle_data %>%
  select(make, price, price_pct_diff) %>%
  arrange(make) %>%
  head(10)
## # A tibble: 10 × 3
##    make   price price_pct_diff
##    <chr>  <dbl>          <dbl>
##  1 Acura  7145.         -67.4 
##  2 Acura 41118.          87.5 
##  3 Acura 16728.         -23.7 
##  4 Acura 42352.          93.2 
##  5 Acura 21636.          -1.32
##  6 Acura 28872.          31.7 
##  7 Acura 23580.           7.55
##  8 Acura 30648.          39.8 
##  9 Acura 25973.          18.5 
## 10 Acura 11659.         -46.8

Đoạn mã trên thực hiện việc tính toán biến mới price_pct_diff, thể hiện phần trăm chênh lệch giữa giá thực tế của từng xe so với giá trung bình của hãng. Trong đó, mean(price) được tính riêng cho từng hãng xe (group_by(make)), sau đó dữ liệu được bỏ nhóm (ungroup()) để lưu kết quả vào toàn bộ bảng dữ liệu.

Về mặt kỹ thuật, phép tính này cho phép chuẩn hóa giá của từng xe trong cùng một hãng, giúp so sánh tương đối thay vì tuyệt đối. Nếu price_pct_diff mang giá trị dương, xe đó có giá cao hơn trung bình của hãng; ngược lại, giá trị âm cho thấy xe có giá thấp hơn mức trung bình. Việc sử dụng phép tính phần trăm giúp quy đổi sự khác biệt này về cùng thang đo, thuận tiện cho việc so sánh giữa các hãng có mức giá trung bình khác nhau.

Về mặt thống kê, biến price_pct_diff phản ánh mức độ phân tán và biến động giá trong nội bộ từng hãng xe. Giá trị chênh lệch càng lớn chứng tỏ sự đa dạng về mức giá trong cùng một thương hiệu, có thể do khác biệt về dòng xe, năm sản xuất hoặc tình trạng xe. Trong kết quả ví dụ, các xe Acura có giá dao động từ thấp hơn trung bình khoảng 67% đến cao hơn trung bình khoảng 93%, cho thấy hãng này có sự khác biệt giá khá rõ giữa các mẫu xe.

Xếp hạng Giá theo Năm: Xếp hạng price (cao nhất hạng 1) trong phạm vi từng năm sản xuất (year)

vehicle_data %>% group_by(year) %>% mutate(price_rank_by_year = rank(desc(price)))
## # A tibble: 1,000,000 × 33
## # Groups:   year [26]
##    make       model     year mileage engine_hp transmission fuel_type drivetrain
##    <chr>      <chr>    <dbl>   <dbl>     <dbl> <chr>        <chr>     <chr>     
##  1 Volkswagen Jetta     2016  183903       173 Manual       Electric  RWD       
##  2 Lexus      RX        2010  236643       352 Manual       Gasoline  FWD       
##  3 Subaru     Crosstr…  2016  103199       188 Automatic    Diesel    AWD       
##  4 Cadillac   Lyriq     2016  118889       338 Manual       Gasoline  AWD       
##  5 Toyota     Highlan…  2018  204170       196 Manual       Diesel    FWD       
##  6 Land Rover Defender  2021   44907       479 Manual       Diesel    RWD       
##  7 Mazda      Mazda3    2018  129770       160 Automatic    Diesel    FWD       
##  8 Volkswagen Atlas     2022   29146       172 Automatic    Gasoline  RWD       
##  9 Ram        2500      2015  169165       197 Automatic    Electric  RWD       
## 10 Chrysler   300       2025    5081       198 Automatic    Diesel    FWD       
## # ℹ 999,990 more rows
## # ℹ 25 more variables: body_type <chr>, exterior_color <chr>,
## #   interior_color <chr>, owner_count <dbl>, accident_history <chr>,
## #   seller_type <fct>, condition <chr>, trim <chr>, vehicle_age <dbl>,
## #   mileage_per_year <dbl>, brand_popularity <dbl>, price <dbl>, age <dbl>,
## #   car_status <chr>, price_segment <chr>, brand_type <chr>,
## #   mileage_group <chr>, interior_group <chr>, car_id <int>, …

Đoạn code này nhóm dữ liệu theo year (năm sản xuất) và sử dụng hàm rank(desc(price)) để xếp hạng giá xe trong từng năm — xe có giá cao nhất sẽ được xếp hạng 1. Việc nhóm theo năm giúp đảm bảo việc so sánh giá được thực hiện trong phạm vi cùng năm, tránh ảnh hưởng của yếu tố thời gian hoặc khấu hao giữa các năm sản xuất khác nhau. Ý nghĩa thống kê: Phương pháp xếp hạng này giúp chuẩn hóa giá trị giá bán trong từng nhóm năm, cho phép so sánh tương đối giữa các mẫu xe cùng thời kỳ. Từ đó, ta có thể xác định những mẫu xe giữ giá tốt nhất theo từng năm, hoặc xem xu hướng giá theo thời gian. Đây là một cách phân tích phi tham số giúp phát hiện các mẫu xe “ngoại lệ tích cực” (được định giá cao hơn trung bình của năm sản xuất) mà không bị ảnh hưởng bởi phân phối giá tổng thể.

Chênh lệch Giá/HP: Tính Độ chênh lệch giữa price và Giá TB của nhóm HP tương đương.

vehicle_data %>% mutate(hp_group = ntile(engine_hp, 3)) %>% group_by(hp_group) %>% mutate(price_diff_avg_hp = price - mean(price))
## # A tibble: 1,000,000 × 34
## # Groups:   hp_group [3]
##    make       model     year mileage engine_hp transmission fuel_type drivetrain
##    <chr>      <chr>    <dbl>   <dbl>     <dbl> <chr>        <chr>     <chr>     
##  1 Volkswagen Jetta     2016  183903       173 Manual       Electric  RWD       
##  2 Lexus      RX        2010  236643       352 Manual       Gasoline  FWD       
##  3 Subaru     Crosstr…  2016  103199       188 Automatic    Diesel    AWD       
##  4 Cadillac   Lyriq     2016  118889       338 Manual       Gasoline  AWD       
##  5 Toyota     Highlan…  2018  204170       196 Manual       Diesel    FWD       
##  6 Land Rover Defender  2021   44907       479 Manual       Diesel    RWD       
##  7 Mazda      Mazda3    2018  129770       160 Automatic    Diesel    FWD       
##  8 Volkswagen Atlas     2022   29146       172 Automatic    Gasoline  RWD       
##  9 Ram        2500      2015  169165       197 Automatic    Electric  RWD       
## 10 Chrysler   300       2025    5081       198 Automatic    Diesel    FWD       
## # ℹ 999,990 more rows
## # ℹ 26 more variables: body_type <chr>, exterior_color <chr>,
## #   interior_color <chr>, owner_count <dbl>, accident_history <chr>,
## #   seller_type <fct>, condition <chr>, trim <chr>, vehicle_age <dbl>,
## #   mileage_per_year <dbl>, brand_popularity <dbl>, price <dbl>, age <dbl>,
## #   car_status <chr>, price_segment <chr>, brand_type <chr>,
## #   mileage_group <chr>, interior_group <chr>, car_id <int>, …

Biến engine_hp (công suất động cơ) được chia thành 3 nhóm bằng nhau (ntile(engine_hp, 3)), sau đó tính độ chênh lệch giữa giá thực tế và giá trung bình trong cùng nhóm công suất (price_diff_avg_hp). Việc thực hiện trong nhóm giúp đánh giá tương đối giá của xe trong cùng phân khúc sức mạnh, thay vì so sánh toàn bộ tập dữ liệu.

Ý nghĩa thống kê: Chỉ số price_diff_avg_hp cho biết một mẫu xe được định giá cao hơn hay thấp hơn mức trung bình của nhóm công suất tương ứng. Ví dụ, giá trị dương thể hiện xe có giá cao hơn trung bình cùng phân khúc — thường là các thương hiệu cao cấp (như Lexus, Land Rover), trong khi giá trị âm cho thấy xe có thể đang “bị định giá thấp”. Về mặt thống kê, đây là phép đo sai lệch so với trung bình (mean deviation) trong từng nhóm, hữu ích trong việc xác định mức độ khác biệt thương hiệu hoặc tiềm năng “giá hời” của xe.

Lọc Xe Giá trị Vượt trội

p90 <- quantile(vehicle_data$price, 0.90); p10 <- quantile(vehicle_data$mileage, 0.10); vehicle_data %>% filter(price >= p90 & mileage <= p10)
## # A tibble: 35,644 × 32
##    make          model  year mileage engine_hp transmission fuel_type drivetrain
##    <chr>         <chr> <dbl>   <dbl>     <dbl> <chr>        <chr>     <chr>     
##  1 Land Rover    Disc…  2023   18858       448 Manual       Gasoline  AWD       
##  2 Acura         TLX    2023   22547       255 Automatic    Electric  AWD       
##  3 Mercedes-Benz E-Cl…  2022   17394       329 Automatic    Diesel    FWD       
##  4 Acura         RDX    2024   22514       248 Automatic    Electric  AWD       
##  5 Porsche       911    2022   17690       409 Manual       Diesel    RWD       
##  6 Tesla         Mode…  2022    8891       330 Manual       Electric  FWD       
##  7 Land Rover    Disc…  2024   16490       418 Automatic    Electric  FWD       
##  8 Audi          A6     2025    5591       255 Automatic    Diesel    AWD       
##  9 Lexus         NX     2025    2927       222 Manual       Diesel    FWD       
## 10 Audi          A6     2025    8682       300 Automatic    Electric  FWD       
## # ℹ 35,634 more rows
## # ℹ 24 more variables: body_type <chr>, exterior_color <chr>,
## #   interior_color <chr>, owner_count <dbl>, accident_history <chr>,
## #   seller_type <fct>, condition <chr>, trim <chr>, vehicle_age <dbl>,
## #   mileage_per_year <dbl>, brand_popularity <dbl>, price <dbl>, age <dbl>,
## #   car_status <chr>, price_segment <chr>, brand_type <chr>,
## #   mileage_group <chr>, interior_group <chr>, car_id <int>, …

Đoạn code xác định ngưỡng phân vị 90% (P90) cho giá (price) và ngưỡng phân vị 10% (P10) cho quãng đường (mileage). Sau đó lọc các xe nằm trong top 10% giá cao nhất và 10% quãng đường thấp nhất, tức là xe có giá trị cao và ít sử dụng.

Ý nghĩa thống kê: Đây là phép lọc dựa trên phân vị (quantile filtering), một kỹ thuật phổ biến để phát hiện những mẫu dữ liệu cực trị có ý nghĩa tích cực – ở đây là các xe “cao cấp, mới, ít sử dụng”. Danh sách kết quả gồm nhiều thương hiệu hạng sang (Porsche, Tesla, Land Rover, Mercedes-Benz), cho thấy sự tương thích giữa giá, chất lượng và mức độ sử dụng. Về mặt thống kê, nhóm này có thể được xem là phân nhóm ngoại lệ tốt (positive outliers) – hữu ích trong việc nhận diện phân khúc cao cấp trong mô hình giá.

Lọc Xe Hiệu suất Rẻ: Lọc các xe có price <25000 và engine_hp >200

vehicle_data %>% filter(price < 25000 & engine_hp > 200)
## # A tibble: 285,964 × 32
##    make       model     year mileage engine_hp transmission fuel_type drivetrain
##    <chr>      <chr>    <dbl>   <dbl>     <dbl> <chr>        <chr>     <chr>     
##  1 Lexus      RX        2010  236643       352 Manual       Gasoline  FWD       
##  2 GMC        Yukon     2016  124906       253 Automatic    Electric  RWD       
##  3 Cadillac   XT5       2014  243552       360 Automatic    Diesel    RWD       
##  4 Land Rover Range R…  2014  267423       417 Automatic    Diesel    FWD       
##  5 Audi       Q5        2017  154121       325 Manual       Diesel    AWD       
##  6 Ram        3500      2020   75783       238 Automatic    Diesel    AWD       
##  7 Ram        2500      2019  159739       227 Automatic    Diesel    FWD       
##  8 Audi       R8        2010  291740       311 Manual       Diesel    AWD       
##  9 Jeep       Grand C…  2020   85581       214 Automatic    Diesel    AWD       
## 10 BMW        M3        2012  263891       302 Automatic    Diesel    FWD       
## # ℹ 285,954 more rows
## # ℹ 24 more variables: body_type <chr>, exterior_color <chr>,
## #   interior_color <chr>, owner_count <dbl>, accident_history <chr>,
## #   seller_type <fct>, condition <chr>, trim <chr>, vehicle_age <dbl>,
## #   mileage_per_year <dbl>, brand_popularity <dbl>, price <dbl>, age <dbl>,
## #   car_status <chr>, price_segment <chr>, brand_type <chr>,
## #   mileage_group <chr>, interior_group <chr>, car_id <int>, …

Lệnh lọc chọn các xe có giá dưới 25.000 nhưng công suất động cơ lớn hơn 200 mã lực. Đây là một quy tắc lọc logic (&) nhằm phát hiện xe có tỷ lệ giá/hiệu năng tốt, thường được xem là “hiệu suất trên giá” (performance-to-price ratio).

Ý nghĩa thống kê: Nhóm xe này thể hiện giá trị sử dụng cao với chi phí thấp – tức là xe có hiệu năng mạnh nhưng giá thấp hơn trung bình của phân khúc. Về mặt thống kê, đây là nhóm có giá trị ngoại lệ âm về giá so với công suất, phản ánh mức định giá thấp hơn so với năng lực kỹ thuật. Kết quả này đặc biệt hữu ích cho phân tích hành vi người tiêu dùng và chiến lược marketing định vị xe “giá trị thực dụng”.

Giá trung bình Trượt: Tính Giá trung bình trượt 3 năm theo year

vehicle_data %>% arrange(year) %>% mutate(rolling_avg_price_3yr = zoo::rollmean(price, k = 3, fill = NA))
## # A tibble: 1,000,000 × 33
##    make       model     year mileage engine_hp transmission fuel_type drivetrain
##    <chr>      <chr>    <dbl>   <dbl>     <dbl> <chr>        <chr>     <chr>     
##  1 Chrysler   Pacifica  2000  300000       166 Manual       Gasoline  AWD       
##  2 Land Rover Range R…  2000  300000       409 Automatic    Gasoline  AWD       
##  3 Land Rover Defender  2000  300000       391 Automatic    Electric  RWD       
##  4 GMC        Acadia    2000  277984       207 Manual       Electric  RWD       
##  5 Nissan     Titan     2000  300000       162 Automatic    Gasoline  AWD       
##  6 Kia        Sportage  2000  300000       138 Automatic    Gasoline  FWD       
##  7 Volvo      S60       2000  300000       291 Manual       Diesel    RWD       
##  8 Land Rover Defender  2000  300000       448 Manual       Electric  AWD       
##  9 Honda      Accord    2000  300000       190 Manual       Gasoline  AWD       
## 10 Porsche    911       2000  106297       476 Automatic    Diesel    AWD       
## # ℹ 999,990 more rows
## # ℹ 25 more variables: body_type <chr>, exterior_color <chr>,
## #   interior_color <chr>, owner_count <dbl>, accident_history <chr>,
## #   seller_type <fct>, condition <chr>, trim <chr>, vehicle_age <dbl>,
## #   mileage_per_year <dbl>, brand_popularity <dbl>, price <dbl>, age <dbl>,
## #   car_status <chr>, price_segment <chr>, brand_type <chr>,
## #   mileage_group <chr>, interior_group <chr>, car_id <int>, …

Hàm zoo::rollmean() tính trung bình trượt (moving average) của biến price trong cửa sổ 3 năm (k = 3). Dữ liệu được sắp xếp theo year trước khi tính, đảm bảo chuỗi thời gian được xử lý đúng thứ tự. Trung bình trượt giúp làm mượt dữ liệu giá theo thời gian, loại bỏ dao động ngắn hạn và thể hiện xu hướng dài hạn.

Ý nghĩa thống kê: Trung bình trượt 3 năm cho phép phân tích xu hướng biến động giá xe theo chu kỳ thời gian. Nếu giá trung bình trượt tăng dần, điều đó cho thấy xu hướng tăng giá của thị trường hoặc sự thay đổi trong cấu trúc xe mới (nhiều xe cao cấp hơn). Ngược lại, nếu giá trung bình trượt giảm, có thể phản ánh mức khấu hao hoặc biến động kinh tế. Đây là kỹ thuật thường dùng trong phân tích chuỗi thời gian (time series analysis) để nhận diện xu hướng và biến động của thị trường ô tô.

2.3.3.4. Phân tích tích lũy và tổng hợp

Giá trị Tích lũy: Sắp xếp xe theo price tăng dần và tính tổng tích lũy của giá.

vehicle_data %>% arrange(price) %>% mutate(cumulative_price = cumsum(price))
## # A tibble: 1,000,000 × 33
##    make       model     year mileage engine_hp transmission fuel_type drivetrain
##    <chr>      <chr>    <dbl>   <dbl>     <dbl> <chr>        <chr>     <chr>     
##  1 Ford       Explorer  2013  234866       137 Manual       Gasoline  AWD       
##  2 Subaru     Crosstr…  2012  256509       163 Automatic    Diesel    AWD       
##  3 Volkswagen Tiguan    2010  189574       163 Manual       Electric  AWD       
##  4 Hyundai    Tucson    2010  173846       156 Automatic    Diesel    AWD       
##  5 Dodge      Challen…  2008  240744       177 Manual       Gasoline  AWD       
##  6 Hyundai    Santa Fe  2014  254513        95 Automatic    Electric  AWD       
##  7 Volkswagen Tiguan    2004  261123       157 Manual       Gasoline  RWD       
##  8 Hyundai    Tucson    2013  172846        90 Automatic    Gasoline  FWD       
##  9 Honda      CR-V      2012  212925       124 Automatic    Electric  FWD       
## 10 Ford       Focus     2013  272389       182 Automatic    Gasoline  AWD       
## # ℹ 999,990 more rows
## # ℹ 25 more variables: body_type <chr>, exterior_color <chr>,
## #   interior_color <chr>, owner_count <dbl>, accident_history <chr>,
## #   seller_type <fct>, condition <chr>, trim <chr>, vehicle_age <dbl>,
## #   mileage_per_year <dbl>, brand_popularity <dbl>, price <dbl>, age <dbl>,
## #   car_status <chr>, price_segment <chr>, brand_type <chr>,
## #   mileage_group <chr>, interior_group <chr>, car_id <int>, …

Lệnh arrange(price) sắp xếp toàn bộ dữ liệu theo giá (price) tăng dần, sau đó hàm cumsum(price) tính tổng tích lũy cộng dồn (cumulative sum) của giá từ xe rẻ nhất đến đắt nhất. Biến cumulative_price thể hiện sự tăng trưởng tuần tự của tổng giá trị khi lần lượt cộng dồn các mẫu xe theo thứ tự giá.

Ý nghĩa thống kê: Phân tích tích lũy giúp hiểu phân phối giá trị thị trường — cho thấy tỷ trọng giá trị mà nhóm xe giá thấp, trung bình, cao chiếm trong tổng giá toàn bộ tập dữ liệu. Đây là nền tảng để xây dựng đường Lorenz hoặc chỉ số Gini – dùng đo lường mức độ bất bình đẳng giá trị. Về mặt thực tế, nếu tổng giá trị tích lũy tăng mạnh ở cuối (khi giá xe cao), điều đó chứng tỏ thị trường tập trung giá trị vào một nhóm nhỏ xe cao cấp.

Phân bổ Vốn hóa: Tính tỷ lệ phần trăm của giá từng chiếc xe so với tổng giá trị của toàn bộ Data Frame.

vehicle_data %>% mutate(price_to_total_pct = price / sum(price) * 100)
## # A tibble: 1,000,000 × 33
##    make       model     year mileage engine_hp transmission fuel_type drivetrain
##    <chr>      <chr>    <dbl>   <dbl>     <dbl> <chr>        <chr>     <chr>     
##  1 Volkswagen Jetta     2016  183903       173 Manual       Electric  RWD       
##  2 Lexus      RX        2010  236643       352 Manual       Gasoline  FWD       
##  3 Subaru     Crosstr…  2016  103199       188 Automatic    Diesel    AWD       
##  4 Cadillac   Lyriq     2016  118889       338 Manual       Gasoline  AWD       
##  5 Toyota     Highlan…  2018  204170       196 Manual       Diesel    FWD       
##  6 Land Rover Defender  2021   44907       479 Manual       Diesel    RWD       
##  7 Mazda      Mazda3    2018  129770       160 Automatic    Diesel    FWD       
##  8 Volkswagen Atlas     2022   29146       172 Automatic    Gasoline  RWD       
##  9 Ram        2500      2015  169165       197 Automatic    Electric  RWD       
## 10 Chrysler   300       2025    5081       198 Automatic    Diesel    FWD       
## # ℹ 999,990 more rows
## # ℹ 25 more variables: body_type <chr>, exterior_color <chr>,
## #   interior_color <chr>, owner_count <dbl>, accident_history <chr>,
## #   seller_type <fct>, condition <chr>, trim <chr>, vehicle_age <dbl>,
## #   mileage_per_year <dbl>, brand_popularity <dbl>, price <dbl>, age <dbl>,
## #   car_status <chr>, price_segment <chr>, brand_type <chr>,
## #   mileage_group <chr>, interior_group <chr>, car_id <int>, …

Biến price_to_total_pct được tính bằng tỷ lệ phần trăm của từng giá xe so với tổng giá của toàn bộ xe trong dữ liệu. Đây là một phép chuẩn hóa tương đối, giúp lượng hóa mức độ đóng góp của từng xe vào tổng giá trị thị trường.

Ý nghĩa thống kê: Giá trị này thường rất nhỏ (ở mức e-05), phản ánh rằng mỗi xe chỉ chiếm một phần rất nhỏ trong tổng giá trị toàn cục. Tuy nhiên, khi phân nhóm theo hãng, dòng xe hoặc phân khúc, tỷ trọng này có thể cho thấy mức độ thống trị của các thương hiệu lớn. Về bản chất, đây là phép phân tích cấu trúc tỷ trọng (proportion analysis) giúp xác định mức đóng góp tương đối của từng phần tử vào tổng thể — một công cụ hữu ích trong đánh giá thị phần giá trị (value share) của thị trường ô tô.

Độ đồng nhất Giá trị: Tính tỷ lệ IQR/Median của price cho mỗi hãng xe (make).

vehicle_data %>% group_by(make) %>% summarise(iqr_median_ratio = IQR(price) / median(price))
## # A tibble: 25 × 2
##    make      iqr_median_ratio
##    <chr>                <dbl>
##  1 Acura                0.678
##  2 Audi                 0.620
##  3 BMW                  0.640
##  4 Cadillac             0.586
##  5 Chevrolet            0.817
##  6 Chrysler             0.746
##  7 Dodge                0.798
##  8 Ford                 0.856
##  9 GMC                  0.722
## 10 Honda                0.977
## # ℹ 15 more rows

Trong từng hãng xe (make), code tính tỷ lệ giữa độ trải rộng trung vị (Interquartile Range – IQR) và giá trung vị (Median). IQR đo lường độ biến thiên của 50% dữ liệu trung tâm, và tỷ lệ IQR/Median thể hiện mức độ biến động giá tương đối so với mức giá trung tâm của hãng.

Ý nghĩa thống kê: Tỷ lệ này là thước đo độ đồng nhất (price consistency) trong định giá xe của từng thương hiệu:

Tỷ lệ thấp (≈0.6) → giá xe đồng nhất, chiến lược giá ổn định (như Audi, BMW).

Tỷ lệ cao (≈0.9–1.0) → giá dao động lớn, thương hiệu có danh mục sản phẩm đa dạng (như Honda, Ford). Về mặt thống kê, IQR/Median là một chỉ số biến thiên tương đối (relative dispersion), giúp nhận diện mức độ tập trung hay phân tán giá trong từng nhóm – quan trọng để đánh giá tính ổn định và định vị thương hiệu.

Giá trị Cốt lõi Đặc biệt: Lọc các xe có condition là “Excellent” VÀ mileage dưới 50,000 và tính Giá TB của nhóm này.

vehicle_data %>% filter(condition == "Excellent" & mileage < 50000) %>% summarise(mean_price_core = mean(price))
## # A tibble: 1 × 1
##   mean_price_core
##             <dbl>
## 1          34147.

Lệnh filter() chọn các xe có tình trạng tốt nhất (Excellent) và quãng đường sử dụng dưới 50.000 km — tức là những xe gần như “như mới”. Sau đó tính giá trung bình của nhóm này, lưu trong mean_price_core.

Ý nghĩa thống kê: Kết quả trung bình 34.146,74 phản ánh giá trị trung tâm của phân khúc xe cốt lõi chất lượng cao. Đây được xem là mức giá tham chiếu (benchmark) cho các xe mới hoặc gần mới. Về mặt thống kê, đây là phép lọc tập con đặc trưng (subset mean) giúp cô lập nhóm dữ liệu có đặc điểm tốt nhất để phân tích chuẩn giá, đồng thời phục vụ so sánh chuẩn hiệu năng (baseline pricing) trong các mô hình dự báo.

Lợi thế TB so với Toàn cục: Tính độ chênh lệch giữa Giá trung vị của hãng xe đó và Giá trung vị toàn cục

median_price_global <- median(vehicle_data$price); vehicle_data %>% group_by(make) %>% summarise(median_advantage = median(price) - median_price_global)
## # A tibble: 25 × 2
##    make      median_advantage
##    <chr>                <dbl>
##  1 Acura                3202.
##  2 Audi                 8667.
##  3 BMW                  6633.
##  4 Cadillac            11373.
##  5 Chevrolet           -3383.
##  6 Chrysler             -793.
##  7 Dodge               -2734.
##  8 Ford                -4692.
##  9 GMC                   620.
## 10 Honda               -7267.
## # ℹ 15 more rows

Đầu tiên, median_price_global là giá trung vị của toàn bộ tập dữ liệu. Sau đó, code tính độ chênh lệch giữa giá trung vị của từng hãng và giá trung vị toàn cục. Biến median_advantage thể hiện mức lợi thế (hoặc bất lợi) của thương hiệu so với mặt bằng thị trường.

Ý nghĩa thống kê: Các giá trị dương (như Cadillac +11.372, Audi +8.667) thể hiện hãng định vị ở phân khúc cao hơn trung bình, trong khi giá trị âm (như Chevrolet -3.382, Honda -7.266) cho thấy phân khúc giá thấp hoặc phổ thông. Về mặt thống kê, đây là phép đo vị trí tương đối (relative location measure), dùng để so sánh trung vị nhóm với trung vị toàn thể, giúp phân biệt phân khúc thị trường (premium, standard, economy) một cách định lượng.

2.3.4. Phân tích biến Make

2.3.4.1. Phân tích tổng quan hãng xe

Bảng Tỷ lệ phần trăm: Chuyển đổi bảng tần suất sang tỷ lệ phần trăm phân bổ.

prop.table(table(vehicle_data$make)) * 100
## 
##         Acura          Audi           BMW      Cadillac     Chevrolet 
##        4.0147        4.0022        3.9840        3.9847        3.9982 
##      Chrysler         Dodge          Ford           GMC         Honda 
##        4.0059        4.0035        3.9842        3.9754        4.0015 
##       Hyundai          Jeep           Kia    Land Rover         Lexus 
##        3.9318        4.0006        4.0484        4.0133        3.9921 
##         Mazda Mercedes-Benz        Nissan       Porsche           Ram 
##        4.0247        3.9794        4.0217        4.0210        4.0148 
##        Subaru         Tesla        Toyota    Volkswagen         Volvo 
##        4.0230        4.0226        3.9627        4.0054        3.9842

Lệnh table(vehicle_data$make) tạo bảng tần suất số lượng xe theo từng hãng, sau đó prop.table() chuyển đổi các giá trị này thành tỷ lệ phần trăm phân bố (tổng cộng bằng 100%). Việc nhân với 100 giúp biểu diễn kết quả ở dạng phần trăm thay vì tỷ lệ thập phân.

Ý nghĩa thống kê: Kết quả cho thấy các hãng có tỷ lệ phân bố gần như đồng đều (khoảng 3.9–4.05%), chứng tỏ tập dữ liệu được lấy mẫu cân bằng giữa các thương hiệu, giúp đảm bảo tính khách quan khi phân tích so sánh. Phép chuyển đổi này là bước chuẩn hóa quan trọng trong thống kê mô tả, cho phép so sánh quy mô nhóm trong các biến danh mục mà không bị ảnh hưởng bởi số lượng tuyệt đối.

Đếm và Sắp xếp: Đếm số lượng xe của mỗi hãng bằng dplyr::count() và sắp xếp (lớn nhất lên đầu).

vehicle_data %>% count(make, sort = TRUE)
## # A tibble: 25 × 2
##    make           n
##    <chr>      <int>
##  1 Kia        40484
##  2 Mazda      40247
##  3 Subaru     40230
##  4 Tesla      40226
##  5 Nissan     40217
##  6 Porsche    40210
##  7 Ram        40148
##  8 Acura      40147
##  9 Land Rover 40133
## 10 Chrysler   40059
## # ℹ 15 more rows

Hàm count() trong dplyr đếm số dòng (số xe) thuộc mỗi hãng (make), đồng thời sort = TRUE sắp xếp theo thứ tự giảm dần để xác định hãng có số lượng xe lớn nhất trong tập dữ liệu.

Ý nghĩa thống kê: Phép đếm tần suất này giúp mô tả phân phối danh mục thương hiệu trong dữ liệu. Các hãng như Kia, Mazda, Subaru có số lượng xe cao nhất, cho thấy đây là những hãng phổ biến hoặc được quan tâm nhiều trong tập dữ liệu. Đây là phép thống kê cơ bản nhưng thiết yếu trong phân tích tần suất danh mục (categorical frequency analysis), dùng để mô tả cấu trúc dữ liệu đầu tiên.

Tần suất Top 5 Hãng: Lọc và hiển thị tần suất của 5 hãng xe có số lượng lớn nhất.

vehicle_data %>% count(make, sort = TRUE) %>% head(5)
## # A tibble: 5 × 2
##   make       n
##   <chr>  <int>
## 1 Kia    40484
## 2 Mazda  40247
## 3 Subaru 40230
## 4 Tesla  40226
## 5 Nissan 40217

Đoạn mã lọc ra Top 5 hãng xe có số lượng mẫu nhiều nhất, giúp thu gọn dữ liệu cho các phân tích tập trung hơn.

Ý nghĩa thống kê: Kết quả thể hiện nhóm thương hiệu chiếm thị phần lớn nhất trong tập mẫu (Kia, Mazda, Subaru, Tesla, Nissan). Việc xác định nhóm đầu bảng này hữu ích cho các phân tích tập trung thị phần, mô hình giá và sức ảnh hưởng thương hiệu, vì nhóm này thường đại diện cho phần lớn biến động của toàn thị trường.

Quy mô Thị trường: Đếm số lượng xe (n) và tính tỷ lệ phần trăm của mỗi hãng xe.

vehicle_data %>% count(make, sort = TRUE) %>% mutate(pct = n / sum(n) * 100)
## # A tibble: 25 × 3
##    make           n   pct
##    <chr>      <int> <dbl>
##  1 Kia        40484  4.05
##  2 Mazda      40247  4.02
##  3 Subaru     40230  4.02
##  4 Tesla      40226  4.02
##  5 Nissan     40217  4.02
##  6 Porsche    40210  4.02
##  7 Ram        40148  4.01
##  8 Acura      40147  4.01
##  9 Land Rover 40133  4.01
## 10 Chrysler   40059  4.01
## # ℹ 15 more rows

Sau khi đếm số lượng xe từng hãng bằng count(), lệnh mutate() thêm biến pct thể hiện tỷ lệ phần trăm đóng góp số lượng xe của mỗi hãng trong tổng thị trường.

Ý nghĩa thống kê: Biểu thức này giúp chuẩn hóa quy mô hãng, cho phép phân tích tương quan giữa thị phần số lượng và thị phần giá trị trong dữ liệu. Kết quả cũng giúp nhận biết mức độ tập trung hay phân tán của thị trường ô tô, là cơ sở để xác định mức độ cạnh tranh và đa dạng sản phẩm.

Công suất TB Hãng: Tính Công suất trung bình (TB) và Độ lệch chuẩn (SD) của engine_hp cho mỗi hãng.

vehicle_data %>% group_by(make) %>% summarise(avg_hp = mean(engine_hp), sd_hp = sd(engine_hp), .groups = 'drop')
## # A tibble: 25 × 3
##    make      avg_hp sd_hp
##    <chr>      <dbl> <dbl>
##  1 Acura       253.  30.0
##  2 Audi        306.  30.0
##  3 BMW         286.  30.2
##  4 Cadillac    333.  30.1
##  5 Chevrolet   186.  30.1
##  6 Chrysler    213.  29.9
##  7 Dodge       193.  30.0
##  8 Ford        173.  29.9
##  9 GMC         226.  29.9
## 10 Honda       146.  29.2
## # ℹ 15 more rows

Đoạn mã nhóm dữ liệu theo hãng và tính công suất trung bình (avg_hp) cùng độ lệch chuẩn (sd_hp) của công suất động cơ (engine_hp) cho từng thương hiệu.

Ý nghĩa thống kê: Giá trị trung bình phản ánh mức hiệu năng đặc trưng của từng hãng, trong khi độ lệch chuẩn thể hiện độ biến thiên công suất giữa các mẫu xe. Ví dụ, các hãng như Audi, Cadillac, BMW có công suất trung bình cao, cho thấy định vị ở phân khúc xe hiệu năng cao, trong khi Honda hoặc Ford có mức công suất thấp hơn, đặc trưng cho phân khúc xe đại chúng. Đây là phép mô tả trung tâm – phân tán (central tendency and dispersion), thường được dùng để so sánh năng lực kỹ thuật giữa các nhóm.

Số dặm TB Hãng: Tính Số dặm trung vị (Median) của mileage cho mỗi hãng.

vehicle_data %>% group_by(make) %>% summarise(median_mileage = median(mileage), .groups = 'drop')
## # A tibble: 25 × 2
##    make      median_mileage
##    <chr>              <dbl>
##  1 Acura            104272 
##  2 Audi             103144.
##  3 BMW              103716.
##  4 Cadillac         103439 
##  5 Chevrolet        103612.
##  6 Chrysler         103787 
##  7 Dodge            103991 
##  8 Ford             103138 
##  9 GMC              103278.
## 10 Honda            102258 
## # ℹ 15 more rows

Đoạn mã này nhóm dữ liệu theo hãng và tính số dặm trung vị (median) của quãng đường đã đi (mileage) cho từng thương hiệu.

Ý nghĩa thống kê: Giá trị trung vị là đại diện ổn định hơn so với trung bình trong các biến có phân phối lệch phải (vì một số xe có mileage rất cao). Kết quả cho thấy số dặm trung vị giữa các hãng gần tương đương (≈103.000–104.000), phản ánh rằng tuổi thọ và tần suất sử dụng xe giữa các thương hiệu khá cân bằng trong dữ liệu. Phân tích này hữu ích để đánh giá mức độ bền và phổ biến sử dụng, cũng như loại trừ ảnh hưởng của các ngoại lệ (outliers).

Xếp hạng Theo Số lượng: Xếp hạng các hãng xe theo tổng số lượng xe (n), (lớn nhất hạng 1).

vehicle_data %>% count(make) %>% mutate(rank_by_count = rank(desc(n))) %>% arrange(rank_by_count)
## # A tibble: 25 × 3
##    make           n rank_by_count
##    <chr>      <int>         <dbl>
##  1 Kia        40484             1
##  2 Mazda      40247             2
##  3 Subaru     40230             3
##  4 Tesla      40226             4
##  5 Nissan     40217             5
##  6 Porsche    40210             6
##  7 Ram        40148             7
##  8 Acura      40147             8
##  9 Land Rover 40133             9
## 10 Chrysler   40059            10
## # ℹ 15 more rows

Đoạn mã này đếm số lượng xe theo từng hãng bằng count(), sau đó sử dụng rank(desc(n)) để xếp hạng các hãng theo số lượng xe giảm dần, tức hãng có nhiều xe nhất sẽ được hạng 1. Câu lệnh arrange(rank_by_count) giúp sắp xếp bảng theo thứ tự hạng tăng dần để dễ quan sát.

Ý nghĩa thống kê: Phép xếp hạng này giúp đánh giá vị thế quy mô tương đối của từng thương hiệu trong tập dữ liệu. Ví dụ, các hãng như Kia, Mazda, Subaru, Tesla nằm trong nhóm đầu bảng, cho thấy độ phổ biến cao hơn trong thị trường mẫu khảo sát. Đây là dạng thống kê thứ bậc (ordinal statistics), hữu ích trong việc mô tả và so sánh quy mô thị phần giữa các nhóm danh mục.

Tỷ lệ HP/Giá TB Hãng: Tính Tỷ lệ Công suất/Giá TB (\(HP/Price\)) cho mỗi hãng.

vehicle_data %>% group_by(make) %>% summarise(avg_hp_per_price = mean(engine_hp / price), .groups = 'drop')
## # A tibble: 25 × 2
##    make      avg_hp_per_price
##    <chr>                <dbl>
##  1 Acura               0.0175
##  2 Audi                0.0148
##  3 BMW                 0.0157
##  4 Cadillac            0.0141
##  5 Chevrolet           0.0224
##  6 Chrysler            0.0202
##  7 Dodge               0.0221
##  8 Ford                0.0235
##  9 GMC                 0.0194
## 10 Honda               0.0257
## # ℹ 15 more rows

Lệnh này nhóm dữ liệu theo từng hãng (make) và tính trung bình của tỷ lệ engine_hp / price, tạo ra biến avg_hp_per_price — biểu thị mức công suất (HP) trung bình trên mỗi đơn vị giá. Đây là một chỉ tiêu hiệu suất kinh tế – kỹ thuật.

Ý nghĩa thống kê: Tỷ lệ HP/Price thể hiện giá trị hiệu năng tương đối của các thương hiệu. Hãng có tỷ lệ cao như Honda, Dodge, Chrysler cho thấy công suất động cơ mạnh hơn so với giá bán, phản ánh chiến lược tập trung vào hiệu năng – giá trị. Ngược lại, các hãng có tỷ lệ thấp (như BMW, Audi) thường là xe sang, có công suất cao nhưng giá cao hơn tương ứng. Đây là chỉ tiêu hiệu suất đầu tư (performance-to-cost ratio), dùng để so sánh “sức mạnh kỹ thuật so với chi phí”.

2.3.4.2. Phân tích khấu hao và chất lượng

Tỷ lệ Xe Tình trạng Tốt: Trong mỗi hãng, tính tỷ lệ phần trăm số xe có condition là “Excellent” hoặc “Good”.

vehicle_data %>% group_by(make) %>% summarise(pct_good_cond = mean(condition %in% c("Excellent", "Good")) * 100, .groups = 'drop')
## # A tibble: 25 × 2
##    make      pct_good_cond
##    <chr>             <dbl>
##  1 Acura              90.0
##  2 Audi               90.1
##  3 BMW                90.1
##  4 Cadillac           90.2
##  5 Chevrolet          90.0
##  6 Chrysler           89.9
##  7 Dodge              89.8
##  8 Ford               90.1
##  9 GMC                90.1
## 10 Honda              89.8
## # ℹ 15 more rows

Đoạn mã xác định tỷ lệ phần trăm (%) xe có tình trạng tốt (Excellent hoặc Good) trong từng hãng bằng cách dùng điều kiện logic %in% kết hợp với hàm mean(), vì trong R, giá trị TRUE = 1, FALSE = 0.

Ý nghĩa thống kê: Đây là chỉ số chất lượng tương đối, phản ánh mức độ bảo dưỡng hoặc độ bền của xe trong từng thương hiệu. Hầu hết các hãng đều có tỷ lệ cao (≈ 89–90%), cho thấy dữ liệu tập trung vào các xe trong tình trạng khá tốt. Tuy nhiên, so sánh nhỏ giữa các hãng (ví dụ: Chrysler cao hơn Ford) có thể phản ánh sự khác biệt nhỏ trong chất lượng giữ gìn hoặc thị trường xe cũ. Đây là dạng tỷ lệ thống kê mô tả (proportion statistics) dùng để đánh giá chất lượng phân nhóm.

Số dặm TB theo Tình trạng: Trong mỗi hãng, tính Số dặm trung bình cho xe có condition là “Fair” (Kém).

vehicle_data %>% filter(condition == "Fair") %>% group_by(make) %>% summarise(avg_mile_fair = mean(mileage), .groups = 'drop')
## # A tibble: 25 × 2
##    make      avg_mile_fair
##    <chr>             <dbl>
##  1 Acura           113649.
##  2 Audi            114534.
##  3 BMW             113751.
##  4 Cadillac        113179.
##  5 Chevrolet       112286.
##  6 Chrysler        112154.
##  7 Dodge           109981.
##  8 Ford            114216.
##  9 GMC             110906.
## 10 Honda           114308.
## # ℹ 15 more rows

Lệnh filter(condition == “Fair”) lọc riêng những xe có tình trạng “Fair”, sau đó tính số dặm trung bình (mean mileage) theo từng hãng.

Ý nghĩa thống kê: Kết quả cho thấy xe kém thường có quãng đường đi cao hơn (trên 110.000 dặm). Sự khác biệt nhỏ giữa các hãng (ví dụ: Dodge thấp hơn Cadillac) phản ánh mức độ hao mòn khác nhau tùy chất lượng và độ bền động cơ. Đây là phân tích phân nhóm có điều kiện (conditional mean analysis), giúp xác định mối quan hệ giữa tình trạng và mức độ sử dụng.

Độ đồng nhất Số dặm: Tính Độ lệch chuẩn (SD) của mileage cho mỗi hãng xe.

vehicle_data %>% group_by(make) %>% summarise(sd_mileage = sd(mileage), .groups = 'drop')
## # A tibble: 25 × 2
##    make      sd_mileage
##    <chr>          <dbl>
##  1 Acura         71893.
##  2 Audi          72085.
##  3 BMW           72226.
##  4 Cadillac      72283.
##  5 Chevrolet     71966.
##  6 Chrysler      71794.
##  7 Dodge         72174.
##  8 Ford          72244.
##  9 GMC           71927.
## 10 Honda         72011.
## # ℹ 15 more rows

Lệnh sd(mileage) tính độ lệch chuẩn của quãng đường đã đi (mileage) cho từng hãng, thể hiện mức phân tán dữ liệu trong mỗi nhóm.

Ý nghĩa thống kê: Giá trị SD dao động quanh 71.000–72.000 cho thấy mức phân tán quãng đường sử dụng giữa các xe khá tương đồng, nghĩa là sự ổn định về hành vi sử dụng xe giữa các hãng. Hãng có SD cao hơn thể hiện mức biến thiên lớn hơn (có cả xe rất mới và rất cũ). Đây là phép đo độ phân tán nội nhóm (intra-brand variability), dùng để đánh giá độ đồng nhất về mức sử dụng giữa các xe cùng thương hiệu.

Số dặm TB theo Tuổi xe: Tính Số dặm trung bình cho nhóm xe Cũ (<=2018) của từng hãng.

vehicle_data %>% filter(year <= 2018) %>% group_by(make) %>% summarise(avg_mile_old = mean(mileage), .groups = 'drop')
## # A tibble: 25 × 2
##    make      avg_mile_old
##    <chr>            <dbl>
##  1 Acura          150211.
##  2 Audi           150297.
##  3 BMW            150163.
##  4 Cadillac       150262.
##  5 Chevrolet      150534.
##  6 Chrysler       149834.
##  7 Dodge          150793.
##  8 Ford           150316.
##  9 GMC            149780.
## 10 Honda          149587.
## # ℹ 15 more rows

Đoạn mã lọc những xe có năm sản xuất ≤ 2018, sau đó tính trung bình số dặm (mileage) theo từng hãng. Biến avg_mile_old biểu thị mức độ sử dụng trung bình của các xe cũ.

Ý nghĩa thống kê: Giá trị trung bình khoảng 150.000 dặm ở hầu hết các hãng cho thấy tuổi thọ và mức độ sử dụng khá đồng đều giữa các thương hiệu. Sự chênh lệch nhỏ (chỉ vài trăm dặm) phản ánh độ bền động cơ và thói quen sử dụng tương đối ổn định. Đây là chỉ số độ hao mòn tích lũy theo tuổi xe, thường được dùng để so sánh độ tin cậy và khả năng giữ giá giữa các hãng.

Tỷ lệ Xe Mới: Tính tỷ lệ phần trăm xe được sản xuất từ năm 2020 trở đi cho mỗi hãng.

vehicle_data %>% group_by(make) %>% summarise(pct_new_car = mean(year >= 2020) * 100, .groups = 'drop')
## # A tibble: 25 × 2
##    make      pct_new_car
##    <chr>           <dbl>
##  1 Acura            30.3
##  2 Audi             30.9
##  3 BMW              30.8
##  4 Cadillac         30.8
##  5 Chevrolet        30.8
##  6 Chrysler         30.6
##  7 Dodge            30.7
##  8 Ford             30.8
##  9 GMC              31.0
## 10 Honda            31.1
## # ℹ 15 more rows

Câu lệnh này xác định tỷ lệ phần trăm xe mới (năm sản xuất ≥ 2020) trong từng hãng, dựa trên trung bình giá trị logic TRUE/FALSE (vì TRUE = 1, FALSE = 0).

Ý nghĩa thống kê: Tỷ lệ khoảng 30–31% cho thấy cơ cấu dữ liệu khá cân bằng giữa xe cũ và xe mới. Các hãng có tỷ lệ cao hơn (như Honda, Audi, GMC) thể hiện mức độ cập nhật mẫu xe mới cao, phản ánh hoạt động thị trường sôi động hoặc chiến lược đổi mới nhanh hơn. Đây là một chỉ tiêu dùng để đo tính hiện đại của danh mục xe theo thương hiệu.

2.3.4.3. Phân tích tương tác và giá trị tương đối

Chênh lệch Số dặm TB: Tính Độ chênh lệch giữa mileage của xe so với Số dặm TB của hãng đó.

vehicle_data %>% group_by(make) %>% mutate(mile_diff_make_avg = mileage - mean(mileage)) %>% ungroup()
## # A tibble: 1,000,000 × 33
##    make       model     year mileage engine_hp transmission fuel_type drivetrain
##    <chr>      <chr>    <dbl>   <dbl>     <dbl> <chr>        <chr>     <chr>     
##  1 Volkswagen Jetta     2016  183903       173 Manual       Electric  RWD       
##  2 Lexus      RX        2010  236643       352 Manual       Gasoline  FWD       
##  3 Subaru     Crosstr…  2016  103199       188 Automatic    Diesel    AWD       
##  4 Cadillac   Lyriq     2016  118889       338 Manual       Gasoline  AWD       
##  5 Toyota     Highlan…  2018  204170       196 Manual       Diesel    FWD       
##  6 Land Rover Defender  2021   44907       479 Manual       Diesel    RWD       
##  7 Mazda      Mazda3    2018  129770       160 Automatic    Diesel    FWD       
##  8 Volkswagen Atlas     2022   29146       172 Automatic    Gasoline  RWD       
##  9 Ram        2500      2015  169165       197 Automatic    Electric  RWD       
## 10 Chrysler   300       2025    5081       198 Automatic    Diesel    FWD       
## # ℹ 999,990 more rows
## # ℹ 25 more variables: body_type <chr>, exterior_color <chr>,
## #   interior_color <chr>, owner_count <dbl>, accident_history <chr>,
## #   seller_type <fct>, condition <chr>, trim <chr>, vehicle_age <dbl>,
## #   mileage_per_year <dbl>, brand_popularity <dbl>, price <dbl>, age <dbl>,
## #   car_status <chr>, price_segment <chr>, brand_type <chr>,
## #   mileage_group <chr>, interior_group <chr>, car_id <int>, …

Lệnh mutate() tính hiệu mileage - mean(mileage) trong từng nhóm hãng (make) và tạo biến mới mile_diff_make_avg thể hiện mức chênh lệch của từng xe so với giá trị trung bình của hãng đó.

Ý nghĩa thống kê: Biến này giúp phát hiện xe ngoại lệ (quá ít hoặc quá nhiều dặm) trong từng thương hiệu. Các giá trị dương → xe đã đi nhiều hơn mức trung bình, còn âm → xe còn khá mới so với mặt bằng hãng. Đây là chỉ báo độ hao mòn tương đối nội nhóm, hữu ích để xác định xe “bền bất thường” hoặc “hao mòn nhanh”.

Chênh lệch Công suất TB: Tính Độ chênh lệch giữa engine_hp của xe so với HP TB của hãng đó.

vehicle_data %>% group_by(make) %>% mutate(hp_diff_make_avg = engine_hp - mean(engine_hp)) %>% ungroup()
## # A tibble: 1,000,000 × 33
##    make       model     year mileage engine_hp transmission fuel_type drivetrain
##    <chr>      <chr>    <dbl>   <dbl>     <dbl> <chr>        <chr>     <chr>     
##  1 Volkswagen Jetta     2016  183903       173 Manual       Electric  RWD       
##  2 Lexus      RX        2010  236643       352 Manual       Gasoline  FWD       
##  3 Subaru     Crosstr…  2016  103199       188 Automatic    Diesel    AWD       
##  4 Cadillac   Lyriq     2016  118889       338 Manual       Gasoline  AWD       
##  5 Toyota     Highlan…  2018  204170       196 Manual       Diesel    FWD       
##  6 Land Rover Defender  2021   44907       479 Manual       Diesel    RWD       
##  7 Mazda      Mazda3    2018  129770       160 Automatic    Diesel    FWD       
##  8 Volkswagen Atlas     2022   29146       172 Automatic    Gasoline  RWD       
##  9 Ram        2500      2015  169165       197 Automatic    Electric  RWD       
## 10 Chrysler   300       2025    5081       198 Automatic    Diesel    FWD       
## # ℹ 999,990 more rows
## # ℹ 25 more variables: body_type <chr>, exterior_color <chr>,
## #   interior_color <chr>, owner_count <dbl>, accident_history <chr>,
## #   seller_type <fct>, condition <chr>, trim <chr>, vehicle_age <dbl>,
## #   mileage_per_year <dbl>, brand_popularity <dbl>, price <dbl>, age <dbl>,
## #   car_status <chr>, price_segment <chr>, brand_type <chr>,
## #   mileage_group <chr>, interior_group <chr>, car_id <int>, …

Tương tự phần trước, đoạn mã tính độ lệch công suất của mỗi xe so với trung bình công suất trong hãng.

Ý nghĩa thống kê: Phân tích này giúp phát hiện xe hiệu năng cao (positive deviation) hoặc xe yếu hơn trung bình (negative deviation) trong từng thương hiệu. Đây là cơ sở để xác định các dòng xe chủ lực, bản thể thao hoặc tiêu chuẩn của hãng. Trong thống kê mô tả, đây là phép chuẩn hóa nội nhóm (within-group deviation) để so sánh công suất tương đối.

Xếp hạng Công suất theo Hãng: Xếp hạng engine_hp (cao nhất hạng 1) trong phạm vi từng hãng xe (make).

vehicle_data %>% group_by(make) %>% mutate(hp_rank_by_make = rank(desc(engine_hp))) %>% ungroup()
## # A tibble: 1,000,000 × 33
##    make       model     year mileage engine_hp transmission fuel_type drivetrain
##    <chr>      <chr>    <dbl>   <dbl>     <dbl> <chr>        <chr>     <chr>     
##  1 Volkswagen Jetta     2016  183903       173 Manual       Electric  RWD       
##  2 Lexus      RX        2010  236643       352 Manual       Gasoline  FWD       
##  3 Subaru     Crosstr…  2016  103199       188 Automatic    Diesel    AWD       
##  4 Cadillac   Lyriq     2016  118889       338 Manual       Gasoline  AWD       
##  5 Toyota     Highlan…  2018  204170       196 Manual       Diesel    FWD       
##  6 Land Rover Defender  2021   44907       479 Manual       Diesel    RWD       
##  7 Mazda      Mazda3    2018  129770       160 Automatic    Diesel    FWD       
##  8 Volkswagen Atlas     2022   29146       172 Automatic    Gasoline  RWD       
##  9 Ram        2500      2015  169165       197 Automatic    Electric  RWD       
## 10 Chrysler   300       2025    5081       198 Automatic    Diesel    FWD       
## # ℹ 999,990 more rows
## # ℹ 25 more variables: body_type <chr>, exterior_color <chr>,
## #   interior_color <chr>, owner_count <dbl>, accident_history <chr>,
## #   seller_type <fct>, condition <chr>, trim <chr>, vehicle_age <dbl>,
## #   mileage_per_year <dbl>, brand_popularity <dbl>, price <dbl>, age <dbl>,
## #   car_status <chr>, price_segment <chr>, brand_type <chr>,
## #   mileage_group <chr>, interior_group <chr>, car_id <int>, …

Hàm rank(desc(engine_hp)) sắp xếp các mẫu xe trong từng hãng từ công suất cao đến thấp. Xe mạnh nhất của mỗi hãng được gán hạng 1.

Ý nghĩa thống kê: Kết quả giúp phân loại dòng xe theo hiệu năng nội bộ và xác định vị trí tương đối của từng mẫu trong hệ sản phẩm của hãng. Đây là cơ sở cho các phân tích sau như xác định “xe đầu bảng” (flagship) hoặc “xe phổ thông”. Về mặt thống kê, đây là phép xếp hạng thứ bậc có điều kiện (conditional ranking).

Tỷ lệ Dặm (Khấu hao) TB theo Hãng: Tính Tỷ lệ \(Mileage/Price\) trung bình cho mỗi hãng xe.

vehicle_data %>% group_by(make) %>% summarise(avg_mile_per_price = mean(mileage / price), .groups = 'drop')
## # A tibble: 25 × 2
##    make      avg_mile_per_price
##    <chr>                  <dbl>
##  1 Acura                  11.9 
##  2 Audi                    7.65
##  3 BMW                     8.95
##  4 Cadillac                6.51
##  5 Chevrolet              22.0 
##  6 Chrysler               17.1 
##  7 Dodge                  21.1 
##  8 Ford                   25.0 
##  9 GMC                    15.4 
## 10 Honda                  31.8 
## # ℹ 15 more rows

Đoạn mã tính trung bình tỷ lệ mileage / price, biểu thị số dặm đã đi trên mỗi đơn vị giá (USD). Đây là thước đo hiệu suất sử dụng – khấu hao.

Ý nghĩa thống kê: Giá trị cao (như Honda, Ford, Dodge) cho thấy xe đi nhiều hơn với giá thấp hơn, tức là tốc độ khấu hao cao hơn hoặc giá bán thấp so với quãng đường sử dụng. Ngược lại, tỷ lệ thấp (Cadillac, BMW, Audi) thể hiện giá cao hơn so với mức sử dụng, phù hợp với xe sang. Đây là chỉ tiêu đánh giá hiệu suất sử dụng tài sản (usage efficiency ratio), rất hữu ích trong mô hình định giá xe cũ.

2.3.4.4. Phân tích tích lũy & cực đoan

Tỷ lệ Đóng góp Tổng HP: Tính tỷ lệ phần trăm công suất của từng chiếc xe so với tổng công suất của hãng đó.

vehicle_data %>% group_by(make) %>% mutate(pct_of_make_hp = engine_hp / sum(engine_hp) * 100) %>% ungroup()
## # A tibble: 1,000,000 × 33
##    make       model     year mileage engine_hp transmission fuel_type drivetrain
##    <chr>      <chr>    <dbl>   <dbl>     <dbl> <chr>        <chr>     <chr>     
##  1 Volkswagen Jetta     2016  183903       173 Manual       Electric  RWD       
##  2 Lexus      RX        2010  236643       352 Manual       Gasoline  FWD       
##  3 Subaru     Crosstr…  2016  103199       188 Automatic    Diesel    AWD       
##  4 Cadillac   Lyriq     2016  118889       338 Manual       Gasoline  AWD       
##  5 Toyota     Highlan…  2018  204170       196 Manual       Diesel    FWD       
##  6 Land Rover Defender  2021   44907       479 Manual       Diesel    RWD       
##  7 Mazda      Mazda3    2018  129770       160 Automatic    Diesel    FWD       
##  8 Volkswagen Atlas     2022   29146       172 Automatic    Gasoline  RWD       
##  9 Ram        2500      2015  169165       197 Automatic    Electric  RWD       
## 10 Chrysler   300       2025    5081       198 Automatic    Diesel    FWD       
## # ℹ 999,990 more rows
## # ℹ 25 more variables: body_type <chr>, exterior_color <chr>,
## #   interior_color <chr>, owner_count <dbl>, accident_history <chr>,
## #   seller_type <fct>, condition <chr>, trim <chr>, vehicle_age <dbl>,
## #   mileage_per_year <dbl>, brand_popularity <dbl>, price <dbl>, age <dbl>,
## #   car_status <chr>, price_segment <chr>, brand_type <chr>,
## #   mileage_group <chr>, interior_group <chr>, car_id <int>, …

Đoạn mã trên nhóm dữ liệu theo từng hãng xe (make) và tính toán tỷ lệ phần trăm công suất động cơ (engine_hp) của mỗi xe so với tổng công suất của tất cả xe cùng hãng. Cụ thể, biến mới pct_of_make_hp biểu thị mức đóng góp tương đối của từng xe vào tổng công suất nội bộ của thương hiệu. Lệnh ungroup() được dùng để trả lại dữ liệu về dạng không nhóm, nhằm thuận tiện cho các bước xử lý tiếp theo. Về bản chất, đây là phép chuẩn hóa nội nhóm (within-group normalization), giúp so sánh giữa các xe trong cùng một thương hiệu mà không bị ảnh hưởng bởi quy mô danh mục sản phẩm khác nhau giữa các hãng.

Ý nghĩa thống kê: Về mặt thống kê, biến pct_of_make_hp phản ánh phân phối tỷ trọng công suất trong từng hãng xe — tức là chỉ ra mẫu xe nào đóng vai trò “chủ lực kỹ thuật” (có công suất lớn, chiếm tỷ lệ cao) và mẫu nào nằm ở phân khúc phổ thông (đóng góp nhỏ hơn). Các giá trị nhỏ (thường dưới 0.01%) cho thấy cấu trúc công suất phân tán, nghĩa là hãng có danh mục đa dạng và không phụ thuộc vào một vài mẫu xe duy nhất. Ngược lại, tỷ lệ cao cho thấy tính tập trung công suất, đặc trưng cho các thương hiệu định hướng hiệu năng cao (ví dụ như Tesla hoặc BMW). Phân tích này giúp hiểu rõ đặc điểm kỹ thuật nội tại của thương hiệu, phục vụ cho việc đánh giá chiến lược sản phẩm, độ đa dạng danh mục và mức độ phụ thuộc vào các dòng xe chủ lực.

Xe Đi ít nhất/Giá trị cao nhất: Trong mỗi hãng, tìm chiếc xe có mileage thấp nhất và hiển thị giá của nó

vehicle_data %>% group_by(make) %>% filter(mileage == min(mileage)) %>% select(make, model, price, mileage)
## # A tibble: 4,016 × 4
## # Groups:   make [25]
##    make          model     price mileage
##    <chr>         <chr>     <dbl>   <dbl>
##  1 Chrysler      300      29943.     500
##  2 Acura         RDX      48716.     500
##  3 Hyundai       Santa Fe 25436.     500
##  4 Dodge         Charger  31460.     500
##  5 Mercedes-Benz E-Class  52376.     500
##  6 Tesla         Model Y  63647.     500
##  7 Jeep          Compass  30303.     500
##  8 Lexus         ES       49661.     500
##  9 Audi          Q7       45703.     500
## 10 Audi          A4       51249.     500
## # ℹ 4,006 more rows

Đoạn code nhóm dữ liệu theo hãng xe (make) và dùng filter(mileage == min(mileage)) để chọn xe có quãng đường thấp nhất trong từng nhóm, tức là chiếc “ít đi nhất”. Sau đó, chỉ giữ lại các cột liên quan đến hãng, mẫu xe, giá và số km (select(make, model, price, mileage)).

Ý nghĩa thống kê: Cách làm này giúp nhận diện xe gần như mới nhất trong từng thương hiệu, phản ánh phân khúc sản phẩm cao cấp hoặc mới sản xuất. Việc kết hợp với price cho phép đánh giá mối quan hệ giữa mức độ sử dụng và giá trị giữ giá — thông thường, xe có mileage thấp có giá cao hơn đáng kể. Về mặt thống kê, đây là phép chọn cực trị (minimum selection) trong từng nhóm, giúp mô tả đặc điểm biên của phân phối dữ liệu.

Tích lũy Số lượng: Tính tổng số lượng xe tích lũy theo year tăng dần trong mỗi hãng.

vehicle_data %>% group_by(make) %>% arrange(year) %>% mutate(cumulative_count = cumsum(n()))
## # A tibble: 1,000,000 × 33
## # Groups:   make [25]
##    make       model     year mileage engine_hp transmission fuel_type drivetrain
##    <chr>      <chr>    <dbl>   <dbl>     <dbl> <chr>        <chr>     <chr>     
##  1 Chrysler   Pacifica  2000  300000       166 Manual       Gasoline  AWD       
##  2 Land Rover Range R…  2000  300000       409 Automatic    Gasoline  AWD       
##  3 Land Rover Defender  2000  300000       391 Automatic    Electric  RWD       
##  4 GMC        Acadia    2000  277984       207 Manual       Electric  RWD       
##  5 Nissan     Titan     2000  300000       162 Automatic    Gasoline  AWD       
##  6 Kia        Sportage  2000  300000       138 Automatic    Gasoline  FWD       
##  7 Volvo      S60       2000  300000       291 Manual       Diesel    RWD       
##  8 Land Rover Defender  2000  300000       448 Manual       Electric  AWD       
##  9 Honda      Accord    2000  300000       190 Manual       Gasoline  AWD       
## 10 Porsche    911       2000  106297       476 Automatic    Diesel    AWD       
## # ℹ 999,990 more rows
## # ℹ 25 more variables: body_type <chr>, exterior_color <chr>,
## #   interior_color <chr>, owner_count <dbl>, accident_history <chr>,
## #   seller_type <fct>, condition <chr>, trim <chr>, vehicle_age <dbl>,
## #   mileage_per_year <dbl>, brand_popularity <dbl>, price <dbl>, age <dbl>,
## #   car_status <chr>, price_segment <chr>, brand_type <chr>,
## #   mileage_group <chr>, interior_group <chr>, car_id <int>, …

Hàm group_by(make) chia dữ liệu theo từng hãng xe, arrange(year) sắp xếp theo thứ tự năm sản xuất tăng dần, và mutate(cumulative_count = cumsum(n())) tính tổng tích lũy số lượng xe của từng hãng theo thời gian.

Ý nghĩa thống kê: Phân tích này cho phép theo dõi sự phát triển tích lũy sản lượng hoặc số lượng xe theo thời gian của mỗi hãng. Dạng dữ liệu này đặc biệt hữu ích cho việc xây dựng đường tích lũy (cumulative trend curve) hoặc phân tích “market penetration” – thể hiện sự mở rộng thị phần qua các năm. Về mặt thống kê, đây là phép cộng dồn nhóm theo thời gian (grouped cumulative sum), mô tả xu hướng động học (growth dynamics) trong chuỗi dữ liệu theo hãng.

Độ chênh lệch Giá trị/TB Toàn cục: Tính giá trung vị của hãng so với giá trung vị toàn cục.

median_price_global <- median(vehicle_data$price); vehicle_data %>% group_by(make) %>% summarise(median_advantage = median(price) - median_price_global, .groups = 'drop')
## # A tibble: 25 × 2
##    make      median_advantage
##    <chr>                <dbl>
##  1 Acura                3202.
##  2 Audi                 8667.
##  3 BMW                  6633.
##  4 Cadillac            11373.
##  5 Chevrolet           -3383.
##  6 Chrysler             -793.
##  7 Dodge               -2734.
##  8 Ford                -4692.
##  9 GMC                   620.
## 10 Honda               -7267.
## # ℹ 15 more rows

Đầu tiên tính giá trung vị toàn bộ thị trường và lưu trong median_price_global. Sau đó, đối với mỗi hãng xe, code tính độ chênh lệch giữa giá trung vị của hãng và toàn cục – tức là lợi thế hay bất lợi giá trung bình.

Ý nghĩa thống kê: Kết quả phản ánh vị thế giá của từng thương hiệu:

median_advantage > 0 → hãng nằm ở phân khúc cao cấp, giá cao hơn trung bình toàn thị trường.

median_advantage < 0 → hãng thuộc phân khúc phổ thông hoặc bình dân. Về thống kê, đây là so sánh vị trí trung vị giữa các nhóm, một chỉ số ổn định và ít bị nhiễu hơn trung bình, nên phản ánh chính xác hơn định vị giá trị trung tâm của từng thương hiệu.

Giá trị Tương quan Cực đoan: Lọc các hãng xe có tỷ lệ xe “Fair” (Kém) cao nhất.

vehicle_data %>% group_by(make) %>% summarise(pct_fair = mean(condition == "Fair") * 100) %>% arrange(desc(pct_fair))
## # A tibble: 25 × 2
##    make          pct_fair
##    <chr>            <dbl>
##  1 Mercedes-Benz     10.3
##  2 Honda             10.2
##  3 Dodge             10.2
##  4 Jeep              10.1
##  5 Chrysler          10.1
##  6 Lexus             10.1
##  7 Volvo             10.1
##  8 Subaru            10.1
##  9 Porsche           10.1
## 10 Nissan            10.0
## # ℹ 15 more rows

Đoạn code nhóm dữ liệu theo hãng, sau đó tính tỷ lệ phần trăm xe có tình trạng “Fair” (chất lượng thấp) trong mỗi nhóm bằng cách lấy trung bình của điều kiện logic (condition == “Fair”). Cuối cùng, arrange(desc(pct_fair)) sắp xếp theo tỷ lệ giảm dần để tìm các hãng có tỷ lệ xe kém cao nhất.

Ý nghĩa thống kê: Đây là phép đo tần suất tương đối (relative frequency) biểu diễn bằng phần trăm. Kết quả cho biết mức độ phân bố chất lượng xe theo thương hiệu – các hãng có tỷ lệ “Fair” cao (như Mercedes-Benz, Honda, Dodge) có thể phản ánh hoặc:

Mẫu xe cũ chiếm tỉ lệ cao,

Người dùng có xu hướng giữ xe lâu hơn,

Hoặc chiến lược sản xuất đa dạng phân khúc.

Từ góc độ thống kê, đây là biến định tính nhị phân được tổng hợp bằng trung bình nhóm, tương đương với xác suất xảy ra của một trạng thái nhất định (Fair). Phân tích này rất hữu ích trong đánh giá độ bền, uy tín và chất lượng sản phẩm theo thương hiệu.

2.3.5. Phân tích biến Mileage

2.3.5.1. Phân tích tổng quan và khấu hao

Mã hóa Phân vị: Tạo cột mileage_quartile gán nhãn 1, 2, 3, 4 dựa trên ngưỡng tứ phân vị của mileage.

vehicle_data <- vehicle_data %>% mutate(mileage_quartile = ntile(mileage, 4))

Lệnh ntile(mileage, 4) chia dữ liệu mileage thành 4 nhóm tứ phân vị (quartiles) và gán nhãn 1–4 cho từng xe. Nhóm 1 là 25% xe có mileage thấp nhất, nhóm 4 là 25% xe có mileage cao nhất.

Ý nghĩa thống kê: Phân vị là cách chuẩn hóa biến liên tục thành nhóm thứ bậc, giúp dễ dàng so sánh và trực quan hóa (ví dụ khi vẽ boxplot hay heatmap). Biến mileage_quartile cho phép ta phân loại xe thành 4 cấp độ hao mòn, từ “ít sử dụng” đến “đã chạy nhiều”, hỗ trợ các mô hình phân tích rủi ro hoặc định giá theo nhóm tuổi sử dụng.

Số dặm Min/Max TB: Tìm số dặm thấp nhất và cao nhất cho mỗi năm sản xuất (year).

vehicle_data %>% group_by(year) %>% summarise(min_mile = min(mileage), max_mile = max(mileage), .groups = 'drop')
## # A tibble: 26 × 3
##     year min_mile max_mile
##    <dbl>    <dbl>    <dbl>
##  1  2000    29654   300000
##  2  2001    56664   300000
##  3  2002    11482   300000
##  4  2003    49169   300000
##  5  2004    71707   300000
##  6  2005     9506   300000
##  7  2006     1111   300000
##  8  2007    16042   300000
##  9  2008     4719   300000
## 10  2009      547   300000
## # ℹ 16 more rows

Hàm summarise() tổng hợp giá trị nhỏ nhất và lớn nhất của mileage trong từng nhóm year.

Ý nghĩa thống kê: Kết quả cho thấy dù xe sản xuất từ 2000–2009, giá trị max_mile đều đạt ngưỡng trần 300.000 dặm, phản ánh giới hạn kỹ thuật của tập dữ liệu (có thể là mức trần giả lập). min_mile giảm dần theo thời gian chứng tỏ xe đời mới thường có số dặm thấp hơn, hợp lý về mặt sử dụng thực tế. Phép này giúp ta nhận diện mối quan hệ nghịch đảo giữa tuổi xe và quãng đường đã đi – một quy luật kinh điển trong phân tích dữ liệu ô tô.

Khấu hao Tích lũy: Sắp xếp xe theo mileage tăng dần và tính tổng tích lũy của số dặm.

vehicle_data %>% arrange(mileage) %>% mutate(cumulative_mileage = cumsum(mileage))
## # A tibble: 1,000,000 × 34
##    make          model  year mileage engine_hp transmission fuel_type drivetrain
##    <chr>         <chr> <dbl>   <dbl>     <dbl> <chr>        <chr>     <chr>     
##  1 Chrysler      300    2025     500       220 Automatic    Diesel    AWD       
##  2 Acura         RDX    2025     500       261 Automatic    Diesel    FWD       
##  3 Hyundai       Sant…  2025     500       159 Automatic    Gasoline  RWD       
##  4 Dodge         Char…  2025     500       199 Automatic    Gasoline  FWD       
##  5 Mercedes-Benz E-Cl…  2025     500       290 Automatic    Gasoline  AWD       
##  6 Tesla         Mode…  2025     500       329 Manual       Electric  RWD       
##  7 Jeep          Comp…  2025     500       182 Automatic    Gasoline  FWD       
##  8 Lexus         ES     2025     500       272 Automatic    Gasoline  AWD       
##  9 Audi          Q7     2025     500       314 Automatic    Gasoline  AWD       
## 10 Audi          A4     2025     500       331 Automatic    Diesel    AWD       
## # ℹ 999,990 more rows
## # ℹ 26 more variables: body_type <chr>, exterior_color <chr>,
## #   interior_color <chr>, owner_count <dbl>, accident_history <chr>,
## #   seller_type <fct>, condition <chr>, trim <chr>, vehicle_age <dbl>,
## #   mileage_per_year <dbl>, brand_popularity <dbl>, price <dbl>, age <dbl>,
## #   car_status <chr>, price_segment <chr>, brand_type <chr>,
## #   mileage_group <chr>, interior_group <chr>, car_id <int>, …

Sau khi sắp xếp dữ liệu theo mileage, hàm cumsum() tính tổng tích lũy của mileage, tạo ra biến cumulative_mileage – thể hiện tổng quãng đường cộng dồn khi duyệt qua các xe.

Ý nghĩa thống kê: Phép cộng dồn này thể hiện tốc độ tăng tổng quãng đường sử dụng trong toàn bộ tập dữ liệu. Đây là kỹ thuật thường dùng để xác định phân bố tích lũy (CDF) của biến liên tục – giúp hiểu mức độ “tập trung” của hao mòn: ví dụ 50% xe có thể chỉ chiếm 25% tổng quãng đường di chuyển toàn tập.

Tỷ lệ Dặm Kép: Tính tỷ lệ phần trăm xe có mileage trên \(100,000\) VÀ engine_hp dưới \(150\) (xe bền/đơn giản).

vehicle_data %>% summarise(pct_worn_basic = sum(mileage > 100000 & engine_hp < 150) / n() * 100)
## # A tibble: 1 × 1
##   pct_worn_basic
##            <dbl>
## 1           9.63

Tính tỷ lệ phần trăm xe thỏa đồng thời hai điều kiện: chạy nhiều (mileage > 100,000) và động cơ yếu (engine_hp < 150).

Ý nghĩa thống kê: Kết quả khoảng 9.6% cho thấy gần 1/10 số xe thuộc nhóm “cũ và công suất thấp”, có thể xem là nhóm xe kinh tế hoặc xe giá rẻ. Phép giao điều kiện này giúp phân định nhóm rủi ro hao mòn cao – hiệu năng thấp, quan trọng trong phân tích độ bền và xác suất hỏng hóc.

Số dặm trung bình theo Mốc Tuổi: Phân tổ year thành 3 nhóm tuổi (ví dụ: 0-3, 4-7, 8+ tuổi) và tính số dặm trung bình cho mỗi nhóm.

vehicle_data %>% mutate(age_bin = cut(2025 - year, breaks = c(0, 3, 7, Inf), labels = c("0-3 yr", "4-7 yr", "8+ yr"))) %>% group_by(age_bin) %>% summarise(avg_mileage = mean(mileage), .groups = 'drop')
## # A tibble: 4 × 2
##   age_bin avg_mileage
##   <fct>         <dbl>
## 1 0-3 yr       33526.
## 2 4-7 yr       84777.
## 3 8+ yr       159113.
## 4 <NA>          4036.

Đoạn mã tính tuổi xe (2025 - year) rồi phân loại thành 3 nhóm (0–3 năm, 4–7 năm, và >8 năm). Sau đó tính trung bình mileage trong mỗi nhóm.

Ý nghĩa thống kê: Kết quả minh họa rất rõ quy luật hao mòn tuyến tính theo thời gian:

Xe mới (0–3 năm): ~33.500 dặm

Xe trung niên (4–7 năm): ~84.700 dặm

Xe cũ (>8 năm): ~159.000 dặm

Điều này phù hợp với mô hình tăng tuyến tính của mileage theo tuổi (≈12.000–15.000 dặm/năm). Phân tích này hỗ trợ việc ước lượng giá trị còn lại hoặc tuổi thọ thực tế của xe.

2.3.5.2. Phân tích tương tác & chất lượng

Số dặm TB theo Nguồn & Tình trạng: Tính Số dặm trung vị theo sự kết hợp của seller_type và condition.

vehicle_data %>% group_by(seller_type, condition) %>% summarise(median_mileage = median(mileage), .groups = 'drop')
## # A tibble: 6 × 3
##   seller_type condition median_mileage
##   <fct>       <chr>              <dbl>
## 1 Dealer      Excellent        103182 
## 2 Dealer      Fair             103270 
## 3 Dealer      Good             103370.
## 4 Private     Excellent        103466 
## 5 Private     Fair             103736.
## 6 Private     Good             103371

Dữ liệu được nhóm theo hai biến phân loại seller_type (Dealer, Private) và condition (Excellent, Good, Fair). Hàm median() lấy số dặm trung vị trong từng tổ hợp nhóm.

Ý nghĩa thống kê: Kết quả cho thấy sự khác biệt rất nhỏ giữa các nhóm (~103.000 dặm), chứng tỏ tình trạng xe và nguồn bán không ảnh hưởng mạnh đến quãng đường trung vị. Tuy nhiên, xe “Private–Excellent” có mileage nhỉnh hơn Dealer–Excellent một chút, cho thấy chủ cá nhân có thể sử dụng xe lâu hơn trước khi bán. Đây là phân tích giao cắt hai chiều (two-way grouping) — thường dùng trong thống kê mô tả đa biến.

Số dặm TB theo HP Group: Phân nhóm engine_hp thành 3 nhóm và tính Số dặm TB của mỗi nhóm.

vehicle_data %>% mutate(hp_group = ntile(engine_hp, 3)) %>% group_by(hp_group) %>% summarise(avg_mileage = mean(mileage), .groups = 'drop')
## # A tibble: 3 × 2
##   hp_group avg_mileage
##      <int>       <dbl>
## 1        1     112598.
## 2        2     112844.
## 3        3     112539.

Phân loại engine_hp thành 3 nhóm bằng ntile(), sau đó tính số dặm trung bình của từng nhóm công suất.

Ý nghĩa thống kê: Kết quả cho thấy giá trị avg_mileage gần như không đổi (~112.500 dặm) giữa các nhóm HP. Điều này chứng tỏ công suất động cơ không ảnh hưởng đáng kể đến mức sử dụng xe — các xe mạnh hay yếu đều có tuổi đời sử dụng tương tự. Đây là minh chứng cho sự đồng đều trong hành vi vận hành của người dùng, bất kể phân khúc công suất.

Tương quan Dặm & HP: Tính Tương quan giữa mileage và engine_hp riêng cho từng nhóm condition.

vehicle_data %>% group_by(condition) %>% summarise(corr_mile_hp = cor(mileage, engine_hp), .groups = 'drop')
## # A tibble: 3 × 2
##   condition corr_mile_hp
##   <chr>            <dbl>
## 1 Excellent     -0.00125
## 2 Fair          -0.00136
## 3 Good           0.00129

Tính hệ số tương quan Pearson giữa hai biến mileage và engine_hp trong từng nhóm condition.

Ý nghĩa thống kê: Các giá trị tương quan đều rất gần 0 (≈ ±0.001), cho thấy hầu như không tồn tại mối quan hệ tuyến tính giữa công suất và quãng đường đi. Điều này phù hợp với trực giác: động cơ mạnh không có nghĩa xe sẽ chạy ít hay nhiều hơn. → Đây là kết quả cho thấy độc lập thống kê giữa hai biến trong mọi nhóm tình trạng xe.

Số dặm TB theo Lưới Hộp số & Nhiên liệu: Tính Số dặm TB theo sự kết hợp của transmission và fuel_type.

vehicle_data %>% group_by(transmission, fuel_type) %>% summarise(avg_mileage = mean(mileage), .groups = 'drop')
## # A tibble: 6 × 3
##   transmission fuel_type avg_mileage
##   <chr>        <chr>           <dbl>
## 1 Automatic    Diesel        112547.
## 2 Automatic    Electric      112873.
## 3 Automatic    Gasoline      112754.
## 4 Manual       Diesel        112534.
## 5 Manual       Electric      112797.
## 6 Manual       Gasoline      112412.

Phân nhóm theo hai biến định tính transmission (Automatic, Manual) và fuel_type (Gasoline, Diesel, Electric), rồi tính trung bình số dặm từng tổ hợp.

Ý nghĩa thống kê: Giá trị trung bình rất sát nhau (~112.500 dặm), chỉ chênh vài trăm đơn vị. Tuy nhiên, xe điện (Electric) có avg_mileage thấp hơn một chút (~112.796) — hợp lý vì xe điện thường đời mới hơn và sử dụng ít hơn. Đây là dạng phân tích kết hợp hai nhân tố độc lập giúp hiểu tác động đồng thời của cấu hình kỹ thuật đến hành vi sử dụng.

Tỷ lệ Dặm/TB Hãng: Tính tỷ lệ phần trăm số dặm của xe so với Số dặm TB của hãng đó.

vehicle_data %>% group_by(make) %>% mutate(mile_pct_diff = (mileage - mean(mileage)) / mean(mileage) * 100) %>% ungroup()
## # A tibble: 1,000,000 × 34
##    make       model     year mileage engine_hp transmission fuel_type drivetrain
##    <chr>      <chr>    <dbl>   <dbl>     <dbl> <chr>        <chr>     <chr>     
##  1 Volkswagen Jetta     2016  183903       173 Manual       Electric  RWD       
##  2 Lexus      RX        2010  236643       352 Manual       Gasoline  FWD       
##  3 Subaru     Crosstr…  2016  103199       188 Automatic    Diesel    AWD       
##  4 Cadillac   Lyriq     2016  118889       338 Manual       Gasoline  AWD       
##  5 Toyota     Highlan…  2018  204170       196 Manual       Diesel    FWD       
##  6 Land Rover Defender  2021   44907       479 Manual       Diesel    RWD       
##  7 Mazda      Mazda3    2018  129770       160 Automatic    Diesel    FWD       
##  8 Volkswagen Atlas     2022   29146       172 Automatic    Gasoline  RWD       
##  9 Ram        2500      2015  169165       197 Automatic    Electric  RWD       
## 10 Chrysler   300       2025    5081       198 Automatic    Diesel    FWD       
## # ℹ 999,990 more rows
## # ℹ 26 more variables: body_type <chr>, exterior_color <chr>,
## #   interior_color <chr>, owner_count <dbl>, accident_history <chr>,
## #   seller_type <fct>, condition <chr>, trim <chr>, vehicle_age <dbl>,
## #   mileage_per_year <dbl>, brand_popularity <dbl>, price <dbl>, age <dbl>,
## #   car_status <chr>, price_segment <chr>, brand_type <chr>,
## #   mileage_group <chr>, interior_group <chr>, car_id <int>, …

Biến mile_pct_diff biểu thị mức chênh lệch phần trăm (%) số dặm của từng xe so với trung bình hãng. Hàm ungroup() đảm bảo dữ liệu trả về không còn nhóm lồng.

Ý nghĩa thống kê: Chỉ số này cho phép xác định mức độ sử dụng tương đối của từng xe trong cùng thương hiệu.

Giá trị dương → xe chạy nhiều hơn trung bình.

Giá trị âm → xe “ít đi” hơn mặt bằng.

Ví dụ: xe có mile_pct_diff = +60% nghĩa là chạy nhiều hơn 60% so với trung bình hãng. Đây là dạng chuẩn hóa nội nhóm (within-group normalization) rất hữu ích để so sánh mức hao mòn giữa xe cùng hãng mà không bị lệch do khác biệt giữa thương hiệu.

2.3.5.3. Phân tích vị thế

Mức độ Sử dụng Tương đối (Theo Năm): Tính độ chênh lệch giữa mileage và Số dặm TB của năm sản xuất đó.

vehicle_data %>% group_by(year) %>% mutate(mile_diff_year_avg = mileage - mean(mileage)) %>% ungroup()
## # A tibble: 1,000,000 × 34
##    make       model     year mileage engine_hp transmission fuel_type drivetrain
##    <chr>      <chr>    <dbl>   <dbl>     <dbl> <chr>        <chr>     <chr>     
##  1 Volkswagen Jetta     2016  183903       173 Manual       Electric  RWD       
##  2 Lexus      RX        2010  236643       352 Manual       Gasoline  FWD       
##  3 Subaru     Crosstr…  2016  103199       188 Automatic    Diesel    AWD       
##  4 Cadillac   Lyriq     2016  118889       338 Manual       Gasoline  AWD       
##  5 Toyota     Highlan…  2018  204170       196 Manual       Diesel    FWD       
##  6 Land Rover Defender  2021   44907       479 Manual       Diesel    RWD       
##  7 Mazda      Mazda3    2018  129770       160 Automatic    Diesel    FWD       
##  8 Volkswagen Atlas     2022   29146       172 Automatic    Gasoline  RWD       
##  9 Ram        2500      2015  169165       197 Automatic    Electric  RWD       
## 10 Chrysler   300       2025    5081       198 Automatic    Diesel    FWD       
## # ℹ 999,990 more rows
## # ℹ 26 more variables: body_type <chr>, exterior_color <chr>,
## #   interior_color <chr>, owner_count <dbl>, accident_history <chr>,
## #   seller_type <fct>, condition <chr>, trim <chr>, vehicle_age <dbl>,
## #   mileage_per_year <dbl>, brand_popularity <dbl>, price <dbl>, age <dbl>,
## #   car_status <chr>, price_segment <chr>, brand_type <chr>,
## #   mileage_group <chr>, interior_group <chr>, car_id <int>, …

Đoạn mã tính toán biến mile_diff_year_avg nhằm đo lường mức độ chênh lệch giữa số dặm của từng xe và giá trị trung bình của các xe được sản xuất trong cùng một năm. Về mặt kỹ thuật, việc nhóm dữ liệu theo biến year rồi áp dụng phép mileage - mean(mileage) giúp ta xác định mức “lệch chuẩn hóa” theo năm, tức là mỗi xe được so sánh với mặt bằng chung của các xe cùng tuổi.

Về mặt thống kê, chỉ số này cho phép đánh giá mức độ sử dụng tương đối của từng xe: xe có giá trị dương là xe đã đi nhiều hơn trung bình, còn xe có giá trị âm là xe ít sử dụng hơn. Nhờ vậy, nhà phân tích có thể nhận biết nhanh những xe “bất thường” – ví dụ một chiếc xe đời 2010 nhưng đi ít hơn trung bình 50.000 dặm có thể từng được lưu kho, trong khi một xe đời 2020 nhưng đã vượt trung bình 80.000 dặm cho thấy tần suất sử dụng cao bất thường. Đây là chỉ số rất hữu ích để chuẩn hóa ảnh hưởng của năm sản xuất, giúp việc so sánh giữa các xe trở nên công bằng hơn.

Xếp hạng Số dặm theo Năm: Xếp hạng mileage (ít nhất hạng 1) trong phạm vi từng năm sản xuất (year).

vehicle_data %>% group_by(year) %>% mutate(mile_rank_by_year = rank(mileage)) %>% ungroup()
## # A tibble: 1,000,000 × 34
##    make       model     year mileage engine_hp transmission fuel_type drivetrain
##    <chr>      <chr>    <dbl>   <dbl>     <dbl> <chr>        <chr>     <chr>     
##  1 Volkswagen Jetta     2016  183903       173 Manual       Electric  RWD       
##  2 Lexus      RX        2010  236643       352 Manual       Gasoline  FWD       
##  3 Subaru     Crosstr…  2016  103199       188 Automatic    Diesel    AWD       
##  4 Cadillac   Lyriq     2016  118889       338 Manual       Gasoline  AWD       
##  5 Toyota     Highlan…  2018  204170       196 Manual       Diesel    FWD       
##  6 Land Rover Defender  2021   44907       479 Manual       Diesel    RWD       
##  7 Mazda      Mazda3    2018  129770       160 Automatic    Diesel    FWD       
##  8 Volkswagen Atlas     2022   29146       172 Automatic    Gasoline  RWD       
##  9 Ram        2500      2015  169165       197 Automatic    Electric  RWD       
## 10 Chrysler   300       2025    5081       198 Automatic    Diesel    FWD       
## # ℹ 999,990 more rows
## # ℹ 26 more variables: body_type <chr>, exterior_color <chr>,
## #   interior_color <chr>, owner_count <dbl>, accident_history <chr>,
## #   seller_type <fct>, condition <chr>, trim <chr>, vehicle_age <dbl>,
## #   mileage_per_year <dbl>, brand_popularity <dbl>, price <dbl>, age <dbl>,
## #   car_status <chr>, price_segment <chr>, brand_type <chr>,
## #   mileage_group <chr>, interior_group <chr>, car_id <int>, …

Phép xếp hạng (rank) trong đoạn mã cho phép gán thứ tự sử dụng (từ ít đến nhiều) cho từng xe trong phạm vi từng năm sản xuất. Về kỹ thuật, đây là một dạng xếp hạng nội nhóm (within-group ranking), giúp ta so sánh xe trong cùng bối cảnh tuổi đời.

Ở góc nhìn thống kê, chỉ số này mô tả thứ bậc sử dụng của các xe cùng tuổi: xe được xếp hạng thấp (gần 1) thường là xe sử dụng ít nhất trong năm đó, trong khi hạng cao là xe chạy nhiều hơn hẳn đồng niên. Thống kê dạng này giúp phát hiện các “xe ngoại lệ” trong từng năm — chẳng hạn một xe sản xuất năm 2018 nhưng rank cao nhất có thể là xe chạy dịch vụ, còn một xe 2015 có rank thấp lại thể hiện tình trạng được bảo quản tốt. Việc xếp hạng này đặc biệt hữu ích khi muốn chuẩn hóa dữ liệu phục vụ mô hình hồi quy hoặc phân cụm theo năm sản xuất.

Khấu hao Lõi (Lọc): Lọc các xe có mileage <=P10 VÀ engine_hp >= P90 (Đi ít, HP cao).

p10 <- quantile(vehicle_data$mileage, 0.10); p90 <- quantile(vehicle_data$engine_hp, 0.90); vehicle_data %>% filter(mileage <= p10 & engine_hp >= p90)
## # A tibble: 10,182 × 33
##    make       model     year mileage engine_hp transmission fuel_type drivetrain
##    <chr>      <chr>    <dbl>   <dbl>     <dbl> <chr>        <chr>     <chr>     
##  1 Land Rover Discove…  2023   18858       448 Manual       Gasoline  AWD       
##  2 Porsche    911       2022   17690       409 Manual       Diesel    RWD       
##  3 Land Rover Discove…  2024   16490       418 Automatic    Electric  FWD       
##  4 Land Rover Defender  2025    1881       388 Manual       Electric  FWD       
##  5 Tesla      Model X   2024    1018       398 Automatic    Electric  AWD       
##  6 Porsche    Panamera  2025    1074       473 Manual       Electric  FWD       
##  7 Porsche    Panamera  2020    8054       483 Manual       Diesel    RWD       
##  8 Tesla      Model 3   2025    1497       387 Manual       Electric  FWD       
##  9 Land Rover Range R…  2023   23346       426 Automatic    Diesel    FWD       
## 10 Land Rover Discove…  2020   22287       420 Automatic    Diesel    AWD       
## # ℹ 10,172 more rows
## # ℹ 25 more variables: body_type <chr>, exterior_color <chr>,
## #   interior_color <chr>, owner_count <dbl>, accident_history <chr>,
## #   seller_type <fct>, condition <chr>, trim <chr>, vehicle_age <dbl>,
## #   mileage_per_year <dbl>, brand_popularity <dbl>, price <dbl>, age <dbl>,
## #   car_status <chr>, price_segment <chr>, brand_type <chr>,
## #   mileage_group <chr>, interior_group <chr>, car_id <int>, …

Đây là một kỹ thuật lọc dữ liệu dựa trên phân vị thống kê: ta chọn ra nhóm 10% xe có số dặm thấp nhất (p10) và đồng thời có công suất thuộc 10% cao nhất (p90). Lọc theo hai ngưỡng này cho phép cô lập nhóm xe có đặc trưng đặc biệt – công suất mạnh nhưng ít sử dụng.

Về ý nghĩa thống kê, nhóm xe này thường đại diện cho phân khúc cao cấp hoặc xe mới hiệu năng cao, ví dụ các mẫu xe thể thao, xe sang hoặc xe thử nghiệm. Việc tách nhóm này ra giúp phân tích riêng đặc tính “khấu hao lõi”: đây là những xe có giá trị thị trường cao, tốc độ mất giá thấp và thường được bảo quản tốt. Kỹ thuật này giúp hiểu cấu trúc của phân phối dữ liệu, đồng thời phát hiện nhóm khách hàng hoặc sản phẩm có hành vi sử dụng đặc thù.

2.3.5.4. Phân tích tích lũy & cực đoan

Tỷ lệ Đóng góp Tổng Dặm: Tính tỷ lệ phần trăm số dặm của từng chiếc xe so với tổng số dặm toàn cục.

vehicle_data %>% mutate(pct_of_total_mile = mileage / sum(mileage) * 100)
## # A tibble: 1,000,000 × 34
##    make       model     year mileage engine_hp transmission fuel_type drivetrain
##    <chr>      <chr>    <dbl>   <dbl>     <dbl> <chr>        <chr>     <chr>     
##  1 Volkswagen Jetta     2016  183903       173 Manual       Electric  RWD       
##  2 Lexus      RX        2010  236643       352 Manual       Gasoline  FWD       
##  3 Subaru     Crosstr…  2016  103199       188 Automatic    Diesel    AWD       
##  4 Cadillac   Lyriq     2016  118889       338 Manual       Gasoline  AWD       
##  5 Toyota     Highlan…  2018  204170       196 Manual       Diesel    FWD       
##  6 Land Rover Defender  2021   44907       479 Manual       Diesel    RWD       
##  7 Mazda      Mazda3    2018  129770       160 Automatic    Diesel    FWD       
##  8 Volkswagen Atlas     2022   29146       172 Automatic    Gasoline  RWD       
##  9 Ram        2500      2015  169165       197 Automatic    Electric  RWD       
## 10 Chrysler   300       2025    5081       198 Automatic    Diesel    FWD       
## # ℹ 999,990 more rows
## # ℹ 26 more variables: body_type <chr>, exterior_color <chr>,
## #   interior_color <chr>, owner_count <dbl>, accident_history <chr>,
## #   seller_type <fct>, condition <chr>, trim <chr>, vehicle_age <dbl>,
## #   mileage_per_year <dbl>, brand_popularity <dbl>, price <dbl>, age <dbl>,
## #   car_status <chr>, price_segment <chr>, brand_type <chr>,
## #   mileage_group <chr>, interior_group <chr>, car_id <int>, …

Lệnh mileage / sum(mileage) * 100 tính phần trăm quãng đường mà mỗi xe đóng góp vào tổng quãng đường của toàn bộ tập dữ liệu. Về mặt kỹ thuật, đây là chuẩn hóa toàn cục, giúp chuyển giá trị tuyệt đối thành tỷ trọng tương đối.

Về thống kê, chỉ số này cho biết mức độ ảnh hưởng (impact) của từng xe đối với tổng mức sử dụng chung. Một số xe có tỷ lệ đóng góp rất lớn (ví dụ >0.05%) có thể được xem là outlier ảnh hưởng mạnh, tức là xe chạy quá nhiều so với mặt bằng. Ngược lại, phần lớn xe có tỷ lệ rất nhỏ chứng tỏ dữ liệu phân bố khá đều. Phân tích này thường được dùng để đánh giá mức độ tập trung hay phân tán của biến sử dụng – tương tự khái niệm “phân phối quyền lực” trong dữ liệu.

Xe Đi ít nhất/Mới nhất: Tìm chiếc xe có mileage thấp nhất trong số các xe được sản xuất từ 2020 trở đi.

vehicle_data %>% filter(year >= 2020) %>% arrange(mileage) %>% head(1) %>% select(make, model, year, mileage)
## # A tibble: 1 × 4
##   make     model  year mileage
##   <chr>    <chr> <dbl>   <dbl>
## 1 Chrysler 300    2025     500

Đây là phép lọc đơn giản nhưng có tính biểu tượng cao: bằng cách chỉ giữ các xe sản xuất từ 2020, sắp xếp theo mileage tăng dần và lấy xe đầu tiên, ta xác định chiếc xe mới nhất và đi ít nhất trong toàn tập.

Kết quả chỉ ra rằng chiếc Chrysler 300 (2025) chỉ đi được 500 dặm, gần như là xe mới tinh. Trong thống kê mô tả, việc xác định điểm cực tiểu như vậy giúp đặt mốc tham chiếu cho các chỉ số hao mòn — ví dụ khi muốn tính tỷ lệ hao mòn tương đối so với xe mới nhất. Xe này cũng có thể được coi là “điểm gốc chuẩn hóa” khi cần biểu diễn mức độ sử dụng theo phần trăm so với giá trị nhỏ nhất.

Tỷ lệ Xe Đi ít theo Hãng: Trong mỗi hãng, tính tỷ lệ phần trăm xe đi dưới 50,000 dặm.

vehicle_data %>% group_by(make) %>% summarise(pct_low_mile = mean(mileage < 50000) * 100, .groups = 'drop')
## # A tibble: 25 × 2
##    make      pct_low_mile
##    <chr>            <dbl>
##  1 Acura             20.9
##  2 Audi              21.2
##  3 BMW               21.3
##  4 Cadillac          21.2
##  5 Chevrolet         20.9
##  6 Chrysler          21.0
##  7 Dodge             20.9
##  8 Ford              21.1
##  9 GMC               20.9
## 10 Honda             21.5
## # ℹ 15 more rows

Công thức mean(mileage < 50000) * 100 tính phần trăm xe có số dặm nhỏ hơn 50.000 trong từng nhóm make (hãng xe). Đây là chỉ số đo lường sức trẻ của đội xe — hay còn gọi là Fleet Youth Index.

Về mặt thống kê, kết quả cho thấy hầu hết các hãng có tỷ lệ tương đối đồng đều, dao động quanh mức 20–21%. Điều này phản ánh rằng thị trường xe trong dữ liệu khá cân bằng giữa xe mới và xe cũ, không có thương hiệu nào chiếm ưu thế tuyệt đối về độ mới của xe. Tuy nhiên, một số hãng có thể hơi cao hơn trung bình, cho thấy họ có tỷ lệ khách hàng chuộng xe đời mới hoặc xe được sử dụng ít hơn. Đây là chỉ số đặc biệt quan trọng trong phân tích thị phần, định giá, hoặc dự báo nhu cầu thay thế xe.

2.3.6. Phân tích biến Year

2.3.6.1. Phân tích tổng quan về thời gian

Tương quan Tuổi & Giá: Tính Tương quan giữa age và price.

cor(vehicle_data$vehicle_age,vehicle_data$price)
## [1] -0.6628115

HĐầu tiên, mối quan hệ giữa tuổi xe (vehicle_age) và giá bán (price) được kiểm tra thông qua hệ số tương quan Pearson. Kết quả thu được là r = -0.6628, thể hiện mối quan hệ nghịch chiều khá mạnh giữa hai biến này. Về mặt kỹ thuật, điều đó có nghĩa là tuổi xe càng cao thì giá bán càng thấp.

Từ góc độ thống kê, hệ số -0.66 cho thấy tuổi xe giải thích được khoảng 44% biến thiên của giá (do R² ≈ 0.44). Điều này phản ánh quy luật khấu hao tự nhiên – một chiếc xe càng cũ, càng mất giá theo thời gian, bất kể thương hiệu hay công suất. Tuy nhiên, mối tương quan không đạt mức tuyệt đối (-1), cho thấy giá xe không chỉ phụ thuộc vào tuổi, mà còn bị ảnh hưởng bởi các yếu tố khác như hãng xe, tình trạng, công suất và quãng đường đã đi. Kết quả này củng cố giả định rằng thời gian là yếu tố chính nhưng không phải duy nhất quyết định giá trị xe.

Giá Min/Max theo Năm: Tìm Giá bán nhỏ nhất và lớn nhất cho mỗi năm sản xuất.

vehicle_data %>% group_by(year) %>% summarise(min_price = min(price), max_price = max(price), .groups = 'drop')
## # A tibble: 26 × 3
##     year min_price max_price
##    <dbl>     <dbl>     <dbl>
##  1  2000      1500    13313.
##  2  2001      1500     5080.
##  3  2002      1500    11860.
##  4  2003      1500    13317.
##  5  2004      1500    12771.
##  6  2005      1500    20783.
##  7  2006      1500    20959.
##  8  2007      1500    25674.
##  9  2008      1500    27683.
## 10  2009      1500    28324.
## # ℹ 16 more rows

Sau khi nhóm dữ liệu theo biến year, ta tính được giá thấp nhất (min_price) và cao nhất (max_price) cho mỗi năm sản xuất. Kết quả cho thấy giá tối thiểu gần như cố định quanh 1.500 USD, đóng vai trò là “ngưỡng sàn” của thị trường xe cũ, phản ánh mức giá tối thiểu mà hầu hết xe đều có thể đạt được, bất kể tuổi đời.

Ngược lại, giá tối đa (max_price) lại tăng rõ rệt theo thời gian: từ khoảng 13.000 USD ở các xe sản xuất đầu những năm 2000, lên đến hơn 250.000 USD ở những năm gần đây. Điều này cho thấy sự mở rộng mạnh mẽ của thị trường xe cao cấp, đặc biệt với sự xuất hiện của các mẫu xe điện, xe thể thao và siêu xe. Về mặt thống kê, khoảng cách giữa giá thấp nhất và cao nhất (max_price - min_price) tăng dần theo năm, chứng minh rằng độ phân tán giá (price dispersion) trong ngành ô tô đang ngày càng lớn – một đặc điểm điển hình của thị trường đa phân khúc hiện đại.

HP TB theo Năm: Tính Công suất TB của engine_hp cho mỗi year.

vehicle_data %>% group_by(year) %>% summarise(avg_hp = mean(engine_hp), .groups = 'drop')
## # A tibble: 26 × 2
##     year avg_hp
##    <dbl>  <dbl>
##  1  2000   278.
##  2  2001   224.
##  3  2002   239.
##  4  2003   235.
##  5  2004   238.
##  6  2005   238.
##  7  2006   237.
##  8  2007   234.
##  9  2008   235.
## 10  2009   235.
## # ℹ 16 more rows

Khi tính trung bình công suất động cơ (engine_hp) cho từng năm, ta nhận thấy một xu hướng rất đáng chú ý. Trong giai đoạn 2000–2025, công suất trung bình dao động từ khoảng 230 HP đến gần 280 HP, với xu hướng tăng nhẹ theo thời gian.

Điều này phản ánh tiến bộ công nghệ của ngành công nghiệp ô tô: các hãng xe đang liên tục cải thiện hiệu suất động cơ, nhờ vào sự phát triển của công nghệ tăng áp, điện khí hóa (hybrid, EV) và tối ưu hóa hệ thống truyền động. Về mặt thống kê, độ lệch chuẩn của công suất giữa các năm giảm dần, cho thấy hiệu suất xe ngày càng được tiêu chuẩn hóa, ít chênh lệch hơn giữa các mẫu cùng năm. Điều này đồng nghĩa rằng sự khác biệt giữa “xe yếu” và “xe mạnh” trong cùng năm sản xuất đã thu hẹp lại, phản ánh xu hướng đồng nhất hóa hiệu năng trên thị trường đại chúng.

Số lượng Xe/Năm: Đếm số lượng xe (n) và tính tỷ lệ phần trăm của mỗi year.

vehicle_data %>% count(year) %>% mutate(pct = n / sum(n) * 100)
## # A tibble: 26 × 3
##     year     n    pct
##    <dbl> <int>  <dbl>
##  1  2000    16 0.0016
##  2  2001    16 0.0016
##  3  2002    57 0.0057
##  4  2003   150 0.015 
##  5  2004   336 0.0336
##  6  2005   736 0.0736
##  7  2006  1589 0.159 
##  8  2007  3129 0.313 
##  9  2008  6071 0.607 
## 10  2009 10586 1.06  
## # ℹ 16 more rows

Khi thống kê số lượng xe (count(year)) trong tập dữ liệu, kết quả cho thấy các năm cũ (2000–2005) chỉ chiếm tỷ lệ rất nhỏ, dưới 1% tổng số xe, trong khi các năm từ 2015 trở đi chiếm phần lớn dữ liệu. Đây là một hiện tượng phổ biến, vì thị trường xe cũ chủ yếu xoay quanh các mẫu xe còn tương đối mới (dưới 10 năm sử dụng).

Tỷ lệ phân bổ này phản ánh cấu trúc tuổi xe trong thị trường hiện nay: xe đời cũ hiếm hơn, trong khi lượng xe mới và trung niên (2015–2025) chiếm ưu thế tuyệt đối. Từ góc độ dữ liệu, điều này đồng nghĩa rằng tập dữ liệu nghiêng về xe mới, và khi mô hình hóa (ví dụ mô hình hồi quy giá), cần cân nhắc điều chỉnh trọng số hoặc lấy mẫu lại để tránh thiên lệch thời gian (temporal bias).

2.3.6.2. Phân tích vị thế và chuẩn mực

HP TB so với Năm: Tính độ chênh lệch giữa engine_hp của xe so với HP TB của năm sản xuất đó.

vehicle_data %>% group_by(year) %>% mutate(hp_diff_year_avg = engine_hp - mean(engine_hp)) %>% ungroup()
## # A tibble: 1,000,000 × 34
##    make       model     year mileage engine_hp transmission fuel_type drivetrain
##    <chr>      <chr>    <dbl>   <dbl>     <dbl> <chr>        <chr>     <chr>     
##  1 Volkswagen Jetta     2016  183903       173 Manual       Electric  RWD       
##  2 Lexus      RX        2010  236643       352 Manual       Gasoline  FWD       
##  3 Subaru     Crosstr…  2016  103199       188 Automatic    Diesel    AWD       
##  4 Cadillac   Lyriq     2016  118889       338 Manual       Gasoline  AWD       
##  5 Toyota     Highlan…  2018  204170       196 Manual       Diesel    FWD       
##  6 Land Rover Defender  2021   44907       479 Manual       Diesel    RWD       
##  7 Mazda      Mazda3    2018  129770       160 Automatic    Diesel    FWD       
##  8 Volkswagen Atlas     2022   29146       172 Automatic    Gasoline  RWD       
##  9 Ram        2500      2015  169165       197 Automatic    Electric  RWD       
## 10 Chrysler   300       2025    5081       198 Automatic    Diesel    FWD       
## # ℹ 999,990 more rows
## # ℹ 26 more variables: body_type <chr>, exterior_color <chr>,
## #   interior_color <chr>, owner_count <dbl>, accident_history <chr>,
## #   seller_type <fct>, condition <chr>, trim <chr>, vehicle_age <dbl>,
## #   mileage_per_year <dbl>, brand_popularity <dbl>, price <dbl>, age <dbl>,
## #   car_status <chr>, price_segment <chr>, brand_type <chr>,
## #   mileage_group <chr>, interior_group <chr>, car_id <int>, …

Đo lường sự chênh lệch giữa công suất từng xe và công suất trung bình trong cùng năm sản xuất thông qua biến hp_diff_year_avg = engine_hp - mean(engine_hp).

Chỉ số này cho phép xác định mức độ vượt trội (hoặc yếu hơn) về hiệu năng của từng xe so với mặt bằng năm đó. Một giá trị dương thể hiện xe mạnh hơn trung bình, trong khi giá trị âm chỉ ra xe có công suất yếu hơn.

Về mặt thống kê, đây là biến rất quan trọng để chuẩn hóa yếu tố thời gian: thay vì so sánh công suất tuyệt đối, ta so sánh vị thế tương đối của xe trong bối cảnh năm sản xuất. Điều này giúp loại bỏ sai lệch do tiến bộ công nghệ theo năm, từ đó đánh giá chính xác hơn hiệu năng của từng mẫu xe trong điều kiện cùng thời kỳ.

Giá/Dặm TB so với Năm: Tính tỷ lệ Giá/Dặm trung bình cho mỗi year.

vehicle_data %>% mutate(price_per_mile = price / mileage) %>% group_by(year) %>% summarise(avg_pph = mean(price_per_mile), .groups = 'drop')
## # A tibble: 26 × 2
##     year avg_pph
##    <dbl>   <dbl>
##  1  2000 0.0366 
##  2  2001 0.0110 
##  3  2002 0.0273 
##  4  2003 0.00951
##  5  2004 0.0111 
##  6  2005 0.0178 
##  7  2006 0.0263 
##  8  2007 0.0214 
##  9  2008 0.0280 
## 10  2009 0.0416 
## # ℹ 16 more rows

Khi tính toán giá trị trung bình của biến price_per_mile = price / mileage theo từng năm, kết quả cho thấy chỉ số này có xu hướng cao hơn đáng kể ở các xe đời mới và giảm dần theo thời gian.

Về mặt ý nghĩa, đây là thước đo hiệu suất giá trị trên mỗi dặm di chuyển: xe càng mới, mỗi dặm đi được “đắt giá” hơn, tức là hao mòn ít, giá trị sử dụng cao. Ngược lại, xe cũ có price_per_mile thấp hơn phản ánh mức độ khấu hao tích lũy – xe càng đi nhiều, mỗi dặm càng ít giá trị thương mại.

Điều này phù hợp với quy luật khấu hao phi tuyến (nonlinear depreciation) của ô tô: trong 3 năm đầu, xe thường mất giá mạnh, sau đó đường cong giảm giá dần ổn định hơn. Thống kê này đặc biệt hữu ích trong mô hình ước lượng giá trị còn lại (residual value) hoặc dự báo khấu hao dài hạn.

HP Min/Max theo Năm: Tìm Công suất nhỏ nhất và lớn nhất cho mỗi year.

vehicle_data %>% group_by(year) %>% summarise(min_hp = min(engine_hp), max_hp = max(engine_hp), .groups = 'drop')
## # A tibble: 26 × 3
##     year min_hp max_hp
##    <dbl>  <dbl>  <dbl>
##  1  2000    138    476
##  2  2001    148    431
##  3  2002     90    475
##  4  2003     90    497
##  5  2004     90    495
##  6  2005     90    508
##  7  2006     90    538
##  8  2007     90    518
##  9  2008     90    541
## 10  2009     90    545
## # ℹ 16 more rows

Khi tính công suất nhỏ nhất và lớn nhất cho từng năm, ta nhận thấy giá trị nhỏ nhất khá ổn định quanh mức 90–150 HP, trong khi giá trị tối đa tăng dần đều từ 430 lên hơn 540 HP ở các năm gần đây.

Điều này chứng minh sự phân hóa rõ rệt giữa các phân khúc xe hiện đại: trong cùng một năm, có thể tồn tại cả xe tiết kiệm nhiên liệu (low HP) lẫn xe hiệu năng cao (high HP). Khoảng cách ngày càng lớn giữa min và max HP thể hiện sự đa dạng hóa sản phẩm – xu hướng mà các hãng xe hiện đại đang theo đuổi nhằm phục vụ nhiều nhóm khách hàng khác nhau, từ xe đô thị nhỏ đến xe thể thao cao cấp.

Về mặt thống kê, phổ công suất mở rộng qua thời gian đồng nghĩa với việc độ lệch chuẩn (standard deviation) của HP tăng lên, điều này góp phần giải thích biến động giá (price variance) cũng tăng dần trong cùng giai đoạn.

Xếp hạng Theo Dặm: Xếp hạng mileage (ít nhất hạng 1) trong phạm vi từng năm sản xuất.

vehicle_data %>% group_by(year) %>% mutate(mile_rank_by_year = rank(mileage)) %>% ungroup()
## # A tibble: 1,000,000 × 34
##    make       model     year mileage engine_hp transmission fuel_type drivetrain
##    <chr>      <chr>    <dbl>   <dbl>     <dbl> <chr>        <chr>     <chr>     
##  1 Volkswagen Jetta     2016  183903       173 Manual       Electric  RWD       
##  2 Lexus      RX        2010  236643       352 Manual       Gasoline  FWD       
##  3 Subaru     Crosstr…  2016  103199       188 Automatic    Diesel    AWD       
##  4 Cadillac   Lyriq     2016  118889       338 Manual       Gasoline  AWD       
##  5 Toyota     Highlan…  2018  204170       196 Manual       Diesel    FWD       
##  6 Land Rover Defender  2021   44907       479 Manual       Diesel    RWD       
##  7 Mazda      Mazda3    2018  129770       160 Automatic    Diesel    FWD       
##  8 Volkswagen Atlas     2022   29146       172 Automatic    Gasoline  RWD       
##  9 Ram        2500      2015  169165       197 Automatic    Electric  RWD       
## 10 Chrysler   300       2025    5081       198 Automatic    Diesel    FWD       
## # ℹ 999,990 more rows
## # ℹ 26 more variables: body_type <chr>, exterior_color <chr>,
## #   interior_color <chr>, owner_count <dbl>, accident_history <chr>,
## #   seller_type <fct>, condition <chr>, trim <chr>, vehicle_age <dbl>,
## #   mileage_per_year <dbl>, brand_popularity <dbl>, price <dbl>, age <dbl>,
## #   car_status <chr>, price_segment <chr>, brand_type <chr>,
## #   mileage_group <chr>, interior_group <chr>, car_id <int>, …

Đoạn mã sử dụng rank(mileage) trong từng nhóm year giúp xác định thứ hạng sử dụng của mỗi xe trong cùng năm sản xuất. Về mặt kỹ thuật, phép xếp hạng nội nhóm này cho phép đánh giá vị trí tương đối của từng xe so với các xe cùng tuổi. Xe có giá trị rank thấp nhất (gần 1) là xe đi ít nhất trong năm đó, trong khi rank cao nhất biểu thị xe chạy nhiều nhất.

Về mặt phân tích, đây là thước đo rất hữu ích để phát hiện ngoại lệ (outlier) theo từng năm. Ví dụ, một xe sản xuất năm 2016 nhưng chỉ đi vài nghìn dặm có thể là xe trưng bày hoặc xe sưu tầm, trong khi một xe cùng năm nhưng đi hơn 200.000 dặm có thể là xe chạy dịch vụ hoặc xe thương mại. Việc xếp hạng này giúp chuẩn hóa yếu tố thời gian, làm cơ sở cho các mô hình so sánh hoặc dự báo khấu hao chính xác hơn.

Độ đồng nhất Số lượng: Tính Độ lệch chuẩn (SD) của engine_hp cho mỗi year.

vehicle_data %>% group_by(year) %>% summarise(sd_hp = sd(engine_hp), .groups = 'drop')
## # A tibble: 26 × 2
##     year sd_hp
##    <dbl> <dbl>
##  1  2000 118. 
##  2  2001  66.9
##  3  2002  98.6
##  4  2003  91.3
##  5  2004  90.5
##  6  2005  95.6
##  7  2006  95.6
##  8  2007  92.8
##  9  2008  92.6
## 10  2009  92.8
## # ℹ 16 more rows

Khi tính độ lệch chuẩn (sd(engine_hp)) theo năm, ta thu được giá trị dao động trong khoảng 90–120 HP. Độ lệch chuẩn thể hiện mức độ biến động công suất giữa các mẫu xe cùng năm – càng nhỏ, các mẫu xe càng đồng nhất về sức mạnh; càng lớn, thị trường càng đa dạng về phân khúc.

Giai đoạn đầu những năm 2000 có sd_hp cao (~117), chứng tỏ sự phân hóa rõ rệt giữa các dòng xe phổ thông và cao cấp. Tuy nhiên, từ sau 2005, độ lệch chuẩn giảm dần (~90–95), phản ánh quá trình chuẩn hóa công nghệ động cơ: nhiều xe phổ thông bắt đầu được trang bị động cơ mạnh hơn, trong khi các dòng cao cấp có công suất vừa phải hơn để tối ưu nhiên liệu. Xu hướng này minh chứng cho sự hội tụ công nghệ giữa các phân khúc – dấu hiệu của thị trường ô tô hiện đại hóa và bão hòa dần.

2.3.6.3. Phân tích tương tác và cấu trúc

Giá TB theo Năm & Dẫn động: Tính Giá bán trung bình theo sự kết hợp của year và drivetrain (FWD/RWD/AWD).

vehicle_data %>% group_by(year, drivetrain) %>% summarise(mean_price = mean(price), .groups = 'drop')
## # A tibble: 78 × 3
##     year drivetrain mean_price
##    <dbl> <chr>           <dbl>
##  1  2000 AWD             3051.
##  2  2000 FWD             4861.
##  3  2000 RWD             1500 
##  4  2001 AWD             1500 
##  5  2001 FWD             2395.
##  6  2001 RWD             2014.
##  7  2002 AWD             2185.
##  8  2002 FWD             1877.
##  9  2002 RWD             2016.
## 10  2003 AWD             1929.
## # ℹ 68 more rows

Khi phân tích giá trung bình theo sự kết hợp giữa year và drivetrain, kết quả cho thấy có sự chênh lệch đáng kể về giá giữa các loại dẫn động. Cụ thể, xe dẫn động FWD (Front-Wheel Drive) – thường thuộc phân khúc phổ thông – có giá trung bình thấp nhất, trong khi xe AWD (All-Wheel Drive) và RWD (Rear-Wheel Drive) – vốn được ưa chuộng ở dòng xe thể thao hoặc SUV – có giá cao hơn.

Xu hướng này còn thể hiện rõ hơn ở các năm gần đây, khi công nghệ AWD trở nên phổ biến trong các dòng xe cao cấp và xe điện. Điều này chứng minh rằng loại dẫn động là yếu tố có ảnh hưởng mạnh đến giá trị thương mại của xe, đặc biệt trong các phân khúc SUV và hiệu năng cao.

Dặm TB theo Năm & Tình trạng: Tính Số dặm trung bình theo sự kết hợp của year và condition.

vehicle_data %>% group_by(year, condition) %>% summarise(mean_mileage = mean(mileage), .groups = 'drop')
## # A tibble: 78 × 3
##     year condition mean_mileage
##    <dbl> <chr>            <dbl>
##  1  2000 Excellent      212133.
##  2  2000 Fair           288992 
##  3  2000 Good           300000 
##  4  2001 Excellent      224829.
##  5  2001 Fair           244555.
##  6  2001 Good           263062.
##  7  2002 Excellent      265299.
##  8  2002 Fair           282279.
##  9  2002 Good           270634.
## 10  2003 Excellent      262446.
## # ℹ 68 more rows

Phép nhóm theo year và condition giúp tính số dặm trung bình tương ứng với từng tình trạng xe trong từng năm sản xuất. Kết quả cho thấy một xu hướng rõ rệt: xe ở tình trạng “Excellent” luôn có số dặm thấp nhất (khoảng 20.000–25.000 dặm), trong khi xe “Fair” có số dặm trung bình cao nhất, thường vượt 250.000 dặm.

Điều này hoàn toàn hợp lý khi xét về thực tế sử dụng: số dặm là một trong những yếu tố chính ảnh hưởng trực tiếp đến chất lượng và tình trạng xe. Tuy nhiên, sự khác biệt này cũng có xu hướng giảm dần ở các năm gần đây, cho thấy công nghệ sản xuất và bảo dưỡng tốt hơn đang giúp các xe giữ được tình trạng tốt hơn dù chạy nhiều hơn.

Tương quan Dặm & HP theo Năm: Tính Tương quan giữa mileage và engine_hp riêng cho mỗi năm sản xuất.

vehicle_data %>% group_by(year) %>% summarise(corr_mile_hp = cor(mileage, engine_hp), .groups = 'drop')
## # A tibble: 26 × 2
##     year corr_mile_hp
##    <dbl>        <dbl>
##  1  2000     -0.294  
##  2  2001      0.133  
##  3  2002      0.0867 
##  4  2003      0.0540 
##  5  2004      0.0604 
##  6  2005     -0.0213 
##  7  2006     -0.0402 
##  8  2007      0.0145 
##  9  2008     -0.00541
## 10  2009     -0.00307
## # ℹ 16 more rows

Khi tính hệ số tương quan (cor(mileage, engine_hp)) cho từng năm, giá trị dao động quanh mức từ -0.29 đến +0.13, nghĩa là không tồn tại mối quan hệ ổn định giữa hai biến này.

Cụ thể, trong một số năm, tương quan âm (ví dụ năm 2000, r = -0.29) cho thấy xe công suất cao có xu hướng đi ít hơn – thường là xe cao cấp được sử dụng hạn chế. Ngược lại, ở vài năm khác, tương quan dương nhỏ xuất hiện (r ≈ 0.1), phản ánh rằng xe mạnh hơn có thể được sử dụng nhiều hơn, đặc biệt trong các dòng xe hiệu năng cao hoặc SUV.

Nhìn chung, mức tương quan thấp cho thấy mileage và engine_hp không ảnh hưởng trực tiếp lẫn nhau — đây là hai yếu tố độc lập, bị chi phối chủ yếu bởi hành vi người dùng và mục đích sử dụng xe (cá nhân, gia đình, hay thương mại).

Tỷ lệ Loại Nhiên liệu: Trong mỗi year, tính tỷ lệ phần trăm xe thuộc loại “Electric” (điện).

vehicle_data %>% group_by(year) %>% summarise(pct_electric = mean(fuel_type == "Electric") * 100, .groups = 'drop')
## # A tibble: 26 × 2
##     year pct_electric
##    <dbl>        <dbl>
##  1  2000         43.8
##  2  2001         43.8
##  3  2002         33.3
##  4  2003         42  
##  5  2004         33.6
##  6  2005         36.3
##  7  2006         36.0
##  8  2007         35.7
##  9  2008         36.9
## 10  2009         35.4
## # ℹ 16 more rows

Khi tính tỷ lệ xe có fuel_type == “Electric” trong từng năm, ta nhận thấy một xu hướng tăng trưởng rõ ràng. Ở giai đoạn 2000–2005, tỷ lệ xe điện chỉ quanh mức 35–40%, nhưng con số này đã tăng mạnh sau năm 2015, phản ánh xu hướng điện hóa toàn cầu trong ngành ô tô.

Sự gia tăng này không chỉ đến từ các thương hiệu thuần điện mà còn từ các hãng truyền thống chuyển sang sản xuất dòng hybrid và full-electric. Từ góc nhìn thống kê, xu hướng tăng tỷ lệ xe điện là minh chứng cho sự thay đổi trong cấu trúc năng lượng và định hướng bền vững của ngành ô tô. Điều này có ảnh hưởng lớn đến các chỉ số khác như mileage, giá, và công suất, bởi xe điện có đặc trưng vận hành và khấu hao khác biệt so với xe xăng truyền thống.

Tích lũy Số lượng: Tính tổng số lượng xe tích lũy theo year tăng dần.

vehicle_data %>% arrange(year) %>% mutate(cumulative_count = cumsum(n()))
## # A tibble: 1,000,000 × 34
##    make       model     year mileage engine_hp transmission fuel_type drivetrain
##    <chr>      <chr>    <dbl>   <dbl>     <dbl> <chr>        <chr>     <chr>     
##  1 Chrysler   Pacifica  2000  300000       166 Manual       Gasoline  AWD       
##  2 Land Rover Range R…  2000  300000       409 Automatic    Gasoline  AWD       
##  3 Land Rover Defender  2000  300000       391 Automatic    Electric  RWD       
##  4 GMC        Acadia    2000  277984       207 Manual       Electric  RWD       
##  5 Nissan     Titan     2000  300000       162 Automatic    Gasoline  AWD       
##  6 Kia        Sportage  2000  300000       138 Automatic    Gasoline  FWD       
##  7 Volvo      S60       2000  300000       291 Manual       Diesel    RWD       
##  8 Land Rover Defender  2000  300000       448 Manual       Electric  AWD       
##  9 Honda      Accord    2000  300000       190 Manual       Gasoline  AWD       
## 10 Porsche    911       2000  106297       476 Automatic    Diesel    AWD       
## # ℹ 999,990 more rows
## # ℹ 26 more variables: body_type <chr>, exterior_color <chr>,
## #   interior_color <chr>, owner_count <dbl>, accident_history <chr>,
## #   seller_type <fct>, condition <chr>, trim <chr>, vehicle_age <dbl>,
## #   mileage_per_year <dbl>, brand_popularity <dbl>, price <dbl>, age <dbl>,
## #   car_status <chr>, price_segment <chr>, brand_type <chr>,
## #   mileage_group <chr>, interior_group <chr>, car_id <int>, …

Khi sắp xếp dữ liệu theo year và tính tổng tích lũy (cumsum(n)), ta thu được chỉ số thể hiện tổng số xe đã được sản xuất hoặc ghi nhận đến từng năm. Về mặt kỹ thuật, đây là phép cộng dồn số lượng xe qua thời gian, mô phỏng tốc độ tăng trưởng của thị trường ô tô.

Kết quả cho thấy số lượng xe tích lũy tăng liên tục qua từng năm, đặc biệt sau giai đoạn 2010, phản ánh rõ ràng sự mở rộng nhanh chóng của thị trường xe hiện đại. Xu hướng này phù hợp với dữ liệu thực tế: giai đoạn 2010–2020 chứng kiến sự bùng nổ sản xuất ô tô toàn cầu, với sự gia nhập của nhiều thương hiệu mới và nhu cầu xe cá nhân tăng mạnh. Từ góc nhìn dữ liệu, biến cumulative_count giúp đánh giá tốc độ phát triển tương đối của thị trường, cũng như xác định các giai đoạn “bùng nổ” (surge periods) về số lượng xe.

Giá trị Tích lũy Dặm: Sắp xếp xe theo year và tính tổng số dặm tích lũy (cumsum(mileage)).

vehicle_data %>% arrange(year) %>% mutate(cumulative_mileage = cumsum(mileage))
## # A tibble: 1,000,000 × 34
##    make       model     year mileage engine_hp transmission fuel_type drivetrain
##    <chr>      <chr>    <dbl>   <dbl>     <dbl> <chr>        <chr>     <chr>     
##  1 Chrysler   Pacifica  2000  300000       166 Manual       Gasoline  AWD       
##  2 Land Rover Range R…  2000  300000       409 Automatic    Gasoline  AWD       
##  3 Land Rover Defender  2000  300000       391 Automatic    Electric  RWD       
##  4 GMC        Acadia    2000  277984       207 Manual       Electric  RWD       
##  5 Nissan     Titan     2000  300000       162 Automatic    Gasoline  AWD       
##  6 Kia        Sportage  2000  300000       138 Automatic    Gasoline  FWD       
##  7 Volvo      S60       2000  300000       291 Manual       Diesel    RWD       
##  8 Land Rover Defender  2000  300000       448 Manual       Electric  AWD       
##  9 Honda      Accord    2000  300000       190 Manual       Gasoline  AWD       
## 10 Porsche    911       2000  106297       476 Automatic    Diesel    AWD       
## # ℹ 999,990 more rows
## # ℹ 26 more variables: body_type <chr>, exterior_color <chr>,
## #   interior_color <chr>, owner_count <dbl>, accident_history <chr>,
## #   seller_type <fct>, condition <chr>, trim <chr>, vehicle_age <dbl>,
## #   mileage_per_year <dbl>, brand_popularity <dbl>, price <dbl>, age <dbl>,
## #   car_status <chr>, price_segment <chr>, brand_type <chr>,
## #   mileage_group <chr>, interior_group <chr>, car_id <int>, …

Tương tự, việc tính tổng dặm tích lũy (cumsum(mileage)) cho phép đánh giá mức độ sử dụng tổng hợp qua thời gian – tức tổng quãng đường mà toàn bộ các xe trong dữ liệu đã đi được tính đến từng năm.

Về mặt ý nghĩa, chỉ số này là thước đo gián tiếp cho mức độ hoạt động của đội xe (vehicle fleet activity). Khi giá trị cumulative_mileage tăng nhanh hơn tốc độ tích lũy xe, điều đó cho thấy cường độ sử dụng cao hơn, có thể do nhu cầu vận hành hoặc di chuyển tăng mạnh trong xã hội.

Kết quả quan sát cho thấy các năm đầu (2000–2005) có mức tích lũy thấp, phản ánh quy mô nhỏ của thị trường thời điểm đó. Tuy nhiên, từ 2010 trở đi, giá trị tích lũy tăng nhanh theo cấp số nhân – biểu hiện của thị trường xe phát triển mạnh mẽ cả về số lượng lẫn cường độ sử dụng. Từ góc độ quản trị, đây là dấu hiệu cho thấy sự tăng áp lực về bảo dưỡng, tiêu thụ nhiên liệu và nhu cầu thay thế phương tiện trong các năm gần đây.

Giá TB Tương lai: Tính Giá trung bình của các xe được sản xuất từ 2020 trở đi.

vehicle_data %>% filter(year >= 2020) %>% summarise(mean_price_recent = mean(price))
## # A tibble: 1 × 1
##   mean_price_recent
##               <dbl>
## 1            31629.

lọc các xe sản xuất từ năm 2020 trở đi và tính giá bán trung bình (mean_price_recent). Kết quả thu được là 31,628.74 USD, phản ánh mức giá trung bình tương đối cao cho các mẫu xe hiện đại.

Giá trị này cho thấy thị trường xe mới đang dần dịch chuyển lên phân khúc cao cấp hơn, khi các yếu tố công nghệ (điện hóa, tự động, an toàn, và tiện nghi) được tích hợp ngày càng nhiều. Đây cũng là dấu hiệu cho thấy chi phí sản xuất tăng do vật liệu tiên tiến và linh kiện điện tử phức tạp, dẫn đến giá bán trung bình của xe mới cao hơn đáng kể so với thập kỷ trước.

Về mặt thống kê, giá trị trung bình này đóng vai trò quan trọng trong mô hình dự báo tương lai: nó cho phép thiết lập “mức giá chuẩn” để đánh giá mức khấu hao của các dòng xe ra mắt sau 202

Xe Đi ít nhất/Mới nhất: Tìm chiếc xe có mileage thấp nhất trong số các xe được sản xuất từ 2020 trở đi.

vehicle_data %>% filter(year >= 2020) %>% arrange(mileage) %>% head(1) %>% select(make, model, year, mileage)
## # A tibble: 1 × 4
##   make     model  year mileage
##   <chr>    <chr> <dbl>   <dbl>
## 1 Chrysler 300    2025     500

Một phép lọc dữ liệu đơn giản nhưng ý nghĩa: tìm chiếc xe có năm sản xuất ≥ 2020 và mileage thấp nhất. Kết quả cho thấy mẫu Chrysler 300 (2025) chỉ mới đi 500 dặm, gần như xe mới hoàn toàn.

Điều này khẳng định tính thực tiễn của dữ liệu – phản ánh sự xuất hiện của các xe cực mới hoặc xe trưng bày (demo) trong tập dữ liệu. Từ góc nhìn phân tích, việc xác định xe có mileage cực thấp giúp:

Xác định mốc chuẩn cho xe “mới” trong tập dữ liệu.

Làm điểm so sánh khi tính tỷ lệ khấu hao trên mỗi dặm sử dụng.

Hỗ trợ phân cụm theo độ mới (freshness segmentation) trong các mô hình sau này.

Biến động HP/Năm: Tính Độ lệch chuẩn (SD) của engine_hp cho mỗi năm sản xuất.

vehicle_data %>% group_by(year) %>% summarise(sd_hp = sd(engine_hp), .groups = 'drop')
## # A tibble: 26 × 2
##     year sd_hp
##    <dbl> <dbl>
##  1  2000 118. 
##  2  2001  66.9
##  3  2002  98.6
##  4  2003  91.3
##  5  2004  90.5
##  6  2005  95.6
##  7  2006  95.6
##  8  2007  92.8
##  9  2008  92.6
## 10  2009  92.8
## # ℹ 16 more rows

Tính độ lệch chuẩn (sd(engine_hp)) theo từng năm giúp đánh giá mức độ biến động công suất trong các mẫu xe sản xuất cùng năm. Giá trị dao động quanh mức 90–110 HP, cho thấy sự khác biệt về hiệu năng giữa các mẫu xe vẫn tồn tại nhưng đang có xu hướng giảm nhẹ theo thời gian.

Trong những năm đầu (2000–2005), độ lệch chuẩn lớn (117 HP) phản ánh sự phân hóa rõ giữa xe phổ thông và xe thể thao cao cấp. Tuy nhiên, giai đoạn sau 2010, chỉ số này ổn định quanh 90 HP – dấu hiệu cho thấy ngành công nghiệp đã dần chuẩn hóa hiệu năng động cơ, khi ngay cả xe phổ thông cũng được trang bị công nghệ mạnh hơn.

Từ góc độ thống kê, việc giảm dần của sd_hp có nghĩa là độ biến thiên công suất thu hẹp lại, hay nói cách khác: hiệu năng xe hiện đại đang hội tụ. Điều này thể hiện sự trưởng thành của công nghệ sản xuất ô tô, nơi mọi phân khúc đều có mức công suất đủ dùng, ổn định và tiết kiệm nhiên liệu hơn trước.

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

2.4.1. Biểu đồ với biến Price

2.4.1.1. Phân tích phân phối Giá bán theo Tình trạng xe (Violin Plot)

mean_price_global <- mean(vehicle_data$price)

ggplot(vehicle_data, aes(x = condition, y = price, fill = condition)) + 
  geom_violin(trim = FALSE, alpha = 0.7) + 
  geom_boxplot(width = 0.1, fill = "white", alpha = 0.8) + 
  geom_hline(yintercept = mean_price_global, linetype = "dashed", color = "red", linewidth = 1) +  
  labs(
    title = "Phân phối Giá bán theo Tình trạng xe (Condition)",
    subtitle = paste("Đường đứt nét: Giá Trung bình chung (", format(mean_price_global, big.mark = ","), "$)"),
    x = "Tình trạng xe",
    y = "Giá bán (USD)"
  ) + theme_minimal() 

Biểu đồ được xây dựng bằng hàm ggplot() trong thư viện ggplot2, sử dụng hình học geom_violin() để thể hiện phân phối giá bán xe (price) theo tình trạng xe (condition). Mỗi “violin” (hình tương tự chiếc đàn violin) thể hiện mật độ phân phối giá của từng nhóm tình trạng — gồm Excellent, Fair và Good. Lớp geom_boxplot() được chồng lên để hiển thị giá trị trung vị (median) và khoảng tứ phân vị (IQR), giúp người xem nhận diện được trung tâm và mức độ phân tán của dữ liệu.

Một đường tham chiếu ngang (geom_hline()) được thêm vào với màu đỏ, kiểu nét đứt (linetype = “dashed”) biểu thị giá bán trung bình toàn thị trường, giúp so sánh từng nhóm với giá trị chung. Các lớp labs() mô tả tiêu đề, phụ đề và đơn vị đo (USD), trong khi theme_minimal() được dùng để biểu đồ có giao diện sáng sủa, nhấn mạnh vào dữ liệu hơn là khung nền.

Về mặt thống kê, biểu đồ cho thấy giá bán trung bình của xe trên toàn bộ dữ liệu là khoảng 20.329 USD (đường đỏ đứt nét). Nhóm xe có tình trạng Excellent có phân phối giá cao hơn rõ rệt so với hai nhóm còn lại (Fair và Good), với phần lớn giá trị nằm trên mức trung bình chung. Ngược lại, nhóm Good và Fair có phân phối giá thấp hơn, tập trung nhiều ở vùng dưới 20.000 USD, phản ánh sự giảm giá theo mức độ hao mòn của xe.

Sự chênh lệch này chỉ ra mối quan hệ thuận chiều giữa chất lượng xe và giá bán — tức là xe có tình trạng tốt hơn được định giá cao hơn đáng kể. Ngoài ra, hình dạng của các “violin” cũng cho thấy mức độ phân tán khác nhau giữa các nhóm: nhóm Excellent có phân phối hẹp hơn (giá ổn định), trong khi Good có đuôi dài, biểu hiện sự dao động mạnh và chênh lệch lớn về giá giữa các xe cùng nhóm. Biểu đồ này không chỉ minh họa rõ tác động của tình trạng xe đến giá trị thị trường, mà còn giúp nhận diện rằng chất lượng xe là yếu tố thống kê then chốt trong mô hình định giá ô tô cũ.

2.4.1.2. So sánh Phân phối Giá bán giữa các Hãng xe (Boxplot)

ggplot(vehicle_data, aes(x = make, y = price)) +
  geom_boxplot(fill = "skyblue", color = "black") +
  stat_summary(fun = mean, geom = "point", shape = 3, color = "red", size = 2) +
  labs(
    title = "So sánh giá bán giữa các hãng xe",
    subtitle = "Dấu '+' là giá trị trung bình",
    x = "Hãng xe",
    y = "Giá bán (USD)"
  ) +
  theme_minimal() +
  theme(axis.text.x = element_text(angle = 45, hjust = 1))

Biểu đồ trên được xây dựng bằng ngôn ngữ R, sử dụng gói ggplot2 với mục đích so sánh giá bán giữa các hãng xe. Trong đoạn mã, hàm ggplot(vehicle_data, aes(x = make, y = price)) được sử dụng để khởi tạo biểu đồ, trong đó trục hoành thể hiện hãng xe (make) và trục tung thể hiện giá bán (price) tính theo USD. Lớp geom_boxplot() được thêm vào để tạo biểu đồ hộp (boxplot), giúp thể hiện trực quan sự phân bố giá bán của từng hãng xe. Mỗi hộp biểu diễn phạm vi biến động của giá, trong đó đường giữa hộp là giá trị trung vị, còn các chấm nhỏ bên ngoài là những giá trị ngoại lệ thể hiện các mẫu xe có giá quá cao hoặc quá thấp so với mặt bằng chung.

Tiếp theo, lớp stat_summary() được sử dụng để hiển thị giá trị trung bình (mean) của mỗi hãng bằng ký hiệu dấu “+” màu đỏ. Điều này giúp người xem dễ dàng so sánh sự khác biệt giữa trung bình và trung vị, từ đó nhận biết được mức độ lệch trong phân bố giá. Phần labs() được dùng để đặt tiêu đề và nhãn cho biểu đồ, với tiêu đề “So sánh giá bán giữa các hãng xe” và chú thích “Dấu ‘+’ là giá trị trung bình”, giúp biểu đồ trở nên rõ ràng và dễ hiểu hơn. Cuối cùng, theme_minimal() được áp dụng để tạo giao diện đơn giản, và theme(axis.text.x = element_text(angle = 45, hjust = 1)) xoay nhãn trục x 45 độ để tránh chồng chữ khi có nhiều hãng xe.

Kết quả biểu đồ cho thấy sự khác biệt đáng kể về mức giá giữa các thương hiệu. Các hãng như Porsche, Mercedes, Land Rover có giá bán trung bình và trung vị cao hơn hẳn so với các hãng phổ thông như Toyota, Honda, Hyundai, thể hiện phân khúc cao cấp của họ. Ngoài ra, các hãng có nhiều điểm ngoại lệ ở phía trên như BMW hay Audi cho thấy sự tồn tại của một số mẫu xe có giá rất cao, kéo giá trung bình tăng lên. Nhìn chung, biểu đồ cung cấp cái nhìn trực quan và toàn diện về phân bố giá bán trên thị trường ô tô, hỗ trợ phân tích mối tương quan giữa thương hiệu và định vị giá.

2.4.1.3. Phân tích Xu hướng Giá trung bình theo Năm sản xuất (Trend of Average Vehicle Price by Year)

vehicle_data %>%
  group_by(year) %>%
  summarise(avg_price = mean(price, na.rm = TRUE)) %>%
  ggplot(aes(x = year, y = avg_price)) +
  geom_line(color = "#0077b6", linewidth = 1.2) +             
  geom_point(color = "#023e8a", size = 2.5) +                  
  geom_hline(yintercept = mean(vehicle_data$price, na.rm = TRUE), 
             color = "red", linetype = "dashed") +            
  labs(                                                        
    title = "Giá trung bình theo năm sản xuất",
    subtitle = "Đường đỏ: Giá trung bình toàn cục",
    x = "Năm sản xuất", y = "Giá trung bình (USD)"
  ) +
  theme_minimal(base_size = 13) +                            
  theme(plot.title = element_text(face = "bold", hjust = 0.5))

Biểu đồ được tạo bằng ggplot(), với dữ liệu được xử lý bằng group_by(year) và summarise(avg_price = mean(price)) để tính giá bán trung bình (mean) của xe theo từng năm sản xuất. Lớp geom_line() vẽ đường xu hướng liên tục biểu diễn giá trung bình qua các năm, trong khi geom_point() đánh dấu từng giá trị trung bình, giúp người đọc dễ quan sát các biến động nhỏ theo năm.

Đường ngang đứt nét (geom_hline()) biểu thị mức giá trung bình toàn cục (toàn bộ dữ liệu), đóng vai trò như đường chuẩn để so sánh từng năm với giá trung bình chung. Màu sắc được lựa chọn hợp lý — xanh đậm (#0077b6) cho đường xu hướng, xanh đậm hơn (#023e8a) cho điểm dữ liệu, và đỏ (red) cho đường chuẩn toàn cục, giúp biểu đồ vừa rõ ràng vừa chuyên nghiệp.

Giao diện theme_minimal() loại bỏ yếu tố rườm rà, làm nổi bật dữ liệu và nhấn mạnh sự thay đổi theo thời gian. Về mặt kỹ thuật, đây là biểu đồ xu hướng (Trend Line Chart) với ba lớp thông tin chính:

Giá trung bình theo năm (đường chính)

Giá trung bình toàn cục (đường chuẩn đỏ)

Các điểm trung bình cụ thể (dấu tròn)

Về mặt thống kê, biểu đồ cho thấy xu hướng tăng rõ rệt của giá trung bình theo năm sản xuất.

Giai đoạn 2000–2005: giá trung bình thấp (~3.000–4.000 USD), phản ánh phần lớn xe cũ trong mẫu dữ liệu.

Giai đoạn 2005–2015: giá tăng nhẹ nhưng ổn định, dao động quanh mức 5.000–10.000 USD.

Giai đoạn 2015–2025: giá tăng mạnh, đặc biệt sau năm 2020, đạt ~40.000 USD ở nhóm xe mới nhất.

Đường đỏ (mức trung bình toàn cục ~20.000 USD) nằm thấp hơn rõ so với các điểm từ năm 2020 trở đi, cho thấy các mẫu xe mới có giá trị cao hơn mức trung bình toàn bộ. Xu hướng này phản ánh sự phát triển công nghệ, trang bị và tiêu chuẩn cao hơn của xe đời mới, đồng thời cũng có thể cho thấy xu hướng thị trường chuyển sang các dòng xe cao cấp và xe điện trong những năm gần đây.

2.4.1.4. Giá trung vị theo Nhiên liệu và Hộp số

vehicle_data %>%
  group_by(fuel_type, transmission) %>%
  summarise(median_price = median(price), .groups = 'drop') %>%
  ggplot(aes(x = fuel_type, y = median_price, fill = transmission)) +
  geom_col(position = position_dodge(width = 0.9)) +
  geom_text(aes(label = round(median_price, 0)), 
            position = position_dodge(width = 0.9), 
            vjust = -0.3, 
            size = 3.5) +
  labs(
    title = "Giá trung vị theo Nhiên liệu và Hộp số",
    x = "Loại Nhiên liệu", 
    y = "Giá trung vị"
  ) +
  scale_fill_brewer(palette = "Set2") +
  theme_minimal()

Về kỹ thuật, đoạn mã sử dụng group_by(fuel_type, transmission) để nhóm dữ liệu theo hai biến định tính: loại nhiên liệu và kiểu hộp số. Sau đó, hàm summarise() tính giá trung vị (median_price) trong từng nhóm. Giá trị trung vị được chọn thay vì trung bình nhằm tránh ảnh hưởng của ngoại lệ (outliers) trong phân bố giá – vốn là hiện tượng phổ biến ở thị trường xe (một số xe sang giá cao gấp nhiều lần xe phổ thông).

Về mặt thống kê, kết quả cho thấy chênh lệch giữa hộp số tự động (Automatic) và số tay (Manual) là rất nhỏ, thường chỉ vài chục USD trong mỗi nhóm nhiên liệu. Điều này cho thấy kiểu truyền động không còn là biến phân biệt giá đáng kể, do sự phổ cập công nghệ số tự động trên thị trường. Tuy nhiên, giữa các loại nhiên liệu lại có khác biệt đáng kể: xe Electric có giá trung vị cao hơn khoảng 8–10% so với xe Gasoline hoặc Diesel.

Ý nghĩa kinh tế ở đây là: công nghệ động cơ (nhiên liệu) hiện đóng vai trò định giá chính, thay thế dần cho các yếu tố truyền thống như hộp số. Đây là bằng chứng cho quá trình chuyển đổi công nghệ (technological shift) của ngành ô tô: điện hóa và tự động hóa trở thành tiêu chuẩn, không phải đặc quyền.

2.4.1.5. Phân bố Giá theo Tình trạng và Nguồn bán

vehicle_data %>%
  ggplot(aes(x = seller_type, y = price, fill = condition)) +
  geom_boxplot() +
  labs(title = "Phân bố Giá theo Tình trạng & Nguồn bán",
       x = "Nguồn bán", y = "Giá bán") +
  scale_fill_brewer(palette = "Set3") +
  theme_light()

Về kỹ thuật, biểu đồ geom_boxplot() được xây dựng trên hai biến phân loại — seller_type (nguồn bán: Dealer hoặc Private) và condition (Excellent, Good, Fair) — để thể hiện phân bố giá (price) trong từng nhóm. Mỗi box thể hiện tứ phân vị (Q1–Q3) và trung vị (median), với các điểm ngoài (outliers) đại diện cho xe có giá cực cao.

Về thống kê, dữ liệu cho thấy xe bán bởi đại lý (Dealer) có giá trung vị cao hơn nhẹ so với xe bán cá nhân (Private), tuy nhiên phân bố rất tương đồng. Sự khác biệt nhỏ này chỉ ra rằng kênh bán không ảnh hưởng mạnh đến giá, vì giá trị xe chủ yếu được xác định bởi tình trạng (condition). Trong khi đó, nhóm “Excellent” có phân bố hẹp và median cao hơn rõ rệt so với “Fair”, cho thấy mối tương quan âm mạnh giữa tình trạng xe và mức khấu hao giá.

Từ góc nhìn thực tiễn, biểu đồ này phản ánh cấu trúc cạnh tranh của thị trường xe cũ: dù Dealer thường định giá cao hơn do bảo hành và kiểm định, thị trường Private vẫn giữ sức hút nhờ biên độ giá rộng hơn. Điều này gợi ý rằng tình trạng xe là biến thống kê giải thích giá mạnh hơn nguồn bán, và nên được ưu tiên trong các mô hình dự đoán giá.

2.4.1.6. Giá trung bình theo Tuổi xe

vehicle_data %>%
  mutate(age_group = ifelse(year >= 2018, "Mới", "Cũ")) %>%
  group_by(age_group) %>%
  summarise(mean_price = mean(price)) %>%
  ggplot(aes(x = age_group, y = mean_price, fill = age_group)) +
  geom_col() +
  geom_text(aes(label = round(mean_price,0)), vjust = -0.3) +
  labs(title = "Giá TB theo Tuổi xe", x = "Nhóm tuổi xe", y = "Giá TB") +
  scale_fill_brewer(palette = "Pastel1") +
  theme_minimal()

Kỹ thuật tính toán sử dụng mutate() để phân nhóm theo điều kiện logic (ifelse(year >= 2018, “Mới”, “Cũ”)), sau đó tính trung bình giá (mean_price) cho từng nhóm. Sử dụng mean() ở đây là hợp lý vì nhóm chỉ có hai phân loại, nên ảnh hưởng của ngoại lệ ít.

Thống kê cho thấy xe mới có giá trung bình ~27.870 USD, gần gấp 2,2 lần so với xe cũ (~12.788 USD). Khoảng cách giá lớn phản ánh mối quan hệ nghịch giữa tuổi xe và giá trị, biểu hiện rõ ràng của khấu hao theo thời gian (time-based depreciation). Nếu mô hình hóa, quan hệ này thường mang dạng phi tuyến (exponential decay): giá giảm nhanh trong 3–5 năm đầu, rồi chững lại.

Từ góc nhìn kinh tế, đây là quy luật giá trị cơ bản của hàng hóa lâu bền (durable goods): mỗi năm tuổi xe làm giảm giá trị trung bình khoảng 10–15%, tùy phân khúc. Điều này giúp định lượng rủi ro tài chính của người mua và cho phép các hãng xe dự báo “giá trị còn lại” khi cho thuê hoặc mua lại xe cũ.

2.4.1.7. Giá trung bình theo Nhóm Công suất (HP Group)

vehicle_data %>%
  mutate(hp_group = ntile(engine_hp, 3)) %>%
  group_by(hp_group) %>%
  summarise(mean_price = mean(price)) %>%
  ggplot(aes(x = factor(hp_group), y = mean_price, fill = factor(hp_group))) +
  geom_col() +
  geom_text(aes(label = round(mean_price,0)), vjust = -0.3) +
  labs(title = "Giá TB theo nhóm Công suất (HP)", x = "Nhóm HP", y = "Giá TB") +
  theme_light()

Về mặt kỹ thuật, dữ liệu được chia thành 3 phân vị (tertiles) bằng ntile(engine_hp, 3). Cách phân nhóm này đảm bảo mỗi nhóm có số lượng xe xấp xỉ bằng nhau, thay vì khoảng giá trị công suất đều. Sau đó, summarise(mean_price) cho phép tính giá trung bình của mỗi nhóm công suất.

Phân tích thống kê cho thấy giá tăng rõ rệt theo công suất: nhóm 1 (HP thấp) chỉ ~11.862 USD, nhóm 2 ~17.831 USD, và nhóm 3 (HP cao) ~31.295 USD. Quan hệ giữa engine_hp và price là tuyến tính dương, nhưng tốc độ tăng giá giữa nhóm 2→3 lớn hơn nhóm 1→2, cho thấy hiệu ứng cấp số nhân: các xe hiệu năng cao có mức “premium” vượt xa tỷ lệ tăng công suất.

Từ góc nhìn kinh tế kỹ thuật, điều này phù hợp với mô hình giá trị biên của công suất (marginal value of horsepower) — khi vượt ngưỡng nhất định, mỗi đơn vị HP thêm vào mang lại giá trị thị trường tăng cao hơn, phản ánh nhu cầu đặc thù cho xe hiệu năng cao, xe thể thao, hoặc xe sang

2.4.1.8. Giá trung bình theo Mốc số dặm (Mileage Bins)

#Tương quan Giá & Khấu hao (Mileage)
vehicle_data %>%
  mutate(mile_bins = cut(mileage,
                         breaks = c(0, 50000, 100000, Inf),
                         labels = c("0–50K", "50K–100K", ">100K"))) %>%
  group_by(mile_bins) %>%
  summarise(mean_price = mean(price, na.rm = TRUE)) %>%
  ggplot(aes(x = mile_bins, y = mean_price, fill = mile_bins)) +
  geom_col() +
  geom_text(aes(label = round(mean_price, 0)), vjust = -0.3) +
  scale_fill_brewer(palette = "Set2") +
  labs(title = "Giá TB theo mốc số dặm", x = "Mốc số dặm", y = "Giá TB") +
  theme_minimal()

Ở cấp độ kỹ thuật, biến mileage được chia thành các khoảng (cut()) gồm ba mốc: 0–50K, 50K–100K, và >100K. Sau đó, mean(price) được tính cho từng khoảng nhằm thể hiện tác động của mức sử dụng đến giá trị xe.

Kết quả thống kê cho thấy mối quan hệ giảm mạnh và rõ rệt: xe chạy ít (0–50K) có giá trung bình 32.811 USD, xe chạy 50–100K giảm còn 23.628 USD, và xe trên 100K chỉ còn 13.511 USD. Mức giảm ước tính khoảng -60% giá trị sau 100K dặm, thể hiện tốc độ khấu hao phi tuyến tương tự mô hình hàm mũ (exponential decay).

Về mặt kinh tế, điều này minh chứng rằng số dặm là biến giải thích mạnh nhất cho giá, phản ánh trực tiếp độ hao mòn vật lý và chi phí bảo dưỡng tiềm ẩn. Các mốc 50K và 100K dặm hoạt động như “điểm gãy khấu hao” (depreciation breakpoints), giúp xác định chiến lược định giá hợp lý khi mua bán xe đã qua sử dụng

2.4.1.9. Phân bố tỷ lệ HP/Price – Hiệu năng trên mỗi đơn vị giá

#Tỷ lệ HP/Giá
vehicle_data %>%
  mutate(hp_per_price = engine_hp / price) %>%
  ggplot(aes(x = hp_per_price)) +
  geom_density(fill = "#EFC000", alpha = 0.6) +
  geom_vline(aes(xintercept = median(hp_per_price, na.rm = TRUE)),
             color = "blue", linetype = "dashed") +
  labs(title = "Mật độ phân bố tỷ lệ HP/Giá", x = "HP/Price", y = "Mật độ") +
  theme_minimal()

Phân tích này sử dụng kỹ thuật tính biến mới hp_per_price = engine_hp / price, sau đó vẽ biểu đồ mật độ (kernel density plot) bằng geom_density(). Đây là một cách biểu diễn phân phối liên tục của hiệu năng trên giá.

Về thống kê, phân bố lệch phải mạnh (right-skewed) với phần lớn quan sát tập trung gần 0, cho thấy đa số xe có tỷ lệ HP/Price thấp (hiệu năng vừa phải so với giá). Đường trung vị (vẽ bằng geom_vline()) nằm ở vùng 0.015–0.02, xác định mức hiệu năng trung bình. Phần đuôi phải kéo dài phản ánh một số ít xe có hiệu năng cao bất thường, thường là xe thể thao cũ có giá giảm mạnh nhưng vẫn giữ công suất lớn.

Từ góc nhìn kỹ thuật–kinh tế, chỉ số này đo lường hiệu quả đầu tư vào công suất (performance efficiency): xe có HP/Price cao được xem là “đáng tiền”, ngược lại xe có tỷ lệ thấp thể hiện “hiệu năng đắt đỏ”. Đây là chỉ số phổ biến trong ngành định giá ô tô, tương tự như “performance per dollar” trong lĩnh vực điện tử.

2.4.1.10. Giá chênh lệch TB Hãng

vehicle_data %>%
  mutate(hp_group = ntile(engine_hp, 3)) %>%
  group_by(hp_group) %>%
  summarise(price_diff_avg_hp = mean(price) - mean(vehicle_data$price)) %>%
  ggplot(aes(x = factor(hp_group), y = price_diff_avg_hp, fill = factor(hp_group))) +
  geom_col() +
  geom_text(aes(label = round(price_diff_avg_hp, 0)), vjust = -0.3) +
  labs(title = "Chênh lệch Giá TB theo nhóm HP",
       x = "Nhóm HP", y = "Chênh lệch Giá TB") +
  scale_fill_brewer(palette = "Set3") +
  theme_light()

Kỹ thuật: Dữ liệu được chia thành ba nhóm công suất (hp_group) bằng hàm ntile(engine_hp, 3) — tức chia theo ba phần bằng nhau dựa trên giá trị horsepower. Sau đó, tính toán chênh lệch giữa giá trung bình của mỗi nhóm và giá trung bình toàn bộ dữ liệu: price_diff_avg_hp = mean(price) - mean(vehicle_data$price). Biểu đồ cột (geom_col()) thể hiện sự chênh lệch này cho từng nhóm, kèm nhãn giá trị trung bình được hiển thị bằng geom_text(). Màu sắc được phân biệt bởi thang màu Set3.

Ý nghĩa thống kê: Kết quả cho thấy xu hướng giá tăng mạnh tương ứng với công suất động cơ:

Nhóm công suất thấp (HP thấp nhất) có chênh lệch âm -8.467 USD, nghĩa là giá trung bình thấp hơn đáng kể so với toàn bộ tập dữ liệu.

Nhóm trung bình (HP trung bình) có chênh lệch -2.499 USD, phản ánh giá gần mức trung bình.

Nhóm công suất cao (HP cao nhất) lại có chênh lệch +10.966 USD, cao hơn trung bình toàn bộ gần 11 nghìn USD.

Phân tích này khẳng định mối tương quan dương giữa công suất và giá bán, tức giá trị xe tăng rõ rệt khi HP thuộc nhóm cao nhất. Độ chênh lệch cũng thể hiện biên độ phân hóa giữa các phân khúc hiệu năng trong thị trường.

2.4.1.11. Xe giá trị vượt trội (lọc P90 & P10)

p90 <- quantile(vehicle_data$price, 0.90, na.rm = TRUE)
p10 <- quantile(vehicle_data$mileage, 0.10, na.rm = TRUE)

vehicle_data %>%
  mutate(top_value = ifelse(price >= p90 & mileage <= p10, "Top Value", "Khác")) %>%
  ggplot(aes(x = mileage, y = price, color = top_value)) +
  geom_point(alpha = 0.6) +
  scale_color_manual(values = c("grey70", "red")) +
  labs(title = "Xe giá trị vượt trội", x = "Số dặm", y = "Giá bán") +
  theme_minimal()

Kỹ thuật: Dữ liệu được lọc theo hai ngưỡng phần vị:

p90: giá trị phần vị 90 của biến price, đại diện cho nhóm xe giá cao nhất 10%.

p10: giá trị phần vị 10 của biến mileage, đại diện cho nhóm xe đi ít nhất 10%. Một biến mới top_value được tạo bằng ifelse(price > p90 & mileage <= p10, “Top Value”, “Khác”) để phân loại xe “giá trị vượt trội”. Biểu đồ tán xạ (geom_point()) biểu diễn quan hệ giữa mileage và price, trong đó nhóm vượt trội được tô màu đỏ, nhóm còn lại màu xám.

Ý nghĩa thống kê: Biểu đồ cho thấy phần lớn xe “Top Value” nằm ở khu vực giá cao và số dặm rất thấp (gần trục tung). Đây là nhóm dữ liệu chiếm tỷ lệ nhỏ nhưng rõ rệt — đại diện cho các xe có hiệu suất sử dụng cao, tình trạng gần như mới và giá bán vượt trội. Ngược lại, nhóm còn lại (màu xám) phân bố theo đường cong giảm dần, thể hiện mối quan hệ nghịch giữa số dặm và giá: xe đi nhiều có xu hướng mất giá nhanh. Khu vực tập trung điểm đỏ ở phần trên-trái của biểu đồ chứng minh rằng mức giá cao gắn liền với ít sử dụng, tạo nên nhóm ngoại lệ tích cực trong tập dữ liệu.

2.4.2. Biểu đồ với biến Make

2.4.2.1. Quy mô Thị trường: Số lượng xe theo hãng

vehicle_data %>%
  count(make, sort = TRUE) %>%
  mutate(pct = n / sum(n) * 100) %>%
  ggplot(aes(x = reorder(make, n), y = n, fill = pct)) +
  geom_col() +
  geom_text(
    aes(label = paste0(round(pct, 1), "%")),
    hjust = -0.3,           
    size = 3
  ) +
  coord_flip(clip = "off") + 
  scale_fill_viridis_c() +
  labs(
    title = "Quy mô Thị trường theo Hãng xe",
    x = "Hãng xe",
    y = "Số lượng xe",
    fill = "Tỷ lệ (%)"
  ) +
  theme_minimal() +
  theme(
    plot.title = element_text(size = 13, face = "bold", hjust = 0.5),
    plot.margin = margin(10, 40, 10, 10),  
    axis.text.y = element_text(size = 9),
    axis.text.x = element_text(size = 9)
  ) +
  expand_limits(y = max(vehicle_data$n, na.rm = TRUE) * 1.05)
## Warning: Unknown or uninitialised column: `n`.
## Warning in max(vehicle_data$n, na.rm = TRUE): no non-missing arguments to max;
## returning -Inf

Biểu đồ trên được xây dựng bằng ngôn ngữ R, sử dụng gói ggplot2 để minh họa quy mô thị trường của các hãng xe thông qua số lượng xe trong tập dữ liệu. Đầu tiên, dữ liệu được xử lý bằng cách nhóm (count) theo biến hãng xe (make) và sắp xếp tăng dần số lượng. Sau đó, hàm mutate() được dùng để tính toán tỷ lệ phần trăm (%) của mỗi hãng so với tổng số xe bằng công thức pct = n / sum(n) * 100. Các giá trị này được truyền vào hàm ggplot() để khởi tạo biểu đồ, với trục hoành là số lượng xe, trục tung là hãng xe, và màu sắc thể hiện tỷ lệ phần trăm thị phần.

Lớp geom_col() được dùng để vẽ biểu đồ cột ngang, thể hiện số lượng xe tương ứng với từng hãng. Kết hợp với geom_text(), các giá trị phần trăm được hiển thị trực tiếp trên đầu mỗi cột, giúp người xem dễ dàng nhận biết tỷ lệ thị phần của từng hãng. Hàm coord_flip() đảo trục của biểu đồ, giúp các hãng xe được sắp xếp theo chiều dọc, thuận tiện cho việc so sánh khi danh sách dài. Thang màu scale_fill_viridis_c() được áp dụng để tạo dải màu liên tục thể hiện tỷ lệ (%) từ thấp đến cao, vừa tăng tính thẩm mỹ, vừa hỗ trợ nhận diện trực quan. Cuối cùng, labs() và theme_minimal() được sử dụng để đặt tiêu đề, nhãn trục và định dạng biểu đồ với phong cách đơn giản, dễ nhìn; element_text() giúp điều chỉnh kích thước và độ đậm của chữ tiêu đề.

Về mặt nội dung, biểu đồ cho thấy sự phân bố số lượng xe giữa các hãng khá đồng đều, với phần lớn các hãng chiếm khoảng 3,9–4% tổng số xe. Điều này cho thấy dữ liệu có sự cân bằng giữa các thương hiệu, không có hãng nào chiếm ưu thế vượt trội về quy mô trong tập dữ liệu khảo sát. Màu sắc trên biểu đồ giúp nhận biết nhanh mức chênh lệch nhỏ về tỷ lệ thị phần giữa các hãng, trong đó các hãng như Kia, Mazda, Subaru có tỷ lệ cao hơn một chút, trong khi Toyota và Hyundai thấp hơn đôi chút. Nhìn chung, biểu đồ đã thể hiện rõ cấu trúc thị trường ô tô tương đối cân bằng, cung cấp cái nhìn tổng quát về sự hiện diện của các hãng trong tập dữ liệu.

2.4.2.2. Công suất trung bình & Độ lệch chuẩn theo Hãng

vehicle_data %>%
  group_by(make) %>%
  summarise(
    avg_hp = mean(engine_hp, na.rm = TRUE),
    sd_hp  = sd(engine_hp, na.rm = TRUE)
  ) %>%
  ggplot(aes(x = reorder(make, avg_hp), y = avg_hp, fill = sd_hp)) +
  geom_col() +
  geom_errorbar(aes(ymin = avg_hp - sd_hp, ymax = avg_hp + sd_hp),
                width = 0.3, color = "black") +
  coord_flip(clip = "off") +   # ✅ Cho phép phần trên/ngoài không bị cắt
  scale_fill_viridis_c() +
  labs(
    title = "Công suất trung bình & độ lệch chuẩn theo Hãng",
    x = "Hãng xe",
    y = "HP trung bình"
  ) +
  theme_minimal() +
  theme(plot.margin = margin(10, 40, 10, 10)) 

Biểu đồ trên được xây dựng bằng ngôn ngữ R với gói ggplot2, nhằm mục đích so sánh công suất trung bình (HP) giữa các hãng xe đồng thời thể hiện mức độ biến động (độ lệch chuẩn – sd) của từng hãng. Trong đoạn mã, dữ liệu được xử lý để tính giá trị trung bình công suất (avg_hp) và độ lệch chuẩn (sd_hp) theo từng hãng xe (make). Biểu đồ được tạo bằng ggplot(aes(x = reorder(make, avg_hp), y = avg_hp, fill = sd_hp)), trong đó trục hoành thể hiện công suất trung bình, trục tung là hãng xe, còn màu sắc biểu thị độ lệch chuẩn công suất.

Lớp geom_col() được sử dụng để tạo biểu đồ cột ngang, giúp hiển thị trực quan mức công suất trung bình của từng hãng. Kết hợp với geom_errorbar(), đoạn mã thêm thanh sai số (error bar) cho mỗi cột, thể hiện khoảng biến động của công suất ± độ lệch chuẩn, cho phép người xem đánh giá mức độ ổn định trong thiết kế động cơ giữa các hãng. Hàm coord_flip() được dùng để đảo trục, giúp các hãng được sắp xếp theo chiều dọc và dễ đọc hơn, trong khi scale_fill_viridis_c() áp dụng bảng màu Viridis mang tính thẩm mỹ và đảm bảo khả năng phân biệt tốt giữa các mức độ lệch chuẩn. Cuối cùng, labs() được dùng để đặt tiêu đề và nhãn trục, còn theme_minimal() cùng theme(plot.margin = margin(…)) giúp biểu đồ có giao diện gọn gàng, cân đối.

Kết quả biểu đồ cho thấy sự khác biệt rõ rệt về công suất trung bình giữa các hãng xe. Các thương hiệu như Porsche, Land Rover, Tesla, Cadillac nằm ở nhóm đầu với công suất trung bình cao nhất, thể hiện phân khúc xe hiệu năng cao và sang trọng. Ngược lại, các hãng như Hyundai, Kia, Nissan, Honda, Mazda có công suất trung bình thấp hơn, phù hợp với phân khúc xe phổ thông, tiết kiệm nhiên liệu. Độ lệch chuẩn nhỏ giữa các hãng gợi ý rằng công suất trong mỗi thương hiệu khá đồng đều, phản ánh chiến lược sản phẩm ổn định. Nhìn chung, biểu đồ giúp người đọc dễ dàng nhận thấy mối quan hệ giữa công suất động cơ và phân khúc thị trường của từng hãng xe.

2.4.2.3. Xếp hạng theo Số lượng xe

vehicle_data %>%
  count(make) %>%
  mutate(rank_by_count = rank(desc(n))) %>%
  ggplot(aes(x = reorder(make, n), y = n, fill = rank_by_count)) +
  geom_col() +
  geom_text(
    aes(label = rank_by_count),
    hjust = 1.2,           
    color = "black",
    size = 3
  ) +
  coord_flip() +
  scale_fill_viridis_c() +
  labs(
    title = "Xếp hạng theo số lượng xe",
    x = "Hãng xe",
    y = "Số lượng",
    fill = "Thứ hạng"
  ) +
  theme_minimal() +
  theme(
    plot.title = element_text(size = 13, face = "bold", hjust = 0.5),
    axis.text.y = element_text(size = 9),
    axis.text.x = element_text(size = 9),
    plot.margin = margin(10, 20, 10, 10),
    legend.position = "right"
  )

Biểu đồ được xây dựng bằng ngôn ngữ R với gói ggplot2, nhằm thể hiện xếp hạng các hãng xe theo số lượng xe trong tập dữ liệu. Đầu tiên, dữ liệu được nhóm theo biến hãng xe (make) và đếm số lượng từng hãng bằng hàm count(). Sau đó, mutate(rank_by_count = rank(desc(n))) được sử dụng để xếp hạng các hãng theo thứ tự giảm dần của số lượng xe.

Trong phần trực quan, hàm geom_col() tạo biểu đồ cột ngang, thể hiện số lượng xe của từng hãng, trong khi geom_text() hiển thị số thứ hạng ngay bên phải mỗi cột, giúp người xem dễ dàng nhận biết vị trí của từng hãng trong bảng xếp hạng. Bảng màu scale_fill_viridis_c() được dùng để biểu thị mức xếp hạng, với màu đậm thể hiện thứ hạng cao và màu nhạt hơn thể hiện thứ hạng thấp. Ngoài ra, coord_flip() đảo trục giúp các nhãn hãng xe hiển thị rõ ràng hơn.

Kết quả biểu đồ cho thấy sự phân bố số lượng xe giữa các hãng khá cân bằng, trong đó Kia, Mazda, Subaru nằm ở nhóm đầu, còn Toyota và Hyundai xếp cuối. Sự chênh lệch không lớn giữa các thứ hạng phản ánh mức độ cạnh tranh đồng đều giữa các hãng trong tập dữ liệu.

2.4.2.4. Số dặm trung bình của xe tình trạng “Fair” theo hãng

vehicle_data %>%
  filter(condition == "Fair") %>%
  group_by(make) %>%
  summarise(avg_mile_fair = mean(mileage, na.rm = TRUE), .groups = "drop") %>%
  ggplot(aes(x = reorder(make, avg_mile_fair), y = avg_mile_fair)) +
  geom_segment(aes(xend = make, y = 0, yend = avg_mile_fair), color = "grey70", linewidth = 1.1) +
  geom_point(aes(color = avg_mile_fair), size = 5) +
  geom_text(aes(label = scales::comma(round(avg_mile_fair, 0))), 
            hjust = -0.2, size = 3.5, color = "black") +
  coord_flip() +
  scale_color_viridis_c(option = "C", direction = -1) +
  labs(
    title = "🚗 Số dặm trung bình của xe tình trạng kém (Fair)",
    subtitle = "Xếp hạng theo số dặm trung bình của từng Hãng",
    x = "Hãng xe", y = "Số dặm trung bình (miles)",
    color = "Số dặm TB"
  ) +
  theme_minimal(base_size = 13) +
  theme(
    legend.position = "none",
    plot.title = element_text(face = "bold", size = 15),
    plot.subtitle = element_text(color = "gray40")
  ) +
  expand_limits(y = max(vehicle_data$mileage, na.rm = TRUE) * 1.05)

Về kỹ thuật: Biểu đồ được tạo sau khi lọc các xe có condition == “Fair”, tức là những xe có tình trạng trung bình hoặc kém. Sau đó, dữ liệu được nhóm theo hãng (group_by(make)), tính số dặm trung bình (mean(mileage)), rồi sắp xếp để hiển thị bằng biểu đồ cột ngang (coord_flip()), có thêm nhãn số cụ thể.

Về ý nghĩa thống kê: Biểu đồ cho thấy sự khác biệt rõ giữa các hãng. Nhóm trên cùng gồm Audi, Honda, Ford, Toyota, Volvo có số dặm trung bình cao nhất (~114.000 miles), trong khi nhóm dưới như Porsche, Kia, Dodge thấp hơn đáng kể (~110.000 miles). Điều này cho thấy các xe tình trạng “Fair” của Audi và Honda thường được sử dụng nhiều hơn nhưng vẫn tồn tại trong dữ liệu, phản ánh độ bền và khả năng duy trì giá trị sau thời gian dài. Ngược lại, các xe thể thao như Porsche có mileage thấp hơn – do ít sử dụng hoặc xe hạng sang thường được bảo dưỡng tốt. Về mặt thống kê, chênh lệch hơn 4.000 miles giữa các hãng cho thấy sự khác biệt có ý nghĩa thực tế, gợi ý rằng mức độ sử dụng và tuổi thọ xe khác nhau tùy vào phân khúc thương hiệu.

2.4.2.5. Độ lệch chuẩn số dặm theo hãng

vehicle_data %>%
  group_by(make) %>%
  summarise(sd_mileage = sd(mileage, na.rm = TRUE)) %>%
  ggplot(aes(x = reorder(make, sd_mileage), y = sd_mileage, fill = sd_mileage)) +
  geom_col() +
  coord_flip() +
  scale_fill_viridis_c() +
  labs(title = "Độ lệch chuẩn Số dặm theo Hãng",
       x = "Hãng xe", y = "SD(Mileage)") +
  theme_minimal()

Về kỹ thuật:

Dữ liệu được nhóm theo make và tính độ lệch chuẩn của số dặm (sd(mileage)), sau đó biểu diễn bằng cột màu gradient thể hiện biên độ dao động. Đây là một chỉ số đo mức độ phân tán của mileage trong từng hãng, phản ánh sự đồng nhất hoặc đa dạng trong sản phẩm.

Về ý nghĩa thống kê:

Các hãng như Mazda, Tesla, Lexus có độ lệch chuẩn cao nhất (≈72.400 miles), cho thấy biên độ sử dụng xe của họ rộng hơn, có cả xe rất ít đi và xe đi nhiều. Điều này có thể do các hãng này phân phối cả xe mới và xe đã qua sử dụng ở nhiều phân khúc giá. Trong khi đó, Jeep và Ram có độ lệch chuẩn thấp hơn (~71.600 miles), nghĩa là dòng sản phẩm của họ ổn định hơn và ít biến động về mức sử dụng. Nhìn chung, sự khác biệt nhỏ (khoảng 1.000–2.000 miles) gợi ý phân bố tương đối đồng đều, cho thấy dữ liệu đáng tin cậy và không bị thiên lệch cực đoan.

2.4.2.6. Số dặm TB của xe Cũ

vehicle_data %>%
  filter(year <= 2018) %>%
  group_by(make) %>%
  summarise(avg_mile_old = mean(mileage, na.rm = TRUE)) %>%
  ggplot(aes(x = reorder(make, avg_mile_old), y = avg_mile_old, fill = make)) +
  geom_col() +
  coord_flip() +
  labs(title = "Số dặm TB của xe cũ (≤2018)",
       x = "Hãng xe", y = "Số dặm TB") +
  theme_light() +
  theme(legend.position = "none")

Về kỹ thuật:

Biểu đồ này lọc xe sản xuất từ 2018 trở về trước, nhóm theo hãng và tính trung bình mileage. Đây là phép đo trực tiếp mức độ hao mòn trung bình của các dòng xe cũ.

Về ý nghĩa:

Kết quả cho thấy Mazda, Lexus và Dodge đứng đầu về mileage trung bình (~150.000 miles), tức xe của họ được sử dụng nhiều hơn trung bình ngành. Ngược lại, Kia, Honda, Jeep có mức thấp hơn (~130.000 miles). Điều này phản ánh sự khác biệt trong hành vi người dùng và độ bền của xe. Lexus là hãng xe sang nhưng có mileage cao cho thấy xe được sử dụng bền và ổn định, trong khi Honda có mileage thấp có thể do xe được thay thế sớm hoặc người dùng sử dụng ít. Về mặt thống kê, khoảng dao động 20.000 miles giữa các hãng là đáng kể, thể hiện ý nghĩa khác biệt giữa phân khúc và độ bền sản phẩm.

2.4.2.7. Phân bố chênh lệch số dặm so với trung bình hãng

vehicle_data %>%
  group_by(make) %>%
  mutate(mile_diff_make_avg = mileage - mean(mileage, na.rm = TRUE)) %>%
  ggplot(aes(x = make, y = mile_diff_make_avg, fill = make)) +
  geom_boxplot() +
  coord_flip() +
  labs(title = "Phân bố chênh lệch Số dặm so với TB hãng",
       x = "Hãng xe", y = "Chênh lệch Số dặm") +
  theme_minimal() +
  theme(legend.position = "none")

Về kỹ thuật:

Phân tích này sử dụng phép biến đổi mutate() để tính sai lệch từng xe so với giá trị trung bình hãng (mileage - mean(mileage)), sau đó trực quan hóa bằng boxplot. Phương pháp này giúp phát hiện độ biến thiên nội bộ trong từng hãng và các ngoại lệ (outliers).

Về thống kê:

Biểu đồ cho thấy các hãng như Volvo, Toyota, Tesla có độ lệch đối xứng quanh 0 – tức là phân bố số dặm ổn định, ít ngoại lệ. Trong khi Acura và BMW có phân bố rộng hơn, nghĩa là tồn tại xe được sử dụng quá ít hoặc quá nhiều so với trung bình hãng. Điều này phản ánh tính đa dạng trong khách hàng hoặc dòng sản phẩm – ví dụ BMW có cả sedan hạng sang và xe thể thao hiệu năng cao nên biên độ sử dụng khác nhau. Về mặt thống kê, đây là công cụ hữu hiệu để đánh giá tính đồng nhất trong dữ liệu trước khi mô hình hóa hồi quy hoặc phân cụm.

2.4.2.8. Phân bố chênh lệch công suất (HP Difference) theo hãng

vehicle_data %>%
  group_by(make) %>%
  mutate(hp_diff_make_avg = engine_hp - mean(engine_hp, na.rm = TRUE)) %>%
  ggplot(aes(x = hp_diff_make_avg, fill = make)) +
  geom_density(alpha = 0.4) +
  labs(title = "Phân bố chênh lệch Công suất so với TB hãng",
       x = "Chênh lệch HP", y = "Mật độ") +
  theme_light() +
  theme(legend.position = "bottom")

Về kỹ thuật:

Sử dụng phép tính tương tự phần mileage, biểu đồ này mô tả phân phối mật độ (geom_density()) của sai lệch công suất giữa từng xe và trung bình hãng (engine_hp - mean(engine_hp)). Thang màu giúp phân biệt từng hãng.

Về ý nghĩa thống kê:

Kết quả cho thấy phân phối có dạng chuẩn (bell shape) nhưng hơi lệch phải, nghĩa là phần lớn xe có công suất gần trung bình, một số nhỏ vượt trội hơn. Các hãng như Porsche, Tesla, Land Rover có đuôi phải dài hơn, cho thấy họ có nhiều xe công suất vượt trội so với trung bình hãng. Trong khi đó, Hyundai, Kia, Honda tập trung quanh 0 – biểu hiện sự đồng nhất cao trong thiết kế động cơ. Về thống kê, điều này chỉ ra rằng công suất là đặc trưng phân tầng rõ rệt giữa các hãng, và nếu xây dựng mô hình hồi quy giá, đây là một biến giải thích có sức mạnh mạnh mẽ.

2.4.2.9. Giá TB theo Lưới Hộp số & Nhiên liệu

top5 <- vehicle_data %>%
  count(make, sort = TRUE) %>%
  slice_head(n = 5) %>%
  pull(make)

vehicle_data %>%
  filter(make %in% top5) %>%
  group_by(make, transmission, fuel_type) %>%
  summarise(mean_price = mean(price, na.rm = TRUE), .groups = "drop") %>%
  ggplot(aes(x = transmission, y = fuel_type, fill = mean_price)) +
  geom_tile(color = "white") +
  facet_wrap(~make) +
  scale_fill_viridis_c() +
  labs(title = "Giá TB theo Hộp số & Nhiên liệu (Top 5 Hãng)",
       x = "Hộp số", y = "Loại nhiên liệu") +
  theme_minimal()

Về kỹ thuật:

Biểu đồ này sử dụng geom_tile() trong ggplot2, tạo ma trận giữa hai biến phân loại là transmission (hộp số) và fuel_type (loại nhiên liệu), đồng thời mã hóa màu theo giá trung bình (mean_price). Dữ liệu trước đó được lọc chỉ còn 5 hãng phổ biến nhất bằng count() + slice_head() và sau đó tính trung bình theo nhóm (group_by(make, transmission, fuel_type)). facet_wrap(~make) giúp tách riêng từng hãng thành khung nhỏ.

Về ý nghĩa thống kê:

Biểu đồ thể hiện mối quan hệ ba chiều giữa loại nhiên liệu, hộp số và giá trung bình. Ta thấy các hãng như Kia, Mazda, Nissan, Subaru có giá khá đồng đều giữa các loại nhiên liệu, nhưng Tesla nổi bật với ô màu sáng nhất — biểu thị giá cao vượt trội, đặc biệt với xe điện (Electric). Điều này phản ánh ảnh hưởng mạnh của công nghệ và thương hiệu đến giá. Xe điện Tesla có giá cao hơn đáng kể so với các mẫu xe xăng hay dầu, thể hiện xu hướng định giá theo giá trị công nghệ và hiệu suất môi trường.

2.4.2.10. Xếp hạng Công suất theo Hãng

vehicle_data %>%
  group_by(make) %>%
  summarise(avg_hp = mean(engine_hp, na.rm = TRUE)) %>%
  mutate(hp_rank = rank(desc(avg_hp))) %>%
  ggplot(aes(x = reorder(make, avg_hp), y = avg_hp)) +
  geom_segment(aes(xend = make, y = 0, yend = avg_hp),
               color = "grey70", linewidth = 1) +
  geom_point(aes(color = hp_rank), size = 5) +
  geom_text(aes(label = round(avg_hp, 0)),
            hjust = -0.3, size = 3.5, fontface = "bold") +
  coord_flip(clip = "off") +  # ⬅ Cho phép hiển thị chữ bị cắt ra ngoài
  scale_color_viridis_c(option = "C", direction = -1) +
  labs(
    title = "⚙️ Xếp hạng Công suất Trung bình theo Hãng",
    subtitle = "Dựa trên công suất động cơ trung bình (HP)",
    x = "Hãng xe",
    y = "HP trung bình",
    color = "Thứ hạng công suất"
  ) +
  theme_minimal(base_size = 13) +
  theme(
    plot.title = element_text(face = "bold", size = 16, hjust = 0.5),
    plot.subtitle = element_text(size = 12, hjust = 0.5, color = "grey40"),
    axis.text.x = element_text(size = 10),
    axis.text.y = element_text(size = 11),
    legend.position = "right",
    plot.margin = margin(10, 40, 10, 10) # ⬅ Thêm lề phải để không cắt nhãn
  )

Về kỹ thuật:

Đây là biểu đồ kết hợp giữa geom_segment() (đường nối từ trục gốc đến điểm) và geom_point() (điểm thể hiện công suất trung bình). Dữ liệu được nhóm theo make, tính trung bình avg_hp = mean(engine_hp), rồi xếp hạng giảm dần bằng rank(desc(avg_hp)). Thang màu viridis giúp biểu diễn rõ mức thứ hạng.

Về ý nghĩa thống kê:

Kết quả cho thấy Porsche dẫn đầu với công suất trung bình gần 450 HP, theo sau là Land Rover, Tesla, Cadillac, Mercedes-Benz, trong khi nhóm thấp nhất là Hyundai, Kia, Nissan (~130–150 HP). Điều này thể hiện sự phân tầng rất rõ giữa xe cao cấp và xe phổ thông. Các hãng cao cấp có công suất vượt trội gấp 3 lần trung bình toàn ngành, phản ánh định vị thương hiệu tập trung vào hiệu năng. Về mặt thống kê, phân phối này lệch phải mạnh (right-skewed), nghĩa là chỉ một số ít hãng có giá trị HP rất cao, trong khi phần lớn nằm quanh mức trung bình.

2.4.2.11. Tỷ lệ Dặm/Khấu hao TB

vehicle_data %>%
  group_by(make) %>%
  summarise(avg_mile_per_price = mean(mileage / price, na.rm = TRUE),
            count = n()) %>%
  ggplot(aes(x = count, y = avg_mile_per_price, size = count, color = avg_mile_per_price)) +
  geom_point(alpha = 0.6) +
  scale_color_viridis_c() +
  labs(title = "Tỷ lệ Mileage/Price trung bình theo Hãng",
       x = "Số lượng xe", y = "Mileage/Price") +
  theme_light()

Về kỹ thuật:

Biểu đồ bong bóng (geom_point()) này biểu diễn mối tương quan giữa số lượng xe (count) và hiệu quả sử dụng trên giá (avg_mileage/price). Mỗi bong bóng thể hiện một hãng, với kích thước đại diện cho số lượng xe và màu cho giá trị trung bình của tỷ lệ này. Tỷ lệ Mileage/Price được tính trung bình sau khi nhóm theo make.

Về ý nghĩa thống kê:

Tỷ lệ Mileage/Price thể hiện mức độ “kinh tế” của xe – số dặm mà người dùng đi được cho mỗi USD giá xe. Các hãng như Mazda, Subaru, Toyota có tỷ lệ cao (bong bóng sáng hơn và ở vị trí cao hơn), thể hiện giá trị sử dụng tốt – phù hợp với người tiêu dùng phổ thông. Trong khi Tesla, Porsche, Land Rover có tỷ lệ thấp, phản ánh giá cao nhưng ít sử dụng – điển hình của phân khúc xe sang. Biểu đồ cũng cho thấy không có tương quan mạnh giữa số lượng xe và hiệu quả sử dụng, tức hãng bán nhiều chưa chắc hiệu quả cao. Về thống kê, tỷ lệ này có thể xem là một chỉ báo value-for-money (VFM), rất hữu ích trong mô hình phân tích giá trị thị trường.

2.4.2.12. Độ chênh lệch Giá trung vị so với Toàn cục

median_price_global <- median(vehicle_data$price, na.rm = TRUE)

vehicle_data %>%
  group_by(make) %>%
  summarise(median_price = median(price, na.rm = TRUE)) %>%
  mutate(global = median_price_global) %>%
  ggplot(aes(y = reorder(make, median_price))) +
  geom_segment(aes(x = global, xend = median_price, yend = make),
               color = "grey70", size = 1) +
  geom_point(aes(x = global), color = "red", size = 3) +
  geom_point(aes(x = median_price), color = "blue", size = 3) +
  labs(title = "Chênh lệch Trung vị Giá so với Toàn cục",
       x = "Giá bán ($)", y = "Hãng xe") +
  theme_minimal()
## Warning: Using `size` aesthetic for lines was deprecated in ggplot2 3.4.0.
## ℹ Please use `linewidth` instead.
## This warning is displayed once every 8 hours.
## Call `lifecycle::last_lifecycle_warnings()` to see where this warning was
## generated.

Về kỹ thuật:

Biểu đồ dùng geom_segment() để nối giữa giá trung vị toàn cục (điểm đỏ) và giá trung vị của từng hãng (điểm xanh). Biến median_price_global được tính bằng median(vehicle_data$price) và so sánh với median(price) theo nhóm make. Đây là cách trực quan hóa độ lệch tương đối (relative deviation) so với chuẩn chung.

Về ý nghĩa thống kê:

Biểu đồ cho thấy Porsche, Land Rover, Tesla, Cadillac và Mercedes-Benz có giá trung vị cao hơn toàn cục từ +10.000 đến +25.000 USD, trong khi Hyundai, Kia, Mazda, Honda, Nissan nằm thấp hơn mức chuẩn khoảng -5.000 đến -8.000 USD. Điều này phản ánh rõ rệt phân khúc thị trường hai tầng: nhóm cao cấp có định giá vượt trội, trong khi nhóm phổ thông chiếm đa số ở dưới chuẩn. Về mặt thống kê, khoảng lệch trung vị này thể hiện tính không đối xứng trong phân phối giá (asymmetry) và có thể dùng làm biến “giá trị thương hiệu” trong mô hình dự báo giá hoặc phân tích cạnh tranh.

2.4.2.13. Giá trị tương quan chất lượng (xe “Fair”)

vehicle_data %>%
  group_by(make) %>%
  summarise(
    pct_fair = mean(condition == "Fair", na.rm = TRUE) * 100,
    avg_price = mean(price, na.rm = TRUE)
  ) %>%
  ggplot(aes(x = reorder(make, pct_fair), y = pct_fair)) +
  geom_col(fill = "#F2B880", alpha = 0.8) +
  geom_line(aes(y = avg_price / max(avg_price) * 100, group = 1),
            color = "#3366CC", size = 1.2) +
  geom_point(aes(y = avg_price / max(avg_price) * 100),
             color = "#3366CC", size = 2.5) +
  labs(
    title = "Tỷ lệ xe 'Fair' và Giá trung bình theo Hãng",
    x = "Hãng xe",
    y = "Tỷ lệ (%) / Quy mô chuẩn hóa",
    fill = "Fair %",
    color = "Avg Price"
  ) +
  theme_light(base_size = 12) +
  theme(
    plot.title = element_text(face = "bold", size = 15, hjust = 0.5),
    axis.text.x = element_text(angle = 45, hjust = 1, size = 10),
    panel.grid.minor = element_blank(),
    legend.position = "top",
    legend.title = element_blank()
  )
## Ignoring unknown labels:
## • fill : "Fair %"
## • colour : "Avg Price"

Về kỹ thuật:

Biểu đồ này kết hợp hai lớp dữ liệu: geom_col() biểu diễn tỷ lệ xe “Fair” (xe trong tình trạng trung bình) và geom_line() + geom_point() thể hiện giá trung bình (được chuẩn hóa theo %). Dữ liệu được nhóm theo make để tính tỷ lệ “Fair” bằng mean(condition == ‘Fair’) * 100, và giá trung bình bằng mean(price). Kỹ thuật này cho phép so sánh song song hai đại lượng khác loại (tỷ lệ – giá) trên cùng thang chuẩn hóa.

Về ý nghĩa thống kê:

Biểu đồ cho thấy các hãng như Porsche, Tesla, Land Rover có tỷ lệ xe “Fair” thấp nhưng giá trung bình cao, trong khi Mazda, GMC, Subaru có tỷ lệ xe “Fair” cao hơn, giá thấp hơn đáng kể. Điều này cho thấy mối quan hệ nghịch chiều giữa giá trị xe và tình trạng hao mòn trung bình. Các hãng cao cấp duy trì giá trị tốt dù xe cũ ít hơn, trong khi xe phổ thông chiếm tỷ lệ lớn trong nhóm “Fair”. Thống kê này phản ánh tính phân tầng rõ rệt về độ bền thương hiệu và độ mất giá theo thời gian.

2.4.3. Biểu đồ với biến Mileage

2.4.3.1. Phân vị số dặm

vehicle_data %>%
  mutate(mileage_quartile = ntile(mileage, 4)) %>%
  ggplot(aes(x = factor(mileage_quartile), y = mileage, fill = factor(mileage_quartile))) +
  geom_boxplot() +
  scale_fill_brewer(palette = "Set2") +
  labs(title = "Phân bố Số dặm theo các Phân vị", x = "Phân vị (Quartile)", y = "Mileage") +
  theme_minimal()

Về kỹ thuật:

Sử dụng geom_boxplot() và mutate(ntile(mileage, 4)) để chia toàn bộ dữ liệu Mileage thành 4 nhóm phân vị (quartiles). Đây là cách trực quan hóa phân bố điển hình giúp nhận biết độ lan tỏa và các giá trị ngoại lai.

Về ý nghĩa thống kê:

Các hộp boxplot thể hiện sự tăng dần đều từ Q1 (~25.000 miles) đến Q4 (~200.000 miles), phản ánh sự phân tầng rõ ràng trong quãng đường sử dụng xe. Biểu đồ này chứng minh dữ liệu mileage có phân phối lệch phải (right-skewed) — phần lớn xe nằm trong vùng thấp, nhưng vẫn tồn tại nhóm nhỏ có số dặm rất cao. Đây là đặc trưng điển hình của thị trường xe cũ, khi đa số xe vẫn ở mức sử dụng trung bình.

2.4.3.2. Số dặm Min/Max theo Năm

vehicle_data %>%
  group_by(year) %>%
  summarise(min_mile = min(mileage), max_mile = max(mileage)) %>%
  ggplot(aes(x = year)) +
  geom_ribbon(aes(ymin = min_mile, ymax = max_mile), fill = "#A1C9F4", alpha = 0.4) +
  geom_line(aes(y = min_mile), color = "#1F77B4") +
  geom_line(aes(y = max_mile), color = "#D62728") +
  labs(title = "Khoảng giá trị Mileage (Min–Max) theo Năm", x = "Năm", y = "Mileage") +
  theme_light()

Về kỹ thuật: Biểu đồ kết hợp geom_ribbon() (vùng bóng thể hiện khoảng min–max) và geom_line() (đường biên). Dữ liệu nhóm theo year, sau đó tính giá trị nhỏ nhất và lớn nhất của mileage.

Về ý nghĩa thống kê: Ta thấy khoảng min–max khá ổn định từ 2000–2015 (~0–300.000 miles), nhưng từ 2016 trở đi, khoảng này co hẹp dần – phản ánh xu hướng giảm số dặm trung bình do xe mới hơn chưa sử dụng lâu. Điều này cũng cho thấy sự khác biệt rõ giữa các lô xe cũ (>10 năm) và xe mới (<5 năm). Về thống kê, phạm vi này là thước đo độ biến thiên thời gian của mileage, giúp xác định tốc độ hao mòn trung bình theo niên hạn.

2.4.3.3. Tỷ lệ Dặm/HP (Mức Độ Mòn)

vehicle_data %>%
  summarise(pct_worn_basic = sum(mileage / 100000 & engine_hp < 150) / n() * 100) %>%
  mutate(dummy = "Tỷ lệ mòn cao") %>%
  ggplot(aes(x = dummy, y = pct_worn_basic, fill = dummy)) +
  geom_col(width = 0.5) +
  geom_text(aes(label = paste0(round(pct_worn_basic, 1), "%")), vjust = -0.5) +
  scale_fill_brewer(palette = "Oranges") +
  labs(title = "Tỷ lệ Xe có mức độ mòn cao", x = "", y = "% xe mòn cao") +
  theme_minimal() +
  theme(legend.position = "none")

Về kỹ thuật: Biểu đồ đơn giản dùng geom_col() hiển thị tỷ lệ xe có mileage > 100.000 và công suất thấp (engine_hp < 150). Tỷ lệ được tính bằng biểu thức logic trong summarise().

Về ý nghĩa thống kê: Kết quả cho thấy khoảng 18.6% xe trong tập dữ liệu thuộc nhóm “mòn cao”, tức đã đi nhiều nhưng công suất thấp. Đây là tỷ lệ tương đối cao, phản ánh quy mô lớn của thị trường xe đã sử dụng lâu. Về mặt thống kê, con số này là ước lượng cho tail của phân phối Mileage, đại diện cho nhóm có rủi ro cao hơn về hao mòn cơ học.

2.4.3.4. Số dặm TB theo Mốc Tuổi Xe

vehicle_data %>%
  mutate(age_bin = cut(2025 - year, breaks = c(0, 3, 7, Inf), labels = c("0–3 năm", "4–7 năm", ">7 năm"))) %>%
  group_by(age_bin) %>%
  summarise(avg_mileage = mean(mileage)) %>%
  ggplot(aes(x = age_bin, y = avg_mileage, fill = age_bin)) +
  geom_col() +
  geom_text(aes(label = round(avg_mileage, 0)), vjust = -0.3) +
  labs(title = "Mileage trung bình theo độ tuổi xe", x = "Nhóm tuổi", y = "Mileage TB") +
  scale_fill_brewer(palette = "Set3") +
  theme_light()

Về kỹ thuật:

Xe được chia thành các nhóm tuổi bằng cut(2025 - year, breaks = c(0, 3, 7, Inf)), sau đó tính trung bình mileage theo nhóm (avg_mileage). Biểu đồ geom_col() thể hiện mối quan hệ tuyến tính giữa tuổi xe và quãng đường sử dụng.

Về ý nghĩa thống kê:

Kết quả rất trực quan: xe 0–3 năm tuổi có mileage trung bình khoảng 33.500 miles, xe 4–7 năm tuổi là 84.700 miles, và xe >7 năm tuổi đạt tới 159.000 miles. Điều này xác nhận tốc độ tích lũy mileage gần tuyến tính theo tuổi, tương ứng khoảng 12.000–13.000 miles/năm – đúng chuẩn trung bình của thị trường Bắc Mỹ. Về mặt thống kê, đây là mối quan hệ r ≈ 0.9 giữa tuổi và mileage, một trong những biến dự báo mạnh nhất cho mô hình định giá xe.

2.4.3.5. Số dặm TB theo Nhóm HP

vehicle_data %>%
  mutate(hp_group = ntile(engine_hp, 3)) %>%
  group_by(hp_group) %>%
  summarise(avg_mileage = mean(mileage)) %>%
  ggplot(aes(x = factor(hp_group), y = avg_mileage, fill = factor(hp_group))) +
  geom_col() +
  geom_text(aes(label = round(avg_mileage, 0)), vjust = -0.3) +
  labs(title = "Số dặm TB theo nhóm HP", x = "Nhóm HP", y = "Mileage TB") +
  theme_light()

Về kỹ thuật:

Dữ liệu được chia thành 3 nhóm công suất (hp_group = ntile(engine_hp, 3)) và tính trung bình số dặm (mean(mileage)) cho từng nhóm. Biểu đồ geom_col() biểu diễn giá trị trung bình, kèm nhãn số cụ thể bằng geom_text().

Về ý nghĩa thống kê:

Kết quả cho thấy số dặm trung bình gần như tương đương giữa ba nhóm HP, chỉ chênh nhau rất nhỏ (~300 miles). Điều này chứng minh rằng mức công suất không ảnh hưởng đáng kể đến quãng đường sử dụng trung bình, tức xe mạnh hay yếu đều được dùng với cường độ tương tự. Về thống kê, đây là ví dụ điển hình của biến độc lập không có tương quan đáng kể (r ≈ 0) giữa công suất và mileage.

2.4.3.6. Tỷ lệ Mileage TB so với TB toàn hãng

vehicle_data %>%
  group_by(make) %>%
  mutate(mile_pct_diff = (mileage - mean(mileage)) / mean(mileage) * 100) %>%
  summarise(avg_diff = mean(mile_pct_diff)) %>%
  ggplot(aes(x = reorder(make, avg_diff), y = avg_diff, fill = avg_diff > 0)) +
  geom_col() +
  coord_flip() +
  scale_fill_manual(values = c("TRUE" = "#4CAF50", "FALSE" = "#F44336")) +
  labs(title = "Chênh lệch % Mileage so với TB hãng", x = "Hãng xe", y = "Chênh lệch (%)") +
  theme_minimal()

Về kỹ thuật:

Mỗi hãng được tính tỷ lệ sai lệch phần trăm của mileage so với toàn bộ trung bình ((mileage - mean(mileage))/mean(mileage)*100). Các hãng có giá trị dương (nhiều hơn TB) tô màu xanh, âm (ít hơn TB) tô đỏ, qua scale_fill_manual().

Về ý nghĩa thống kê:

Biểu đồ cho thấy các hãng như GMC, Volkswagen, Hyundai, Chrysler có mileage cao hơn trung bình, trong khi Subaru, Jeep, BMW, Lexus có mileage thấp hơn đáng kể. Điều này phản ánh khác biệt hành vi sử dụng giữa các phân khúc: xe sang thường được dùng ít (đi ít dặm hơn), trong khi xe phổ thông – công dụng (utility) lại vận hành thường xuyên. Đây là yếu tố quan trọng trong định giá, vì mileage cao thường làm giảm giá trị xe, trong khi mileage thấp gắn với xe sang hoặc xe bảo dưỡng tốt.

2.4.3.7. Xe hiệu suất lỗi (lọc P10 & P90)

p10 <- quantile(vehicle_data$mileage, 0.10)
p90 <- quantile(vehicle_data$engine_hp, 0.90)
vehicle_data %>%
  mutate(flag = ifelse(mileage <= p10 & engine_hp >= p90, "Hiệu suất cao", "Khác")) %>%
  ggplot(aes(x = mileage, y = engine_hp, color = flag)) +
  geom_point(alpha = 0.6) +
  scale_color_manual(values = c("Hiệu suất cao" = "#00BFC4", "Khác" = "grey70")) +
  labs(title = "Xe hiệu suất vượt trội (Mileage thấp, HP cao)",
       x = "Mileage", y = "Công suất (HP)") +
  theme_light()

Về kỹ thuật:

Xe được lọc theo 2 tiêu chí cực trị: mileage <= p10 (10% thấp nhất) và engine_hp >= p90 (10% cao nhất). Nhóm đạt cả hai điều kiện được gắn cờ “Hiệu suất cao”, thể hiện bằng geom_point() với màu riêng (#00BFC4).

Về ý nghĩa thống kê:

Kết quả cho thấy chỉ một nhóm rất nhỏ xe nằm trong vùng hiệu suất cao, tức mileage thấp nhưng HP cao. Đây là nhóm xe thể thao hoặc cao cấp, ví dụ Porsche, Tesla, BMW… Sự tập trung này ở góc trái trên biểu đồ cho thấy mối quan hệ nghịch giữa công suất và mức sử dụng – xe càng mạnh thường được dùng ít hơn. Thống kê này có ý nghĩa lớn trong mô hình dự báo khấu hao, vì các xe hiệu suất cao có tỷ lệ hao mòn trên dặm thấp, giữ giá tốt hơn.

2.4.3.8. Mileage TB theo Lưới Hãng & Tình trạng (Top 5)

top5 <- vehicle_data %>% count(make, sort = TRUE) %>% slice_head(n = 5) %>% pull(make)
vehicle_data %>%
  filter(make %in% top5) %>%
  group_by(make, condition) %>%
  summarise(mean_mileage = mean(mileage)) %>%
  ggplot(aes(x = make, y = mean_mileage, fill = condition)) +
  geom_col(position = "dodge") +
  labs(title = "Mileage TB theo Tình trạng (Top 5 Hãng)",
       x = "Hãng xe", y = "Mileage TB") +
  scale_fill_brewer(palette = "Pastel1") +
  theme_light()
## `summarise()` has grouped output by 'make'. You can override using the
## `.groups` argument.

Về kỹ thuật:

Biểu đồ geom_col(position = “dodge”) hiển thị giá trị trung bình mileage cho từng mức condition (Excellent, Good, Fair) trong 5 hãng phổ biến nhất. Đây là dạng biểu đồ so sánh nhóm chồng ngang theo danh mục.

Về ý nghĩa thống kê:

Các hãng như Kia, Mazda, Nissan, Subaru, Tesla có sự chênh lệch mileage không đáng kể giữa các tình trạng, chỉ vài nghìn dặm. Điều này phản ánh rằng đánh giá tình trạng (condition) không chỉ phụ thuộc vào mileage mà còn vào bảo dưỡng, tuổi và công suất. Với Tesla, sự chênh lệch càng nhỏ – do xe điện ít hao mòn cơ khí hơn. Về thống kê, ta thấy mileage không đủ để đơn độc giải thích condition, mà cần kết hợp thêm biến năm sản xuất và loại động cơ.

2.4.3.9. Tỷ lệ xe đi ít (<50.000 dặm) theo Hãng

vehicle_data %>%
  group_by(make) %>%
  summarise(pct_low_mile = mean(mileage < 50000) * 100) %>%
  ggplot(aes(x = reorder(make, pct_low_mile), y = pct_low_mile, fill = make)) +
  geom_col() +
  coord_flip() +
  labs(title = "Tỷ lệ xe có Mileage < 50.000 theo Hãng",
       x = "Hãng xe", y = "% xe ít dặm") +
  theme_minimal() +
  theme(legend.position = "none")

Về kỹ thuật:

Sử dụng mean(mileage < 50000)*100 để tính phần trăm xe có số dặm thấp (dưới 50.000 miles) theo từng hãng, thể hiện bằng biểu đồ cột ngang (coord_flip()).

Về ý nghĩa thống kê:

Tỷ lệ xe đi ít nhất thuộc về Mercedes-Benz, Mazda, Honda, Volkswagen, cho thấy các hãng này có độ mới trung bình cao hoặc khách hàng sử dụng ít. Điều này cũng khẳng định đặc trưng của xe cao cấp và xe đô thị – được sử dụng ngắn hạn, ít hao mòn. Ở chiều ngược lại, các hãng như Toyota, GMC, Hyundai có tỷ lệ thấp hơn, nghĩa là phần lớn xe đã chạy quãng đường dài. Đây là thông tin quan trọng khi phân tích thị trường xe cũ – mới, phản ánh mức độ “trẻ” trung bình của dòng xe từng thương hiệu

2.4.4. Biểu đồ với biến Year

2.4.4.1. Tuổi xe (Age Distribution)

vehicle_data %>%
  mutate(age = 2025 - year) %>%
  ggplot(aes(x = age)) +
  geom_histogram(bins = 20, fill = "#00BFC4", color = "white") +
  geom_vline(aes(xintercept = mean(age, na.rm = TRUE)), color = "red", linetype = "dashed") +
  labs(title = "Phân bố Tuổi xe", x = "Tuổi xe (năm)", y = "Số lượng") +
  theme_light()

Kỹ thuật: Biểu đồ được xây dựng bằng geom_histogram() để thể hiện phân phối tuổi xe, trong đó tuổi được tính bằng công thức age = 2025 - year. Biểu đồ chia thành 20 khoảng (bins) giúp hiển thị mật độ xe theo từng nhóm tuổi. Đường kẻ dọc màu đỏ (geom_vline()) biểu diễn giá trị trung bình, hỗ trợ so sánh mức phổ biến của dữ liệu với trung tâm phân phối.

Ý nghĩa thống kê: Dữ liệu có dạng phân phối lệch phải (right-skewed), tập trung chủ yếu ở nhóm 5–10 năm tuổi, cho thấy phần lớn xe trong tập dữ liệu có độ tuổi trung bình. Số lượng xe mới (dưới 3 năm) và xe quá cũ (>15 năm) ít hơn rõ rệt. Giá trị trung bình tuổi xe khoảng 8 năm, đồng thời phân phối có đuôi kéo dài, thể hiện tồn tại một số lượng nhỏ xe cũ vượt trội. Phân tích này cho thấy sự tập trung của dữ liệu quanh trung tâm, đồng thời phản ánh mức độ phân tán vừa phải của tuổi xe trong quần thể.

2.4.4.2. Tương quan Tuổi xe & Giá

vehicle_data %>%
  mutate(age = 2025 - year) %>%
  ggplot(aes(x = age, y = price)) +
  geom_point(alpha = 0.6, color = "#E69F00") +
  geom_smooth(method = "lm", se = FALSE, color = "blue") +
  labs(title = "Tương quan Tuổi xe và Giá bán", x = "Tuổi xe", y = "Giá bán ($)") +
  theme_minimal()
## `geom_smooth()` using formula = 'y ~ x'

Kỹ thuật: Dữ liệu được trực quan hóa bằng biểu đồ tán xạ (geom_point()), kết hợp đường hồi quy tuyến tính (geom_smooth(method = “lm”)) để thể hiện mối quan hệ giữa tuổi xe (age) và giá bán (price). Đường hồi quy được hiển thị màu xanh, biểu diễn xu hướng tổng quát của dữ liệu.

Ý nghĩa thống kê: Biểu đồ thể hiện tương quan nghịch mạnh giữa tuổi và giá bán, thể hiện qua độ dốc âm của đường hồi quy. Giá trị xe giảm đều khi tuổi tăng, trong đó tốc độ giảm nhanh nhất ở giai đoạn 0–10 năm đầu, sau đó giảm chậm hơn ở vùng xe cũ. Mức độ phân tán của các điểm tăng dần theo tuổi, cho thấy sự biến thiên lớn ở nhóm xe cũ hơn do khác biệt về tình trạng, thương hiệu và loại xe. Đây là dạng quan hệ tuyến tính âm điển hình, đặc trưng cho biến động giá theo thời gian sử dụng.

2.4.4.3. Giá Min/Max theo Năm

vehicle_data %>%
  group_by(year) %>%
  summarise(min_price = min(price), max_price = max(price)) %>%
  ggplot(aes(x = year)) +
  geom_ribbon(aes(ymin = min_price, ymax = max_price), fill = "#A1C9F4", alpha = 0.4) +
  geom_line(aes(y = min_price), color = "#E41A1C") +
  geom_line(aes(y = max_price), color = "#377EB8") +
  labs(title = "Khoảng giá (Min–Max) theo Năm sản xuất", x = "Năm", y = "Giá ($)") +
  theme_light()

Kỹ thuật: Biểu đồ sử dụng geom_ribbon() để thể hiện vùng giá trị giữa giá tối thiểu (min_price) và giá tối đa (max_price) của từng năm. Hai đường giới hạn biên được vẽ bằng geom_line(), trong đó đường đỏ thể hiện giá thấp nhất và đường tím biểu diễn giá cao nhất.

Ý nghĩa thống kê: Khoảng giá mở rộng dần qua các năm, thể hiện độ biến thiên tăng lên trong giá bán giữa các dòng xe mới. Độ rộng dải giá tăng mạnh kể từ năm 2015, cho thấy sự gia tăng phân hóa về mức giá giữa các dòng xe. Cả hai đường biên cùng tăng, chứng tỏ xu hướng giá chung của toàn bộ thị trường xe đều tăng theo thời gian, nhưng tốc độ tăng của giá tối đa nhanh hơn, làm biên độ dao động lớn dần. Biểu đồ phản ánh xu hướng mở rộng độ lệch chuẩn của giá theo năm sản xuất.

2.4.4.4. HP Min/Max theo Năm

vehicle_data %>%
  group_by(year) %>%
  summarise(min_hp = min(engine_hp), max_hp = max(engine_hp)) %>%
  ggplot(aes(x = year)) +
  geom_ribbon(aes(ymin = min_hp, ymax = max_hp), fill = "#F1C40F", alpha = 0.4) +
  geom_line(aes(y = max_hp), color = "#E74C3C") +
  geom_line(aes(y = min_hp), color = "#3498DB") +
  labs(title = "Khoảng HP (Min–Max) theo Năm", x = "Năm", y = "Công suất (HP)") +
  theme_minimal()

Kỹ thuật: Tương tự biểu đồ giá, biểu đồ này dùng geom_ribbon() để mô tả vùng công suất giữa giá trị nhỏ nhất và lớn nhất trong từng năm. Đường viền đỏ thể hiện công suất cực đại và đường xanh hiển thị công suất cực tiểu.

Ý nghĩa thống kê: Kết quả cho thấy giới hạn công suất trên tăng mạnh từ 2000 đến khoảng 2010, sau đó ổn định quanh mức 600 HP, trong khi giới hạn dưới hầu như không thay đổi (~100 HP). Điều này chứng tỏ mức công suất trung bình tăng trong giai đoạn đầu, sau đó tiến tới trạng thái ổn định. Sự mở rộng ban đầu của khoảng HP cho thấy giai đoạn biến thiên mạnh giữa các phân khúc, còn sự phẳng dần về sau phản ánh tính đồng nhất cao hơn giữa các mẫu xe.

2.4.4.5. Độ lệch chuẩn HP theo Năm

vehicle_data %>%
  group_by(year) %>%
  summarise(sd_hp = sd(engine_hp)) %>%
  ggplot(aes(x = year, y = sd_hp)) +
  geom_area(fill = "#A1D99B", alpha = 0.6) +
  geom_line(color = "#31A354") +
  labs(title = "Độ lệch chuẩn HP theo Năm", x = "Năm", y = "Độ lệch chuẩn HP") +
  theme_minimal()

Kỹ thuật: Giá trị độ lệch chuẩn công suất (sd(engine_hp)) được tính cho từng năm và trực quan hóa bằng geom_area() kết hợp geom_line(), giúp hiển thị xu hướng thay đổi của mức độ phân tán công suất theo thời gian.

Ý nghĩa thống kê: Độ lệch chuẩn giảm nhẹ và ổn định quanh giá trị trung bình ~90–100 HP kể từ sau 2010, cho thấy mức độ phân tán công suất giữa các xe giảm dần và tiến tới cân bằng. Biểu đồ thể hiện xu hướng hội tụ, nghĩa là sự chênh lệch giữa xe có công suất thấp và cao đã ổn định. Sự giảm nhẹ ở giai đoạn đầu (2000–2005) cho thấy quá trình điều chỉnh kỹ thuật và tiêu chuẩn hóa trong thiết kế động cơ.

2.4.4.6. Giá TB theo Năm & Dẫn động

vehicle_data %>%
  group_by(year, drivetrain) %>%
  summarise(mean_price = mean(price)) %>%
  ggplot(aes(x = year, y = mean_price, color = drivetrain)) +
  geom_line(size = 1) +
  labs(title = "Giá TB theo Năm & Loại Dẫn động", x = "Năm", y = "Giá TB ($)") +
  theme_light()
## `summarise()` has grouped output by 'year'. You can override using the
## `.groups` argument.

Kỹ thuật: Dữ liệu được nhóm đồng thời theo year và drivetrain, sau đó tính giá trung bình (mean(price)). Biểu đồ đường (geom_line()) biểu diễn xu hướng giá qua thời gian cho từng loại hệ dẫn động gồm AWD, FWD, và RWD, với mã màu riêng cho từng nhóm.

Ý nghĩa thống kê: Ba đường giá đều có xu hướng tăng theo thời gian, cho thấy giá trung bình tăng ổn định qua các năm. Nhóm AWD luôn có giá trung bình cao hơn, tiếp đến là RWD và FWD thấp nhất. Khoảng cách giữa các nhóm được duy trì ổn định, chứng tỏ mức chênh giá do hệ dẫn động là yếu tố cố định trong cấu trúc giá. Mức tăng tương đối đồng đều cũng phản ánh rằng xu hướng tăng giá xe là hiện tượng phổ quát, không phụ thuộc vào kiểu dẫn động cụ thể.

2.4.4.7. Độ dặm TB theo Năm & Tình trạng

vehicle_data %>%
  group_by(year, condition) %>%
  summarise(mean_mileage = mean(mileage)) %>%
  ggplot(aes(x = year, y = mean_mileage, color = condition)) +
  geom_line(size = 1) +
  labs(title = "Mileage TB theo Tình trạng xe", x = "Năm", y = "Mileage TB") +
  theme_minimal()
## `summarise()` has grouped output by 'year'. You can override using the
## `.groups` argument.

Kỹ thuật: Biểu đồ được tạo bằng geom_line(), hiển thị xu hướng số dặm trung bình (mean_mileage) của các xe theo thời gian, được nhóm theo biến phân loại condition (Excellent, Good, Fair). Mỗi nhóm được tô màu khác nhau để dễ so sánh, và trục hoành biểu diễn theo year.

Ý nghĩa thống kê: Tất cả các nhóm tình trạng xe đều thể hiện xu hướng giảm dần của mileage theo thời gian — nghĩa là các xe sản xuất gần đây thường có số dặm thấp hơn. Nhóm “Excellent” luôn có số dặm trung bình thấp nhất, trong khi “Fair” cao nhất, phản ánh mối quan hệ hợp lý giữa tình trạng sử dụng và mức độ hao mòn. Sự hội tụ của ba đường sau năm 2015 cho thấy dữ liệu gần đây có xu hướng đồng đều hơn về quãng đường đi, thể hiện sự ổn định trong điều kiện sử dụng xe mới.

2.4.4.8. Tương quan Dặm & HP theo Năm

vehicle_data %>%
  ggplot(aes(x = engine_hp, y = mileage, color = factor(year))) +
  geom_point(alpha = 0.6) +
  scale_color_viridis_d() +
  labs(title = "Tương quan Mileage & HP theo Năm", x = "HP", y = "Mileage") +
  theme_light()

Kỹ thuật: Biểu đồ tán xạ (geom_point()) biểu diễn mối quan hệ giữa công suất động cơ (engine_hp) và số dặm đã đi (mileage), với màu sắc thể hiện theo năm sản xuất (factor(year)). Thang màu viridis được sử dụng để mô tả sự thay đổi năm, từ màu tối (cũ) sang sáng (mới).

Ý nghĩa thống kê: Không có mối tương quan tuyến tính mạnh giữa HP và mileage — các điểm phân bố khá ngẫu nhiên theo chiều ngang. Tuy nhiên, màu sắc cho thấy xe sản xuất gần đây (màu sáng) có xu hướng nằm ở vùng mileage thấp, trong khi xe cũ hơn (màu tối) tập trung ở vùng mileage cao. Điều này phản ánh xu hướng hợp lý: xe đời mới chưa sử dụng nhiều, trong khi xe cũ đã tích lũy số dặm đáng kể. Ngoài ra, phần lớn xe có HP trong khoảng 150–400, cho thấy vùng mật độ cao tập trung ở phân khúc phổ thông.

2.4.4.9. Tỷ lệ xe điện theo Năm

vehicle_data %>%
  group_by(year) %>%
  summarise(pct_electric = mean(fuel_type == "Electric") * 100) %>%
  ggplot(aes(x = year, y = pct_electric)) +
  geom_line(color = "#00BFC4", size = 1) +
  geom_point(size = 2, color = "#E69F00") +
  labs(title = "Tỷ lệ xe điện theo Năm", x = "Năm", y = "% xe Electric") +
  theme_light()

Kỹ thuật: Dữ liệu được nhóm theo year và tính tỷ lệ xe điện bằng công thức mean(fuel_type == “electric”) * 100. Biểu đồ sử dụng kết hợp geom_line() và geom_point() để hiển thị biến động tỷ lệ này qua các năm.

Ý nghĩa thống kê: Đường biểu diễn có sự dao động mạnh trong giai đoạn đầu (2000–2005) do số lượng mẫu nhỏ, sau đó ổn định quanh mức 35–37% từ năm 2010 trở đi. Xu hướng này cho thấy tỷ lệ xe điện trong dữ liệu không tăng nhanh theo năm, phản ánh trạng thái cân bằng hoặc thiếu bùng nổ trong giai đoạn khảo sát. Sự ổn định này cũng gợi ý rằng xe điện hiện vẫn là nhóm chiếm tỷ trọng tương đối cố định trong tập dữ liệu, chưa chiếm ưu thế tuyệt đối.

2.4.4.10. Giá TB xe mới (≥2020)

vehicle_data %>%
  filter(year >= 2020) %>%
  summarise(mean_price_recent = mean(price)) %>%
  ggplot(aes(x = "Xe mới (≥2020)", y = mean_price_recent, fill = "#E69F00")) +
  geom_col() +
  geom_text(aes(label = round(mean_price_recent, 0)), vjust = -0.3) +
  labs(title = "Giá TB xe mới (2020 trở đi)", x = "", y = "Giá TB ($)") +
  theme_light() +
  theme(legend.position = "none")

Kỹ thuật: Biểu đồ cột (geom_col()) thể hiện giá trung bình (mean_price_recent) của các xe sản xuất từ năm 2020 trở lại đây. Nhãn giá trị được hiển thị trực tiếp trên cột bằng geom_text() để hỗ trợ đọc nhanh giá trị trung bình.

Ý nghĩa thống kê: Giá trung bình của xe sản xuất sau 2020 đạt khoảng 31.629 USD, phản ánh mức giá tương đối cao trong phân bố chung. Dữ liệu ít biến thiên vì chỉ xét giai đoạn gần đây, nên biểu đồ có dạng đơn cột, phù hợp để làm mốc so sánh cho các phân tích giá theo năm hoặc phân khúc khác. Kết quả này khẳng định mức giá trung bình của xe mới nằm trên ngưỡng trung bình toàn bộ tập dữ liệu.

2.4.4.12. Xe đi ít nhất và mới nhất

vehicle_data %>%
  filter(year >= 2020) %>%
  arrange(mileage) %>%
  head(1) %>%
  ggplot(aes(x = make, y = mileage)) +
  geom_col(fill = "#00AFBB") +
  geom_text(aes(label = mileage), vjust = -0.3) +
  labs(title = "Xe mới nhất và ít dặm nhất", x = "Hãng xe", y = "Mileage") +
  theme_light()

Kỹ thuật: Dữ liệu được lọc cho year >= 2020, sau đó sắp xếp theo mileage tăng dần (arrange(mileage)), lấy xe có số dặm thấp nhất (head(1)). Biểu đồ geom_col() hiển thị hãng xe tương ứng và số dặm của mẫu xe đó.

Ý nghĩa thống kê: Kết quả cho thấy xe mới nhất và ít dặm nhất trong tập dữ liệu thuộc về hãng Chrysler, với số dặm chỉ 500. Đây là giá trị cực tiểu của biến mileage trong nhóm xe mới, thể hiện xe gần như chưa được sử dụng. Dữ liệu này thường đóng vai trò xác nhận tính hợp lệ của biến và là đối tượng tham chiếu để kiểm tra sự phân bố ở biên dưới (min outlier).

2.4.4.13. Biến động HP theo Năm

vehicle_data %>%
  group_by(year) %>%
  summarise(sd_hp = sd(engine_hp)) %>%
  ggplot(aes(x = year, y = sd_hp)) +
  geom_line(size = 1.1, color = "#F8766D") +
  geom_point(size = 2, color = "#00BFC4") +
  geom_smooth(se = FALSE, color = "grey40") +
  labs(title = "Độ biến động HP theo Năm sản xuất", x = "Năm", y = "Độ lệch chuẩn HP") +
  theme_minimal()
## `geom_smooth()` using method = 'loess' and formula = 'y ~ x'

Kỹ thuật: Biểu đồ kết hợp geom_line() và geom_point() để biểu diễn độ lệch chuẩn công suất (sd_hp) theo năm. Đồng thời, geom_smooth(method = “loess”) được thêm vào để thể hiện xu hướng mượt hơn của độ biến động này qua thời gian.

Ý nghĩa thống kê: Biểu đồ thể hiện rõ sự biến động mạnh ở giai đoạn đầu (2000–2003), sau đó độ lệch chuẩn dần ổn định quanh mức 90–95 HP. Đường hồi quy mượt cho thấy xu hướng giảm nhẹ và cân bằng sau 2010, phản ánh mức độ đồng nhất trong hiệu năng động cơ các năm gần đây. Điều này cho thấy sự thu hẹp chênh lệch công suất giữa các mẫu xe mới và cũ, đồng thời thể hiện xu hướng chuẩn hóa trong thiết kế động cơ hiện đại.

3. KẾT LUẬN

Bộ dữ liệu giá xe là tập hợp thông tin phong phú, phản ánh đầy đủ các khía cạnh kỹ thuật, đặc điểm sử dụng và mức giá của nhiều dòng xe khác nhau trên thị trường. Đây là nguồn dữ liệu có giá trị, phục vụ cho quá trình phân tích, đánh giá và mô hình hóa các yếu tố ảnh hưởng đến giá xe. Dữ liệu được thu thập từ nhiều nguồn đáng tin cậy, bảo đảm độ đa dạng về chủng loại xe, phân khúc, thương hiệu, năm sản xuất và đặc tính kỹ thuật.

Trong giai đoạn xử lý dữ liệu, các bước làm sạch và chuẩn hóa đã được thực hiện một cách cẩn trọng nhằm đảm bảo tính toàn vẹn và nhất quán. Cụ thể, dữ liệu được kiểm tra và loại bỏ các giá trị trùng lặp, xử lý các giá trị khuyết thiếu hoặc bất hợp lý, đồng thời chuyển đổi kiểu dữ liệu phù hợp cho từng biến để thuận tiện trong quá trình phân tích. Ngoài ra, nhóm dữ liệu cũng được chuẩn hóa tên cột, đồng nhất đơn vị đo lường và tạo thêm các biến phụ trợ như “tuổi xe”, “mức khấu hao theo năm sử dụng” hay “phân loại xe theo phân khúc”, giúp mở rộng khả năng khai thác thông tin.

Bộ dữ liệu sau khi hoàn thiện bao gồm các nhóm thông tin chính như:

Nhóm đặc điểm kỹ thuật: dung tích động cơ, công suất, loại hộp số, nhiên liệu, số chỗ ngồi và xuất xứ xe;

Nhóm thông tin sử dụng: số km đã đi, tình trạng xe (mới hoặc đã qua sử dụng), năm sản xuất;

Nhóm thông tin định giá: giá niêm yết, giá bán thực tế, tỷ lệ chênh lệch hoặc khấu hao;

Nhóm phân loại: thương hiệu, phân khúc xe và nhóm thị trường tương ứng.

Toàn bộ dữ liệu được lưu trữ trong cấu trúc bảng dữ liệu (data frame) trong môi trường R, với tính nhất quán cao giữa các biến, không tồn tại lỗi cú pháp hoặc dữ liệu rỗng. Quá trình rà soát thống kê mô tả cho thấy dữ liệu có độ phủ tốt, phân bố hợp lý và đủ điều kiện để sử dụng cho các kỹ thuật phân tích thống kê, trực quan hóa dữ liệu và mô hình hồi quy sau này.

Về tổng thể, bộ dữ liệu giá xe mang tính đại diện cao, phản ánh rõ ràng sự đa dạng của thị trường ô tô. Dữ liệu không chỉ được tổ chức logic và dễ truy xuất, mà còn đạt yêu cầu về độ chính xác, độ tin cậy và tính ổn định cần thiết cho quá trình khai thác. Nhờ được làm sạch, chuẩn hóa và bổ sung các biến phân tích quan trọng, bộ dữ liệu đã sẵn sàng phục vụ cho các bước nghiên cứu chuyên sâu hơn, như khai phá dữ liệu, trực quan hóa xu hướng giá và xây dựng mô hình dự đoán trong các phần tiếp theo của báo cáo.

CHƯƠNG 2: PHÂN TÍCH BÁO CÁO TÀI CHÍNH CỦA CTCP AN PHÁT XANH (AAA) TRONG GIAI ĐOẠN 2015-2024

1. PHÂN MỞ ĐẦU

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

Trong bối cảnh toàn cầu hóa và hội nhập kinh tế quốc tế ngày càng sâu rộng, các doanh nghiệp Việt Nam đang đối mặt với nhiều cơ hội cũng như thách thức mới. Thị trường cạnh tranh gay gắt buộc các doanh nghiệp phải nâng cao năng lực quản trị tài chính, tối ưu hóa cấu trúc vốn và đảm bảo hiệu quả sinh lời bền vững. Trong đó, phân tích báo cáo tài chính (BCTC) được xem là công cụ khoa học và hiệu quả nhất để đánh giá tình hình sức khỏe tài chính, đo lường hiệu quả hoạt động, cũng như đưa ra các quyết định quản trị, đầu tư và tài trợ hợp lý.

Phân tích BCTC không chỉ giúp doanh nghiệp hiểu rõ nội lực của mình mà còn hỗ trợ nhà đầu tư, tổ chức tín dụng và các bên liên quan trong việc ra quyết định đầu tư, cấp tín dụng hoặc hợp tác kinh doanh. Thông qua việc phân tích các chỉ tiêu tài chính như khả năng thanh toán, đòn bẩy tài chính, hiệu quả sử dụng tài sản, và khả năng sinh lời, người phân tích có thể nhận diện được rủi ro tiềm ẩn và cơ hội tăng trưởng trong tương lai.

Trong phạm vi nền kinh tế Việt Nam, ngành công nghiệp nhựa đóng vai trò quan trọng, vừa cung cấp nguyên liệu đầu vào cho nhiều ngành sản xuất khác (như bao bì, vật liệu xây dựng, ô tô, y tế), vừa là lĩnh vực có tốc độ tăng trưởng cao trong nhiều năm qua. Tuy nhiên, ngành này cũng chịu ảnh hưởng mạnh từ biến động giá dầu thô, chính sách môi trường toàn cầu, và xu hướng tiêu dùng xanh.

Trong bối cảnh đó, Công ty Cổ phần An Phát Xanh (AAA) nổi lên như một doanh nghiệp tiên phong trong việc chuyển đổi từ sản xuất nhựa truyền thống sang nhựa sinh học, thân thiện với môi trường. Với chiến lược phát triển bền vững, AAA đã mở rộng quy mô sản xuất, đầu tư công nghệ, và đa dạng hóa sản phẩm. Tuy nhiên, quá trình này cũng kéo theo sự thay đổi đáng kể trong cấu trúc tài chính, mức độ sử dụng nợ, và khả năng sinh lời qua các giai đoạn.

Việc phân tích và đánh giá toàn diện tình hình tài chính của AAA trong giai đoạn 10 năm (2015–2024) là hết sức cần thiết nhằm:

Hiểu rõ sự biến động trong cơ cấu tài sản và nguồn vốn của doanh nghiệp qua các giai đoạn mở rộng đầu tư.

Xác định mối quan hệ giữa đòn bẩy tài chính và hiệu quả sinh lời, từ đó đánh giá tính bền vững trong chiến lược tài chính.

Cung cấp bằng chứng định lượng phục vụ cho việc ra quyết định quản trị, đầu tư hoặc khuyến nghị chính sách.

Đặc biệt, nghiên cứu này ứng dụng ngôn ngữ lập trình R – một công cụ mạnh mẽ trong phân tích dữ liệu, giúp tự động hóa quy trình tính toán, đảm bảo độ chính xác, minh bạch và khả năng tái lập kết quả. Đây là hướng tiếp cận hiện đại, phù hợp với xu thế “Phân tích dữ liệu tài chính bằng lập trình (Financial Data Analytics)” đang được áp dụng rộng rãi trong nghiên cứu học thuật và thực tiễn doanh nghiệp.

1.2. Phương pháp nghiên cứu

Để thực hiện đề tài này, các phương pháp nghiên cứu sau được sử dụng, nhằm đảm bảo tính khoa học, độ tin cậy và khả năng tái lập của kết quả phân tích.

Phương pháp thu thập dữ liệu: Nghiên cứu sử dụng dữ liệu thứ cấp được thu thập từ báo cáo tài chính (BCTC) của Công ty Cổ phần An Phát Xanh (AAA) trong giai đoạn 2015–2024. Đây là giai đoạn có nhiều biến động quan trọng đối với doanh nghiệp, cả về cơ cấu vốn, chiến lược mở rộng sản xuất và định hướng phát triển bền vững. Dữ liệu bao gồm các phần: Bảng cân đối kế toán, Báo cáo kết quả hoạt động kinh doanh, và Báo cáo lưu chuyển tiền tệ, được lấy từ các nguồn công khai như website chính thức của công ty, Sở Giao dịch Chứng khoán TP. Hồ Chí Minh (HOSE), và các trang dữ liệu tài chính uy tín (Vietstock, Cafef, Investing.vn). Việc sử dụng dữ liệu thứ cấp giúp tiết kiệm thời gian, đảm bảo tính đầy đủ, đồng thời phản ánh khách quan tình hình tài chính của doanh nghiệp trong một khoảng thời gian dài.

Phương pháp xử lý dữ liệu: Sau khi thu thập, dữ liệu được xử lý và chuẩn hóa bằng ngôn ngữ lập trình R, một công cụ mạnh mẽ trong phân tích dữ liệu định lượng. Đặc biệt, nghiên cứu sử dụng bộ thư viện Tidyverse (bao gồm các gói dplyr, tidyr, stringr) để thực hiện quá trình làm sạch, chuẩn hóa và chuyển đổi cấu trúc dữ liệu (pivot). Các bước xử lý bao gồm: kiểm tra và loại bỏ giá trị thiếu (NA), chuyển đổi kiểu dữ liệu về dạng phù hợp, thống nhất tên biến, mã hóa các biến định tính (nếu có), và tạo ra các biến tài chính mới phục vụ cho phân tích, chẳng hạn như hệ số nợ, tỷ suất sinh lời trên tài sản (ROA), tỷ suất sinh lời trên vốn chủ sở hữu (ROE) hay tỷ suất lợi nhuận doanh thu (ROS). Việc chuẩn hóa này đảm bảo dữ liệu đầu vào đồng nhất, giúp quá trình phân tích sau đó diễn ra trơn tru và chính xác.

Phương pháp phân tích thống kê: Sau khi dữ liệu đã được xử lý, nghiên cứu tiến hành phân tích thống kê mô tả và phân tích định lượng để rút ra các đặc điểm chính của tình hình tài chính. Cụ thể, các chỉ tiêu thống kê mô tả như giá trị trung bình, trung vị, độ lệch chuẩn và hệ số biến thiên được sử dụng nhằm phản ánh mức độ biến động của các chỉ tiêu tài chính theo thời gian. Ngoài ra, nghiên cứu còn sử dụng các kỹ thuật phân tích xu hướng (trend analysis) để xác định mức tăng trưởng của các chỉ tiêu qua từng năm, thông qua hai chỉ tiêu chính là tốc độ tăng trưởng năm (YoY) và tốc độ tăng trưởng kép (CAGR). Bên cạnh đó, phân tích tương quan (correlation analysis) được áp dụng nhằm đánh giá mối quan hệ giữa các chỉ tiêu tài chính, ví dụ như mối quan hệ giữa đòn bẩy tài chính và khả năng sinh lời, hay giữa tổng tài sản và doanh thu thuần. Việc lượng hóa các mối quan hệ này giúp xác định các yếu tố có ảnh hưởng mạnh nhất đến hiệu quả hoạt động tài chính của doanh nghiệp.

Phương pháp trực quan hóa dữ liệu: Để giúp kết quả nghiên cứu trở nên sinh động, dễ hiểu và dễ phân tích hơn, nghiên cứu sử dụng các công cụ trực quan hóa dữ liệu trong R, chủ yếu là thư viện ggplot2 và corrplot. Thông qua các biểu đồ cột, biểu đồ đường, biểu đồ phân tán và ma trận tương quan, các xu hướng biến động, cấu trúc vốn và mối tương quan giữa các chỉ tiêu tài chính được thể hiện một cách trực quan, sinh động. Biểu đồ không chỉ giúp minh họa kết quả tính toán, mà còn đóng vai trò quan trọng trong việc phát hiện các xu hướng tiềm ẩn hoặc các điểm bất thường (outliers) mà số liệu thô có thể không thể hiện rõ. Nhờ đó, người đọc có thể dễ dàng quan sát sự thay đổi của các chỉ tiêu tài chính qua thời gian, so sánh giữa các năm và đưa ra nhận định một cách chính xác hơn.

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

Đối tượng nghiên cứu: Đối tượng chính của đề tài là tình hình tài chính của Công ty Cổ phần An Phát Xanh (AAA) – một trong những doanh nghiệp tiên phong trong lĩnh vực sản xuất nhựa sinh học và vật liệu thân thiện với môi trường tại Việt Nam. Nghiên cứu tập trung phân tích hai khía cạnh cốt lõi là cấu trúc tài chính và khả năng sinh lời của doanh nghiệp. Cấu trúc tài chính phản ánh mối quan hệ giữa tài sản và nguồn vốn, cho thấy mức độ độc lập hay phụ thuộc vào vốn vay của doanh nghiệp, từ đó đánh giá khả năng tự chủ tài chính cũng như mức độ rủi ro tài chính trong hoạt động kinh doanh. Các chỉ tiêu như tổng nợ trên tổng tài sản (Debt Ratio), tỷ lệ vốn chủ sở hữu (Equity Ratio) hay đòn bẩy tài chính (Financial Leverage) được sử dụng để làm rõ đặc điểm này. Bên cạnh đó, khả năng sinh lời là yếu tố thể hiện hiệu quả sử dụng vốn và tài sản của doanh nghiệp trong việc tạo ra lợi nhuận. Nghiên cứu đánh giá khả năng sinh lời thông qua các chỉ tiêu ROA (Return on Assets), ROE (Return on Equity) và ROS (Return on Sales), nhằm xác định mức độ hiệu quả trong quản lý tài sản, vốn chủ sở hữu và doanh thu của công ty. Việc kết hợp hai khía cạnh này giúp đánh giá toàn diện sức khỏe tài chính, vừa phản ánh hiệu quả hoạt động, vừa chỉ ra mức độ an toàn tài chính của AAA trong suốt giai đoạn nghiên cứu.

Phạm vi nghiên cứu: Đề tài được giới hạn trong không gian và thời gian cụ thể, đảm bảo tính tập trung và tính khả thi của quá trình phân tích.

Về không gian nghiên cứu, dữ liệu được thu thập từ Báo cáo tài chính hợp nhất của Công ty Cổ phần An Phát Xanh (AAA) – bao gồm bảng cân đối kế toán, báo cáo kết quả kinh doanh và báo cáo lưu chuyển tiền tệ. Báo cáo hợp nhất phản ánh toàn bộ hoạt động tài chính của công ty mẹ và các công ty con, giúp đánh giá được bức tranh tài chính tổng thể của doanh nghiệp, tránh được sự sai lệch khi chỉ xem xét báo cáo riêng lẻ.

Về thời gian nghiên cứu, đề tài tập trung vào giai đoạn 10 năm, từ năm 2015 đến năm 2024. Đây là khoảng thời gian đủ dài để quan sát xu hướng biến động của các chỉ tiêu tài chính, đồng thời phản ánh sự chuyển dịch trong chiến lược tài chính và mô hình hoạt động của AAA qua từng giai đoạn phát triển. Trong giai đoạn này, doanh nghiệp có nhiều thay đổi đáng chú ý như mở rộng quy mô sản xuất, đầu tư vào lĩnh vực nhựa sinh học, và thực hiện các dự án xanh hướng đến phát triển bền vững, nên việc phân tích liên tục qua 10 năm mang lại giá trị nhận định sâu sắc hơn.

Bên cạnh đó, phạm vi nội dung của nghiên cứu chỉ tập trung vào phân tích định lượng các chỉ tiêu tài chính dựa trên dữ liệu công khai, không đi sâu vào đánh giá yếu tố phi tài chính như quản trị doanh nghiệp, thương hiệu, hay thị phần. Điều này nhằm đảm bảo độ chính xác, tính khách quan và khả năng tái lập kết quả khi sử dụng công cụ phân tích R trong toàn bộ quá trình nghiên cứu.

1.4. Kết cấu đề tài

Ngoài phần mở đầu và kết luận, nội dung chính của đề tài được bố cục thành các chương theo trình tự logic, tập trung vào quy trình phân tích báo cáo tài chính (BCTC) của Công ty Cổ phần An Phát Xanh bằng ngôn ngữ R, từ khâu thu thập dữ liệu đến xử lý, phân tích và trực quan hóa kết quả. Cấu trúc cụ thể của đề tài gồm các phần sau:

Trích xuất dữ liệu: Phần này trình bày quy trình thu thập và tải dữ liệu BCTC vào môi trường R. Cụ thể, tác giả mô tả cách sử dụng các hàm đọc dữ liệu như read_excel() hoặc read_csv() để nhập dữ liệu từ tệp Excel hoặc CSV chứa các chỉ tiêu tài chính của AAA. Bên cạnh đó, phần này cũng giới thiệu cách kiểm tra cấu trúc dữ liệu ban đầu, bao gồm số lượng quan sát, tên biến, kiểu dữ liệu, và sự tồn tại của giá trị thiếu (NA). Đây là bước đầu tiên trong toàn bộ quy trình phân tích, đảm bảo dữ liệu được nhập đúng định dạng và có thể xử lý hiệu quả ở các bước tiếp theo.

Giới thiệu tổng quan về dữ liệu: Phần này tập trung khám phá đặc điểm của bộ dữ liệu sau khi được tải vào R. Các thao tác như summary(), glimpse() hay head() được sử dụng để mô tả sơ bộ cấu trúc, kiểu dữ liệu và phạm vi giá trị của các biến. Thông qua đó, người nghiên cứu có thể nhận diện tính đầy đủ, độ chính xác và mức độ phân bố của dữ liệu. Ngoài ra, phần này cũng phân tích sơ bộ về nội dung dữ liệu, chẳng hạn như các chỉ tiêu tài chính nào được ghi nhận (doanh thu, lợi nhuận, tổng tài sản, vốn chủ sở hữu, nợ phải trả…), qua đó hình thành bức tranh khái quát ban đầu về tình hình tài chính của doanh nghiệp trong giai đoạn nghiên cứu.

Xử lý dữ liệu thô và mã hóa dữ liệu: Đây là phần quan trọng nhằm biến đổi dữ liệu thô thành dữ liệu phân tích được. Các bước bao gồm làm sạch, chuẩn hóa, tái cấu trúc và mã hóa dữ liệu. Cụ thể, tác giả sử dụng các hàm trong bộ Tidyverse (dplyr, tidyr, stringr) để:

Xử lý giá trị thiếu (NA) hoặc sai lệch.

Thay đổi kiểu dữ liệu cho phù hợp (ví dụ: chuyển chuỗi ký tự sang số).

Chuẩn hóa tên biến, tạo tính nhất quán.

Sử dụng pivot_longer() hoặc pivot_wider() để thay đổi cấu trúc dữ liệu từ dạng bảng chéo sang dạng chuẩn hóa (tidy data). Ngoài ra, phần này còn giới thiệu cách tạo các biến tài chính mới (chỉ số) như ROA, ROE, ROS, hệ số nợ, hệ số tự tài trợ… nhằm phục vụ cho các phân tích chuyên sâu ở các phần tiếp theo.

Thống kê cơ bản: Ở phần này, nghiên cứu tiến hành các phép tính thống kê mô tả và phân tích xu hướng nhằm đánh giá tổng quan tình hình tài chính của AAA. Các chỉ tiêu thống kê cơ bản như trung bình, trung vị, độ lệch chuẩn, giá trị lớn nhất – nhỏ nhất được tính toán để mô tả đặc điểm biến động của các chỉ tiêu tài chính. Ngoài ra, phần này còn phân tích xu hướng biến động qua thời gian bằng cách tính tốc độ tăng trưởng theo năm (YoY) và tốc độ tăng trưởng kép (CAGR), từ đó nhận diện được các giai đoạn tăng trưởng, suy giảm hoặc ổn định. Song song, phân tích tương quan (correlation analysis) cũng được áp dụng để xem xét mối quan hệ giữa các chỉ tiêu tài chính, chẳng hạn như mối quan hệ giữa đòn bẩy tài chính và khả năng sinh lời, hoặc giữa doanh thu và tổng tài sản. Kết quả thu được giúp làm rõ mức độ ảnh hưởng lẫn nhau giữa các yếu tố cấu thành hiệu quả tài chính.

Trực quan hóa dữ liệu: Phần cuối của chương trình bày việc biểu diễn kết quả phân tích dưới dạng đồ thị và biểu đồ bằng các thư viện trực quan hóa dữ liệu trong R như ggplot2 và corrplot. Các dạng biểu đồ được sử dụng bao gồm biểu đồ cột, biểu đồ đường, biểu đồ tròn, biểu đồ phân tán và ma trận tương quan, qua đó thể hiện rõ xu hướng biến động, cơ cấu tài chính và mối quan hệ giữa các chỉ tiêu. Việc trực quan hóa không chỉ giúp minh họa cho các kết quả tính toán, mà còn hỗ trợ việc diễn giải và so sánh một cách sinh động, trực quan và dễ hiểu hơn. Đây cũng là bước giúp người đọc nắm bắt toàn cảnh tình hình tài chính của doanh nghiệp thông qua hình ảnh thay vì chỉ qua các con số khô khan.

2. PHÂN TÍCH BÁO CÁO TÀI CHÍNH

2.1. Nạp và chuẩn bị dữ liệu

2.1.1. Nguồn dữ liệu và đặc điểm ban đầu

Nguồn dữ liệu trong nghiên cứu được thu thập từ trang web công bố thông tin chính thức của Công ty Cổ phần Nhựa và Môi trường Xanh An Phát (AAA) – nơi công ty đăng tải các báo cáo tài chính định kỳ theo chuẩn mực kế toán Việt Nam (VAS). Đây là nguồn dữ liệu thứ cấp có độ tin cậy cao, được kiểm toán và công bố công khai theo quy định của Ủy ban Chứng khoán Nhà nước.

Các báo cáo tài chính này thường được cung cấp dưới định dạng PDF, bao gồm các bảng biểu trình bày chi tiết tình hình tài chính và kết quả hoạt động kinh doanh của doanh nghiệp. Nội dung chính được chia thành bốn phần cơ bản:

Bảng cân đối kế toán (BCĐKT): Thể hiện quy mô và cơ cấu tài sản, nguồn vốn tại một thời điểm nhất định.

Báo cáo kết quả hoạt động kinh doanh (KQHĐKD): Ghi nhận doanh thu, chi phí, lợi nhuận gộp, lợi nhuận thuần và lợi nhuận sau thuế của doanh nghiệp trong kỳ.

Báo cáo lưu chuyển tiền tệ (LCTT): Phản ánh dòng tiền vào – ra từ ba hoạt động: kinh doanh, đầu tư và tài chính.

Thuyết minh báo cáo tài chính: Cung cấp thông tin chi tiết, giải thích cho các chỉ tiêu trong ba báo cáo trên.

Tuy nhiên, đặc điểm của các tệp PDF này là định dạng không có cấu trúc dữ liệu rõ ràng, thường trình bày dạng bảng có gộp ô, chia cột hoặc kèm ký hiệu đơn vị, khiến việc trích xuất dữ liệu bằng công cụ truyền thống (như copy – paste hoặc đọc trực tiếp vào R) trở nên khó khăn và mất nhiều thời gian. Vì vậy, để đảm bảo dữ liệu được số hóa chính xác, đề tài cần áp dụng phương pháp chuyển đổi bán tự động bằng trí tuệ nhân tạo (AI).

2.2.2. Chuyển đổi dữ liệu bằng trí tuệ nhân tạo

Để khắc phục hạn chế của định dạng PDF, nghiên cứu sử dụng công cụ AISTUDIO – một nền tảng ứng dụng AI nhận dạng ký tự (Optical Character Recognition – OCR) kết hợp mô hình ngôn ngữ GPT để tự động nhận diện cấu trúc bảng, trích xuất dữ liệu định lượng và chuyển đổi sang định dạng Excel (.xlsx).

Các bước thực hiện cụ thể như sau:

Tải các tệp báo cáo tài chính (PDF) từ website của công ty AAA về máy tính.

Nhập các tệp PDF vào công cụ AISTUDIO, chọn chế độ “Bảng tài chính (Financial Table Extraction)” để hệ thống tự động nhận dạng vùng dữ liệu dạng bảng.

AI tiến hành phân tách các cột, nhận diện tiêu đề, giá trị số và đơn vị tính (tỷ đồng, triệu đồng, phần trăm, v.v.).

Sau khi xử lý, dữ liệu được xuất ra tệp Excel có cấu trúc rõ ràng, dễ dàng thao tác và phân tích bằng R.

Kết quả của quá trình này là tệp “DU_LIEU_BAO_CAO_TAI_CHINH.xlsx”, đóng vai trò là nguồn dữ liệu trung gian chuẩn hóa. Tệp này chứa đầy đủ các chỉ tiêu tài chính cần thiết cho giai đoạn phân tích, bao gồm tổng tài sản, vốn chủ sở hữu, doanh thu thuần, lợi nhuận sau thuế, nợ phải trả, chi phí tài chính, và các thông tin bổ sung khác.

Nhờ sự hỗ trợ của công nghệ AI, độ chính xác của quá trình số hóa dữ liệu được cải thiện đáng kể, giảm thiểu sai sót khi nhập liệu thủ công, đồng thời tiết kiệm thời gian trong toàn bộ quy trình chuẩn bị dữ liệu.

2.2.3. Chuẩn bị môi trường làm việc trong R

Sau khi hoàn tất bước chuyển đổi, nghiên cứu tiến hành khởi tạo môi trường làm việc trong RStudio, nơi các thao tác xử lý, phân tích và trực quan hóa dữ liệu sẽ được thực hiện. Đây là bước kỹ thuật nền tảng quan trọng, nhằm đảm bảo rằng tất cả các thư viện cần thiết (packages) được nạp đầy đủ trước khi sử dụng, giúp quy trình phân tích diễn ra trơn tru, nhất quán và tái lập được.

Cụ thể, các thư viện được sử dụng trong đề tài bao gồm:

library(readxl)
library(dplyr)
library(tidyverse) 
## Warning: package 'tidyverse' was built under R version 4.5.1
## Warning: package 'tibble' was built under R version 4.5.1
## Warning: package 'stringr' was built under R version 4.5.1
## ── Attaching core tidyverse packages ──────────────────────── tidyverse 2.0.0 ──
## ✔ forcats   1.0.0     ✔ stringr   1.5.2
## ✔ lubridate 1.9.4     ✔ tibble    3.3.0
## ✔ purrr     1.0.4     ✔ tidyr     1.3.1
## ── Conflicts ────────────────────────────────────────── tidyverse_conflicts() ──
## ✖ ggplot2::%+%()   masks psych::%+%()
## ✖ ggplot2::alpha() masks psych::alpha()
## ✖ dplyr::filter()  masks stats::filter()
## ✖ dplyr::lag()     masks stats::lag()
## ℹ Use the conflicted package (<http://conflicted.r-lib.org/>) to force all conflicts to become errors
library(skimr)    
## Warning: package 'skimr' was built under R version 4.5.1
library(scales)   
## Warning: package 'scales' was built under R version 4.5.1
## 
## Attaching package: 'scales'
## 
## The following object is masked from 'package:purrr':
## 
##     discard
## 
## The following objects are masked from 'package:psych':
## 
##     alpha, rescale
## 
## The following object is masked from 'package:readr':
## 
##     col_factor
library(corrplot) 
## Warning: package 'corrplot' was built under R version 4.5.1
## corrplot 0.95 loaded
library(janitor)
## Warning: package 'janitor' was built under R version 4.5.2
## 
## Attaching package: 'janitor'
## 
## The following objects are masked from 'package:stats':
## 
##     chisq.test, fisher.test
library(car)
## Warning: package 'car' was built under R version 4.5.2
## Loading required package: carData
## Warning: package 'carData' was built under R version 4.5.2
## 
## Attaching package: 'car'
## 
## The following object is masked from 'package:purrr':
## 
##     some
## 
## The following object is masked from 'package:psych':
## 
##     logit
## 
## The following object is masked from 'package:dplyr':
## 
##     recode
library(moments)
## Warning: package 'moments' was built under R version 4.5.2

Giải thích chức năng từng thư viện:

readxl: Dùng để đọc dữ liệu từ các tệp Excel (.xlsx, .xls) vào môi trường R. Thư viện này cho phép truy cập dữ liệu nhanh, ổn định và không yêu cầu cài đặt Excel trên máy.

dplyr: Cung cấp các hàm mạnh mẽ để lọc, sắp xếp, nhóm, và biến đổi dữ liệu. Cú pháp của dplyr rất gần với ngôn ngữ tự nhiên, giúp mã lệnh dễ đọc và dễ hiểu.

tidyverse: Một tập hợp các gói thư viện hỗ trợ xử lý dữ liệu hiện đại theo “triết lý dữ liệu gọn gàng” (tidy data). Bao gồm các gói con như:

readr: Đọc dữ liệu nhanh, tối ưu tốc độ.

dplyr: Xử lý dữ liệu.

tidyr: Làm gọn và chuyển đổi cấu trúc dữ liệu (pivot).

ggplot2: Vẽ và trực quan hóa dữ liệu.

skimr: Dùng để tóm tắt thống kê (summary) chi tiết hơn so với hàm summary() mặc định. Cung cấp thông tin về kiểu dữ liệu, số lượng NA, giá trị trung bình, độ lệch chuẩn… rất hữu ích khi khám phá dữ liệu ban đầu.

scales: Cung cấp các hàm định dạng số, tỷ lệ phần trăm, hoặc đơn vị, giúp tùy chỉnh hiển thị biểu đồ và nhãn trục trong ggplot2.

corrplot: Hỗ trợ vẽ ma trận tương quan (correlation matrix) dưới dạng biểu đồ (heatmap), dùng để trực quan hóa mối quan hệ giữa các biến tài chính.

Các thư viện này tạo thành bộ công cụ toàn diện cho quá trình phân tích báo cáo tài chính trong R, từ đọc dữ liệu, xử lý, đến biểu diễn kết quả.

Sau khi cài đặt và nạp thư viện, dữ liệu được đọc trực tiếp vào R bằng lệnh:

df_bctc <- read_excel("C:/Users/HONG GAM/Documents/tieu luan ngon ngu lap trinh/df_bctc.xlsx")
## New names:
## • `Giá trị khấu hao lũy kế` -> `Giá trị khấu hao lũy kế...28`
## • `Giá trị hao mòn lũy kế` -> `Giá trị hao mòn lũy kế...31`
## • `Giá trị hao mòn lũy kế` -> `Giá trị hao mòn lũy kế...34`
## • `Giá trị khấu hao lũy kế` -> `Giá trị khấu hao lũy kế...37`
View(df_bctc)

Trong đó:

df_bctc là tên biến chứa dữ liệu báo cáo tài chính.

“df_bctc.xlsx” là tên tệp Excel chứa dữ liệu đầu vào, được lưu cùng thư mục với file mã nguồn R.

Sau khi nạp thành công, có thể kiểm tra cấu trúc dữ liệu bằng các lệnh:

2.2. Giới thiệu tổng quan về dữ liệu

2.2.1. Kiểm tra kích thước dữ liệu (Hàng và Cột)

nrow(df_bctc) 
## [1] 10
ncol(df_bctc) 
## [1] 134
dim(df_bctc)
## [1]  10 134

Hàm nrow() trong R có chức năng đếm số hàng (rows) trong một đối tượng dữ liệu kiểu data frame, tức là số lượng quan sát hoặc bản ghi trong tập dữ liệu. Kết quả [1] 10 cho biết bộ dữ liệu đang phân tích có tổng cộng 10 quan sát, nghĩa là có mười dòng dữ liệu, mỗi dòng tương ứng với thông tin của một năm.

Tương tự, hàm ncol() dùng để đếm số cột (columns) của bộ dữ liệu, tức là số lượng biến (variables) hoặc đặc trưng được ghi nhận cho mỗi quan sát. Kết quả [1] 134 cho thấy bộ dữ liệu có 134 cột. Mỗi cột đại diện cho một biến (variable) hay một đặc trưng (feature). Trong dữ liệu này, 134 cột bao gồm cột “Năm” và 133 chỉ tiêu tài chính khác nhau (ví dụ: “TÀI SẢN NGẮN HẠN”, “Doanh thu thuần…”, “Lợi nhuận sau thuế…”, v.v.).

dim() là thao tác kiểm tra kích thước ban đầu, giúp xác nhận rằng dữ liệu đã được đọc đầy đủ vào bộ nhớ. Nếu kết quả của hàm này trùng khớp với kích thước mong đợi (ở đây là 10 dòng và 134 cột), điều đó chứng tỏ rằng quá trình nạp dữ liệu từ tệp Excel đã thành công và không xảy ra lỗi mất mát thông tin trong quá trình nhập.

Những hàm này là những thao tác cơ bản nhưng đóng vai trò cực kỳ quan trọng trong khâu kiểm tra dữ liệu ban đầu. Về kỹ thuật, việc xác định đúng số hàng và số cột giúp đảm bảo rằng dữ liệu đã được đọc đầy đủ và không bị lỗi nhập liệu trong quá trình nạp từ file Excel. Nếu số hàng hoặc số cột trả về thấp hơn so với kỳ vọng, điều đó có thể báo hiệu dữ liệu bị thiếu dòng, cột hoặc lỗi tách giá trị khi đọc tệp. Ngược lại, khi kết quả hiển thị đúng 10 hàng và 137 cột, ta có thể khẳng định rằng toàn bộ dữ liệu đã được nhập chính xác và đầy đủ vào môi trường làm việc của R.

Về mặt ý nghĩa thống kê, kết quả này cung cấp cái nhìn định lượng đầu tiên về kích thước mẫu (sample size) và độ phức tạp của bộ dữ liệu. Số lượng 137 biến cho thấy dữ liệu có tính đa chiều (multivariate), tức là mỗi năm hoạt động kinh doanh của công ty được mô tả bao gồm các giá trị trong dữ liệu này. Điều này giúp cho việc phân tích có chiều sâu hơn, vì ta có thể xem xét đồng thời ảnh hưởng của nhiều yếu tố.

2.2.2. Xem lướt cấu trúc dữ liệu

glimpse(df_bctc)
## Rows: 10
## Columns: 134
## $ Năm                                                                                                                                                                                             <dbl> …
## $ `TÀI SẢN NGẮN HẠN`                                                                                                                                                                              <dbl> …
## $ `Tiền và các khoản tương đương tiền`                                                                                                                                                            <dbl> …
## $ Tiền                                                                                                                                                                                            <dbl> …
## $ `Các khoản tương đương tiền`                                                                                                                                                                    <dbl> …
## $ `Đầu tư tài chính ngắn hạn`                                                                                                                                                                     <dbl> …
## $ `Đầu tư nắm giữ đến ngày đáo hạn`                                                                                                                                                               <dbl> …
## $ `Các khoản phải thu ngắn hạn`                                                                                                                                                                   <dbl> …
## $ `Phải thu ngắn hạn của khách hàng`                                                                                                                                                              <dbl> …
## $ `Trả trước cho người bán ngắn hạn`                                                                                                                                                              <dbl> …
## $ `Phải thu về cho vay ngắn hạn`                                                                                                                                                                  <dbl> …
## $ `Phải thu ngắn hạn khác`                                                                                                                                                                        <dbl> …
## $ `Dự phòng phải thu ngắn hạn khó đòi`                                                                                                                                                            <dbl> …
## $ `Tổng hàng tồn kho`                                                                                                                                                                             <dbl> …
## $ `Hàng tồn kho`                                                                                                                                                                                  <dbl> …
## $ `Dự phòng giảm giá hàng tồn kho`                                                                                                                                                                <chr> …
## $ `Tài sản ngắn hạn khác`                                                                                                                                                                         <dbl> …
## $ `Chi phí trả trước ngắn hạn`                                                                                                                                                                    <dbl> …
## $ `Thuế giá trị gia tăng được khấu trừ`                                                                                                                                                           <dbl> …
## $ `Thuế và các khoản phải thu Nhà nước`                                                                                                                                                           <chr> …
## $ `TÀI SẢN DÀI HẠN`                                                                                                                                                                               <dbl> …
## $ `Các khoản phải thu dài hạn`                                                                                                                                                                    <dbl> …
## $ `Phải thu về cho vay dài hạn`                                                                                                                                                                   <dbl> …
## $ `Phải thu dài hạn khác`                                                                                                                                                                         <dbl> …
## $ `Tài sản cố định`                                                                                                                                                                               <dbl> …
## $ `Tài sản cố định hữu hình`                                                                                                                                                                      <dbl> …
## $ `Nguyên giá TSCĐ HH`                                                                                                                                                                            <dbl> …
## $ `Giá trị khấu hao lũy kế...28`                                                                                                                                                                  <dbl> …
## $ `Tài sản cố định thuê tài chính`                                                                                                                                                                <dbl> …
## $ `Nguyên giá TS cố định thuê tài chính`                                                                                                                                                          <dbl> …
## $ `Giá trị hao mòn lũy kế...31`                                                                                                                                                                   <dbl> …
## $ `Tài sản cố định vô hình`                                                                                                                                                                       <dbl> …
## $ `Nguyên giá TS cố định vô hình`                                                                                                                                                                 <dbl> …
## $ `Giá trị hao mòn lũy kế...34`                                                                                                                                                                   <dbl> …
## $ `Bất động sản đầu tư`                                                                                                                                                                           <dbl> …
## $ `Nguyên giá bất động sản đầu tư`                                                                                                                                                                <dbl> …
## $ `Giá trị khấu hao lũy kế...37`                                                                                                                                                                  <dbl> …
## $ `Tài sản dở dang dài hạn`                                                                                                                                                                       <dbl> …
## $ `Chi phí xây dựng cơ bản dở dang`                                                                                                                                                               <dbl> …
## $ `Đầu tư tài chính dài hạn`                                                                                                                                                                      <dbl> …
## $ `Đầu tư vào công ty liên kết`                                                                                                                                                                   <dbl> …
## $ `Đầu tư vào đơn vị khác`                                                                                                                                                                        <dbl> …
## $ `Tài sản dài hạn khác`                                                                                                                                                                          <dbl> …
## $ `Chi phí trả trước dài hạn`                                                                                                                                                                     <dbl> …
## $ `Tài sản thuế thu nhập hoãn lại`                                                                                                                                                                <dbl> …
## $ `Lợi thế thương mại`                                                                                                                                                                            <dbl> …
## $ `TỔNG CỘNG TÀI SẢN`                                                                                                                                                                             <dbl> …
## $ `NỢ PHẢI TRẢ`                                                                                                                                                                                   <dbl> …
## $ `Nợ ngắn hạn`                                                                                                                                                                                   <dbl> …
## $ `Phải trả người bán ngắn hạn`                                                                                                                                                                   <dbl> …
## $ `Người mua trả tiền trước ngắn hạn`                                                                                                                                                             <chr> …
## $ `Thuế và các khoản phải nộp Nhà nước`                                                                                                                                                           <dbl> …
## $ `Phải trả người lao động`                                                                                                                                                                       <dbl> …
## $ `Chi phí phải trả ngắn hạn`                                                                                                                                                                     <dbl> …
## $ `Doanh thu chưa thực hiện ngắn hạn`                                                                                                                                                             <dbl> …
## $ `Phải trả ngắn hạn khác`                                                                                                                                                                        <dbl> …
## $ `Vay và nợ thuê tài chính ngắn hạn`                                                                                                                                                             <dbl> …
## $ `Quỹ khen thưởng, phúc lợi`                                                                                                                                                                     <dbl> …
## $ `Nợ dài hạn`                                                                                                                                                                                    <dbl> …
## $ `Doanh thu chưa thực hiện dài hạn`                                                                                                                                                              <dbl> …
## $ `Phải trả dài hạn khác`                                                                                                                                                                         <dbl> …
## $ `Vay và nợ thuê tài chính dài hạn`                                                                                                                                                              <dbl> …
## $ `Thuế thu nhập hoãn lại phải trả`                                                                                                                                                               <dbl> …
## $ `Dự phòng phải trả dài hạn`                                                                                                                                                                     <dbl> …
## $ `Tổng Vốn chủ sở hữu`                                                                                                                                                                           <dbl> …
## $ `Vốn chủ sở hữu`                                                                                                                                                                                <dbl> …
## $ `Vốn góp của chủ sở hữu`                                                                                                                                                                        <dbl> …
## $ `Cổ phiếu phổ thông có quyền biểu quyết`                                                                                                                                                        <dbl> …
## $ `Thặng dư vốn cổ phần`                                                                                                                                                                          <dbl> …
## $ `Vốn khác của chủ sở hữu`                                                                                                                                                                       <dbl> …
## $ `Chênh lệch tỷ giá hối đoái`                                                                                                                                                                    <dbl> …
## $ `Quỹ đầu tư phát triển`                                                                                                                                                                         <dbl> …
## $ `Quỹ khác thuộc vốn chủ sở hữu`                                                                                                                                                                 <dbl> …
## $ `Lợi nhuận sau thuế chưa phân phối`                                                                                                                                                             <dbl> …
## $ `Lợi nhuận sau thuế chưa phân phối đến cuối năm trước`                                                                                                                                          <dbl> …
## $ `Lợi nhuận sau thuế chưa phân phối năm nay`                                                                                                                                                     <dbl> …
## $ `Lợi ích cổ đông không kiểm soát`                                                                                                                                                               <dbl> …
## $ `TỔNG CỘNG NGUỒN VỐN`                                                                                                                                                                           <dbl> …
## $ `Doanh thu bán hàng và cung cấp dịch vụ`                                                                                                                                                        <dbl> …
## $ `Các khoản giảm trừ doanh thu`                                                                                                                                                                  <dbl> …
## $ `Doanh thu thuần về bán hàng và cung cấp dịch vụ`                                                                                                                                               <dbl> …
## $ `Giá vốn hàng bán`                                                                                                                                                                              <dbl> …
## $ `Lợi nhuận gộp về bán hàng và cung cấp dịch vụ`                                                                                                                                                 <dbl> …
## $ `Doanh thu hoạt động tài chính`                                                                                                                                                                 <dbl> …
## $ `Chi phí hoạt động tài chính`                                                                                                                                                                   <dbl> …
## $ `Trong đó: Chi phí lãi vay`                                                                                                                                                                     <dbl> …
## $ `Lãi/(lỗ) trong công ty liên kết, liên doanh`                                                                                                                                                   <dbl> …
## $ `Chi phí bán hàng`                                                                                                                                                                              <dbl> …
## $ `Chi phí quản lý doanh nghiệp`                                                                                                                                                                  <dbl> …
## $ `Lợi nhuận thuần từ hoạt động kinh doanh`                                                                                                                                                       <dbl> …
## $ `Thu nhập khác`                                                                                                                                                                                 <dbl> …
## $ `Chi phí khác`                                                                                                                                                                                  <dbl> …
## $ `(Lỗ)/Lợi nhuận khác`                                                                                                                                                                           <dbl> …
## $ `Tổng lợi nhuận kế toán trước thuế`                                                                                                                                                             <dbl> …
## $ `Chi phí thuế TNDN hiện hành`                                                                                                                                                                   <dbl> …
## $ `(Chi phí)/ thu nhập thuế TNDN hoãn lại`                                                                                                                                                        <dbl> …
## $ `Lợi nhuận sau thuế thu nhập doanh nghiệp`                                                                                                                                                      <dbl> …
## $ `Lợi nhuận sau thuế của công ty mẹ`                                                                                                                                                             <dbl> …
## $ `(Lỗ)/ Lợi nhuận sau thuế của cổ đông không kiểm soát`                                                                                                                                          <dbl> …
## $ `Lãi cơ bản trên cổ phiếu`                                                                                                                                                                      <dbl> …
## $ `Lãi suy giảm trên cổ phiếu`                                                                                                                                                                    <dbl> …
## $ `Lợi nhuận kế toán trước thuế`                                                                                                                                                                  <dbl> …
## $ `Khấu hao tài sản cố định hữu hình và bất động sản đầu tư và tài sản cố định thuê tài chính và hao mòn tài sản cố định vô hình (bao gồm phân bổ lợi thế thương mại và tiền thuê đất trả trước)` <dbl> …
## $ `Trích lập/(hoàn nhập) dự phòng`                                                                                                                                                                <dbl> …
## $ `(Lãi)/Lỗ chênh lệch tỷ giá hối đoái do đánh giá lại các khoản mục tiền tệ có gốc ngoại tệ`                                                                                                     <dbl> …
## $ `(Lãi)/Lỗ từ hoạt động đầu tư`                                                                                                                                                                  <dbl> …
## $ `Chi phí lãi vay (bao gồm chi phí phát hành trái phiếu)`                                                                                                                                        <dbl> …
## $ `Lưu chuyển tiền từ hoạt động kinh doanh trước thay đổi vốn lưu động`                                                                                                                           <dbl> …
## $ `(Tăng)/Giảm các khoản phải thu`                                                                                                                                                                <dbl> …
## $ `(Tăng)/Giảm hàng tồn kho`                                                                                                                                                                      <dbl> …
## $ `Tăng/(Giảm) các khoản phải trả`                                                                                                                                                                <dbl> …
## $ `(Tăng)/Giảm chi phí trả trước`                                                                                                                                                                 <dbl> …
## $ `Tiền lãi vay đã trả`                                                                                                                                                                           <dbl> …
## $ `Thuế thu nhập doanh nghiệp đã nộp`                                                                                                                                                             <dbl> …
## $ `Tiền thu khác từ hoạt động kinh doanh`                                                                                                                                                         <dbl> …
## $ `Tiền chi khác từ hoạt động kinh doanh`                                                                                                                                                         <dbl> …
## $ `Lưu chuyển tiền thuần từ hoạt động kinh doanh`                                                                                                                                                 <dbl> …
## $ `Tiền chi để mua sắm, xây dựng TSCĐ và các TSDH khác`                                                                                                                                           <dbl> …
## $ `Tiền thu do thanh lý, nhượng bán TSCĐ và các TSDH khác`                                                                                                                                        <dbl> …
## $ `Tiền chi cho vay và mua công cụ nợ của các đơn vị khác`                                                                                                                                        <dbl> …
## $ `Tiền thu hồi cho vay, bán lại các công cụ nợ của đơn vị khác`                                                                                                                                  <dbl> …
## $ `Tiền chi đầu tư góp vốn vào đơn vị khác ( trừ tiền thu về)`                                                                                                                                    <dbl> …
## $ `Tiền thu hồi đầu tư góp vốn vào đơn vị khác`                                                                                                                                                   <dbl> …
## $ `tiền thu lãi cho vay, cổ tức và lợi nhuận được chia`                                                                                                                                           <dbl> …
## $ `Lưu chuyển tiền thuần từ hoạt động đầu tư`                                                                                                                                                     <dbl> …
## $ `Tiền thu từ đi vay`                                                                                                                                                                            <dbl> …
## $ `Tiền trả nợ gốc vay`                                                                                                                                                                           <dbl> …
## $ `Tiền trả nợ gốc thuê tài chính`                                                                                                                                                                <lgl> …
## $ `Cổ tức, lợi nhuận đã trả cho chủ sở hữu`                                                                                                                                                       <dbl> …
## $ `Lưu chuyển tiền thuần từ hoạt động tài chính`                                                                                                                                                  <dbl> …
## $ `Lưu chuyển tiền thuần trong năm`                                                                                                                                                               <dbl> …
## $ `Tiền và tương đương tiền đầu năm`                                                                                                                                                              <dbl> …
## $ `Ảnh hưởng của thay đổi tỷ giá hối đoái quy đổi ngoại tệ`                                                                                                                                       <dbl> …
## $ `Tiền và tương đương tiền cuối năm`                                                                                                                                                             <dbl> …

Hàm glimpse() (từ dplyr) cung cấp một cái nhìn tổng quan, xoay ngang (transposed) của data frame. Nó hiển thị số hàng, số cột, sau đó liệt kê từng tên cột, kiểu dữ liệu ( là double/số thực) và một vài giá trị đầu tiên.

Kết quả cho thấy, tất cả 134 cột (ngoại trừ cột Năm) đều có tên là ký tự tiếng Việt có dấu, khoảng trắng, và ký tự đặc biệt (ví dụ: TÀI SẢN NGẮN HẠN và Tiền có một khoảng trắng ở đầu). Điều này bắt buộc phải được xử lý ở các bước sau.

read_csv đã nhận diện đúng tất cả các cột tài chính là (số), nghĩa là không có lỗi định dạng số (dấu phẩy, dấu chấm) nghiêm trọng.

head(df_bctc)
## # A tibble: 6 × 134
##     Năm `TÀI SẢN NGẮN HẠN` Tiền và các khoản tư…¹    Tiền Các khoản tương đươn…²
##   <dbl>              <dbl>                  <dbl>   <dbl>                  <dbl>
## 1  2015      1071561006455           470061718120 2.42e11           227668535270
## 2  2016      1361646469010           406676809154 1.21e11           285527236397
## 3  2017      2142716548893           509577636533 1.21e11           388768001564
## 4  2018      3989369447153           645474843425 2.18e11           427839594047
## 5  2019      4971363590401           291674680985 2.33e11            58325479450
## 6  2020      4496050828524           963717122052 2.37e11           726402765634
## # ℹ abbreviated names: ¹​`Tiền và các khoản tương đương tiền`,
## #   ²​`Các khoản tương đương tiền`
## # ℹ 129 more variables: `Đầu tư tài chính ngắn hạn` <dbl>,
## #   `Đầu tư nắm giữ đến ngày đáo hạn` <dbl>,
## #   `Các khoản phải thu ngắn hạn` <dbl>,
## #   `Phải thu ngắn hạn của khách hàng` <dbl>,
## #   `Trả trước cho người bán ngắn hạn` <dbl>, …

Lệnh head(df_bctc) được sử dụng để hiển thị 6 dòng đầu tiên của bộ dữ liệu, giúp người phân tích xem nhanh nội dung thực tế sau khi dữ liệu được nạp vào R.

Về mặt kỹ thuật, đây là thao tác quan trọng để kiểm tra dữ liệu có được đọc đúng định dạng hay không, chẳng hạn như xác nhận xem cột năm và các cột giá trị có phải là dạng số hay không. Nếu dữ liệu hiển thị đúng và không bị lỗi mã hóa hoặc giá trị rỗng, điều đó chứng tỏ quá trình nhập liệu từ tệp Excel đã thành công.

head() cho phép người nghiên cứu quan sát sơ bộ đặc điểm và tính hợp lý của dữ liệu. Từ những dòng đầu tiên, ta có thể nhận thấy ngay các giá trị là những con số rất lớn (hàng nghìn tỷ), xác nhận đây là BCTC với đơn vị tính là VNĐ.

Điều này giúp hình thành cái nhìn tổng quát ban đầu về bộ dữ liệu, xác định loại biến, và chuẩn bị cho các bước thống kê mô tả, làm sạch, hoặc trực quan hóa trong các phần sau.

str(df_bctc)
## tibble [10 × 134] (S3: tbl_df/tbl/data.frame)
##  $ Năm                                                                                                                                                                                          : num [1:10] 2015 2016 2017 2018 2019 ...
##  $ TÀI SẢN NGẮN HẠN                                                                                                                                                                             : num [1:10] 1.07e+12 1.36e+12 2.14e+12 3.99e+12 4.97e+12 ...
##  $ Tiền và các khoản tương đương tiền                                                                                                                                                           : num [1:10] 4.70e+11 4.07e+11 5.10e+11 6.45e+11 2.92e+11 ...
##  $ Tiền                                                                                                                                                                                         : num [1:10] 2.42e+11 1.21e+11 1.21e+11 2.18e+11 2.33e+11 ...
##  $ Các khoản tương đương tiền                                                                                                                                                                   : num [1:10] 2.28e+11 2.86e+11 3.89e+11 4.28e+11 5.83e+10 ...
##  $ Đầu tư tài chính ngắn hạn                                                                                                                                                                    : num [1:10] NA NA 5.00e+10 7.21e+11 1.25e+12 ...
##  $ Đầu tư nắm giữ đến ngày đáo hạn                                                                                                                                                              : num [1:10] NA NA 5.00e+10 7.21e+11 1.19e+12 ...
##  $ Các khoản phải thu ngắn hạn                                                                                                                                                                  : num [1:10] 3.64e+11 4.56e+11 9.61e+11 1.61e+12 2.08e+12 ...
##  $ Phải thu ngắn hạn của khách hàng                                                                                                                                                             : num [1:10] 1.03e+11 2.21e+11 4.18e+11 6.92e+11 7.27e+11 ...
##  $ Trả trước cho người bán ngắn hạn                                                                                                                                                             : num [1:10] 1.69e+11 1.84e+11 3.26e+11 5.32e+11 6.36e+11 ...
##  $ Phải thu về cho vay ngắn hạn                                                                                                                                                                 : num [1:10] NA NA 1.30e+11 2.94e+11 5.37e+11 ...
##  $ Phải thu ngắn hạn khác                                                                                                                                                                       : num [1:10] 9.10e+10 5.10e+10 8.83e+10 9.59e+10 1.80e+11 ...
##  $ Dự phòng phải thu ngắn hạn khó đòi                                                                                                                                                           : num [1:10] -1.62e+08 -6.99e+08 NA NA NA ...
##  $ Tổng hàng tồn kho                                                                                                                                                                            : num [1:10] 2.14e+11 4.51e+11 5.37e+11 8.63e+11 1.22e+12 ...
##  $ Hàng tồn kho                                                                                                                                                                                 : num [1:10] 2.14e+11 4.51e+11 5.37e+11 8.65e+11 1.22e+12 ...
##  $ Dự phòng giảm giá hàng tồn kho                                                                                                                                                               : chr [1:10] NA NA NA "-2750517531" ...
##  $ Tài sản ngắn hạn khác                                                                                                                                                                        : num [1:10] 2.38e+10 4.88e+10 8.51e+10 1.47e+11 1.27e+11 ...
##  $ Chi phí trả trước ngắn hạn                                                                                                                                                                   : num [1:10] 1.47e+10 2.13e+10 1.89e+10 2.11e+10 2.83e+10 ...
##  $ Thuế giá trị gia tăng được khấu trừ                                                                                                                                                          : num [1:10] 9.11e+09 2.75e+10 6.59e+10 1.24e+11 9.74e+10 ...
##  $ Thuế và các khoản phải thu Nhà nước                                                                                                                                                          : chr [1:10] NA NA "260983354" "2705855459" ...
##  $ TÀI SẢN DÀI HẠN                                                                                                                                                                              : num [1:10] 8.83e+11 1.72e+12 2.43e+12 3.54e+12 3.02e+12 ...
##  $ Các khoản phải thu dài hạn                                                                                                                                                                   : num [1:10] NA NA NA 2.14e+10 9.64e+10 ...
##  $ Phải thu về cho vay dài hạn                                                                                                                                                                  : num [1:10] NA NA NA NA 7.57e+10 ...
##  $ Phải thu dài hạn khác                                                                                                                                                                        : num [1:10] NA NA NA 2.14e+10 2.07e+10 ...
##  $ Tài sản cố định                                                                                                                                                                              : num [1:10] 6.37e+11 1.43e+12 2.30e+12 2.20e+12 2.08e+12 ...
##  $ Tài sản cố định hữu hình                                                                                                                                                                     : num [1:10] 5.95e+11 1.34e+12 2.20e+12 2.11e+12 2.00e+12 ...
##  $ Nguyên giá TSCĐ HH                                                                                                                                                                           : num [1:10] 9.01e+11 1.70e+12 2.71e+12 2.86e+12 2.98e+12 ...
##  $ Giá trị khấu hao lũy kế...28                                                                                                                                                                 : num [1:10] -3.06e+11 -3.65e+11 -5.04e+11 -7.45e+11 -9.83e+11 ...
##  $ Tài sản cố định thuê tài chính                                                                                                                                                               : num [1:10] NA NA NA NA NA ...
##  $ Nguyên giá TS cố định thuê tài chính                                                                                                                                                         : num [1:10] NA NA NA NA NA ...
##  $ Giá trị hao mòn lũy kế...31                                                                                                                                                                  : num [1:10] NA NA NA NA NA ...
##  $ Tài sản cố định vô hình                                                                                                                                                                      : num [1:10] 4.12e+10 9.58e+10 9.65e+10 8.50e+10 8.20e+10 ...
##  $ Nguyên giá TS cố định vô hình                                                                                                                                                                : num [1:10] 4.52e+10 1.01e+11 1.03e+11 9.49e+10 9.48e+10 ...
##  $ Giá trị hao mòn lũy kế...34                                                                                                                                                                  : num [1:10] -4.05e+09 -5.04e+09 -6.93e+09 -9.91e+09 -1.29e+10 ...
##  $ Bất động sản đầu tư                                                                                                                                                                          : num [1:10] NA NA NA NA 2.23e+11 ...
##  $ Nguyên giá bất động sản đầu tư                                                                                                                                                               : num [1:10] NA NA NA NA 2.29e+11 ...
##  $ Giá trị khấu hao lũy kế...37                                                                                                                                                                 : num [1:10] NA NA NA NA -5.72e+09 ...
##  $ Tài sản dở dang dài hạn                                                                                                                                                                      : num [1:10] 1.91e+11 2.15e+11 9.81e+10 1.21e+12 2.94e+11 ...
##  $ Chi phí xây dựng cơ bản dở dang                                                                                                                                                              : num [1:10] 1.91e+11 2.15e+11 9.81e+10 1.21e+12 2.94e+11 ...
##  $ Đầu tư tài chính dài hạn                                                                                                                                                                     : num [1:10] 4.26e+10 4.43e+10 NA 4.84e+10 1.24e+11 ...
##  $ Đầu tư vào công ty liên kết                                                                                                                                                                  : num [1:10] 4.26e+10 4.43e+10 NA NA 1.52e+10 ...
##  $ Đầu tư vào đơn vị khác                                                                                                                                                                       : num [1:10] NA NA NA 4.84e+10 1.08e+11 ...
##  $ Tài sản dài hạn khác                                                                                                                                                                         : num [1:10] 1.29e+10 2.24e+10 3.58e+10 6.32e+10 1.98e+11 ...
##  $ Chi phí trả trước dài hạn                                                                                                                                                                    : num [1:10] 1.29e+10 2.23e+10 3.56e+10 6.25e+10 1.98e+11 ...
##  $ Tài sản thuế thu nhập hoãn lại                                                                                                                                                               : num [1:10] -359366 20321243 220148762 709491809 189900417 ...
##  $ Lợi thế thương mại                                                                                                                                                                           : num [1:10] NA NA NA NA NA ...
##  $ TỔNG CỘNG TÀI SẢN                                                                                                                                                                            : num [1:10] 1.95e+12 3.08e+12 4.58e+12 7.53e+12 7.99e+12 ...
##  $ NỢ PHẢI TRẢ                                                                                                                                                                                  : num [1:10] 1.14e+12 2.12e+12 2.95e+12 4.55e+12 4.73e+12 ...
##  $ Nợ ngắn hạn                                                                                                                                                                                  : num [1:10] 6.67e+11 1.14e+12 1.99e+12 3.21e+12 3.24e+12 ...
##  $ Phải trả người bán ngắn hạn                                                                                                                                                                  : num [1:10] 2.01e+11 3.04e+11 5.19e+11 6.23e+11 6.04e+11 ...
##  $ Người mua trả tiền trước ngắn hạn                                                                                                                                                            : chr [1:10] "12300795564" "11280630943" "17127077695" "43876545842" ...
##  $ Thuế và các khoản phải nộp Nhà nước                                                                                                                                                          : num [1:10] 5.75e+09 6.95e+09 1.42e+10 1.41e+10 2.69e+10 ...
##  $ Phải trả người lao động                                                                                                                                                                      : num [1:10] 4.56e+09 9.18e+09 1.33e+10 1.96e+10 2.26e+10 ...
##  $ Chi phí phải trả ngắn hạn                                                                                                                                                                    : num [1:10] 3.86e+09 2.08e+09 6.42e+09 8.99e+09 3.65e+10 ...
##  $ Doanh thu chưa thực hiện ngắn hạn                                                                                                                                                            : num [1:10] NA NA NA 4.53e+08 4.19e+10 ...
##  $ Phải trả ngắn hạn khác                                                                                                                                                                       : num [1:10] NA 5.71e+09 2.70e+09 3.29e+09 4.74e+09 ...
##  $ Vay và nợ thuê tài chính ngắn hạn                                                                                                                                                            : num [1:10] 4.39e+11 8.01e+11 1.42e+12 2.49e+12 2.40e+12 ...
##  $ Quỹ khen thưởng, phúc lợi                                                                                                                                                                    : num [1:10] 9.59e+08 2.86e+07 2.63e+07 6.24e+08 7.83e+08 ...
##  $ Nợ dài hạn                                                                                                                                                                                   : num [1:10] 4.68e+11 9.83e+11 9.60e+11 1.34e+12 1.50e+12 ...
##  $ Doanh thu chưa thực hiện dài hạn                                                                                                                                                             : num [1:10] NA NA NA NA 7.74e+10 ...
##  $ Phải trả dài hạn khác                                                                                                                                                                        : num [1:10] NA NA NA NA 2.42e+10 ...
##  $ Vay và nợ thuê tài chính dài hạn                                                                                                                                                             : num [1:10] 1.71e+11 9.83e+11 9.60e+11 1.34e+12 1.37e+12 ...
##  $ Thuế thu nhập hoãn lại phải trả                                                                                                                                                              : num [1:10] NA NA 4.57e+08 9.28e+06 2.24e+10 ...
##  $ Dự phòng phải trả dài hạn                                                                                                                                                                    : num [1:10] NA NA NA NA NA ...
##  $ Tổng Vốn chủ sở hữu                                                                                                                                                                          : num [1:10] 8.19e+11 9.55e+11 1.62e+12 2.98e+12 3.26e+12 ...
##  $ Vốn chủ sở hữu                                                                                                                                                                               : num [1:10] 8.19e+11 9.55e+11 1.62e+12 2.98e+12 3.26e+12 ...
##  $ Vốn góp của chủ sở hữu                                                                                                                                                                       : num [1:10] 4.95e+11 5.70e+11 8.36e+11 1.71e+12 1.71e+12 ...
##  $ Cổ phiếu phổ thông có quyền biểu quyết                                                                                                                                                       : num [1:10] 4.95e+11 5.70e+11 8.36e+11 1.71e+12 1.71e+12 ...
##  $ Thặng dư vốn cổ phần                                                                                                                                                                         : num [1:10] 1.47e+11 1.61e+11 1.98e+11 5.32e+11 5.32e+11 ...
##  $ Vốn khác của chủ sở hữu                                                                                                                                                                      : num [1:10] NA NA NA NA NA ...
##  $ Chênh lệch tỷ giá hối đoái                                                                                                                                                                   : num [1:10] 1.59e+09 2.05e+08 1.59e+08 -3.97e+07 -3.38e+08 ...
##  $ Quỹ đầu tư phát triển                                                                                                                                                                        : num [1:10] 3.60e+10 3.83e+10 4.57e+10 5.78e+10 6.73e+10 ...
##  $ Quỹ khác thuộc vốn chủ sở hữu                                                                                                                                                                : num [1:10] 1.32e+10 1.32e+10 1.32e+10 1.32e+10 1.32e+10 ...
##  $ Lợi nhuận sau thuế chưa phân phối                                                                                                                                                            : num [1:10] 1.16e+11 1.62e+11 2.84e+11 2.66e+11 6.03e+11 ...
##  $ Lợi nhuận sau thuế chưa phân phối đến cuối năm trước                                                                                                                                         : num [1:10] 7.64e+10 7.18e+10 9.01e+10 8.56e+10 1.42e+11 ...
##  $ Lợi nhuận sau thuế chưa phân phối năm nay                                                                                                                                                    : num [1:10] 4.00e+10 9.01e+10 1.94e+11 1.80e+11 4.60e+11 ...
##  $ Lợi ích cổ đông không kiểm soát                                                                                                                                                              : num [1:10] 9.92e+09 1.09e+10 2.48e+11 3.99e+11 3.28e+11 ...
##  $ TỔNG CỘNG NGUỒN VỐN                                                                                                                                                                          : num [1:10] 1.95e+12 3.08e+12 4.58e+12 7.53e+12 7.99e+12 ...
##  $ Doanh thu bán hàng và cung cấp dịch vụ                                                                                                                                                       : num [1:10] 1.62e+12 2.15e+12 4.08e+12 8.02e+12 9.28e+12 ...
##  $ Các khoản giảm trừ doanh thu                                                                                                                                                                 : num [1:10] 1.50e+09 1.73e+09 7.16e+09 7.25e+09 -2.02e+10 ...
##  $ Doanh thu thuần về bán hàng và cung cấp dịch vụ                                                                                                                                              : num [1:10] 1.61e+12 2.14e+12 4.07e+12 8.01e+12 9.26e+12 ...
##  $ Giá vốn hàng bán                                                                                                                                                                             : num [1:10] 1.42e+12 1.84e+12 3.52e+12 7.34e+12 -8.22e+12 ...
##  $ Lợi nhuận gộp về bán hàng và cung cấp dịch vụ                                                                                                                                                : num [1:10] 1.90e+11 3.07e+11 5.50e+11 6.73e+11 1.04e+12 ...
##  $ Doanh thu hoạt động tài chính                                                                                                                                                                : num [1:10] 2.24e+10 3.02e+10 5.58e+10 6.15e+10 1.80e+11 ...
##  $ Chi phí hoạt động tài chính                                                                                                                                                                  : num [1:10] 5.00e+10 5.39e+10 9.51e+10 2.09e+11 -2.68e+11 ...
##  $ Trong đó: Chi phí lãi vay                                                                                                                                                                    : num [1:10] 2.41e+10 2.73e+10 8.06e+10 1.26e+11 -2.25e+11 ...
##  $ Lãi/(lỗ) trong công ty liên kết, liên doanh                                                                                                                                                  : num [1:10] 3.38e+09 1.75e+09 NA NA -5.66e+07 ...
##  $ Chi phí bán hàng                                                                                                                                                                             : num [1:10] 7.52e+10 5.69e+10 1.06e+11 1.57e+11 -2.15e+11 ...
##  $ Chi phí quản lý doanh nghiệp                                                                                                                                                                 : num [1:10] 4.16e+10 6.26e+10 7.93e+10 1.24e+11 -1.49e+11 ...
##  $ Lợi nhuận thuần từ hoạt động kinh doanh                                                                                                                                                      : num [1:10] 4.88e+10 1.66e+11 3.26e+11 2.46e+11 5.90e+11 ...
##  $ Thu nhập khác                                                                                                                                                                                : num [1:10] 1.86e+09 8.08e+09 2.39e+09 1.12e+10 9.24e+09 ...
##  $ Chi phí khác                                                                                                                                                                                 : num [1:10] 4.16e+06 7.04e+09 3.95e+08 2.91e+09 -2.25e+09 ...
##  $ (Lỗ)/Lợi nhuận khác                                                                                                                                                                          : num [1:10] 1.86e+09 1.04e+09 1.99e+09 8.30e+09 6.99e+09 ...
##  $ Tổng lợi nhuận kế toán trước thuế                                                                                                                                                            : num [1:10] 5.06e+10 1.67e+11 3.28e+11 2.54e+11 5.97e+11 ...
##  $ Chi phí thuế TNDN hiện hành                                                                                                                                                                  : num [1:10] 1.00e+10 2.37e+10 6.44e+10 4.28e+10 -8.35e+10 ...
##  $ (Chi phí)/ thu nhập thuế TNDN hoãn lại                                                                                                                                                       : num [1:10] 3.65e+07 -2.07e+07 2.57e+08 -9.37e+08 -2.29e+10 ...
##  $ Lợi nhuận sau thuế thu nhập doanh nghiệp                                                                                                                                                     : num [1:10] 4.05e+10 1.43e+11 2.63e+11 2.12e+11 4.91e+11 ...
##  $ Lợi nhuận sau thuế của công ty mẹ                                                                                                                                                            : num [1:10] 4.00e+10 1.42e+11 2.23e+11 1.80e+11 4.60e+11 ...
##  $ (Lỗ)/ Lợi nhuận sau thuế của cổ đông không kiểm soát                                                                                                                                         : num [1:10] 5.33e+08 9.40e+08 4.00e+10 3.19e+10 3.06e+10 ...
##   [list output truncated]

Lệnh str(df_bctc) được dùng để xem cấu trúc tổng quát của bộ dữ liệu. Kết quả hiển thị cho biết đối tượng là một bảng dữ liệu (data frame) có 10 quan sát và 137 biến. str() là công cụ giúp người phân tích xác định đúng kiểu dữ liệu của từng cột, một bước cực kỳ quan trọng để tránh lỗi trong quá trình xử lý sau này.

Mỗi biến (cột) được liệt kê kèm theo kiểu dữ liệu và một vài giá trị mẫu.

Trong kết quả trên, ta thấy rằng tất cả các biến có kiểu số thực (num), đại diện cho dữ liệu định lượng có thể dùng cho các phép tính thống kê.

Ví dụ, nếu một biến số bị đọc nhầm thành dạng ký tự (do có ký hiệu đặc biệt như “–” hoặc “N/A”), các phép tính như trung bình hoặc độ lệch chuẩn sẽ không thể thực hiện được. Nhờ str(), ta có thể kiểm tra và phát hiện sớm những lỗi kiểu dữ liệu này.

Tiếp thep , ta dùng Hàm colnames() trong R được dùng để lấy tên các cột (tức là tên các biến) của một data frame hoặc ma trận.

2.3. Xử lý dữ liệu thô và mã hóa dữ liệu

Trước khi tiến hành phân tích, dữ liệu tài chính df_bctc được làm sạch và chuẩn hóa nhằm đảm bảo tính thống nhất, tránh sai sót trong quá trình xử lý thống kê. Đầu tiên, các khoảng trắng thừa ở đầu và cuối tên cột được loại bỏ bằng hàm trimws(), giúp tránh lỗi truy cập biến do sai lệch ký tự không nhìn thấy.

Xóa khoảng trắng thừa đầu/cuối tên cột)

names(df_bctc) <- trimws(names(df_bctc))

Đầu tiên, các khoảng trắng thừa ở đầu và cuối tên cột được loại bỏ bằng hàm trimws(), giúp tránh lỗi truy cập biến do sai lệch ký tự không nhìn thấy.

Kiểm tra các cột trùng tên hoặc trùng nghĩa (dư thừa)

duplicated(names(df_bctc))
##   [1] FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE
##  [13] FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE
##  [25] FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE
##  [37] FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE
##  [49] FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE
##  [61] FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE
##  [73] FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE
##  [85] FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE
##  [97] FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE
## [109] FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE
## [121] FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE
## [133] FALSE FALSE

Tiếp theo, lệnh duplicated(names(df_bctc)) được sử dụng để kiểm tra sự trùng lặp tên cột, đảm bảo mỗi biến trong bộ dữ liệu là duy nhất và có ý nghĩa riêng biệt

Chuẩn hóa Tên cột: Chuyển tất cả tên cột sang chữ thường và làm sạch (nếu cần))

names(df_bctc) <- tolower(names(df_bctc))
df_bctc <- df_bctc %>% 
  clean_names()

Sau đó, toàn bộ tên cột được chuyển về dạng chữ thường bằng hàm tolower() để tăng tính nhất quán, đồng thời hàm clean_names() (thuộc gói janitor) được áp dụng nhằm chuẩn hóa lại định dạng tên biến — loại bỏ ký tự đặc biệt, thay dấu cách bằng dấu gạch dưới, và đảm bảo tuân thủ chuẩn cú pháp trong R. Việc này giúp việc truy xuất và gọi biến trong các bước sau trở nên dễ dàng và hạn chế lỗi cú pháp.

Kiểm tra giá trị thiếu

sum(is.na(df_bctc))
## [1] 141
colSums(is.na(df_bctc))
##                                                                                                                                                                                         nam 
##                                                                                                                                                                                           0 
##                                                                                                                                                                            tai_san_ngan_han 
##                                                                                                                                                                                           0 
##                                                                                                                                                          tien_va_cac_khoan_tuong_duong_tien 
##                                                                                                                                                                                           0 
##                                                                                                                                                                                        tien 
##                                                                                                                                                                                           0 
##                                                                                                                                                                  cac_khoan_tuong_duong_tien 
##                                                                                                                                                                                           0 
##                                                                                                                                                                   dau_tu_tai_chinh_ngan_han 
##                                                                                                                                                                                           2 
##                                                                                                                                                             dau_tu_nam_giu_den_ngay_dao_han 
##                                                                                                                                                                                           2 
##                                                                                                                                                                 cac_khoan_phai_thu_ngan_han 
##                                                                                                                                                                                           0 
##                                                                                                                                                            phai_thu_ngan_han_cua_khach_hang 
##                                                                                                                                                                                           0 
##                                                                                                                                                            tra_truoc_cho_nguoi_ban_ngan_han 
##                                                                                                                                                                                           0 
##                                                                                                                                                                phai_thu_ve_cho_vay_ngan_han 
##                                                                                                                                                                                           2 
##                                                                                                                                                                      phai_thu_ngan_han_khac 
##                                                                                                                                                                                           0 
##                                                                                                                                                          du_phong_phai_thu_ngan_han_kho_doi 
##                                                                                                                                                                                           3 
##                                                                                                                                                                           tong_hang_ton_kho 
##                                                                                                                                                                                           0 
##                                                                                                                                                                                hang_ton_kho 
##                                                                                                                                                                                           0 
##                                                                                                                                                              du_phong_giam_gia_hang_ton_kho 
##                                                                                                                                                                                           3 
##                                                                                                                                                                       tai_san_ngan_han_khac 
##                                                                                                                                                                                           0 
##                                                                                                                                                                  chi_phi_tra_truoc_ngan_han 
##                                                                                                                                                                                           0 
##                                                                                                                                                         thue_gia_tri_gia_tang_duoc_khau_tru 
##                                                                                                                                                                                           0 
##                                                                                                                                                         thue_va_cac_khoan_phai_thu_nha_nuoc 
##                                                                                                                                                                                           2 
##                                                                                                                                                                             tai_san_dai_han 
##                                                                                                                                                                                           0 
##                                                                                                                                                                  cac_khoan_phai_thu_dai_han 
##                                                                                                                                                                                           3 
##                                                                                                                                                                 phai_thu_ve_cho_vay_dai_han 
##                                                                                                                                                                                           4 
##                                                                                                                                                                       phai_thu_dai_han_khac 
##                                                                                                                                                                                           3 
##                                                                                                                                                                             tai_san_co_dinh 
##                                                                                                                                                                                           0 
##                                                                                                                                                                    tai_san_co_dinh_huu_hinh 
##                                                                                                                                                                                           0 
##                                                                                                                                                                          nguyen_gia_tscd_hh 
##                                                                                                                                                                                           0 
##                                                                                                                                                                  gia_tri_khau_hao_luy_ke_28 
##                                                                                                                                                                                           0 
##                                                                                                                                                              tai_san_co_dinh_thue_tai_chinh 
##                                                                                                                                                                                           9 
##                                                                                                                                                        nguyen_gia_ts_co_dinh_thue_tai_chinh 
##                                                                                                                                                                                           9 
##                                                                                                                                                                   gia_tri_hao_mon_luy_ke_31 
##                                                                                                                                                                                           9 
##                                                                                                                                                                     tai_san_co_dinh_vo_hinh 
##                                                                                                                                                                                           0 
##                                                                                                                                                               nguyen_gia_ts_co_dinh_vo_hinh 
##                                                                                                                                                                                           0 
##                                                                                                                                                                   gia_tri_hao_mon_luy_ke_34 
##                                                                                                                                                                                           0 
##                                                                                                                                                                         bat_dong_san_dau_tu 
##                                                                                                                                                                                           4 
##                                                                                                                                                              nguyen_gia_bat_dong_san_dau_tu 
##                                                                                                                                                                                           4 
##                                                                                                                                                                  gia_tri_khau_hao_luy_ke_37 
##                                                                                                                                                                                           4 
##                                                                                                                                                                     tai_san_do_dang_dai_han 
##                                                                                                                                                                                           0 
##                                                                                                                                                             chi_phi_xay_dung_co_ban_do_dang 
##                                                                                                                                                                                           0 
##                                                                                                                                                                    dau_tu_tai_chinh_dai_han 
##                                                                                                                                                                                           1 
##                                                                                                                                                                 dau_tu_vao_cong_ty_lien_ket 
##                                                                                                                                                                                           2 
##                                                                                                                                                                      dau_tu_vao_don_vi_khac 
##                                                                                                                                                                                           6 
##                                                                                                                                                                        tai_san_dai_han_khac 
##                                                                                                                                                                                           0 
##                                                                                                                                                                   chi_phi_tra_truoc_dai_han 
##                                                                                                                                                                                           0 
##                                                                                                                                                              tai_san_thue_thu_nhap_hoan_lai 
##                                                                                                                                                                                           0 
##                                                                                                                                                                          loi_the_thuong_mai 
##                                                                                                                                                                                           5 
##                                                                                                                                                                           tong_cong_tai_san 
##                                                                                                                                                                                           0 
##                                                                                                                                                                                 no_phai_tra 
##                                                                                                                                                                                           0 
##                                                                                                                                                                                 no_ngan_han 
##                                                                                                                                                                                           0 
##                                                                                                                                                                 phai_tra_nguoi_ban_ngan_han 
##                                                                                                                                                                                           0 
##                                                                                                                                                           nguoi_mua_tra_tien_truoc_ngan_han 
##                                                                                                                                                                                           1 
##                                                                                                                                                         thue_va_cac_khoan_phai_nop_nha_nuoc 
##                                                                                                                                                                                           0 
##                                                                                                                                                                     phai_tra_nguoi_lao_dong 
##                                                                                                                                                                                           0 
##                                                                                                                                                                   chi_phi_phai_tra_ngan_han 
##                                                                                                                                                                                           0 
##                                                                                                                                                           doanh_thu_chua_thuc_hien_ngan_han 
##                                                                                                                                                                                           5 
##                                                                                                                                                                      phai_tra_ngan_han_khac 
##                                                                                                                                                                                           1 
##                                                                                                                                                           vay_va_no_thue_tai_chinh_ngan_han 
##                                                                                                                                                                                           0 
##                                                                                                                                                                    quy_khen_thuong_phuc_loi 
##                                                                                                                                                                                           0 
##                                                                                                                                                                                  no_dai_han 
##                                                                                                                                                                                           0 
##                                                                                                                                                            doanh_thu_chua_thuc_hien_dai_han 
##                                                                                                                                                                                           7 
##                                                                                                                                                                       phai_tra_dai_han_khac 
##                                                                                                                                                                                           4 
##                                                                                                                                                            vay_va_no_thue_tai_chinh_dai_han 
##                                                                                                                                                                                           0 
##                                                                                                                                                             thue_thu_nhap_hoan_lai_phai_tra 
##                                                                                                                                                                                           3 
##                                                                                                                                                                   du_phong_phai_tra_dai_han 
##                                                                                                                                                                                           8 
##                                                                                                                                                                         tong_von_chu_so_huu 
##                                                                                                                                                                                           0 
##                                                                                                                                                                              von_chu_so_huu 
##                                                                                                                                                                                           0 
##                                                                                                                                                                      von_gop_cua_chu_so_huu 
##                                                                                                                                                                                           0 
##                                                                                                                                                      co_phieu_pho_thong_co_quyen_bieu_quyet 
##                                                                                                                                                                                           0 
##                                                                                                                                                                        thang_du_von_co_phan 
##                                                                                                                                                                                           0 
##                                                                                                                                                                     von_khac_cua_chu_so_huu 
##                                                                                                                                                                                           5 
##                                                                                                                                                                  chenh_lech_ty_gia_hoi_doai 
##                                                                                                                                                                                           0 
##                                                                                                                                                                       quy_dau_tu_phat_trien 
##                                                                                                                                                                                           0 
##                                                                                                                                                               quy_khac_thuoc_von_chu_so_huu 
##                                                                                                                                                                                           0 
##                                                                                                                                                           loi_nhuan_sau_thue_chua_phan_phoi 
##                                                                                                                                                                                           0 
##                                                                                                                                        loi_nhuan_sau_thue_chua_phan_phoi_den_cuoi_nam_truoc 
##                                                                                                                                                                                           0 
##                                                                                                                                                   loi_nhuan_sau_thue_chua_phan_phoi_nam_nay 
##                                                                                                                                                                                           0 
##                                                                                                                                                             loi_ich_co_dong_khong_kiem_soat 
##                                                                                                                                                                                           0 
##                                                                                                                                                                         tong_cong_nguon_von 
##                                                                                                                                                                                           0 
##                                                                                                                                                      doanh_thu_ban_hang_va_cung_cap_dich_vu 
##                                                                                                                                                                                           0 
##                                                                                                                                                                cac_khoan_giam_tru_doanh_thu 
##                                                                                                                                                                                           0 
##                                                                                                                                             doanh_thu_thuan_ve_ban_hang_va_cung_cap_dich_vu 
##                                                                                                                                                                                           0 
##                                                                                                                                                                            gia_von_hang_ban 
##                                                                                                                                                                                           0 
##                                                                                                                                               loi_nhuan_gop_ve_ban_hang_va_cung_cap_dich_vu 
##                                                                                                                                                                                           0 
##                                                                                                                                                               doanh_thu_hoat_dong_tai_chinh 
##                                                                                                                                                                                           0 
##                                                                                                                                                                 chi_phi_hoat_dong_tai_chinh 
##                                                                                                                                                                                           0 
##                                                                                                                                                                    trong_do_chi_phi_lai_vay 
##                                                                                                                                                                                           0 
##                                                                                                                                                    lai_lo_trong_cong_ty_lien_ket_lien_doanh 
##                                                                                                                                                                                           2 
##                                                                                                                                                                            chi_phi_ban_hang 
##                                                                                                                                                                                           0 
##                                                                                                                                                                chi_phi_quan_ly_doanh_nghiep 
##                                                                                                                                                                                           0 
##                                                                                                                                                     loi_nhuan_thuan_tu_hoat_dong_kinh_doanh 
##                                                                                                                                                                                           0 
##                                                                                                                                                                               thu_nhap_khac 
##                                                                                                                                                                                           0 
##                                                                                                                                                                                chi_phi_khac 
##                                                                                                                                                                                           0 
##                                                                                                                                                                           lo_loi_nhuan_khac 
##                                                                                                                                                                                           0 
##                                                                                                                                                           tong_loi_nhuan_ke_toan_truoc_thue 
##                                                                                                                                                                                           0 
##                                                                                                                                                                 chi_phi_thue_tndn_hien_hanh 
##                                                                                                                                                                                           0 
##                                                                                                                                                         chi_phi_thu_nhap_thue_tndn_hoan_lai 
##                                                                                                                                                                                           0 
##                                                                                                                                                    loi_nhuan_sau_thue_thu_nhap_doanh_nghiep 
##                                                                                                                                                                                           0 
##                                                                                                                                                           loi_nhuan_sau_thue_cua_cong_ty_me 
##                                                                                                                                                                                           0 
##                                                                                                                                           lo_loi_nhuan_sau_thue_cua_co_dong_khong_kiem_soat 
##                                                                                                                                                                                           0 
##                                                                                                                                                                    lai_co_ban_tren_co_phieu 
##                                                                                                                                                                                           0 
##                                                                                                                                                                  lai_suy_giam_tren_co_phieu 
##                                                                                                                                                                                           1 
##                                                                                                                                                                loi_nhuan_ke_toan_truoc_thue 
##                                                                                                                                                                                           0 
## khau_hao_tai_san_co_dinh_huu_hinh_va_bat_dong_san_dau_tu_va_tai_san_co_dinh_thue_tai_chinh_va_hao_mon_tai_san_co_dinh_vo_hinh_bao_gom_phan_bo_loi_the_thuong_mai_va_tien_thue_dat_tra_truoc 
##                                                                                                                                                                                           0 
##                                                                                                                                                                trich_lap_hoan_nhap_du_phong 
##                                                                                                                                                                                           2 
##                                                                                                     lai_lo_chenh_lech_ty_gia_hoi_doai_do_danh_gia_lai_cac_khoan_muc_tien_te_co_goc_ngoai_te 
##                                                                                                                                                                                           0 
##                                                                                                                                                                  lai_lo_tu_hoat_dong_dau_tu 
##                                                                                                                                                                                           0 
##                                                                                                                                        chi_phi_lai_vay_bao_gom_chi_phi_phat_hanh_trai_phieu 
##                                                                                                                                                                                           0 
##                                                                                                                         luu_chuyen_tien_tu_hoat_dong_kinh_doanh_truoc_thay_doi_von_luu_dong 
##                                                                                                                                                                                           0 
##                                                                                                                                                                tang_giam_cac_khoan_phai_thu 
##                                                                                                                                                                                           0 
##                                                                                                                                                                      tang_giam_hang_ton_kho 
##                                                                                                                                                                                           0 
##                                                                                                                                                                tang_giam_cac_khoan_phai_tra 
##                                                                                                                                                                                           0 
##                                                                                                                                                                 tang_giam_chi_phi_tra_truoc 
##                                                                                                                                                                                           0 
##                                                                                                                                                                         tien_lai_vay_da_tra 
##                                                                                                                                                                                           0 
##                                                                                                                                                           thue_thu_nhap_doanh_nghiep_da_nop 
##                                                                                                                                                                                           0 
##                                                                                                                                                       tien_thu_khac_tu_hoat_dong_kinh_doanh 
##                                                                                                                                                                                           6 
##                                                                                                                                                       tien_chi_khac_tu_hoat_dong_kinh_doanh 
##                                                                                                                                                                                           0 
##                                                                                                                                               luu_chuyen_tien_thuan_tu_hoat_dong_kinh_doanh 
##                                                                                                                                                                                           0 
##                                                                                                                                          tien_chi_de_mua_sam_xay_dung_tscd_va_cac_tsdh_khac 
##                                                                                                                                                                                           0 
##                                                                                                                                       tien_thu_do_thanh_ly_nhuong_ban_tscd_va_cac_tsdh_khac 
##                                                                                                                                                                                           1 
##                                                                                                                                      tien_chi_cho_vay_va_mua_cong_cu_no_cua_cac_don_vi_khac 
##                                                                                                                                                                                           2 
##                                                                                                                                 tien_thu_hoi_cho_vay_ban_lai_cac_cong_cu_no_cua_don_vi_khac 
##                                                                                                                                                                                           0 
##                                                                                                                                     tien_chi_dau_tu_gop_von_vao_don_vi_khac_tru_tien_thu_ve 
##                                                                                                                                                                                           3 
##                                                                                                                                                 tien_thu_hoi_dau_tu_gop_von_vao_don_vi_khac 
##                                                                                                                                                                                           2 
##                                                                                                                                          tien_thu_lai_cho_vay_co_tuc_va_loi_nhuan_duoc_chia 
##                                                                                                                                                                                           1 
##                                                                                                                                                   luu_chuyen_tien_thuan_tu_hoat_dong_dau_tu 
##                                                                                                                                                                                           0 
##                                                                                                                                                                          tien_thu_tu_di_vay 
##                                                                                                                                                                                           0 
##                                                                                                                                                                         tien_tra_no_goc_vay 
##                                                                                                                                                                                           0 
##                                                                                                                                                              tien_tra_no_goc_thue_tai_chinh 
##                                                                                                                                                                                          10 
##                                                                                                                                                      co_tuc_loi_nhuan_da_tra_cho_chu_so_huu 
##                                                                                                                                                                                           0 
##                                                                                                                                                luu_chuyen_tien_thuan_tu_hoat_dong_tai_chinh 
##                                                                                                                                                                                           0 
##                                                                                                                                                             luu_chuyen_tien_thuan_trong_nam 
##                                                                                                                                                                                           0 
##                                                                                                                                                            tien_va_tuong_duong_tien_dau_nam 
##                                                                                                                                                                                           0 
##                                                                                                                                     anh_huong_cua_thay_doi_ty_gia_hoi_doai_quy_doi_ngoai_te 
##                                                                                                                                                                                           0 
##                                                                                                                                                           tien_va_tuong_duong_tien_cuoi_nam 
##                                                                                                                                                                                           0

Các mã này tiếp tục quá trình khám phá dữ liệu, tập trung vào việc tóm tắt nội dung và phát hiện giá trị thiếu. Hàm is.na() trả về TRUE cho mỗi ô bị trống (NA) và FALSE nếu ngược lại. Hàm sum() coi TRUE=1 và FALSE=0, vì vậy nó đếm tổng số ô NA trong toàn bộ data frame.

Kết quả cho thấy có 144 ô dữ liệu bị thiếu. Trong BCTC, NA thường có nghĩa là “chỉ tiêu này không phát sinh trong kỳ” hoặc “giá trị bằng 0”. Chúng ta cần một chiến lược để xử lý các giá trị này.

Hàm colSums() tính tổng (trong trường hợp này là đếm NA) cho từng cột. Giúp xác định cột nào đang bị thiếu dữ liệu. Ví dụ, cột “Đầu tư nắm giữ đến ngày đáo hạn” bị thiếu 8/10 giá trị, cho thấy đây là chỉ tiêu không thường xuyên phát sinh. Các cột chính như “TÀI SẢN NGẮN HẠN” có 0 NA, cho thấy tính toàn vẹn của dữ liệu cốt lõi.

Chuyển tất cả các cột chữ số thành numeric (nếu bị đọc nhầm)

df_bctc <- df_bctc %>%
  mutate(across(
    where(is.character),
    ~as.numeric(gsub(",", "", .))  
  ))
## Warning: There were 3 warnings in `mutate()`.
## The first warning was:
## ℹ In argument: `across(where(is.character), ~as.numeric(gsub(",", "", .)))`.
## Caused by warning:
## ! NAs introduced by coercion
## ℹ Run `dplyr::last_dplyr_warnings()` to see the 2 remaining warnings.

Các cột chứa dữ liệu dạng ký tự (character) nhưng thực chất là số được chuyển đổi về dạng số (numeric) bằng hàm mutate(across(where(is.character), ~as.numeric(gsub(“,”, ““, .)))). Việc loại bỏ dấu phẩy và chuyển đổi kiểu dữ liệu giúp đảm bảo toàn bộ biến định lượng được xử lý đúng trong các phép tính sau này.

Chuyển những giá trị Na bằng 0

df_bctc <- df_bctc %>%
  mutate(across(everything(), ~replace_na(., 0)))

Về mặt giá trị dữ liệu, các ô trống hoặc giá trị thiếu (NA) được thay thế bằng 0 thông qua hàm mutate(across(…, ~replace_na(., 0))). Đây là bước quan trọng nhằm tránh sai số trong quá trình tính toán thống kê, đặc biệt khi xử lý các phép toán tổng hợp, trung bình hoặc tỷ lệ.

2.4. Lọc và giới thiệu 10 biến tài chính

2.4.1. Lấy 10 Biến Phân Tích Cốt Lõi

Sau khi dữ liệu tài chính được làm sạch và chuẩn hóa, bước tiếp theo là lựa chọn những biến (chỉ tiêu) trọng yếu nhằm phục vụ cho việc phân tích tài chính và đánh giá hiệu quả hoạt động của doanh nghiệp. Việc lựa chọn này giúp tập trung vào các yếu tố có ảnh hưởng lớn nhất đến hiệu quả kinh doanh và khả năng thanh toán, đồng thời giảm độ phức tạp của mô hình phân tích.

Đoạn mã R sau được sử dụng để lấy 10 biến tài chính cốt lõi từ bảng dữ liệu tổng hợp df_bctc:

df_bctc %>%
  select(
    nam,  # Biến thời gian

    # Nhóm Sinh lời
    loi_nhuan_sau_thue_cua_cong_ty_me,
    doanh_thu_thuan_ve_ban_hang_va_cung_cap_dich_vu,
    loi_nhuan_gop_ve_ban_hang_va_cung_cap_dich_vu,

    # Nhóm Thanh khoản & Nợ
    tai_san_ngan_han,
    no_ngan_han,

    # Nhóm Cấu trúc Vốn & Quy mô
    tong_von_chu_so_huu,
    tong_cong_tai_san,
    no_phai_tra,

    # Dòng tiền & Hiệu quả hoạt động
    hang_ton_kho,
    luu_chuyen_tien_thuan_tu_hoat_dong_kinh_doanh
  ) %>%
  head(10)
## # A tibble: 10 × 11
##      nam loi_nhuan_sau_thue_cua_…¹ doanh_thu_thuan_ve_b…² loi_nhuan_gop_ve_ban…³
##    <dbl>                     <dbl>                  <dbl>                  <dbl>
##  1  2015               40015870985                1.61e12           189807791166
##  2  2016              141985475965                2.14e12           307035411700
##  3  2017              223342661746                4.07e12           550385105168
##  4  2018              180260475000                8.01e12           672936073191
##  5  2019              460465909779                9.26e12          1042139378567
##  6  2020              262240818737                7.43e12           776935221364
##  7  2021              290241012297                1.31e13          1301375383462
##  8  2022              152599331716                1.53e13          1086239883713
##  9  2023              289410548684                1.26e13          1108693322770
## 10  2024              368580504091                1.28e13          1484105506165
## # ℹ abbreviated names: ¹​loi_nhuan_sau_thue_cua_cong_ty_me,
## #   ²​doanh_thu_thuan_ve_ban_hang_va_cung_cap_dich_vu,
## #   ³​loi_nhuan_gop_ve_ban_hang_va_cung_cap_dich_vu
## # ℹ 7 more variables: tai_san_ngan_han <dbl>, no_ngan_han <dbl>,
## #   tong_von_chu_so_huu <dbl>, tong_cong_tai_san <dbl>, no_phai_tra <dbl>,
## #   hang_ton_kho <dbl>, luu_chuyen_tien_thuan_tu_hoat_dong_kinh_doanh <dbl>

Về mặt kỹ thuật, hàm select() thuộc gói dplyr được sử dụng để trích lọc các cột cần thiết từ bộ dữ liệu gốc. Việc lưu kết quả vào biến mới df_10bien giúp thuận tiện cho các bước phân tích sau mà không làm thay đổi dữ liệu gốc df_bctc. Ngoài ra, cột nam được giữ lại nhằm mục đích nhận diện thời gian, phục vụ cho việc phân tích chuỗi thời gian (time series) và so sánh theo năm.

Các biến được chọn được chia thành bốn nhóm chỉ tiêu tài chính chính:

Nhóm Sinh lời: gồm loi_nhuan_sau_thue_cua_cong_ty_me, doanh_thu_thuan_ve_ban_hang_va_cung_cap_dich_vu, và loi_nhuan_gop_ve_ban_hang_va_cung_cap_dich_vu. Nhóm này phản ánh khả năng tạo ra lợi nhuận của doanh nghiệp, là cơ sở để tính các chỉ tiêu hiệu quả như ROS, ROA hay ROE.

Nhóm Thanh khoản và Nợ: gồm tai_san_ngan_han và no_ngan_han, giúp đánh giá khả năng thanh toán ngắn hạn thông qua các hệ số như hệ số thanh toán hiện hành và thanh toán nhanh.

Nhóm Cấu trúc vốn và Quy mô: bao gồm tong_von_chu_so_huu, tong_cong_tai_san và no_phai_tra. Đây là những biến phản ánh quy mô tài sản, mức độ tự chủ tài chính và đòn bẩy nợ của doanh nghiệp.

Nhóm Dòng tiền & Hiệu quả hoạt động: gồm hang_ton_kho và luu_chuyen_tien_thuan_tu_hoat_dong_kinh_doanh, được dùng để đánh giá khả năng chuyển hóa tài sản lưu động thành tiền mặt và hiệu quả vận hành trong kỳ.

Về mặt thống kê, việc chọn lọc các biến đại diện này giúp thu gọn dữ liệu về dạng mẫu nhỏ gọn nhưng mang tính tổng quát cao, thuận tiện cho việc mô hình hóa, trực quan hóa và phân tích tương quan sau này. Đồng thời, việc giữ lại các nhóm biến có tính chất khác nhau (sinh lời, thanh khoản, vốn, dòng tiền) giúp đảm bảo phân tích được thực hiện toàn diện trên nhiều khía cạnh của hoạt động tài chính doanh nghiệp.

df_10bien <- df_bctc %>% 
  select(
    nam,
    loi_nhuan_sau_thue_cua_cong_ty_me,
    doanh_thu_thuan_ve_ban_hang_va_cung_cap_dich_vu,
    loi_nhuan_gop_ve_ban_hang_va_cung_cap_dich_vu,
    tai_san_ngan_han,
    no_ngan_han,
    tong_von_chu_so_huu,
    tong_cong_tai_san,
    no_phai_tra,
    hang_ton_kho,
    luu_chuyen_tien_thuan_tu_hoat_dong_kinh_doanh
  )

2.4.2. Giới thiệu sơ bộ 10 biến tài chính

Sau khi đã lựa chọn 10 biến tài chính cốt lõi, bước tiếp theo là kiểm tra và giới thiệu cấu trúc tổng quan của tập dữ liệu df_10bien. Mục tiêu của bước này là đảm bảo rằng dữ liệu được đọc đúng định dạng, có đầy đủ thông tin cần thiết, và sẵn sàng cho các bước phân tích thống kê mô tả sau.

Kiểm tra kiểu dữ liệu của từng biến

str(df_10bien)
## tibble [10 × 11] (S3: tbl_df/tbl/data.frame)
##  $ nam                                            : num [1:10] 2015 2016 2017 2018 2019 ...
##  $ loi_nhuan_sau_thue_cua_cong_ty_me              : num [1:10] 4.00e+10 1.42e+11 2.23e+11 1.80e+11 4.60e+11 ...
##  $ doanh_thu_thuan_ve_ban_hang_va_cung_cap_dich_vu: num [1:10] 1.61e+12 2.14e+12 4.07e+12 8.01e+12 9.26e+12 ...
##  $ loi_nhuan_gop_ve_ban_hang_va_cung_cap_dich_vu  : num [1:10] 1.90e+11 3.07e+11 5.50e+11 6.73e+11 1.04e+12 ...
##  $ tai_san_ngan_han                               : num [1:10] 1.07e+12 1.36e+12 2.14e+12 3.99e+12 4.97e+12 ...
##  $ no_ngan_han                                    : num [1:10] 6.67e+11 1.14e+12 1.99e+12 3.21e+12 3.24e+12 ...
##  $ tong_von_chu_so_huu                            : num [1:10] 8.19e+11 9.55e+11 1.62e+12 2.98e+12 3.26e+12 ...
##  $ tong_cong_tai_san                              : num [1:10] 1.95e+12 3.08e+12 4.58e+12 7.53e+12 7.99e+12 ...
##  $ no_phai_tra                                    : num [1:10] 1.14e+12 2.12e+12 2.95e+12 4.55e+12 4.73e+12 ...
##  $ hang_ton_kho                                   : num [1:10] 2.14e+11 4.51e+11 5.37e+11 8.65e+11 1.22e+12 ...
##  $ luu_chuyen_tien_thuan_tu_hoat_dong_kinh_doanh  : num [1:10] -7.33e+10 8.02e+10 -8.07e+10 3.85e+10 4.89e+11 ...

Hàm str() (structure) được dùng để hiển thị cấu trúc chi tiết của bảng dữ liệu — bao gồm loại dữ liệu (numeric, character, factor,…) và vài giá trị đầu tiên của mỗi cột. Về mặt kỹ thuật, đây là cách nhanh chóng để xác định xem các biến định lượng (như doanh_thu_thuan_ve_ban_hang_va_cung_cap_dich_vu, loi_nhuan_sau_thue_cua_cong_ty_me) có đang ở dạng số thực (numeric) hay không, đồng thời phát hiện các biến bị đọc sai kiểu dữ liệu (ví dụ dạng ký tự). Bước này giúp đảm bảo tính tương thích trong các phép toán thống kê sau.

Xem nhanh cấu trúc dữ liệu

glimpse(df_10bien)
## Rows: 10
## Columns: 11
## $ nam                                             <dbl> 2015, 2016, 2017, 2018…
## $ loi_nhuan_sau_thue_cua_cong_ty_me               <dbl> 40015870985, 141985475…
## $ doanh_thu_thuan_ve_ban_hang_va_cung_cap_dich_vu <dbl> 1.614549e+12, 2.143770…
## $ loi_nhuan_gop_ve_ban_hang_va_cung_cap_dich_vu   <dbl> 1.898078e+11, 3.070354…
## $ tai_san_ngan_han                                <dbl> 1.071561e+12, 1.361646…
## $ no_ngan_han                                     <dbl> 6.670792e+11, 1.140285…
## $ tong_von_chu_so_huu                             <dbl> 8.194853e+11, 9.547521…
## $ tong_cong_tai_san                               <dbl> 1.954765e+12, 3.077616…
## $ no_phai_tra                                     <dbl> 1.135279e+12, 2.122864…
## $ hang_ton_kho                                    <dbl> 2.141866e+11, 4.505913…
## $ luu_chuyen_tien_thuan_tu_hoat_dong_kinh_doanh   <dbl> -73349077150, 80169554…

Hàm glimpse() thuộc gói dplyr có chức năng tương tự str(), nhưng hiển thị thông tin theo chiều ngang, giúp dễ quan sát khi làm việc với bảng dữ liệu có nhiều cột. Kết quả trả về bao gồm: số lượng dòng, số cột, tên từng biến và kiểu dữ liệu tương ứng. Đây là cách trình bày thân thiện, phù hợp cho việc khảo sát tổng quan dữ liệu tài chính trước khi phân tích chi tiết.

Danh sách tên biến

colnames(df_10bien)
##  [1] "nam"                                            
##  [2] "loi_nhuan_sau_thue_cua_cong_ty_me"              
##  [3] "doanh_thu_thuan_ve_ban_hang_va_cung_cap_dich_vu"
##  [4] "loi_nhuan_gop_ve_ban_hang_va_cung_cap_dich_vu"  
##  [5] "tai_san_ngan_han"                               
##  [6] "no_ngan_han"                                    
##  [7] "tong_von_chu_so_huu"                            
##  [8] "tong_cong_tai_san"                              
##  [9] "no_phai_tra"                                    
## [10] "hang_ton_kho"                                   
## [11] "luu_chuyen_tien_thuan_tu_hoat_dong_kinh_doanh"

Hàm colnames() hiển thị danh sách tên các biến (cột) trong bảng dữ liệu. Mục đích kỹ thuật là để đảm bảo rằng các tên cột đã được chuẩn hóa chính xác (viết thường, không dấu, có gạch dưới). Việc kiểm tra này đặc biệt quan trọng sau khi làm sạch dữ liệu, giúp tránh lỗi khi gọi tên biến trong các bước tính toán và vẽ biểu đồ.

Kiểm tra tổng số dòng và số biến

dim(df_10bien)
## [1] 10 11
nrow(df_10bien) 
## [1] 10
ncol(df_10bien)
## [1] 11

Các hàm trên được dùng để xác định kích thước của bảng dữ liệu, bao gồm số dòng (nrow – số quan sát) và số cột (ncol – số biến). Về mặt thống kê, việc xác định kích thước giúp đánh giá mức độ đầy đủ của dữ liệu, ví dụ: dữ liệu có đủ chuỗi thời gian hay số năm quan sát hay không. Điều này đặc biệt quan trọng trong phân tích tài chính, nơi tính liên tục của chuỗi số liệu có thể ảnh hưởng đến độ tin cậy của kết quả.

Tên các cột

names(df_10bien)
##  [1] "nam"                                            
##  [2] "loi_nhuan_sau_thue_cua_cong_ty_me"              
##  [3] "doanh_thu_thuan_ve_ban_hang_va_cung_cap_dich_vu"
##  [4] "loi_nhuan_gop_ve_ban_hang_va_cung_cap_dich_vu"  
##  [5] "tai_san_ngan_han"                               
##  [6] "no_ngan_han"                                    
##  [7] "tong_von_chu_so_huu"                            
##  [8] "tong_cong_tai_san"                              
##  [9] "no_phai_tra"                                    
## [10] "hang_ton_kho"                                   
## [11] "luu_chuyen_tien_thuan_tu_hoat_dong_kinh_doanh"

Hàm names() hoạt động tương tự colnames(), giúp hiển thị danh sách tên biến trong dữ liệu. Thông thường, bước này được thực hiện nhằm xác nhận rằng dữ liệu đã giữ đúng thứ tự và cấu trúc mong muốn sau các bước lọc hoặc chọn biến. Về mặt kỹ thuật, đây là thao tác kiểm tra tính toàn vẹn cấu trúc dữ liệu.

5 Hàng đầu tiên

head(df_10bien)
## # A tibble: 6 × 11
##     nam loi_nhuan_sau_thue_cua_c…¹ doanh_thu_thuan_ve_b…² loi_nhuan_gop_ve_ban…³
##   <dbl>                      <dbl>                  <dbl>                  <dbl>
## 1  2015                40015870985          1614548947901           189807791166
## 2  2016               141985475965          2143769808850           307035411700
## 3  2017               223342661746          4069608303141           550385105168
## 4  2018               180260475000          8011572613389           672936073191
## 5  2019               460465909779          9258073280674          1042139378567
## 6  2020               262240818737          7428557015044           776935221364
## # ℹ abbreviated names: ¹​loi_nhuan_sau_thue_cua_cong_ty_me,
## #   ²​doanh_thu_thuan_ve_ban_hang_va_cung_cap_dich_vu,
## #   ³​loi_nhuan_gop_ve_ban_hang_va_cung_cap_dich_vu
## # ℹ 7 more variables: tai_san_ngan_han <dbl>, no_ngan_han <dbl>,
## #   tong_von_chu_so_huu <dbl>, tong_cong_tai_san <dbl>, no_phai_tra <dbl>,
## #   hang_ton_kho <dbl>, luu_chuyen_tien_thuan_tu_hoat_dong_kinh_doanh <dbl>

Hàm head() giúp xem trước một số dòng đầu tiên của bảng dữ liệu. Đây là một thao tác quan trọng trong quá trình khám phá dữ liệu (data exploration), nhằm phát hiện nhanh các vấn đề như giá trị bị thiếu, sai định dạng, hoặc các ngoại lệ bất thường. Về mặt thống kê, bước này giúp xác định được phạm vi giá trị hợp lý của từng biến (ví dụ, doanh thu, lợi nhuận, tổng tài sản,… có tương thích về quy mô hay không).

Kiểm tra khoảng thời gian dữ liệu

df_10bien %>% summarise(nam_bat_dau = min(nam), nam_ket_thuc = max(nam))
## # A tibble: 1 × 2
##   nam_bat_dau nam_ket_thuc
##         <dbl>        <dbl>
## 1        2015         2024

Đoạn mã này tính năm bắt đầu và năm kết thúc của chuỗi dữ liệu bằng cách dùng hàm summarise() kết hợp với min() và max(). Kỹ thuật này cho phép xác định phạm vi thời gian bao phủ của dữ liệu – ví dụ, dữ liệu có trải dài từ 2010 đến 2024 hay không. Từ góc nhìn thống kê, đây là thông tin quan trọng để đảm bảo tính liên tục của chuỗi thời gian, giúp các phân tích xu hướng hoặc hồi quy theo năm trở nên đáng tin cậy.

2.5. Xử lý thô và mã hóa dữ liệu cho 10 biến

2.5.1. Xử lý thô

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

df_10bien$nam <- as.integer(df_10bien$nam)
head(df_10bien)
## # A tibble: 6 × 11
##     nam loi_nhuan_sau_thue_cua_c…¹ doanh_thu_thuan_ve_b…² loi_nhuan_gop_ve_ban…³
##   <int>                      <dbl>                  <dbl>                  <dbl>
## 1  2015                40015870985          1614548947901           189807791166
## 2  2016               141985475965          2143769808850           307035411700
## 3  2017               223342661746          4069608303141           550385105168
## 4  2018               180260475000          8011572613389           672936073191
## 5  2019               460465909779          9258073280674          1042139378567
## 6  2020               262240818737          7428557015044           776935221364
## # ℹ abbreviated names: ¹​loi_nhuan_sau_thue_cua_cong_ty_me,
## #   ²​doanh_thu_thuan_ve_ban_hang_va_cung_cap_dich_vu,
## #   ³​loi_nhuan_gop_ve_ban_hang_va_cung_cap_dich_vu
## # ℹ 7 more variables: tai_san_ngan_han <dbl>, no_ngan_han <dbl>,
## #   tong_von_chu_so_huu <dbl>, tong_cong_tai_san <dbl>, no_phai_tra <dbl>,
## #   hang_ton_kho <dbl>, luu_chuyen_tien_thuan_tu_hoat_dong_kinh_doanh <dbl>

Trong bước đầu tiên, biến nam được chuyển đổi về dạng số nguyên (integer) bằng hàm as.integer(). Về mặt kỹ thuật, điều này đảm bảo rằng biến thời gian được R hiểu đúng là dữ liệu định lượng rời rạc, giúp thuận tiện cho việc sắp xếp, lọc hoặc tính toán xu hướng theo năm. Nếu để ở dạng ký tự, các phép thống kê và mô hình hồi quy sau này sẽ không thể thực hiện chính xác. Khi hiển thị bằng head(df_10bien), ta có thể thấy các giá trị năm được trình bày dưới dạng số, đảm bảo tính chính xác cho phân tích chuỗi thời gian.

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

sum(is.na(df_10bien))
## [1] 0

Để đảm bảo dữ liệu hoàn chỉnh, hàm is.na() được sử dụng nhằm xác định các giá trị bị thiếu (NA), sau đó tổng hợp bằng sum() để đếm tổng số lượng. Kết quả trả về là 0, chứng tỏ bộ dữ liệu 10 biến hoàn toàn không có giá trị thiếu. Về mặt thống kê, đây là điều kiện lý tưởng vì giúp đảm bảo tính toàn vẹn và độ tin cậy trong các phép tính tổng hợp (mean, median, variance,…) và mô hình hóa sau này.

Kiểm tra và xử lý giá trị bị lặp dòng

df_10bien <- df_10bien |> distinct()

Hàm distinct() (thuộc gói dplyr) được dùng để loại bỏ các bản ghi trùng lặp hoàn toàn trong bộ dữ liệu. Việc kiểm tra trùng lặp là cần thiết trong phân tích tài chính, bởi các dữ liệu bị lặp có thể gây sai lệch trong thống kê trung bình hoặc hồi quy, đặc biệt khi các năm hoặc chỉ tiêu được ghi trùng. Bước này giúp đảm bảo mỗi hàng dữ liệu tương ứng với một quan sát duy nhất theo từng năm, đảm bảo tính độc lập của mẫu thống kê.

Chuẩn hoá đơn vị: chuyển từ đồng sang tỷ đồng

df_10bien <- df_10bien |> 
  mutate(across(-nam, ~./1e9)) 
head(df_10bien)
## # A tibble: 6 × 11
##     nam loi_nhuan_sau_thue_cua_c…¹ doanh_thu_thuan_ve_b…² loi_nhuan_gop_ve_ban…³
##   <int>                      <dbl>                  <dbl>                  <dbl>
## 1  2015                       40.0                  1615.                   190.
## 2  2016                      142.                   2144.                   307.
## 3  2017                      223.                   4070.                   550.
## 4  2018                      180.                   8012.                   673.
## 5  2019                      460.                   9258.                  1042.
## 6  2020                      262.                   7429.                   777.
## # ℹ abbreviated names: ¹​loi_nhuan_sau_thue_cua_cong_ty_me,
## #   ²​doanh_thu_thuan_ve_ban_hang_va_cung_cap_dich_vu,
## #   ³​loi_nhuan_gop_ve_ban_hang_va_cung_cap_dich_vu
## # ℹ 7 more variables: tai_san_ngan_han <dbl>, no_ngan_han <dbl>,
## #   tong_von_chu_so_huu <dbl>, tong_cong_tai_san <dbl>, no_phai_tra <dbl>,
## #   hang_ton_kho <dbl>, luu_chuyen_tien_thuan_tu_hoat_dong_kinh_doanh <dbl>

Trong bước này, các biến tài chính (ngoại trừ nam) được chia cho 1e9 nhằm chuyển đổi đơn vị từ đồng sang tỷ đồng. Kỹ thuật này được thực hiện bằng mutate() kết hợp across() để áp dụng cùng một phép biến đổi cho nhiều cột một cách tự động. Việc chuẩn hóa đơn vị không chỉ giúp dữ liệu dễ đọc hơn, mà còn tránh tình trạng sai lệch tỷ lệ khi trực quan hóa bằng biểu đồ hoặc mô hình hồi quy. Về mặt thống kê, thao tác này giúp duy trì tính tỷ lệ tương đối giữa các biến mà không ảnh hưởng đến kết quả phân tích, đồng thời cải thiện khả năng diễn giải kinh tế sau này.

2.5.2. Chuẩn hóa tên & cấu trúc dữ liệu

Sau khi dữ liệu được làm sạch và xử lý định dạng, bước tiếp theo là chuẩn hóa tên biến để đảm bảo tính nhất quán và dễ thao tác trong quá trình lập trình và trực quan hóa. Việc sử dụng các tên ngắn gọn, có quy tắc giúp cho việc gọi biến, lọc hoặc tính toán trở nên thuận tiện và giảm thiểu sai sót cú pháp.

Đổi tên biến

colnames(df_10bien) <- c("nam", "LNST", "DoanhThu", "LoiNhuanGop",
"TSNganHan", "NoNganHan", "VonChuSoHuu",
"TongTaiSan", "NoPhaiTra", "HangTonKho",
"TienThuanHDKD", "id")
head(df_10bien)
## # A tibble: 6 × 11
##     nam  LNST DoanhThu LoiNhuanGop TSNganHan NoNganHan VonChuSoHuu TongTaiSan
##   <int> <dbl>    <dbl>       <dbl>     <dbl>     <dbl>       <dbl>      <dbl>
## 1  2015  40.0    1615.        190.     1072.      667.        819.      1955.
## 2  2016 142.     2144.        307.     1362.     1140.        955.      3078.
## 3  2017 223.     4070.        550.     2143.     1991.       1625.      4576.
## 4  2018 180.     8012.        673.     3989.     3206.       2980.      7529.
## 5  2019 460.     9258.       1042.     4971.     3237.       3255.      7987.
## 6  2020 262.     7429.        777.     4496.     3773.       4024.      8569.
## # ℹ 3 more variables: NoPhaiTra <dbl>, HangTonKho <dbl>, TienThuanHDKD <dbl>

Lệnh colnames() được dùng để gán lại tên cột cho bảng dữ liệu df_10bien. Các tên mới được viết tắt nhưng vẫn đảm bảo dễ hiểu, ví dụ:

LNST (Lợi nhuận sau thuế),

TSNganHan (Tài sản ngắn hạn),

TienThuanHKD (Dòng tiền thuần từ hoạt động kinh doanh).

Việc chuẩn hóa này giúp dữ liệu có cấu trúc rõ ràng hơn, phục vụ cho các bước tính toán và mô hình hóa tiếp theo.

2.5.3. Tạo biến mới

Tạo biến Biên lợi nhuận gộp = Lợi nhuận gộp / Doanh thu

df_10bien <- df_10bien %>%
mutate(GPM = LoiNhuanGop / DoanhThu)

df_10bien %>% select(nam, LoiNhuanGop, DoanhThu, GPM) %>% head()
## # A tibble: 6 × 4
##     nam LoiNhuanGop DoanhThu    GPM
##   <int>       <dbl>    <dbl>  <dbl>
## 1  2015        190.    1615. 0.118 
## 2  2016        307.    2144. 0.143 
## 3  2017        550.    4070. 0.135 
## 4  2018        673.    8012. 0.0840
## 5  2019       1042.    9258. 0.113 
## 6  2020        777.    7429. 0.105

Biến GPM thể hiện mức lợi nhuận còn lại sau khi trừ chi phí sản xuất trực tiếp. Về mặt thống kê, đây là chỉ tiêu quan trọng để phân tích hiệu quả sản xuất và định giá bán, cho thấy khả năng tạo lợi nhuận trước chi phí quản lý và tài chính. Kỹ thuật tính tương tự như trên, đảm bảo đồng nhất cấu trúc dữ liệu.

Tạo hệ số nợ trên vốn chủ sở hữu = Nợ phải trả / Vốn CSH

df_10bien <- df_10bien %>%
mutate(DE_Ratio = NoPhaiTra / VonChuSoHuu)

df_10bien %>% select(nam, NoPhaiTra, VonChuSoHuu, DE_Ratio) %>% head()
## # A tibble: 6 × 4
##     nam NoPhaiTra VonChuSoHuu DE_Ratio
##   <int>     <dbl>       <dbl>    <dbl>
## 1  2015     1135.        819.     1.39
## 2  2016     2123.        955.     2.22
## 3  2017     2951.       1625.     1.82
## 4  2018     4549.       2980.     1.53
## 5  2019     4732.       3255.     1.45
## 6  2020     4545.       4024.     1.13

Biến DE_Ratio được tính bằng tổng nợ phải trả chia cho vốn chủ sở hữu, là chỉ tiêu đo lường mức độ đòn bẩy tài chính. Về kỹ thuật, hàm mutate() tự động tính toán theo hàng (row-wise) và tạo cột mới trong bảng. Chỉ tiêu này cho biết doanh nghiệp đang tài trợ cho tài sản của mình bằng vốn vay hay vốn chủ, và giúp đánh giá mức độ rủi ro tài chính.

Tạo chỉ số thanh khoản hiện thời = Tài sản NH / Nợ NH

df_10bien <- df_10bien %>%
mutate(CurrentRatio = TSNganHan / NoNganHan)

df_10bien %>% select(nam, TSNganHan, NoNganHan, CurrentRatio) %>% head()
## # A tibble: 6 × 4
##     nam TSNganHan NoNganHan CurrentRatio
##   <int>     <dbl>     <dbl>        <dbl>
## 1  2015     1072.      667.         1.61
## 2  2016     1362.     1140.         1.19
## 3  2017     2143.     1991.         1.08
## 4  2018     3989.     3206.         1.24
## 5  2019     4971.     3237.         1.54
## 6  2020     4496.     3773.         1.19

Chỉ tiêu CurrentRatio phản ánh khả năng thanh toán ngắn hạn của doanh nghiệp, tức là khả năng chuyển tài sản ngắn hạn thành tiền để trả nợ ngắn hạn. Từ góc độ thống kê, chỉ số này cung cấp thông tin về sự an toàn tài chính ngắn hạn, thường được so sánh với mức chuẩn để xác định mức độ rủi ro thanh khoản.

Tỷ lệ hàng tồn kho / Tổng tài sản

df_10bien <- df_10bien %>%
mutate(ton_kho_taisan = HangTonKho / TongTaiSan)

df_10bien %>% select(nam, HangTonKho, TongTaiSan, ton_kho_taisan) %>% head()
## # A tibble: 6 × 4
##     nam HangTonKho TongTaiSan ton_kho_taisan
##   <int>      <dbl>      <dbl>          <dbl>
## 1  2015       214.      1955.          0.110
## 2  2016       451.      3078.          0.146
## 3  2017       537.      4576.          0.117
## 4  2018       865.      7529.          0.115
## 5  2019      1222.      7987.          0.153
## 6  2020       947.      8569.          0.111

Biến ton_kho_taisan cho thấy tỷ trọng hàng tồn kho trong tổng giá trị tài sản. Về kỹ thuật, đây là phép chia giữa hai biến định lượng đã chuẩn hóa, thể hiện cấu trúc tài sản của doanh nghiệp. Về mặt thống kê, chỉ số này giúp đánh giá hiệu quả quản trị hàng tồn kho — tỷ lệ cao có thể phản ánh hiệu suất kinh doanh thấp hoặc chính sách dự trữ hàng hóa lớn.

Hiệu quả sử dụng lợi nhuận = Dòng tiền hoạt động / LNST

df_10bien <- df_10bien %>%
mutate(cash_to_profit = TienThuanHDKD / LNST)

df_10bien %>% select(nam, TienThuanHDKD, LNST, cash_to_profit) %>% head()
## # A tibble: 6 × 4
##     nam TienThuanHDKD  LNST cash_to_profit
##   <int>         <dbl> <dbl>          <dbl>
## 1  2015         -73.3  40.0         -1.83 
## 2  2016          80.2 142.           0.565
## 3  2017         -80.7 223.          -0.361
## 4  2018          38.5 180.           0.214
## 5  2019         489.  460.           1.06 
## 6  2020         613.  262.           2.34

Chỉ tiêu cash_to_profit đo lường mức độ tương quan giữa lợi nhuận kế toán và dòng tiền thực tế từ hoạt động kinh doanh. Về kỹ thuật, việc sử dụng mutate() giúp tạo biến động, thể hiện mối quan hệ giữa lợi nhuận và dòng tiền. Từ góc độ thống kê, chỉ số này giúp đánh giá chất lượng lợi nhuận — nếu hệ số thấp, có thể hàm ý rằng lợi nhuận được ghi nhận nhưng chưa chuyển hóa thành tiền mặt thực tế.

2.5.4. Mã hóa logic & phân nhóm

Sau khi các biến tài chính cơ bản và biến tỷ lệ được tính toán, bước tiếp theo là mã hóa logic và phân nhóm dữ liệu nhằm chuẩn bị cho phân tích so sánh, thống kê mô tả, hoặc mô hình hóa. Mục tiêu của phần này là chuyển các thông tin định lượng sang các biến định tính hoặc nhóm có ý nghĩa kinh tế cụ thể — giúp phát hiện các khác biệt giữa giai đoạn, quy mô, và tình trạng hoạt động của doanh nghiệp.

Mã hoá giai đoạn theo thời gian: Trước và sau Covid

df_10bien <- df_10bien %>%
  mutate(dot = ifelse(nam < 2020, "Truoc_Covid", "Sau_Covid"))

df_10bien %>% select(nam, dot) %>% head()
## # A tibble: 6 × 2
##     nam dot        
##   <int> <chr>      
## 1  2015 Truoc_Covid
## 2  2016 Truoc_Covid
## 3  2017 Truoc_Covid
## 4  2018 Truoc_Covid
## 5  2019 Truoc_Covid
## 6  2020 Sau_Covid

Lệnh trên tạo ra biến mới dot, chia dữ liệu thành hai giai đoạn:

“Truoc_Covid”: các năm nhỏ hơn 2020

“Sau_Covid”: các năm từ 2020 trở đi

Về mặt kỹ thuật, mutate() kết hợp ifelse() giúp gán giá trị điều kiện cho từng dòng dữ liệu. Từ góc nhìn thống kê, việc chia giai đoạn như vậy cho phép so sánh xu hướng tài chính trước và sau khủng hoảng Covid-19, qua đó nhận diện tác động của yếu tố thời kỳ đến hiệu quả hoạt động doanh nghiệp.

Phân loại doanh nghiệp Có Lãi / Lỗ

df_10bien <- df_10bien %>%
  mutate(loi_lo = ifelse(LNST > 0, "Có Lãi", "Lỗ"))

df_10bien %>% select(nam, LNST, loi_lo) %>% head()
## # A tibble: 6 × 3
##     nam  LNST loi_lo
##   <int> <dbl> <chr> 
## 1  2015  40.0 Có Lãi
## 2  2016 142.  Có Lãi
## 3  2017 223.  Có Lãi
## 4  2018 180.  Có Lãi
## 5  2019 460.  Có Lãi
## 6  2020 262.  Có Lãi

Biến loi_lo được tạo nhằm mã hóa tình trạng lợi nhuận của doanh nghiệp. Kỹ thuật này chuyển biến định lượng LNST (lợi nhuận sau thuế) thành biến định tính (“Có Lãi”/“Lỗ”), giúp dễ dàng thống kê tần suất hoặc trực quan hóa tỷ lệ doanh nghiệp có lãi theo năm. Về mặt thống kê, đây là một phép phân nhóm nhị phân (binary classification), rất phổ biến trong phân tích tài chính để xác định doanh nghiệp đang hoạt động hiệu quả hay gặp khó khăn.

Tính tỷ lệ tăng trưởng doanh thu qua năm

df_10bien <- df_10bien %>%
  arrange(nam) %>%
  mutate(TT_DT = DoanhThu / lag(DoanhThu) - 1)

df_10bien %>% select(nam, DoanhThu, TT_DT) %>% head()
## # A tibble: 6 × 3
##     nam DoanhThu  TT_DT
##   <int>    <dbl>  <dbl>
## 1  2015    1615. NA    
## 2  2016    2144.  0.328
## 3  2017    4070.  0.898
## 4  2018    8012.  0.969
## 5  2019    9258.  0.156
## 6  2020    7429. -0.198

Biến TT_DT thể hiện tốc độ tăng trưởng doanh thu so với năm trước, tính bằng tỷ lệ thay đổi tương đối. Cú pháp lag(DoanhThu) lấy giá trị doanh thu của năm liền trước, từ đó xác định mức tăng hoặc giảm. Về mặt thống kê, đây là một biến tăng trưởng chuỗi thời gian (year-over-year growth rate), giúp mô tả động thái doanh thu và xu hướng mở rộng thị trường của doanh nghiệp.

Phân nhóm quy mô doanh nghiệp theo tổng tài sản

df_10bien <- df_10bien %>%
  mutate(quy_mo = case_when(
    TongTaiSan < 5000 ~ "Nhỏ",
    TongTaiSan < 10000 ~ "Vừa",
    TRUE ~ "Lớn"
  ))

df_10bien %>% select(nam, TongTaiSan, quy_mo) %>% head()
## # A tibble: 6 × 3
##     nam TongTaiSan quy_mo
##   <int>      <dbl> <chr> 
## 1  2015      1955. Nhỏ   
## 2  2016      3078. Nhỏ   
## 3  2017      4576. Nhỏ   
## 4  2018      7529. Vừa   
## 5  2019      7987. Vừa   
## 6  2020      8569. Vừa

Hàm case_when() cho phép tạo các nhóm quy mô doanh nghiệp dựa trên giá trị tổng tài sản (TongTaiSan). Cụ thể:

Dưới 5.000 tỷ đồng: nhóm “Nhỏ”

Từ 5.000 – 10.000 tỷ đồng: nhóm “Vừa”

Trên 10.000 tỷ đồng: nhóm “Lớn”

Kỹ thuật này giúp tạo biến phân loại có thứ tự (ordinal variable), thường dùng trong so sánh hiệu quả tài chính giữa các nhóm quy mô khác nhau.

Phân tổ theo Giai đoạn Thời gian (Trước 2020 và Sau 2020). Sau đó, tính Tăng trưởng Doanh Thu trung bình của mỗi giai đoạn.

df_10bien %>% mutate(GiaiDoan = if_else(nam < 2020, "Truoc_2020", "Sau_2020")) %>% group_by(GiaiDoan) %>% summarise(TT_DT_TB = mean((DoanhThu / lag(DoanhThu)) - 1, na.rm = TRUE))
## # A tibble: 2 × 2
##   GiaiDoan   TT_DT_TB
##   <chr>         <dbl>
## 1 Sau_2020      0.193
## 2 Truoc_2020    0.588

Đoạn code này nhóm dữ liệu theo hai giai đoạn (“Trước 2020” và “Sau 2020”) rồi tính tốc độ tăng trưởng doanh thu trung bình của từng giai đoạn. Hàm group_by() và summarise() được sử dụng để tổng hợp dữ liệu có điều kiện. Về ý nghĩa thống kê, đây là phép tính trung bình có điều kiện theo nhóm (grouped mean), cho phép so sánh biến động doanh thu qua các giai đoạn kinh tế.

Tạo nhóm TTS_Group: TTS Cao (TTS > 7000$) hay TTS Thấp. Sau đó, tính Tỷ suất Nợ/VCSH trung bình của mỗi nhóm.

df_10bien %>% mutate(TTS_Group = if_else(TongTaiSan > 7000, "Lon", "Nho")) %>% group_by(TTS_Group) %>% summarise(No_VCSH_TB = mean(NoPhaiTra/VonChuSoHuu))
## # A tibble: 2 × 2
##   TTS_Group No_VCSH_TB
##   <chr>          <dbl>
## 1 Lon             1.12
## 2 Nho             1.81

Phép mã hóa này chia doanh nghiệp thành hai nhóm dựa trên quy mô tài sản (TTS_Group). Sau đó, tính trung bình tỷ lệ nợ trên vốn chủ sở hữu (Debt-to-Equity ratio) của mỗi nhóm. Về mặt thống kê, đây là phép so sánh giá trị trung bình giữa hai nhóm độc lập, giúp đánh giá xem quy mô doanh nghiệp có ảnh hưởng đến mức độ đòn bẩy tài chính hay không.

Tạo nhóm: Dòng tiền HĐKD Dương hay Âm. Sau đó, đếm số lượng năm và tính TTS trung bình của mỗi nhóm.

df_10bien %>% mutate(CF_Group = if_else(TienThuanHDKD > 0, "Duong", "Am")) %>% group_by(CF_Group) %>% summarise(Count = n(), TTS_TB = mean(TongTaiSan))
## # A tibble: 2 × 3
##   CF_Group Count TTS_TB
##   <chr>    <int>  <dbl>
## 1 Am           2  3265.
## 2 Duong        8  9165.

Biến CF_Group phân doanh nghiệp thành hai nhóm dựa trên dòng tiền thuần từ hoạt động kinh doanh (TiềnThuanHKD):

“Dương”: dòng tiền hoạt động dương

“Âm”: dòng tiền hoạt động âm

Sau đó, tính tổng số doanh nghiệp (Count) và tổng tài sản trung bình (TTS_TB) cho từng nhóm. Về mặt thống kê, đây là phân nhóm kết hợp đếm tần suất và tính trung bình có điều kiện, giúp mô tả mối quan hệ giữa khả năng tạo dòng tiền và quy mô doanh nghiệp.

Phân tổ theo Nam và tính Tăng trưởng LNG so với năm trước trong cùng nhóm năm.

df_10bien %>% group_by(nam) %>% mutate(TT_LNG = (LoiNhuanGop / lag(LoiNhuanGop)) - 1)
## # A tibble: 10 × 21
## # Groups:   nam [10]
##      nam  LNST DoanhThu LoiNhuanGop TSNganHan NoNganHan VonChuSoHuu TongTaiSan
##    <int> <dbl>    <dbl>       <dbl>     <dbl>     <dbl>       <dbl>      <dbl>
##  1  2015  40.0    1615.        190.     1072.      667.        819.      1955.
##  2  2016 142.     2144.        307.     1362.     1140.        955.      3078.
##  3  2017 223.     4070.        550.     2143.     1991.       1625.      4576.
##  4  2018 180.     8012.        673.     3989.     3206.       2980.      7529.
##  5  2019 460.     9258.       1042.     4971.     3237.       3255.      7987.
##  6  2020 262.     7429.        777.     4496.     3773.       4024.      8569.
##  7  2021 290.    13143.       1301.     5355.     3282.       5454.     10010.
##  8  2022 153.    15290.       1086.     5659.     3206.       6171.     10796.
##  9  2023 289.    12622.       1109.     5682.     3737.       5964.     11583.
## 10  2024 369.    12782.       1484.     6426.     4133.       6236.     13768.
## # ℹ 13 more variables: NoPhaiTra <dbl>, HangTonKho <dbl>, TienThuanHDKD <dbl>,
## #   GPM <dbl>, DE_Ratio <dbl>, CurrentRatio <dbl>, ton_kho_taisan <dbl>,
## #   cash_to_profit <dbl>, dot <chr>, loi_lo <chr>, TT_DT <dbl>, quy_mo <chr>,
## #   TT_LNG <dbl>

Đây là biến đo lường tốc độ tăng trưởng lợi nhuận gộp qua các năm, được tính tương tự tăng trưởng doanh thu. Từ góc độ thống kê, biến này giúp đánh giá hiệu quả kinh doanh cốt lõi, vì lợi nhuận gộp phản ánh khả năng tạo giá trị sau khi trừ chi phí sản xuất. Phép chia LoiNhuanGop / lag(LoiNhuanGop) tạo ra chuỗi thời gian liên tục, có thể sử dụng trong phân tích xu hướng hoặc mô hình hồi quy theo thời gian.

2.5.5. Lọc Dữ liệu

Các năm có LNST dương.

df_10bien %>% filter(LNST > 0)
## # A tibble: 10 × 20
##      nam  LNST DoanhThu LoiNhuanGop TSNganHan NoNganHan VonChuSoHuu TongTaiSan
##    <int> <dbl>    <dbl>       <dbl>     <dbl>     <dbl>       <dbl>      <dbl>
##  1  2015  40.0    1615.        190.     1072.      667.        819.      1955.
##  2  2016 142.     2144.        307.     1362.     1140.        955.      3078.
##  3  2017 223.     4070.        550.     2143.     1991.       1625.      4576.
##  4  2018 180.     8012.        673.     3989.     3206.       2980.      7529.
##  5  2019 460.     9258.       1042.     4971.     3237.       3255.      7987.
##  6  2020 262.     7429.        777.     4496.     3773.       4024.      8569.
##  7  2021 290.    13143.       1301.     5355.     3282.       5454.     10010.
##  8  2022 153.    15290.       1086.     5659.     3206.       6171.     10796.
##  9  2023 289.    12622.       1109.     5682.     3737.       5964.     11583.
## 10  2024 369.    12782.       1484.     6426.     4133.       6236.     13768.
## # ℹ 12 more variables: NoPhaiTra <dbl>, HangTonKho <dbl>, TienThuanHDKD <dbl>,
## #   GPM <dbl>, DE_Ratio <dbl>, CurrentRatio <dbl>, ton_kho_taisan <dbl>,
## #   cash_to_profit <dbl>, dot <chr>, loi_lo <chr>, TT_DT <dbl>, quy_mo <chr>

Kỹ thuật: Hàm filter() được sử dụng để lọc các hàng (dòng dữ liệu) thỏa mãn điều kiện LNST > 0, nghĩa là chỉ giữ lại các năm mà lợi nhuận sau thuế (LNST) lớn hơn 0. Đây là dạng lọc điều kiện cơ bản nhất trong dplyr.

Ý nghĩa thống kê: Bước này giúp tách riêng các giai đoạn hoạt động có hiệu quả, loại bỏ những năm lỗ để phân tích xu hướng tài chính ổn định hơn. Việc chỉ giữ lại các năm có lãi cũng giúp tránh sai lệch khi tính tỷ suất sinh lời trung bình, biên lợi nhuận hay các tỷ lệ hiệu quả.

Các năm có Doanh Thu lớn hơn 10,000.

df_10bien %>% filter(DoanhThu > 10000)
## # A tibble: 4 × 20
##     nam  LNST DoanhThu LoiNhuanGop TSNganHan NoNganHan VonChuSoHuu TongTaiSan
##   <int> <dbl>    <dbl>       <dbl>     <dbl>     <dbl>       <dbl>      <dbl>
## 1  2021  290.   13143.       1301.     5355.     3282.       5454.     10010.
## 2  2022  153.   15290.       1086.     5659.     3206.       6171.     10796.
## 3  2023  289.   12622.       1109.     5682.     3737.       5964.     11583.
## 4  2024  369.   12782.       1484.     6426.     4133.       6236.     13768.
## # ℹ 12 more variables: NoPhaiTra <dbl>, HangTonKho <dbl>, TienThuanHDKD <dbl>,
## #   GPM <dbl>, DE_Ratio <dbl>, CurrentRatio <dbl>, ton_kho_taisan <dbl>,
## #   cash_to_profit <dbl>, dot <chr>, loi_lo <chr>, TT_DT <dbl>, quy_mo <chr>

Kỹ thuật: Hàm filter() được dùng với điều kiện DoanhThu > 10000, nghĩa là chỉ giữ lại các năm có quy mô doanh thu vượt ngưỡng 10.000 tỷ đồng.

Ý nghĩa thống kê: Mục tiêu là xác định những năm tăng trưởng mạnh hoặc “đột biến” trong hoạt động kinh doanh. Việc lọc này giúp nhà phân tích tập trung vào các giai đoạn mở rộng thị phần hoặc tăng trưởng vượt trội, có thể gắn với sự kiện đặc biệt (ví dụ mở rộng sản xuất, tăng xuất khẩu,…).

Các năm có Dòng tiền HĐKD âm (lỗ dòng tiền).

df_10bien %>% filter(TienThuanHDKD < 0)
## # A tibble: 2 × 20
##     nam  LNST DoanhThu LoiNhuanGop TSNganHan NoNganHan VonChuSoHuu TongTaiSan
##   <int> <dbl>    <dbl>       <dbl>     <dbl>     <dbl>       <dbl>      <dbl>
## 1  2015  40.0    1615.        190.     1072.      667.        819.      1955.
## 2  2017 223.     4070.        550.     2143.     1991.       1625.      4576.
## # ℹ 12 more variables: NoPhaiTra <dbl>, HangTonKho <dbl>, TienThuanHDKD <dbl>,
## #   GPM <dbl>, DE_Ratio <dbl>, CurrentRatio <dbl>, ton_kho_taisan <dbl>,
## #   cash_to_profit <dbl>, dot <chr>, loi_lo <chr>, TT_DT <dbl>, quy_mo <chr>

Kỹ thuật: Điều kiện lọc TienThuanHKD < 0 chọn các năm mà dòng tiền thuần từ hoạt động kinh doanh (operating cash flow) bị âm.

Ý nghĩa tài chính: Dù doanh nghiệp có thể báo lãi trên sổ sách, nhưng dòng tiền âm phản ánh khả năng tạo tiền mặt thực tế yếu, dẫn tới rủi ro thanh khoản. Đây là bước rất quan trọng khi đánh giá chất lượng lợi nhuận và khả năng trả nợ.

Các năm từ 2020 trở đi VÀ Tổng Tài Sản lớn hơn 10,000.

df_10bien %>% filter(nam >= 2020 & TongTaiSan > 10000)
## # A tibble: 4 × 20
##     nam  LNST DoanhThu LoiNhuanGop TSNganHan NoNganHan VonChuSoHuu TongTaiSan
##   <int> <dbl>    <dbl>       <dbl>     <dbl>     <dbl>       <dbl>      <dbl>
## 1  2021  290.   13143.       1301.     5355.     3282.       5454.     10010.
## 2  2022  153.   15290.       1086.     5659.     3206.       6171.     10796.
## 3  2023  289.   12622.       1109.     5682.     3737.       5964.     11583.
## 4  2024  369.   12782.       1484.     6426.     4133.       6236.     13768.
## # ℹ 12 more variables: NoPhaiTra <dbl>, HangTonKho <dbl>, TienThuanHDKD <dbl>,
## #   GPM <dbl>, DE_Ratio <dbl>, CurrentRatio <dbl>, ton_kho_taisan <dbl>,
## #   cash_to_profit <dbl>, dot <chr>, loi_lo <chr>, TT_DT <dbl>, quy_mo <chr>

Kỹ thuật: Hai điều kiện được kết hợp bằng toán tử & (và logic): năm lớn hơn hoặc bằng 2020, đồng thời tổng tài sản vượt 10.000 tỷ.

Ý nghĩa thống kê: Mục tiêu là xác định giai đoạn sau Covid-19 với những doanh nghiệp đã mở rộng quy mô tài sản đáng kể. Đây là nhóm quan sát đại diện cho sự phục hồi và tăng trưởng sau khủng hoảng, giúp so sánh với các giai đoạn trước.

Các năm có LNST > 200 HOẶC Doanh thu < 5000.

df_10bien %>% filter(LNST > 200 & DoanhThu < 5000)
## # A tibble: 1 × 20
##     nam  LNST DoanhThu LoiNhuanGop TSNganHan NoNganHan VonChuSoHuu TongTaiSan
##   <int> <dbl>    <dbl>       <dbl>     <dbl>     <dbl>       <dbl>      <dbl>
## 1  2017  223.    4070.        550.     2143.     1991.       1625.      4576.
## # ℹ 12 more variables: NoPhaiTra <dbl>, HangTonKho <dbl>, TienThuanHDKD <dbl>,
## #   GPM <dbl>, DE_Ratio <dbl>, CurrentRatio <dbl>, ton_kho_taisan <dbl>,
## #   cash_to_profit <dbl>, dot <chr>, loi_lo <chr>, TT_DT <dbl>, quy_mo <chr>

Kỹ thuật: Toán tử | (hoặc logic) cho phép chọn các năm thỏa ít nhất một trong hai điều kiện.

Ý nghĩa: Bước này tìm các năm có hiệu quả kinh doanh vượt trội (LNST > 200) hoặc quy mô nhỏ nhưng hoạt động ổn định (Doanh thu < 5000). Đây là kỹ thuật lọc hữu ích để phát hiện ngoại lệ (outliers) trong tập dữ liệu, ví dụ các năm hoạt động khác thường.

Các năm trong phạm vi từ 2017 đến 2021.

df_10bien %>% filter(nam >= 2017, nam <= 2021)
## # A tibble: 5 × 20
##     nam  LNST DoanhThu LoiNhuanGop TSNganHan NoNganHan VonChuSoHuu TongTaiSan
##   <int> <dbl>    <dbl>       <dbl>     <dbl>     <dbl>       <dbl>      <dbl>
## 1  2017  223.    4070.        550.     2143.     1991.       1625.      4576.
## 2  2018  180.    8012.        673.     3989.     3206.       2980.      7529.
## 3  2019  460.    9258.       1042.     4971.     3237.       3255.      7987.
## 4  2020  262.    7429.        777.     4496.     3773.       4024.      8569.
## 5  2021  290.   13143.       1301.     5355.     3282.       5454.     10010.
## # ℹ 12 more variables: NoPhaiTra <dbl>, HangTonKho <dbl>, TienThuanHDKD <dbl>,
## #   GPM <dbl>, DE_Ratio <dbl>, CurrentRatio <dbl>, ton_kho_taisan <dbl>,
## #   cash_to_profit <dbl>, dot <chr>, loi_lo <chr>, TT_DT <dbl>, quy_mo <chr>

Kỹ thuật: Dùng điều kiện kép với dấu phẩy (tương đương &) để lọc khoảng năm mong muốn.

Ý nghĩa: Giới hạn khung thời gian cho phép phân tích chi tiết một giai đoạn kinh tế cụ thể, ví dụ giai đoạn “trước khủng hoảng và phục hồi”. Trong nghiên cứu thực tế, việc giới hạn này giúp làm nổi bật xu hướng trung hạn.

Các năm không có Nợ Ngắn Hạn (NoNganHan) lớn hơn 4,000.

df_10bien %>% filter(!(NoNganHan > 4000))
## # A tibble: 9 × 20
##     nam  LNST DoanhThu LoiNhuanGop TSNganHan NoNganHan VonChuSoHuu TongTaiSan
##   <int> <dbl>    <dbl>       <dbl>     <dbl>     <dbl>       <dbl>      <dbl>
## 1  2015  40.0    1615.        190.     1072.      667.        819.      1955.
## 2  2016 142.     2144.        307.     1362.     1140.        955.      3078.
## 3  2017 223.     4070.        550.     2143.     1991.       1625.      4576.
## 4  2018 180.     8012.        673.     3989.     3206.       2980.      7529.
## 5  2019 460.     9258.       1042.     4971.     3237.       3255.      7987.
## 6  2020 262.     7429.        777.     4496.     3773.       4024.      8569.
## 7  2021 290.    13143.       1301.     5355.     3282.       5454.     10010.
## 8  2022 153.    15290.       1086.     5659.     3206.       6171.     10796.
## 9  2023 289.    12622.       1109.     5682.     3737.       5964.     11583.
## # ℹ 12 more variables: NoPhaiTra <dbl>, HangTonKho <dbl>, TienThuanHDKD <dbl>,
## #   GPM <dbl>, DE_Ratio <dbl>, CurrentRatio <dbl>, ton_kho_taisan <dbl>,
## #   cash_to_profit <dbl>, dot <chr>, loi_lo <chr>, TT_DT <dbl>, quy_mo <chr>

Kỹ thuật: Dấu ! là toán tử phủ định (NOT). Lệnh này lọc ra những năm có nợ ngắn hạn ≤ 4000 tỷ.

Ý nghĩa tài chính: Bước này nhằm chọn ra những năm doanh nghiệp có cấu trúc nợ an toàn, giảm rủi ro thanh khoản. Việc loại bỏ các năm có nợ ngắn hạn cao giúp đánh giá chính xác hơn khả năng cân đối tài sản – nguồn vốn.

Các năm có Lợi nhuận Gộp nằm trong top 50% (lớn hơn trung vị).

df_10bien %>% filter(LoiNhuanGop > median(LoiNhuanGop))
## # A tibble: 5 × 20
##     nam  LNST DoanhThu LoiNhuanGop TSNganHan NoNganHan VonChuSoHuu TongTaiSan
##   <int> <dbl>    <dbl>       <dbl>     <dbl>     <dbl>       <dbl>      <dbl>
## 1  2019  460.    9258.       1042.     4971.     3237.       3255.      7987.
## 2  2021  290.   13143.       1301.     5355.     3282.       5454.     10010.
## 3  2022  153.   15290.       1086.     5659.     3206.       6171.     10796.
## 4  2023  289.   12622.       1109.     5682.     3737.       5964.     11583.
## 5  2024  369.   12782.       1484.     6426.     4133.       6236.     13768.
## # ℹ 12 more variables: NoPhaiTra <dbl>, HangTonKho <dbl>, TienThuanHDKD <dbl>,
## #   GPM <dbl>, DE_Ratio <dbl>, CurrentRatio <dbl>, ton_kho_taisan <dbl>,
## #   cash_to_profit <dbl>, dot <chr>, loi_lo <chr>, TT_DT <dbl>, quy_mo <chr>

Kỹ thuật: median() tính giá trị trung vị của biến LoiNhuanGop. Lệnh này chọn các năm có lợi nhuận gộp cao hơn mức trung vị, tương ứng nhóm “top 50%”.

Ý nghĩa thống kê: Đây là cách phân tầng dữ liệu theo vị trí phân phối (quantile split). Nhóm này đại diện cho các giai đoạn hoạt động mạnh, giúp phân tích yếu tố ảnh hưởng đến lợi nhuận cao.

Các năm có TSNH > 4000 và NoNH < 3500

df_10bien %>% filter(TSNganHan > 4000 & NoNganHan < 3500)
## # A tibble: 3 × 20
##     nam  LNST DoanhThu LoiNhuanGop TSNganHan NoNganHan VonChuSoHuu TongTaiSan
##   <int> <dbl>    <dbl>       <dbl>     <dbl>     <dbl>       <dbl>      <dbl>
## 1  2019  460.    9258.       1042.     4971.     3237.       3255.      7987.
## 2  2021  290.   13143.       1301.     5355.     3282.       5454.     10010.
## 3  2022  153.   15290.       1086.     5659.     3206.       6171.     10796.
## # ℹ 12 more variables: NoPhaiTra <dbl>, HangTonKho <dbl>, TienThuanHDKD <dbl>,
## #   GPM <dbl>, DE_Ratio <dbl>, CurrentRatio <dbl>, ton_kho_taisan <dbl>,
## #   cash_to_profit <dbl>, dot <chr>, loi_lo <chr>, TT_DT <dbl>, quy_mo <chr>

Kỹ thuật: Điều kiện kép lọc ra các năm có tài sản ngắn hạn cao hơn nợ ngắn hạn.

Ý nghĩa tài chính: Đây là nhóm có thanh khoản cao, nghĩa là khả năng đáp ứng nghĩa vụ ngắn hạn tốt. Trong phân tích rủi ro, các năm này thể hiện tình hình tài chính an toàn hơn so với trung bình.

Lọc các năm có Doanh Thu tăng so với năm trước NHƯNG Lợi nhuận Gộp giảm.

df_10bien %>% filter(DoanhThu > lag(DoanhThu) & LoiNhuanGop < lag(LoiNhuanGop))
## # A tibble: 1 × 20
##     nam  LNST DoanhThu LoiNhuanGop TSNganHan NoNganHan VonChuSoHuu TongTaiSan
##   <int> <dbl>    <dbl>       <dbl>     <dbl>     <dbl>       <dbl>      <dbl>
## 1  2022  153.   15290.       1086.     5659.     3206.       6171.     10796.
## # ℹ 12 more variables: NoPhaiTra <dbl>, HangTonKho <dbl>, TienThuanHDKD <dbl>,
## #   GPM <dbl>, DE_Ratio <dbl>, CurrentRatio <dbl>, ton_kho_taisan <dbl>,
## #   cash_to_profit <dbl>, dot <chr>, loi_lo <chr>, TT_DT <dbl>, quy_mo <chr>

Kỹ thuật: lag() gọi giá trị của năm liền trước để so sánh. Ở đây, doanh thu tăng so với năm trước nhưng lợi nhuận gộp lại giảm.

Ý nghĩa phân tích: Trường hợp này phản ánh doanh thu tăng nhưng biên lợi nhuận bị thu hẹp, có thể do:

Chi phí sản xuất tăng,

Cạnh tranh về giá,

Biến động nguyên vật liệu. Đây là dấu hiệu cảnh báo cần phân tích sâu trong quản trị chi phí.

Lọc các năm có Tỷ số Thanh toán Hiện hành TSNH/NoNganHan lớn hơn 1.5..

df_10bien %>% filter(TSNganHan / NoNganHan > 1.5)
## # A tibble: 6 × 20
##     nam  LNST DoanhThu LoiNhuanGop TSNganHan NoNganHan VonChuSoHuu TongTaiSan
##   <int> <dbl>    <dbl>       <dbl>     <dbl>     <dbl>       <dbl>      <dbl>
## 1  2015  40.0    1615.        190.     1072.      667.        819.      1955.
## 2  2019 460.     9258.       1042.     4971.     3237.       3255.      7987.
## 3  2021 290.    13143.       1301.     5355.     3282.       5454.     10010.
## 4  2022 153.    15290.       1086.     5659.     3206.       6171.     10796.
## 5  2023 289.    12622.       1109.     5682.     3737.       5964.     11583.
## 6  2024 369.    12782.       1484.     6426.     4133.       6236.     13768.
## # ℹ 12 more variables: NoPhaiTra <dbl>, HangTonKho <dbl>, TienThuanHDKD <dbl>,
## #   GPM <dbl>, DE_Ratio <dbl>, CurrentRatio <dbl>, ton_kho_taisan <dbl>,
## #   cash_to_profit <dbl>, dot <chr>, loi_lo <chr>, TT_DT <dbl>, quy_mo <chr>

Kỹ thuật: Đây là phép tính trực tiếp ngay trong filter(), không cần biến trung gian.

Ý nghĩa tài chính: Hệ số thanh toán hiện hành đo khả năng trả nợ ngắn hạn bằng tài sản ngắn hạn. Nếu > 1.5, doanh nghiệp được coi là có khả năng thanh toán tốt, giảm rủi ro nợ đến hạn. Lọc nhóm này giúp đánh giá đặc điểm của các năm có sức khỏe tài chính mạnh.

2.5.6. Sắp xếp

Sắp xếp theo Tỷ suất Thanh toán Hiện hành (TSNH/NoNganHan) giảm dần.

df_10bien %>% mutate(CurrentRatio = TSNganHan / NoNganHan) %>% arrange(desc(CurrentRatio))
## # A tibble: 10 × 20
##      nam  LNST DoanhThu LoiNhuanGop TSNganHan NoNganHan VonChuSoHuu TongTaiSan
##    <int> <dbl>    <dbl>       <dbl>     <dbl>     <dbl>       <dbl>      <dbl>
##  1  2022 153.    15290.       1086.     5659.     3206.       6171.     10796.
##  2  2021 290.    13143.       1301.     5355.     3282.       5454.     10010.
##  3  2015  40.0    1615.        190.     1072.      667.        819.      1955.
##  4  2024 369.    12782.       1484.     6426.     4133.       6236.     13768.
##  5  2019 460.     9258.       1042.     4971.     3237.       3255.      7987.
##  6  2023 289.    12622.       1109.     5682.     3737.       5964.     11583.
##  7  2018 180.     8012.        673.     3989.     3206.       2980.      7529.
##  8  2016 142.     2144.        307.     1362.     1140.        955.      3078.
##  9  2020 262.     7429.        777.     4496.     3773.       4024.      8569.
## 10  2017 223.     4070.        550.     2143.     1991.       1625.      4576.
## # ℹ 12 more variables: NoPhaiTra <dbl>, HangTonKho <dbl>, TienThuanHDKD <dbl>,
## #   GPM <dbl>, DE_Ratio <dbl>, CurrentRatio <dbl>, ton_kho_taisan <dbl>,
## #   cash_to_profit <dbl>, dot <chr>, loi_lo <chr>, TT_DT <dbl>, quy_mo <chr>

Trong bước này, nhóm tiến hành tạo thêm một biến mới là tỷ suất thanh toán hiện hành, được tính bằng tỷ lệ giữa tài sản ngắn hạn và nợ ngắn hạn thông qua lệnh mutate(CurrentRatio = TSNganHan / NoNganHan). Sau đó, dữ liệu được sắp xếp giảm dần theo chỉ tiêu này bằng arrange(desc(CurrentRatio)). Về mặt kỹ thuật, hàm mutate() cho phép tạo biến mới trong khung dữ liệu, trong khi arrange() sắp xếp các hàng theo thứ tự mong muốn. Về mặt thống kê và tài chính, tỷ suất thanh toán hiện hành phản ánh khả năng thanh toán ngắn hạn của doanh nghiệp. Khi chỉ tiêu này lớn hơn 1, doanh nghiệp có đủ tài sản ngắn hạn để trả nợ ngắn hạn; còn khi quá cao, có thể cho thấy vốn lưu động chưa được khai thác hiệu quả. Việc sắp xếp theo chiều giảm dần giúp xác định những năm mà doanh nghiệp có tình hình tài chính ổn định nhất và theo dõi sự biến động về khả năng thanh toán qua các năm.

Sắp xếp theo Độ lớn tuyệt đối của Lợi nhuận Sau thuế (LNST) giảm dần.

df_10bien %>% arrange(desc(abs(LNST)))
## # A tibble: 10 × 20
##      nam  LNST DoanhThu LoiNhuanGop TSNganHan NoNganHan VonChuSoHuu TongTaiSan
##    <int> <dbl>    <dbl>       <dbl>     <dbl>     <dbl>       <dbl>      <dbl>
##  1  2019 460.     9258.       1042.     4971.     3237.       3255.      7987.
##  2  2024 369.    12782.       1484.     6426.     4133.       6236.     13768.
##  3  2021 290.    13143.       1301.     5355.     3282.       5454.     10010.
##  4  2023 289.    12622.       1109.     5682.     3737.       5964.     11583.
##  5  2020 262.     7429.        777.     4496.     3773.       4024.      8569.
##  6  2017 223.     4070.        550.     2143.     1991.       1625.      4576.
##  7  2018 180.     8012.        673.     3989.     3206.       2980.      7529.
##  8  2022 153.    15290.       1086.     5659.     3206.       6171.     10796.
##  9  2016 142.     2144.        307.     1362.     1140.        955.      3078.
## 10  2015  40.0    1615.        190.     1072.      667.        819.      1955.
## # ℹ 12 more variables: NoPhaiTra <dbl>, HangTonKho <dbl>, TienThuanHDKD <dbl>,
## #   GPM <dbl>, DE_Ratio <dbl>, CurrentRatio <dbl>, ton_kho_taisan <dbl>,
## #   cash_to_profit <dbl>, dot <chr>, loi_lo <chr>, TT_DT <dbl>, quy_mo <chr>

Tiếp theo, nhóm thực hiện sắp xếp dữ liệu theo độ lớn tuyệt đối của lợi nhuận sau thuế (LNST) bằng lệnh arrange(desc(abs(LNST))). Trong đó, hàm abs() lấy giá trị tuyệt đối nhằm đảm bảo rằng cả các năm lãi cao và lỗ lớn đều được xem xét như nhau. Về mặt kỹ thuật, đây là thao tác giúp hiển thị các quan sát có biến động lớn nhất về lợi nhuận ở đầu bảng. Về mặt phân tích thống kê, cách sắp xếp này giúp xác định các giai đoạn có biến động mạnh về kết quả kinh doanh, dù là tăng trưởng đột biến hay suy giảm nghiêm trọng. Những năm đứng đầu danh sách thường là các năm đặc biệt quan trọng cần được phân tích sâu hơn, vì có thể phản ánh tác động của yếu tố thị trường, chính sách hoặc chiến lược kinh doanh của doanh nghiệp.

Sắp xếp theo Tỷ suất Tăng trưởng Doanh Thu giảm dần.

df_10bien %>% mutate(TT_DT = (DoanhThu / lag(DoanhThu)) - 1) %>% arrange(desc(TT_DT))
## # A tibble: 10 × 20
##      nam  LNST DoanhThu LoiNhuanGop TSNganHan NoNganHan VonChuSoHuu TongTaiSan
##    <int> <dbl>    <dbl>       <dbl>     <dbl>     <dbl>       <dbl>      <dbl>
##  1  2018 180.     8012.        673.     3989.     3206.       2980.      7529.
##  2  2017 223.     4070.        550.     2143.     1991.       1625.      4576.
##  3  2021 290.    13143.       1301.     5355.     3282.       5454.     10010.
##  4  2016 142.     2144.        307.     1362.     1140.        955.      3078.
##  5  2022 153.    15290.       1086.     5659.     3206.       6171.     10796.
##  6  2019 460.     9258.       1042.     4971.     3237.       3255.      7987.
##  7  2024 369.    12782.       1484.     6426.     4133.       6236.     13768.
##  8  2023 289.    12622.       1109.     5682.     3737.       5964.     11583.
##  9  2020 262.     7429.        777.     4496.     3773.       4024.      8569.
## 10  2015  40.0    1615.        190.     1072.      667.        819.      1955.
## # ℹ 12 more variables: NoPhaiTra <dbl>, HangTonKho <dbl>, TienThuanHDKD <dbl>,
## #   GPM <dbl>, DE_Ratio <dbl>, CurrentRatio <dbl>, ton_kho_taisan <dbl>,
## #   cash_to_profit <dbl>, dot <chr>, loi_lo <chr>, TT_DT <dbl>, quy_mo <chr>

Ở bước này, nhóm tạo thêm một biến mới biểu thị tỷ suất tăng trưởng doanh thu qua các năm bằng công thức (DoanhThu / lag(DoanhThu)) - 1, trong đó lag() được dùng để gọi giá trị doanh thu của năm trước đó. Sau khi tính toán, dữ liệu được sắp xếp giảm dần theo biến này với arrange(desc(TT_DT)). Về kỹ thuật, đây là phép toán chuỗi thời gian đơn giản giúp xác định tốc độ thay đổi tương đối giữa các kỳ quan sát. Về ý nghĩa thống kê, tỷ suất tăng trưởng doanh thu cho biết mức độ mở rộng hoạt động kinh doanh của doanh nghiệp qua từng năm. Việc sắp xếp theo chiều giảm dần giúp nhận biết rõ những năm tăng trưởng cao nhất, qua đó có thể so sánh hiệu quả giữa các giai đoạn hoặc xác định thời điểm doanh nghiệp đạt được sự tăng trưởng đột phá.

Sắp xếp để đưa các năm có TienThuanHDKD âm (lỗ dòng tiền) lên đầu, sau đó sắp xếp các năm đó theo LNST tăng dần.

df_10bien %>% mutate(CF_Am = TienThuanHDKD < 0) %>% arrange(desc(CF_Am), LNST)
## # A tibble: 10 × 21
##      nam  LNST DoanhThu LoiNhuanGop TSNganHan NoNganHan VonChuSoHuu TongTaiSan
##    <int> <dbl>    <dbl>       <dbl>     <dbl>     <dbl>       <dbl>      <dbl>
##  1  2015  40.0    1615.        190.     1072.      667.        819.      1955.
##  2  2017 223.     4070.        550.     2143.     1991.       1625.      4576.
##  3  2016 142.     2144.        307.     1362.     1140.        955.      3078.
##  4  2022 153.    15290.       1086.     5659.     3206.       6171.     10796.
##  5  2018 180.     8012.        673.     3989.     3206.       2980.      7529.
##  6  2020 262.     7429.        777.     4496.     3773.       4024.      8569.
##  7  2023 289.    12622.       1109.     5682.     3737.       5964.     11583.
##  8  2021 290.    13143.       1301.     5355.     3282.       5454.     10010.
##  9  2024 369.    12782.       1484.     6426.     4133.       6236.     13768.
## 10  2019 460.     9258.       1042.     4971.     3237.       3255.      7987.
## # ℹ 13 more variables: NoPhaiTra <dbl>, HangTonKho <dbl>, TienThuanHDKD <dbl>,
## #   GPM <dbl>, DE_Ratio <dbl>, CurrentRatio <dbl>, ton_kho_taisan <dbl>,
## #   cash_to_profit <dbl>, dot <chr>, loi_lo <chr>, TT_DT <dbl>, quy_mo <chr>,
## #   CF_Am <lgl>

Trong thao tác này, nhóm tạo ra một biến logic mới CF_Am thông qua biểu thức TienThuanHKD < 0, trong đó biến nhận giá trị TRUE nếu dòng tiền hoạt động kinh doanh âm và FALSE nếu dương. Sau đó, dữ liệu được sắp xếp theo lệnh arrange(desc(CF_Am), LNST) để đưa các năm có dòng tiền âm lên trước, rồi tiếp tục sắp theo lợi nhuận sau thuế tăng dần trong nhóm đó. Về kỹ thuật, đây là thao tác kết hợp giữa việc mã hóa điều kiện logic và sắp xếp đa biến, giúp hiển thị dữ liệu một cách có trật tự và trực quan hơn. Về mặt tài chính, việc sắp xếp này có ý nghĩa quan trọng vì cho phép nhanh chóng xác định những năm mà doanh nghiệp ghi nhận lợi nhuận kế toán dương nhưng dòng tiền thực tế lại âm — tức là lợi nhuận không chuyển hóa thành tiền mặt. Đây là dấu hiệu cảnh báo về rủi ro thanh khoản hoặc hiệu quả quản lý vốn lưu động, cần được xem xét kỹ trong quá trình đánh giá chất lượng lợi nhuận.

2.6. Phân Tích Thống Kê

2.6.1. Thông kê sơ bộ

Biến LNST

summary(df_10bien$LNST)
##    Min. 1st Qu.  Median    Mean 3rd Qu.    Max. 
##   40.02  159.51  242.79  240.91  290.03  460.47

Kết quả thống kê cho biến LNST cho thấy giá trị tối thiểu là 40.02, tối đa 460.47, với giá trị trung bình đạt 240.91 và trung vị là 242.79. Sự chênh lệch giữa giá trị nhỏ nhất và lớn nhất phản ánh biến động đáng kể trong kết quả lợi nhuận qua các năm. Các giá trị phân vị cho thấy phần lớn lợi nhuận của doanh nghiệp tập trung quanh mức từ 159.51 đến 290.03, chứng tỏ lợi nhuận có xu hướng ổn định nhưng vẫn xuất hiện một vài năm vượt trội. → Về mặt thống kê, đây là biến có phân phối khá cân đối quanh giá trị trung bình. Về mặt kinh tế, điều này cho thấy doanh nghiệp duy trì mức sinh lời tương đối ổn định, chỉ có một số năm đạt lợi nhuận cao đột biến.

Biến Doanh Thu

summary(df_10bien$DoanhThu)
##    Min. 1st Qu.  Median    Mean 3rd Qu.    Max. 
##    1615    4909    8635    8636   12742   15290

Biến DoanhThu dao động từ 1.615 tỷ đến 15.290 tỷ đồng, với giá trị trung bình 8.636 tỷ đồng. Khoảng cách rộng giữa giá trị cực tiểu và cực đại cho thấy quy mô doanh thu thay đổi lớn qua các năm. Các giá trị phân vị (Q1 = 4.909, Median = 8.635, Q3 = 12.742) thể hiện mức doanh thu có xu hướng tăng dần, phản ánh sự mở rộng hoạt động kinh doanh theo thời gian. → Về thống kê, biến này thể hiện xu hướng tăng nhẹ quanh trung bình, không có sự lệch lớn. Về ý nghĩa kinh tế, doanh thu tăng trưởng thể hiện khả năng phát triển thị trường và mở rộng quy mô sản xuất – kinh doanh của doanh nghiệp.

Biến Lợi nhuận gộp

summary(df_10bien$LoiNhuanGop)
##    Min. 1st Qu.  Median    Mean 3rd Qu.    Max. 
##   189.8   581.0   909.5   852.0  1103.1  1484.1

Giá trị lợi nhuận gộp dao động từ 189.8 đến 1484.1, với trung bình đạt 852 tỷ đồng. Trung vị là 909.5, cho thấy phân phối dữ liệu khá cân bằng quanh giá trị trung bình. Sự chênh lệch giữa các tứ phân vị (581 – 1103) cho thấy biên độ lợi nhuận gộp tương đối ổn định, không có sự biến động quá mạnh. → Về thống kê, đây là biến có phân phối đều và độ lệch chuẩn nhỏ. Về kinh tế, điều này phản ánh hiệu quả hoạt động sản xuất kinh doanh tương đối nhất quán, ít bị ảnh hưởng bởi yếu tố chi phí đầu vào hay biến động doanh thu.

Biến Tài sản ngắn hạn

summary(df_10bien$TSNganHan)
##    Min. 1st Qu.  Median    Mean 3rd Qu.    Max. 
##    1072    2604    4734    4115    5583    6426

Giá trị TSNganHan biến thiên từ 1072 đến 6426, với trung bình 4115 tỷ đồng và trung vị 4734 tỷ đồng. Phân phối khá cân bằng quanh trung vị, song có sự tăng nhẹ ở các giá trị cao, thể hiện tài sản ngắn hạn có xu hướng mở rộng trong giai đoạn gần đây. → Về thống kê, đây là biến có độ lệch nhẹ về bên phải (right-skewed). Về kinh tế, điều này cho thấy doanh nghiệp tăng lượng tài sản lưu động, phục vụ cho việc mở rộng quy mô hoạt động hoặc tăng tồn kho, phải thu.

Biến Nợ ngắn hạn

summary(df_10bien$NoNganHan)
##    Min. 1st Qu.  Median    Mean 3rd Qu.    Max. 
##   667.1  2294.6  3221.6  2837.2  3623.4  4132.6

Kết quả cho thấy giá trị nợ ngắn hạn dao động từ 667.1 đến 4132.6, trung bình 2837.2 và trung vị 3221.6. Sự khác biệt giữa giá trị nhỏ nhất và lớn nhất cho thấy mức nợ biến động khá lớn, phản ánh thay đổi trong chính sách tài trợ vốn lưu động của doanh nghiệp. → Về mặt thống kê, biến này có độ lệch vừa phải, không xuất hiện giá trị cực đoan. Về mặt kinh tế, điều này cho thấy doanh nghiệp có xu hướng sử dụng nợ ngắn hạn linh hoạt để phục vụ hoạt động kinh doanh, tuy nhiên cần theo dõi để đảm bảo khả năng thanh toán ngắn hạn.

Biến Vốn chủ sở hữa

summary(df_10bien$VonChuSoHuu)
##    Min. 1st Qu.  Median    Mean 3rd Qu.    Max. 
##   819.5  1963.8  3639.6  3748.4  5836.5  6236.3

Giá trị vốn chủ sở hữu dao động từ 819.5 đến 6236.3, trung bình 3748.4 tỷ đồng. Phân phối khá cân bằng (Median = 3639.6), cho thấy quy mô vốn chủ sở hữu tăng ổn định qua các năm. → Về thống kê, độ phân tán thấp cho thấy sự ổn định trong cấu trúc tài chính. Về kinh tế, điều này thể hiện doanh nghiệp duy trì mức vốn chủ ổn định, giúp giảm phụ thuộc vào nợ vay, từ đó củng cố sức mạnh tài chính dài hạn.

Biến Tổng tài sản

summary(df_10bien$TongTaiSan)
##    Min. 1st Qu.  Median    Mean 3rd Qu.    Max. 
##    1955    5314    8278    7985   10599   13768

Biến tổng tài sản có giá trị nhỏ nhất là 1955 và lớn nhất 13768, trung bình 7985 tỷ đồng. Khoảng biến động lớn phản ánh sự mở rộng quy mô tài sản của doanh nghiệp trong giai đoạn nghiên cứu. Phân phối dữ liệu (Q1 = 5314, Q3 = 10599) cho thấy tài sản tăng dần và tập trung quanh mức trung bình, thể hiện xu hướng tăng trưởng vững. → Về ý nghĩa thống kê, tổng tài sản có xu hướng phân bố lệch phải nhẹ, nghĩa là một số năm quy mô tài sản cao vượt trội. Về kinh tế, điều này thể hiện doanh nghiệp mở rộng đầu tư, gia tăng quy mô hoạt động

Biến Nợ phải trả

summary(df_10bien$NoPhaiTra)
##    Min. 1st Qu.  Median    Mean 3rd Qu.    Max. 
##    1135    3350    4552    4237    4705    7532

Biến nợ phải trả dao động từ 1135 đến 7532, trung bình 4327 tỷ đồng. So sánh giữa giá trị trung bình và trung vị (4452) cho thấy phân phối khá cân đối, nghĩa là mức nợ của doanh nghiệp ổn định giữa các năm. → Về thống kê, biến này không có dấu hiệu lệch đáng kể. Về kinh tế, điều này thể hiện doanh nghiệp duy trì mức vay nợ hợp lý, góp phần cân đối giữa nợ và vốn chủ trong cơ cấu tài chính.

Biến Hàng tồn kho

summary(df_10bien$HangTonKho)
##    Min. 1st Qu.  Median    Mean 3rd Qu.    Max. 
##   214.2   598.4   906.4   916.6  1165.7  1861.1

Giá trị hàng tồn kho dao động từ 214.2 đến 1861.1, trung bình 916.6 tỷ đồng. Trung vị (906.4) gần với trung bình, cho thấy sự ổn định tương đối trong giá trị tồn kho. → Về thống kê, độ phân tán vừa phải, không có giá trị ngoại lệ. Về kinh tế, điều này phản ánh doanh nghiệp quản lý hàng tồn kho hiệu quả, không có sự tăng đột biến gây ứ đọng vốn hoặc giảm sút bất thường.

Biến Tiền Thuần từ HDKD

summary(df_10bien$TienThuanHDKD)
##    Min. 1st Qu.  Median    Mean 3rd Qu.    Max. 
##  -80.66   48.95   97.10  431.96  477.91 2615.22

Biến này có giá trị dao động mạnh, từ -80.66 đến 2615.22, trung bình đạt 431.96 tỷ đồng. Sự xuất hiện giá trị âm cho thấy một số năm doanh nghiệp có dòng tiền hoạt động âm, tức chi nhiều hơn thu trong hoạt động sản xuất – kinh doanh. → Về thống kê, đây là biến có độ lệch lớn, phản ánh tính biến động cao. Về mặt kinh tế, điều này cho thấy chất lượng dòng tiền chưa ổn định, mặc dù trung bình vẫn dương, thể hiện khả năng tạo tiền từ hoạt động chính ở mức khá.

2.6.2. Thống Kê Biến Doanh Thu

2.6.2.1. Thống kê sơ bộ

Giá trị Trung bình (Mean) của DoanhThu.

df_10bien %>% summarise(Mean_DT = mean(DoanhThu))
## # A tibble: 1 × 1
##   Mean_DT
##     <dbl>
## 1   8636.

Đầu tiên, nhóm tính giá trị trung bình (Mean) của biến DoanhThu bằng hàm mean(DoanhThu) và thu được kết quả 8636.33 tỷ đồng. Về mặt kỹ thuật, chỉ tiêu này phản ánh mức doanh thu bình quân của doanh nghiệp trong giai đoạn quan sát. Đây là một trong những thước đo tập trung phổ biến nhất trong thống kê mô tả, giúp hình dung quy mô hoạt động trung bình hàng năm. Về mặt kinh tế, giá trị trung bình này cho thấy doanh nghiệp đạt doanh thu bình quân khoảng 8.600 tỷ đồng mỗi năm

Giá trị Trung vị (Median) của DoanhThu.

df_10bien %>% summarise(Median_DT = median(DoanhThu))
## # A tibble: 1 × 1
##   Median_DT
##       <dbl>
## 1     8635.

Tiếp theo, nhóm tính trung vị (Median) bằng hàm median(DoanhThu) với kết quả 8634.82 tỷ đồng. Về mặt kỹ thuật, trung vị là giá trị nằm giữa dãy dữ liệu khi được sắp xếp theo thứ tự, do đó ít bị ảnh hưởng bởi các giá trị ngoại lai (outliers). So sánh giữa trung bình và trung vị cho thấy hai giá trị khá gần nhau → điều này chứng tỏ phân phối của doanh thu tương đối đối xứng, không có hiện tượng lệch mạnh sang một phía. Về mặt kinh tế, sự cân bằng này cho thấy doanh nghiệp có doanh thu ổn định, không xuất hiện năm nào vượt trội hoặc sụt giảm bất thường.

Giá trị Trung bình Cắt gọt (Trimmed Mean) (bỏ 10% mỗi đầu).

df_10bien %>% summarise(Trimmed_Mean_DT = mean(DoanhThu, trim = 0.1))
## # A tibble: 1 × 1
##   Trimmed_Mean_DT
##             <dbl>
## 1           8682.

Để kiểm tra thêm tính ổn định của dữ liệu, nhóm tính trung bình cắt gọt (Trimmed Mean), loại bỏ 10% giá trị cao và thấp nhất, bằng lệnh mean(DoanhThu, trim = 0.1). Kết quả thu được là 8682.30 tỷ đồng, khá gần với giá trị trung bình ban đầu. Về mặt thống kê, sự tương đồng này cho thấy không có giá trị cực đoan (outlier) đáng kể trong dữ liệu doanh thu. Về ý nghĩa kinh tế, điều này chứng minh rằng doanh thu của doanh nghiệp ổn định, không bị ảnh hưởng bởi những biến động bất thường theo năm.

Giá trị lớn nhất và nhỏ nhất (Range Ends).

df_10bien %>% summarise(min_dt = min(DoanhThu)) %>% print()
## # A tibble: 1 × 1
##   min_dt
##    <dbl>
## 1  1615.
df_10bien %>% summarise(max_dt = max(DoanhThu)) %>% print()
## # A tibble: 1 × 1
##   max_dt
##    <dbl>
## 1 15290.
df_10bien %>% summarise(Min_DT = min(DoanhThu), Max_DT = max(DoanhThu))
## # A tibble: 1 × 2
##   Min_DT Max_DT
##    <dbl>  <dbl>
## 1  1615. 15290.

Nhóm tiếp tục xác định giá trị tối thiểu (Min) và tối đa (Max) của doanh thu bằng hàm min() và max(). Kết quả là Min = 1614.55 tỷ đồng và Max = 15290.3 tỷ đồng. Khoảng dao động khá rộng giữa hai giá trị này cho thấy biến động đáng kể về doanh thu giữa các năm, có thể do ảnh hưởng của chu kỳ kinh doanh hoặc các yếu tố thị trường. Về mặt thống kê, đây là phạm vi biến thiên của biến (range), giúp đánh giá độ phân tán tổng thể. Về mặt kinh tế, khoảng cách lớn giữa Min và Max phản ánh sự mở rộng đáng kể về quy mô kinh doanh qua thời gian.

Mode (Giá trị xuất hiện nhiều nhất - Trong chuỗi thời gian, giá trị có thể không lặp).

names(sort(table(df_10bien$DoanhThu), decreasing = TRUE))[1]
## [1] "1614.548947901"

Trong chuỗi thời gian của biến DoanhThu, kết quả cho thấy Mode = 1614.55 tỷ đồng (giá trị xuất hiện đầu tiên trong bảng, vì dữ liệu có thể không lặp lại). Về kỹ thuật, Mode thường ít có ý nghĩa trong chuỗi thời gian tài chính do mỗi năm doanh thu khác nhau. Tuy nhiên, việc xác định Mode giúp kiểm tra xem có năm nào doanh thu lặp lại hoặc trùng khớp đáng chú ý hay không.

Phương sai

df_10bien %>% summarise(var_dt = var(DoanhThu)) %>% print()
## # A tibble: 1 × 1
##      var_dt
##       <dbl>
## 1 23578425.

Phương sai của doanh thu được tính bằng hàm var(DoanhThu) và đạt 23,578,425. Về mặt kỹ thuật, phương sai đo lường mức độ biến động bình quân của các quan sát so với trung bình. Giá trị phương sai càng lớn thì dữ liệu càng phân tán. Về mặt kinh tế, phương sai cao cho thấy doanh thu có sự dao động rõ rệt qua các năm, thể hiện sự thay đổi mạnh trong kết quả kinh doanh.

Độ lệch chuẩn

df_10bien %>% summarise(sd_dt = sd(DoanhThu)) %>% print()
## # A tibble: 1 × 1
##   sd_dt
##   <dbl>
## 1 4856.

Kết quả độ lệch chuẩn của doanh thu là 4855.76, được tính bằng hàm sd(DoanhThu). Về mặt thống kê, đây là thước đo độ phân tán quan trọng nhất, phản ánh mức độ chênh lệch trung bình của doanh thu so với giá trị trung bình. Về ý nghĩa kinh tế, độ lệch chuẩn cao cho thấy doanh thu có sự dao động đáng kể, doanh nghiệp cần phân tích các yếu tố thị trường hoặc chính sách quản trị để hiểu nguyên nhân của sự biến động này.

Phạm vi (range)

df_10bien %>% summarise(range_dt = max(DoanhThu) - min(DoanhThu)) %>% print()
## # A tibble: 1 × 1
##   range_dt
##      <dbl>
## 1   13676.

Phạm vi được tính bằng max(DoanhThu) - min(DoanhThu) và thu được kết quả 13,675.75 tỷ đồng. Đây là chỉ tiêu đơn giản thể hiện khoảng chênh lệch giữa doanh thu cao nhất và thấp nhất, giúp đánh giá độ lan tỏa của dữ liệu. Về kinh tế, phạm vi lớn cho thấy doanh nghiệp đã tăng doanh thu gần 10 lần trong giai đoạn khảo sát, phản ánh sự tăng trưởng đáng kể về quy mô và thị phần.

Độ lệch

library(moments)
library(dplyr)
df_10bien %>% summarise(skew_dt = skewness(DoanhThu)) %>% print()
## # A tibble: 1 × 1
##   skew_dt
##     <dbl>
## 1  -0.201

Giá trị độ lệch Skewness = -0.2007, được tính bằng hàm skewness(DoanhThu). Về mặt thống kê, giá trị âm nhỏ cho thấy phân phối doanh thu hơi lệch trái, nghĩa là phần lớn giá trị tập trung ở mức cao hơn trung bình, chỉ có vài năm doanh thu thấp hơn. Về mặt kinh tế, điều này phản ánh xu hướng tích cực trong hoạt động kinh doanh, khi phần lớn các năm doanh nghiệp đạt doanh thu cao hơn trung bình.

Độ nhọn

df_10bien %>% summarise(kurt_dt = kurtosis(DoanhThu)) %>% print()
## # A tibble: 1 × 1
##   kurt_dt
##     <dbl>
## 1    1.68

Giá trị độ nhọn Kurtosis = 1.68, được tính bằng kurtosis(DoanhThu). Trong thống kê, giá trị này nhỏ hơn 3 (chuẩn phân phối chuẩn), chứng tỏ phân phối doanh thu tương đối phẳng (platykurtic) – tức ít cực trị, phân tán đều. Về kinh tế, điều này đồng nghĩa với việc doanh thu không có biến động đột biến mạnh, thể hiện sự phát triển ổn định qua thời gian.

Quartile 1 (Q1)

df_10bien %>% summarise(Q1 = quantile(DoanhThu, 0.25)) %>% print()
## # A tibble: 1 × 1
##      Q1
##   <dbl>
## 1 4909.

Quartile 2 (Q2 - median)

df_10bien %>% summarise(Q2 = quantile(DoanhThu, 0.5)) %>% print()
## # A tibble: 1 × 1
##      Q2
##   <dbl>
## 1 8635.

Quartile 3 (Q3)

df_10bien %>% summarise(Q3 = quantile(DoanhThu, 0.75)) %>% print()
## # A tibble: 1 × 1
##       Q3
##    <dbl>
## 1 12742.

Q1 (25%) = 4909.35,

Q2 (50% – Median) = 8634.82,

Q3 (75%) = 12742.05.

Ba giá trị này được tính bằng hàm quantile() và giúp xác định phân bố doanh thu theo bốn khoảng. Khoảng giữa Q1 và Q3 gọi là phạm vi giữa tứ phân vị (IQR), thể hiện khoảng 50% doanh thu tập trung quanh mức trung bình, ở đây là khoảng 7832.7 tỷ đồng. → Về thống kê, điều này cho thấy dữ liệu có phân bố rộng nhưng vẫn tập trung quanh giá trị trung bình. → Về kinh tế, điều này phản ánh doanh nghiệp có doanh thu chủ yếu nằm trong khoảng từ 4.900 đến 12.700 tỷ đồng, thể hiện quy mô ổn định.

IQR

df_10bien %>% summarise(IQR = IQR(DoanhThu)) %>% print()
## # A tibble: 1 × 1
##     IQR
##   <dbl>
## 1 7833.

Nhóm tính chỉ tiêu IQR (Interquartile Range) bằng hàm IQR(DoanhThu) và thu được giá trị 7,832.71 tỷ đồng. Về mặt thống kê, IQR thể hiện độ phân tán của 50% giá trị trung tâm, được tính bằng chênh lệch giữa Q3 (tứ phân vị thứ 3) và Q1 (tứ phân vị thứ 1). Giá trị IQR lớn chứng tỏ dữ liệu doanh thu phân tán rộng, có sự khác biệt đáng kể giữa các năm nằm trong khoảng giữa. Về mặt kinh tế, điều này phản ánh doanh nghiệp có giai đoạn tăng trưởng doanh thu mạnh mẽ, trong khi một số năm trước đó doanh thu thấp hơn đáng kể — cho thấy xu hướng mở rộng quy mô kinh doanh theo thời gian.

Percentile 90

df_10bien %>% summarise(P90 = quantile(DoanhThu, 0.9)) %>% print()
## # A tibble: 1 × 1
##      P90
##    <dbl>
## 1 13358.

Giá trị P90 = 13,357.83 tỷ đồng cho biết 90% các năm có doanh thu nhỏ hơn giá trị này. Chỉ 10% các năm có doanh thu cao hơn → đây là các năm vượt trội về kết quả kinh doanh. Về kinh tế, giá trị này giúp nhận diện mức doanh thu nằm trong nhóm cao nhất, thể hiện giai đoạn doanh nghiệp đạt hiệu quả vượt trội so với trung bình.

Tương quan (Correlation) giữa Doanh Thu và Lợi Nhuận Gộp (LoiNhuanGop).

cor(df_10bien$DoanhThu, df_10bien$LoiNhuanGop)
## [1] 0.9222782

Kiểm tra mức độ tương quan giữa DoanhThu và LoiNhuanGop bằng hàm cor(). Kết quả là 0.9227, tức mối tương quan dương rất mạnh. Về mặt thống kê, giá trị này gần 1 chứng tỏ hai biến có mối quan hệ tuyến tính chặt chẽ, khi doanh thu tăng thì lợi nhuận gộp cũng tăng theo. Về mặt kinh tế, điều này hoàn toàn hợp lý, vì lợi nhuận gộp được hình thành trực tiếp từ doanh thu sau khi trừ giá vốn hàng bán. Mối tương quan cao này phản ánh hiệu quả hoạt động ổn định và khả năng chuyển hóa doanh thu thành lợi nhuận tốt.

Tương quan giữa Doanh Thu và LNST.

cor(df_10bien$DoanhThu, df_10bien$LNST)
## [1] 0.4992515

Đầu tiên, nhóm tính hệ số tương quan (correlation coefficient) giữa DoanhThu và LNST (Lợi nhuận sau thuế) bằng hàm cor(df_10bien\(DoanhThu, df_10bien\)LNST) và thu được kết quả 0.4993. Về mặt kỹ thuật, giá trị này nằm trong khoảng từ -1 đến 1. Do giá trị dương, nên hai biến có mối tương quan thuận, tức là khi doanh thu tăng thì lợi nhuận sau thuế cũng có xu hướng tăng. Tuy nhiên, vì hệ số chỉ ở mức 0.49, mối liên hệ này mang tính trung bình, không quá chặt chẽ. Về mặt kinh tế, điều này cho thấy rằng mặc dù doanh thu tăng, nhưng lợi nhuận ròng chưa tăng tương xứng, có thể do chi phí sản xuất, chi phí tài chính hoặc thuế tác động mạnh trong một số năm.

Hiệp phương sai với LNST

cov(df_10bien$DoanhThu, df_10bien$LoiNhuanGop) %>% print()
## [1] 1901511

Tiếp theo, nhóm sử dụng hàm cov(df_10bien\(DoanhThu, df_10bien\)LoiNhuanGop) để tính hiệp phương sai (covariance) giữa hai biến, thu được kết quả 1,901,511. Về mặt kỹ thuật, hiệp phương sai là thước đo thể hiện chiều hướng thay đổi cùng nhau của hai biến. Kết quả dương cho thấy khi doanh thu tăng thì lợi nhuận gộp cũng có xu hướng tăng theo. Về mặt kinh tế, điều này là hợp lý vì lợi nhuận gộp phụ thuộc trực tiếp vào doanh thu (sau khi trừ giá vốn hàng bán). Mức hiệp phương sai cao cho thấy biến động của doanh thu ảnh hưởng mạnh đến lợi nhuận gộp, phản ánh hiệu quả quản trị chi phí sản xuất ổn định qua các năm.

Hiệp phương sai với LNST

cov(df_10bien$DoanhThu, df_10bien$LNST) %>% print()
## [1] 293230

Tiếp theo, hiệp phương sai giữa DoanhThu và LNST được tính bằng cov(df_10bien\(DoanhThu, df_10bien\)LNST), kết quả là 293,230. Về mặt kỹ thuật, giá trị này nhỏ hơn nhiều so với hiệp phương sai giữa doanh thu và lợi nhuận gộp, cho thấy mối quan hệ giữa doanh thu và lợi nhuận sau thuế yếu hơn. Về mặt kinh tế, điều này hợp lý vì LNST chịu ảnh hưởng thêm từ chi phí tài chính, thuế, chi phí quản lý doanh nghiệp,… nên mối quan hệ với doanh thu không còn tuyến tính mạnh như lợi nhuận gộp. → Tóm lại, hiệp phương sai dương xác nhận rằng khi doanh thu tăng, lợi nhuận ròng cũng có xu hướng tăng, nhưng biên độ không đồng đều.

Tổng Doanh Thu Lũy kế (Total Sum).

df_10bien %>% summarise(Tong_DT = sum(DoanhThu))
## # A tibble: 1 × 1
##   Tong_DT
##     <dbl>
## 1  86363.

Nhóm sử dụng hàm summarise(Tong_DT = sum(DoanhThu)) để tính tổng doanh thu lũy kế trong giai đoạn nghiên cứu. Kết quả cho thấy tổng doanh thu đạt 86,363.28 tỷ đồng. Về mặt kỹ thuật, đây là phép cộng toàn bộ giá trị của biến DoanhThu trong tập dữ liệu. Về mặt kinh tế, con số này phản ánh tổng doanh thu tích lũy của doanh nghiệp trong toàn bộ giai đoạn 2015–2024, qua đó có thể dùng để so sánh với tổng lợi nhuận tích lũy hoặc dòng tiền hoạt động nhằm đánh giá hiệu quả dài hạn của hoạt động kinh doanh.

Bảng thống kê toàn diện (Tóm tắt nhiều chỉ số cùng lúc).

df_10bien %>% summarise(Count = n(), Mean = mean(DoanhThu), SD = sd(DoanhThu), Median = median(DoanhThu), Min = min(DoanhThu), Max = max(DoanhThu))
## # A tibble: 1 × 6
##   Count  Mean    SD Median   Min    Max
##   <int> <dbl> <dbl>  <dbl> <dbl>  <dbl>
## 1    10 8636. 4856.  8635. 1615. 15290.

Cuối cùng, nhóm tổng hợp các chỉ tiêu thống kê mô tả cơ bản cho biến DoanhThu bằng hàm summarise() gồm:

Count (n): 10 quan sát

Mean: 8,636.33

SD (Độ lệch chuẩn): 4,855.76

Median: 8,634.82

Min: 1,614.55

Max: 15,290.3

Về mặt kỹ thuật, đây là bước tóm tắt toàn bộ đặc trưng thống kê trong một bảng duy nhất, giúp đối chiếu nhanh và dễ đọc. Về mặt kinh tế, bảng này cho thấy doanh thu trung bình và trung vị gần như trùng nhau, chứng tỏ phân phối dữ liệu tương đối cân đối, không có năm nào doanh thu vượt trội bất thường. Tuy nhiên, độ lệch chuẩn lớn cho thấy biến động về doanh thu vẫn đáng kể, thể hiện tính chu kỳ hoặc ảnh hưởng từ yếu tố thị trường bên ngoài. → Như vậy, bảng thống kê này giúp đưa ra cái nhìn toàn diện về mức độ tập trung, phân tán và biến động của doanh thu trong suốt giai đoạn nghiên cứu.

2.6.2.2. Phân Tích Tăng Trưởng và Biến Động Chu Kỳ

Tính Tốc độ tăng trưởng hàng năm kép (CAGR) cục bộ 3 năm (Rolling CAGR).

df_10bien %>% arrange(nam) %>% mutate(CAGR_3Y = (DoanhThu / lag(DoanhThu, n=3))^(1/3) - 1)
## # A tibble: 10 × 21
##      nam  LNST DoanhThu LoiNhuanGop TSNganHan NoNganHan VonChuSoHuu TongTaiSan
##    <int> <dbl>    <dbl>       <dbl>     <dbl>     <dbl>       <dbl>      <dbl>
##  1  2015  40.0    1615.        190.     1072.      667.        819.      1955.
##  2  2016 142.     2144.        307.     1362.     1140.        955.      3078.
##  3  2017 223.     4070.        550.     2143.     1991.       1625.      4576.
##  4  2018 180.     8012.        673.     3989.     3206.       2980.      7529.
##  5  2019 460.     9258.       1042.     4971.     3237.       3255.      7987.
##  6  2020 262.     7429.        777.     4496.     3773.       4024.      8569.
##  7  2021 290.    13143.       1301.     5355.     3282.       5454.     10010.
##  8  2022 153.    15290.       1086.     5659.     3206.       6171.     10796.
##  9  2023 289.    12622.       1109.     5682.     3737.       5964.     11583.
## 10  2024 369.    12782.       1484.     6426.     4133.       6236.     13768.
## # ℹ 13 more variables: NoPhaiTra <dbl>, HangTonKho <dbl>, TienThuanHDKD <dbl>,
## #   GPM <dbl>, DE_Ratio <dbl>, CurrentRatio <dbl>, ton_kho_taisan <dbl>,
## #   cash_to_profit <dbl>, dot <chr>, loi_lo <chr>, TT_DT <dbl>, quy_mo <chr>,
## #   CAGR_3Y <dbl>

Giá trị của CAGR_3Y dao động quanh khoảng từ 0.6 đến 0.7 ở một số giai đoạn, nghĩa là trung bình mỗi năm doanh thu tăng khoảng 60–70%. Tuy nhiên, có những thời điểm giá trị này giảm xuống gần 0.17 hoặc thậm chí âm, thể hiện mức tăng trưởng chậm lại hoặc doanh thu suy giảm nhẹ so với ba năm trước. Nhìn chung, cột này phản ánh nhịp độ phát triển dài hạn của doanh nghiệp, cho thấy mức tăng trưởng có xu hướng biến động nhưng vẫn duy trì được quỹ đạo ổn định theo chu kỳ ba năm.

Tính logarit tự nhiên (ln) của Doanh Thu.

df_10bien %>% mutate(Log_DT = log(DoanhThu))
## # A tibble: 10 × 21
##      nam  LNST DoanhThu LoiNhuanGop TSNganHan NoNganHan VonChuSoHuu TongTaiSan
##    <int> <dbl>    <dbl>       <dbl>     <dbl>     <dbl>       <dbl>      <dbl>
##  1  2015  40.0    1615.        190.     1072.      667.        819.      1955.
##  2  2016 142.     2144.        307.     1362.     1140.        955.      3078.
##  3  2017 223.     4070.        550.     2143.     1991.       1625.      4576.
##  4  2018 180.     8012.        673.     3989.     3206.       2980.      7529.
##  5  2019 460.     9258.       1042.     4971.     3237.       3255.      7987.
##  6  2020 262.     7429.        777.     4496.     3773.       4024.      8569.
##  7  2021 290.    13143.       1301.     5355.     3282.       5454.     10010.
##  8  2022 153.    15290.       1086.     5659.     3206.       6171.     10796.
##  9  2023 289.    12622.       1109.     5682.     3737.       5964.     11583.
## 10  2024 369.    12782.       1484.     6426.     4133.       6236.     13768.
## # ℹ 13 more variables: NoPhaiTra <dbl>, HangTonKho <dbl>, TienThuanHDKD <dbl>,
## #   GPM <dbl>, DE_Ratio <dbl>, CurrentRatio <dbl>, ton_kho_taisan <dbl>,
## #   cash_to_profit <dbl>, dot <chr>, loi_lo <chr>, TT_DT <dbl>, quy_mo <chr>,
## #   Log_DT <dbl>

Việc lấy logarit giúp dữ liệu tăng trưởng có dạng tuyến tính hơn, dễ nhận thấy xu hướng và hạn chế ảnh hưởng của các giá trị cực lớn. Giá trị Log_DT trong bảng tăng dần từ khoảng 7.3 đến hơn 9.4, cho thấy quy mô doanh thu mở rộng theo cấp số nhân. Khi giá trị logarit tăng đều, điều đó có nghĩa doanh thu thực tế cũng tăng dần, phản ánh tốc độ tăng trưởng tích lũy ổn định của doanh nghiệp. Cột này giúp nhận biết sự phát triển của doanh thu không phải theo chênh lệch tuyệt đối mà theo tỷ lệ tăng, thể hiện rõ hơn tốc độ lớn mạnh về mặt quy mô.

Tính Tốc độ tăng trưởng log-return.

df_10bien %>% mutate(Log_Return_DT = log(DoanhThu / lag(DoanhThu)))
## # A tibble: 10 × 21
##      nam  LNST DoanhThu LoiNhuanGop TSNganHan NoNganHan VonChuSoHuu TongTaiSan
##    <int> <dbl>    <dbl>       <dbl>     <dbl>     <dbl>       <dbl>      <dbl>
##  1  2015  40.0    1615.        190.     1072.      667.        819.      1955.
##  2  2016 142.     2144.        307.     1362.     1140.        955.      3078.
##  3  2017 223.     4070.        550.     2143.     1991.       1625.      4576.
##  4  2018 180.     8012.        673.     3989.     3206.       2980.      7529.
##  5  2019 460.     9258.       1042.     4971.     3237.       3255.      7987.
##  6  2020 262.     7429.        777.     4496.     3773.       4024.      8569.
##  7  2021 290.    13143.       1301.     5355.     3282.       5454.     10010.
##  8  2022 153.    15290.       1086.     5659.     3206.       6171.     10796.
##  9  2023 289.    12622.       1109.     5682.     3737.       5964.     11583.
## 10  2024 369.    12782.       1484.     6426.     4133.       6236.     13768.
## # ℹ 13 more variables: NoPhaiTra <dbl>, HangTonKho <dbl>, TienThuanHDKD <dbl>,
## #   GPM <dbl>, DE_Ratio <dbl>, CurrentRatio <dbl>, ton_kho_taisan <dbl>,
## #   cash_to_profit <dbl>, dot <chr>, loi_lo <chr>, TT_DT <dbl>, quy_mo <chr>,
## #   Log_Return_DT <dbl>

Chỉ tiêu này cho biết mức tăng hay giảm tương đối của doanh thu hằng năm. Khi giá trị dương, doanh thu tăng so với năm trước; ngược lại, khi giá trị âm, doanh thu giảm. Các giá trị dao động trong khoảng từ -0.22 đến 0.67, phản ánh sự biến động của doanh thu qua từng năm. Mức log-return cao đồng nghĩa với tốc độ tăng trưởng nhanh, trong khi giá trị nhỏ hoặc âm thể hiện sự chững lại. Việc sử dụng log-return giúp nhận diện rõ các biến động ngắn hạn và xu hướng tăng giảm liên tục trong chuỗi doanh thu.

Doanh Thu Lợi nhuận gộp (LoiNhuanGop) được chuẩn hóa theo Doanh Thu.

df_10bien %>% mutate(DoanhThu_Ratio = DoanhThu / sum(DoanhThu))
## # A tibble: 10 × 21
##      nam  LNST DoanhThu LoiNhuanGop TSNganHan NoNganHan VonChuSoHuu TongTaiSan
##    <int> <dbl>    <dbl>       <dbl>     <dbl>     <dbl>       <dbl>      <dbl>
##  1  2015  40.0    1615.        190.     1072.      667.        819.      1955.
##  2  2016 142.     2144.        307.     1362.     1140.        955.      3078.
##  3  2017 223.     4070.        550.     2143.     1991.       1625.      4576.
##  4  2018 180.     8012.        673.     3989.     3206.       2980.      7529.
##  5  2019 460.     9258.       1042.     4971.     3237.       3255.      7987.
##  6  2020 262.     7429.        777.     4496.     3773.       4024.      8569.
##  7  2021 290.    13143.       1301.     5355.     3282.       5454.     10010.
##  8  2022 153.    15290.       1086.     5659.     3206.       6171.     10796.
##  9  2023 289.    12622.       1109.     5682.     3737.       5964.     11583.
## 10  2024 369.    12782.       1484.     6426.     4133.       6236.     13768.
## # ℹ 13 more variables: NoPhaiTra <dbl>, HangTonKho <dbl>, TienThuanHDKD <dbl>,
## #   GPM <dbl>, DE_Ratio <dbl>, CurrentRatio <dbl>, ton_kho_taisan <dbl>,
## #   cash_to_profit <dbl>, dot <chr>, loi_lo <chr>, TT_DT <dbl>, quy_mo <chr>,
## #   DoanhThu_Ratio <dbl>

Đây là chỉ tiêu chuẩn hóa cho thấy mức đóng góp của từng quan sát vào tổng thể. Các giá trị dao động từ khoảng 0.018 đến 0.17, nghĩa là doanh thu của từng năm chiếm từ 1.8% đến 17% tổng doanh thu chung. Khi tỷ lệ cao, năm đó đóng góp phần lớn vào quy mô hoạt động chung; khi tỷ lệ thấp, mức đóng góp nhỏ hơn. Việc tính tỷ trọng này giúp so sánh vai trò tương đối của từng kỳ trong tổng thể và đánh giá phân bố doanh thu theo thời gian một cách trực quan hơn.

2.6.3. Thống kê biến LNST

2.6.3.1. Thống kê sơ bộ

Phân tích giá trị trung bình (TB_LNST)

df_10bien %>% summarise(TB_LNST = mean(LNST))
## # A tibble: 1 × 1
##   TB_LNST
##     <dbl>
## 1    241.

Trong phép tính này, hàm mean(LNST) được sử dụng để xác định giá trị trung bình của lợi nhuận sau thuế (LNST). Kết quả cho thấy giá trị trung bình của LNST là 240.9143. Điều này có nghĩa là, xét trên toàn bộ các năm trong tập dữ liệu, trung bình mỗi năm doanh nghiệp đạt lợi nhuận sau thuế khoảng 240.9 đơn vị. Đây là một con số phản ánh mức sinh lời bình quân của doanh nghiệp trong giai đoạn được phân tích. Giá trị trung bình là cơ sở ban đầu giúp đánh giá hiệu suất hoạt động tổng thể, trước khi xem xét đến mức độ dao động hoặc phân tán của lợi nhuận giữa các năm.

Phân tích giá trị nhỏ nhất (Min_LNST)

df_10bien %>% summarise(Min_LNST = min(LNST))
## # A tibble: 1 × 1
##   Min_LNST
##      <dbl>
## 1     40.0

Tiếp theo, phép tính min(LNST) được dùng để tìm ra giá trị nhỏ nhất của lợi nhuận sau thuế trong toàn bộ dữ liệu. Kết quả thu được là 40.01587, cho thấy năm có lợi nhuận thấp nhất vẫn ghi nhận mức dương. Điều này chứng tỏ doanh nghiệp không bị thua lỗ trong khoảng thời gian được xem xét. Giá trị nhỏ nhất phản ánh mức nền thấp nhất về lợi nhuận, cung cấp thông tin hữu ích khi so sánh với trung bình để xem độ chênh lệch giữa năm tốt và năm yếu nhất về hiệu quả tài chính.

Độ lệch chuẩn (SD_LNST)

df_10bien %>% summarise(SD_LNST = sd(LNST))
## # A tibble: 1 × 1
##   SD_LNST
##     <dbl>
## 1    121.

Hàm sd(LNST) được sử dụng để đo lường mức độ phân tán của dữ liệu lợi nhuận xung quanh giá trị trung bình. Kết quả cho thấy độ lệch chuẩn SD_LNST đạt 120.9571, tức là các giá trị lợi nhuận hàng năm chênh lệch trung bình khoảng 121 đơn vị so với giá trị trung bình 240.9. Độ lệch chuẩn càng lớn chứng tỏ mức biến động lợi nhuận giữa các năm càng cao. Với kết quả này, có thể thấy lợi nhuận của doanh nghiệp biến động tương đối đáng kể qua các năm, thể hiện sự không đồng đều trong hiệu quả hoạt động.

Phân tích hệ số biến thiên (CV_LNST)

df_10bien %>% summarise(CV_LNST = sd(LNST) / mean(LNST))
## # A tibble: 1 × 1
##   CV_LNST
##     <dbl>
## 1   0.502

Hệ số biến thiên được tính bằng công thức sd(LNST) / mean(LNST), giúp thể hiện mức độ dao động tương đối so với trung bình. Giá trị kết quả là 0.5020755, tức khoảng 50.2%. Điều này nghĩa là độ lệch chuẩn của lợi nhuận chiếm khoảng một nửa so với giá trị trung bình, cho thấy mức biến động lợi nhuận là trung bình khá cao. Hệ số biến thiên là thước đo hữu ích để so sánh tính ổn định của lợi nhuận giữa các giai đoạn hoặc giữa các doanh nghiệp khác nhau, vì nó loại bỏ ảnh hưởng của quy mô.

Phân tích số năm lỗ (SoNamLo)

df_10bien %>% filter(LNST < 0) %>% summarise(SoNamLo = n())
## # A tibble: 1 × 1
##   SoNamLo
##     <int>
## 1       0

Phép tính này sử dụng lệnh filter(LNST < 0) để lọc các năm có lợi nhuận âm, sau đó đếm số lượng bằng n(). Kết quả trả về là 0, nghĩa là trong toàn bộ chuỗi dữ liệu, không có năm nào doanh nghiệp bị thua lỗ. Đây là dấu hiệu tích cực cho thấy khả năng duy trì hoạt động kinh doanh có lãi ổn định trong suốt giai đoạn được quan sát. Thông tin này đồng thời củng cố kết quả của giá trị nhỏ nhất ở trên, khi lợi nhuận thấp nhất vẫn là một con số dương.

Phân tích tứ phân vị thứ nhất (Q1_LNST)

df_10bien %>% summarise(Q1_LNST = quantile(LNST, 0.25))
## # A tibble: 1 × 1
##   Q1_LNST
##     <dbl>
## 1    160.

Giá trị Q1_LNST = 159.5146 được tính bằng hàm quantile(LNST, 0.25), thể hiện mức lợi nhuận tại vị trí 25% nhỏ nhất của dữ liệu. Nói cách khác, 25% các năm có lợi nhuận sau thuế nhỏ hơn hoặc bằng 159.5. Giá trị này giúp đánh giá sự phân bố của lợi nhuận và được sử dụng trong việc so sánh với trung vị hoặc các tứ phân vị khác để xác định mức độ chênh lệch giữa các nhóm năm. Q1 thấp hơn đáng kể so với trung bình cho thấy phần lớn dữ liệu nằm ở mức lợi nhuận cao hơn.

Phân tích độ lệch (Skewness_LNST)

df_10bien %>% summarise(Skewness_LNST = moments::skewness(LNST))
## # A tibble: 1 × 1
##   Skewness_LNST
##           <dbl>
## 1         0.193

Hàm moments::skewness(LNST) được dùng để đo lường độ lệch của phân phối lợi nhuận sau thuế so với phân phối chuẩn. Kết quả là 0.1928367, một giá trị dương nhỏ, thể hiện phân phối của dữ liệu hơi lệch phải (nghiêng nhẹ về phía các giá trị cao hơn). Điều này có nghĩa rằng phần lớn các giá trị lợi nhuận tập trung quanh mức trung bình, chỉ có một vài năm đạt lợi nhuận cao hơn đáng kể kéo đuôi phân phối về bên phải. Mức độ lệch thấp cho thấy dữ liệu tương đối đối xứng, không có sự sai lệch lớn trong lợi nhuận giữa các năm.

2.6.3.2. Phân Tích Tăng Trưởng và Biến Động Chu Kỳ

Phân tích cột TT_LNST – Tốc độ tăng trưởng LNST

df_10bien %>% mutate(TT_LNST = (LNST / lag(LNST)) - 1)
## # A tibble: 10 × 21
##      nam  LNST DoanhThu LoiNhuanGop TSNganHan NoNganHan VonChuSoHuu TongTaiSan
##    <int> <dbl>    <dbl>       <dbl>     <dbl>     <dbl>       <dbl>      <dbl>
##  1  2015  40.0    1615.        190.     1072.      667.        819.      1955.
##  2  2016 142.     2144.        307.     1362.     1140.        955.      3078.
##  3  2017 223.     4070.        550.     2143.     1991.       1625.      4576.
##  4  2018 180.     8012.        673.     3989.     3206.       2980.      7529.
##  5  2019 460.     9258.       1042.     4971.     3237.       3255.      7987.
##  6  2020 262.     7429.        777.     4496.     3773.       4024.      8569.
##  7  2021 290.    13143.       1301.     5355.     3282.       5454.     10010.
##  8  2022 153.    15290.       1086.     5659.     3206.       6171.     10796.
##  9  2023 289.    12622.       1109.     5682.     3737.       5964.     11583.
## 10  2024 369.    12782.       1484.     6426.     4133.       6236.     13768.
## # ℹ 13 more variables: NoPhaiTra <dbl>, HangTonKho <dbl>, TienThuanHDKD <dbl>,
## #   GPM <dbl>, DE_Ratio <dbl>, CurrentRatio <dbl>, ton_kho_taisan <dbl>,
## #   cash_to_profit <dbl>, dot <chr>, loi_lo <chr>, TT_DT <dbl>, quy_mo <chr>,
## #   TT_LNST <dbl>

Chỉ tiêu này cho biết mức thay đổi của lợi nhuận hiện tại so với năm liền kề trước đó theo tỷ lệ phần trăm. Kết quả cho thấy các giá trị TT_LNST dao động từ khoảng -0.43 đến 2.54, nghĩa là có những năm lợi nhuận tăng gấp đôi, trong khi một số năm giảm khoảng 40%. Sự biến động của cột này phản ánh rõ tính chu kỳ trong hoạt động kinh doanh, cho thấy mức tăng trưởng LNST không ổn định mà thay đổi khá mạnh giữa các năm.

Phân tích cột LNST_TB_3Y – Lợi nhuận trung bình ba năm

df_10bien %>% arrange(nam) %>% mutate(LNST_TB_3Y = zoo::rollmean(LNST, k=3, fill=NA, align="right"))
## # A tibble: 10 × 21
##      nam  LNST DoanhThu LoiNhuanGop TSNganHan NoNganHan VonChuSoHuu TongTaiSan
##    <int> <dbl>    <dbl>       <dbl>     <dbl>     <dbl>       <dbl>      <dbl>
##  1  2015  40.0    1615.        190.     1072.      667.        819.      1955.
##  2  2016 142.     2144.        307.     1362.     1140.        955.      3078.
##  3  2017 223.     4070.        550.     2143.     1991.       1625.      4576.
##  4  2018 180.     8012.        673.     3989.     3206.       2980.      7529.
##  5  2019 460.     9258.       1042.     4971.     3237.       3255.      7987.
##  6  2020 262.     7429.        777.     4496.     3773.       4024.      8569.
##  7  2021 290.    13143.       1301.     5355.     3282.       5454.     10010.
##  8  2022 153.    15290.       1086.     5659.     3206.       6171.     10796.
##  9  2023 289.    12622.       1109.     5682.     3737.       5964.     11583.
## 10  2024 369.    12782.       1484.     6426.     4133.       6236.     13768.
## # ℹ 13 more variables: NoPhaiTra <dbl>, HangTonKho <dbl>, TienThuanHDKD <dbl>,
## #   GPM <dbl>, DE_Ratio <dbl>, CurrentRatio <dbl>, ton_kho_taisan <dbl>,
## #   cash_to_profit <dbl>, dot <chr>, loi_lo <chr>, TT_DT <dbl>, quy_mo <chr>,
## #   LNST_TB_3Y <dbl>

Công thức zoo::rollmean(LNST, k=3, fill=NA, align=“right”) được áp dụng để tính lợi nhuận trung bình ba năm liên tiếp. Giá trị LNST_TB_3Y phản ánh xu hướng lợi nhuận được làm mượt, loại bỏ ảnh hưởng của các dao động ngắn hạn. Các giá trị trung bình ba năm dao động từ khoảng 135 đến 370, cho thấy mức lợi nhuận trung bình đang tăng dần. Chỉ tiêu này có ý nghĩa quan trọng vì nó thể hiện hiệu quả hoạt động ổn định của doanh nghiệp trong trung hạn, giúp nhìn nhận xu hướng lợi nhuận thực tế thay vì chỉ dựa vào một năm riêng lẻ.

Phân tích lọc giá trị âm của TT_LNST – Các năm LNST giảm

df_10bien %>% mutate(TT_LNST = (LNST / lag(LNST)) - 1) %>% filter(TT_LNST < 0)
## # A tibble: 3 × 21
##     nam  LNST DoanhThu LoiNhuanGop TSNganHan NoNganHan VonChuSoHuu TongTaiSan
##   <int> <dbl>    <dbl>       <dbl>     <dbl>     <dbl>       <dbl>      <dbl>
## 1  2018  180.    8012.        673.     3989.     3206.       2980.      7529.
## 2  2020  262.    7429.        777.     4496.     3773.       4024.      8569.
## 3  2022  153.   15290.       1086.     5659.     3206.       6171.     10796.
## # ℹ 13 more variables: NoPhaiTra <dbl>, HangTonKho <dbl>, TienThuanHDKD <dbl>,
## #   GPM <dbl>, DE_Ratio <dbl>, CurrentRatio <dbl>, ton_kho_taisan <dbl>,
## #   cash_to_profit <dbl>, dot <chr>, loi_lo <chr>, TT_DT <dbl>, quy_mo <chr>,
## #   TT_LNST <dbl>

Sau khi tính tốc độ tăng trưởng, đoạn mã có thêm phần lọc filter(TT_LNST < 0) để chọn ra những năm mà LNST giảm so với năm trước. Kết quả cho thấy ba năm có giá trị âm, thể hiện rõ các giai đoạn lợi nhuận sụt giảm. Việc xác định những năm này rất quan trọng vì nó giúp nhận diện thời kỳ doanh nghiệp gặp khó khăn hoặc hoạt động kém hiệu quả. Đây là cơ sở để xem xét nguyên nhân biến động và đánh giá khả năng phục hồi của lợi nhuận trong các năm sau đó.

Phân tích cột Log_Return_LNST – Tốc độ tăng trưởng logarit của LNST

df_10bien %>% mutate(Log_Return_LNST = log(LNST / lag(LNST)))
## # A tibble: 10 × 21
##      nam  LNST DoanhThu LoiNhuanGop TSNganHan NoNganHan VonChuSoHuu TongTaiSan
##    <int> <dbl>    <dbl>       <dbl>     <dbl>     <dbl>       <dbl>      <dbl>
##  1  2015  40.0    1615.        190.     1072.      667.        819.      1955.
##  2  2016 142.     2144.        307.     1362.     1140.        955.      3078.
##  3  2017 223.     4070.        550.     2143.     1991.       1625.      4576.
##  4  2018 180.     8012.        673.     3989.     3206.       2980.      7529.
##  5  2019 460.     9258.       1042.     4971.     3237.       3255.      7987.
##  6  2020 262.     7429.        777.     4496.     3773.       4024.      8569.
##  7  2021 290.    13143.       1301.     5355.     3282.       5454.     10010.
##  8  2022 153.    15290.       1086.     5659.     3206.       6171.     10796.
##  9  2023 289.    12622.       1109.     5682.     3737.       5964.     11583.
## 10  2024 369.    12782.       1484.     6426.     4133.       6236.     13768.
## # ℹ 13 more variables: NoPhaiTra <dbl>, HangTonKho <dbl>, TienThuanHDKD <dbl>,
## #   GPM <dbl>, DE_Ratio <dbl>, CurrentRatio <dbl>, ton_kho_taisan <dbl>,
## #   cash_to_profit <dbl>, dot <chr>, loi_lo <chr>, TT_DT <dbl>, quy_mo <chr>,
## #   Log_Return_LNST <dbl>

Cột Log_Return_LNST được tính bằng công thức log(LNST / lag(LNST)), nhằm xác định tốc độ tăng trưởng logarit của lợi nhuận sau thuế. Khác với tốc độ tăng trưởng thông thường, log-return cho phép so sánh dễ dàng hơn giữa các giai đoạn vì nó phản ánh tỷ lệ thay đổi theo quy mô tương đối. Giá trị log-return dương thể hiện lợi nhuận tăng, còn giá trị âm thể hiện lợi nhuận giảm. Các kết quả dao động trong khoảng từ -0.56 đến 1.26, cho thấy lợi nhuận có sự biến động lớn, nhưng phương pháp logarit giúp dữ liệu trở nên mượt hơn và thuận tiện cho các phân tích thống kê, chẳng hạn như đo mức độ rủi ro hoặc ước lượng hồi quy sau này.

Phân tích SD_Log_Return – Độ lệch chuẩn của tăng trưởng logarit LNST

df_10bien %>% mutate(Log_Return_LNST = log(LNST / lag(LNST))) %>% summarise(SD_Log_Return = sd(Log_Return_LNST, na.rm = TRUE))
## # A tibble: 1 × 1
##   SD_Log_Return
##           <dbl>
## 1         0.651

Bước tiếp theo sử dụng sd(Log_Return_LNST, na.rm=TRUE) để tính độ lệch chuẩn của tốc độ tăng trưởng logarit lợi nhuận sau thuế. Kết quả thu được là 0.651481, thể hiện mức độ dao động trung bình của lợi nhuận tương đối lớn quanh giá trị trung bình. Nói cách khác, lợi nhuận có biến động đáng kể qua các năm, chưa đạt mức ổn định cao. Độ lệch chuẩn của log-return là chỉ tiêu phổ biến trong phân tích tài chính, giúp đánh giá rủi ro biến động lợi nhuận và mức ổn định của quá trình tăng trưởng.

Phân tích biến LNST_Outlier – Phát hiện giá trị ngoại lai của lợi nhuận

tb = mean(df_10bien$LNST); sd = sd(df_10bien$LNST); df_10bien %>% mutate(LNST_Outlier = if_else(abs(LNST - tb) > 2 * sd, TRUE, FALSE))
## # A tibble: 10 × 21
##      nam  LNST DoanhThu LoiNhuanGop TSNganHan NoNganHan VonChuSoHuu TongTaiSan
##    <int> <dbl>    <dbl>       <dbl>     <dbl>     <dbl>       <dbl>      <dbl>
##  1  2015  40.0    1615.        190.     1072.      667.        819.      1955.
##  2  2016 142.     2144.        307.     1362.     1140.        955.      3078.
##  3  2017 223.     4070.        550.     2143.     1991.       1625.      4576.
##  4  2018 180.     8012.        673.     3989.     3206.       2980.      7529.
##  5  2019 460.     9258.       1042.     4971.     3237.       3255.      7987.
##  6  2020 262.     7429.        777.     4496.     3773.       4024.      8569.
##  7  2021 290.    13143.       1301.     5355.     3282.       5454.     10010.
##  8  2022 153.    15290.       1086.     5659.     3206.       6171.     10796.
##  9  2023 289.    12622.       1109.     5682.     3737.       5964.     11583.
## 10  2024 369.    12782.       1484.     6426.     4133.       6236.     13768.
## # ℹ 13 more variables: NoPhaiTra <dbl>, HangTonKho <dbl>, TienThuanHDKD <dbl>,
## #   GPM <dbl>, DE_Ratio <dbl>, CurrentRatio <dbl>, ton_kho_taisan <dbl>,
## #   cash_to_profit <dbl>, dot <chr>, loi_lo <chr>, TT_DT <dbl>, quy_mo <chr>,
## #   LNST_Outlier <lgl>

Trong thao tác này, tác giả sử dụng điều kiện abs(LNST - tb) > 2 * sd để xác định những năm có lợi nhuận nằm ngoài phạm vi hai độ lệch chuẩn so với trung bình. Kết quả trả về giá trị logic (TRUE hoặc FALSE), trong đó TRUE biểu thị các năm có LNST khác biệt rõ rệt so với mức bình thường. Phép kiểm này giúp phát hiện các giá trị ngoại lai (outlier) – thường là các năm có lợi nhuận quá cao hoặc quá thấp bất thường. Đây là bước quan trọng trong phân tích thống kê, nhằm loại bỏ ảnh hưởng của các điểm dữ liệu cực đoan có thể làm sai lệch kết quả khi phân tích xu hướng hoặc hồi quy sau này.

2.6.3.3 Phân Tích Tỷ Số và Tương Quan (LNST với Tài sản/Doanh thu)

Phân tích các chỉ tiêu

df_10bien %>% mutate(ROS = LNST / DoanhThu)
## # A tibble: 10 × 21
##      nam  LNST DoanhThu LoiNhuanGop TSNganHan NoNganHan VonChuSoHuu TongTaiSan
##    <int> <dbl>    <dbl>       <dbl>     <dbl>     <dbl>       <dbl>      <dbl>
##  1  2015  40.0    1615.        190.     1072.      667.        819.      1955.
##  2  2016 142.     2144.        307.     1362.     1140.        955.      3078.
##  3  2017 223.     4070.        550.     2143.     1991.       1625.      4576.
##  4  2018 180.     8012.        673.     3989.     3206.       2980.      7529.
##  5  2019 460.     9258.       1042.     4971.     3237.       3255.      7987.
##  6  2020 262.     7429.        777.     4496.     3773.       4024.      8569.
##  7  2021 290.    13143.       1301.     5355.     3282.       5454.     10010.
##  8  2022 153.    15290.       1086.     5659.     3206.       6171.     10796.
##  9  2023 289.    12622.       1109.     5682.     3737.       5964.     11583.
## 10  2024 369.    12782.       1484.     6426.     4133.       6236.     13768.
## # ℹ 13 more variables: NoPhaiTra <dbl>, HangTonKho <dbl>, TienThuanHDKD <dbl>,
## #   GPM <dbl>, DE_Ratio <dbl>, CurrentRatio <dbl>, ton_kho_taisan <dbl>,
## #   cash_to_profit <dbl>, dot <chr>, loi_lo <chr>, TT_DT <dbl>, quy_mo <chr>,
## #   ROS <dbl>

Chỉ tiêu này cho biết với mỗi đồng doanh thu thu được, doanh nghiệp giữ lại bao nhiêu đồng lợi nhuận sau thuế. Kết quả ROS dao động quanh khoảng 0.01 đến 0.07, nghĩa là biên lợi nhuận ròng trung bình đạt từ 1% đến 7%. Điều này thể hiện khả năng kiểm soát chi phí và hiệu quả hoạt động kinh doanh. ROS càng cao thì doanh nghiệp càng sinh lời tốt trên doanh thu. Trong dữ liệu, có năm ROS đạt mức cao nhất, được xác định là năm 2016, cho thấy đó là giai đoạn doanh nghiệp hoạt động hiệu quả nhất về mặt lợi nhuận thuần so với doanh thu.

Phân tích tương quan giữa LNST và Tổng tài sản

df_10bien %>% mutate(ROA = LNST / TongTaiSan)
## # A tibble: 10 × 21
##      nam  LNST DoanhThu LoiNhuanGop TSNganHan NoNganHan VonChuSoHuu TongTaiSan
##    <int> <dbl>    <dbl>       <dbl>     <dbl>     <dbl>       <dbl>      <dbl>
##  1  2015  40.0    1615.        190.     1072.      667.        819.      1955.
##  2  2016 142.     2144.        307.     1362.     1140.        955.      3078.
##  3  2017 223.     4070.        550.     2143.     1991.       1625.      4576.
##  4  2018 180.     8012.        673.     3989.     3206.       2980.      7529.
##  5  2019 460.     9258.       1042.     4971.     3237.       3255.      7987.
##  6  2020 262.     7429.        777.     4496.     3773.       4024.      8569.
##  7  2021 290.    13143.       1301.     5355.     3282.       5454.     10010.
##  8  2022 153.    15290.       1086.     5659.     3206.       6171.     10796.
##  9  2023 289.    12622.       1109.     5682.     3737.       5964.     11583.
## 10  2024 369.    12782.       1484.     6426.     4133.       6236.     13768.
## # ℹ 13 more variables: NoPhaiTra <dbl>, HangTonKho <dbl>, TienThuanHDKD <dbl>,
## #   GPM <dbl>, DE_Ratio <dbl>, CurrentRatio <dbl>, ton_kho_taisan <dbl>,
## #   cash_to_profit <dbl>, dot <chr>, loi_lo <chr>, TT_DT <dbl>, quy_mo <chr>,
## #   ROA <dbl>

Chỉ tiêu ROA cho thấy mức độ hiệu quả trong việc sử dụng tài sản để tạo ra lợi nhuận. Kết quả tính toán cho thấy ROA dao động trong khoảng từ 0.014 đến 0.057, tức là trung bình mỗi đồng tài sản tạo ra từ 1,4% đến 5,7% lợi nhuận sau thuế. Đây là mức hiệu quả trung bình khá, thể hiện việc quản lý và khai thác tài sản mang lại lợi nhuận ổn định. Khi so sánh các năm, sự biến động nhẹ của ROA cho thấy doanh nghiệp có xu hướng duy trì hiệu suất sử dụng tài sản ở mức ổn định, không có năm nào hiệu quả quá thấp hoặc bất thường.

Phân tích tương quan giữa tốc độ tăng trưởng của LNST và Doanh thu

df_10bien %>% mutate(ROE = LNST / VonChuSoHuu)
## # A tibble: 10 × 21
##      nam  LNST DoanhThu LoiNhuanGop TSNganHan NoNganHan VonChuSoHuu TongTaiSan
##    <int> <dbl>    <dbl>       <dbl>     <dbl>     <dbl>       <dbl>      <dbl>
##  1  2015  40.0    1615.        190.     1072.      667.        819.      1955.
##  2  2016 142.     2144.        307.     1362.     1140.        955.      3078.
##  3  2017 223.     4070.        550.     2143.     1991.       1625.      4576.
##  4  2018 180.     8012.        673.     3989.     3206.       2980.      7529.
##  5  2019 460.     9258.       1042.     4971.     3237.       3255.      7987.
##  6  2020 262.     7429.        777.     4496.     3773.       4024.      8569.
##  7  2021 290.    13143.       1301.     5355.     3282.       5454.     10010.
##  8  2022 153.    15290.       1086.     5659.     3206.       6171.     10796.
##  9  2023 289.    12622.       1109.     5682.     3737.       5964.     11583.
## 10  2024 369.    12782.       1484.     6426.     4133.       6236.     13768.
## # ℹ 13 more variables: NoPhaiTra <dbl>, HangTonKho <dbl>, TienThuanHDKD <dbl>,
## #   GPM <dbl>, DE_Ratio <dbl>, CurrentRatio <dbl>, ton_kho_taisan <dbl>,
## #   cash_to_profit <dbl>, dot <chr>, loi_lo <chr>, TT_DT <dbl>, quy_mo <chr>,
## #   ROE <dbl>

Đây là chỉ tiêu quan trọng phản ánh hiệu quả đầu tư của cổ đông, cho biết mỗi đồng vốn góp mang lại bao nhiêu đồng lợi nhuận. Kết quả cho thấy ROE dao động từ khoảng 0.024 đến 0.148, nghĩa là tỷ suất sinh lời dao động từ 2,4% đến 14,8%. ROE cao thể hiện khả năng sử dụng vốn chủ hiệu quả, giúp tối đa hóa lợi ích của nhà đầu tư. Những năm có ROE cao đồng thời là những giai đoạn doanh nghiệp vận hành tốt và kiểm soát chi phí vốn hiệu quả.

Phân tích tương quan giữa LNST và Tổng tài sản

cor(df_10bien$LNST, df_10bien$TongTaiSan)
## [1] 0.6168319

Phép tính cor(df_10bien\(LNST, df_10bien\)TongTaiSan) cho kết quả hệ số tương quan bằng 0.6168319, cho thấy mối liên hệ tương quan thuận trung bình – khá mạnh giữa lợi nhuận sau thuế và tổng tài sản. Nói cách khác, khi quy mô tài sản tăng, lợi nhuận của doanh nghiệp cũng có xu hướng tăng theo. Đây là dấu hiệu tích cực, phản ánh rằng việc mở rộng quy mô đầu tư vào tài sản đang mang lại hiệu quả sinh lời tương đối tốt.

Phân tích xác định năm có ROS cao nhất

cor(log(df_10bien$LNST/lag(df_10bien$LNST))[-1], log(df_10bien$DoanhThu/lag(df_10bien$DoanhThu))[-1])
## [1] 0.05307028

Khi áp dụng công thức cor(log(LNST/lag(LNST))[-1], log(DoanhThu/lag(DoanhThu))[-1]), hệ số tương quan thu được là 0.05307028, gần bằng 0. Điều này cho thấy mối quan hệ rất yếu giữa tốc độ tăng trưởng lợi nhuận và tốc độ tăng doanh thu theo thời gian. Nói cách khác, việc doanh thu tăng chưa chắc kéo theo lợi nhuận tăng tương ứng, điều này có thể phản ánh tác động của chi phí, giá vốn, hoặc yếu tố hiệu quả quản lý ảnh hưởng đến biên lợi nhuận.

df_10bien %>% mutate(ROS = LNST / DoanhThu) %>% arrange(desc(ROS)) %>% head(1)
## # A tibble: 1 × 21
##     nam  LNST DoanhThu LoiNhuanGop TSNganHan NoNganHan VonChuSoHuu TongTaiSan
##   <int> <dbl>    <dbl>       <dbl>     <dbl>     <dbl>       <dbl>      <dbl>
## 1  2016  142.    2144.        307.     1362.     1140.        955.      3078.
## # ℹ 13 more variables: NoPhaiTra <dbl>, HangTonKho <dbl>, TienThuanHDKD <dbl>,
## #   GPM <dbl>, DE_Ratio <dbl>, CurrentRatio <dbl>, ton_kho_taisan <dbl>,
## #   cash_to_profit <dbl>, dot <chr>, loi_lo <chr>, TT_DT <dbl>, quy_mo <chr>,
## #   ROS <dbl>

Trong bước này, dữ liệu được sắp xếp theo ROS giảm dần bằng arrange(desc(ROS)) và chọn dòng đầu tiên bằng head(1). Kết quả xác định năm có tỷ suất lợi nhuận trên doanh thu cao nhất là năm 2016, với giá trị ROS đạt mức vượt trội so với các năm khác. Điều này chứng tỏ năm 2016 là thời điểm doanh nghiệp vận hành hiệu quả nhất, vừa tối ưu doanh thu, vừa kiểm soát tốt chi phí để đạt biên lợi nhuận ròng cao nhất trong chuỗi dữ liệu.

Phân tích tổng hợp ba chỉ tiêu ROS, ROA và ROE

df_10bien %>% mutate(ROS = LNST / DoanhThu, ROA = LNST / TongTaiSan, ROE = LNST / VonChuSoHuu) %>% select(nam, ROS, ROA, ROE)
## # A tibble: 10 × 4
##      nam     ROS    ROA    ROE
##    <int>   <dbl>  <dbl>  <dbl>
##  1  2015 0.0248  0.0205 0.0488
##  2  2016 0.0662  0.0461 0.149 
##  3  2017 0.0549  0.0488 0.137 
##  4  2018 0.0225  0.0239 0.0605
##  5  2019 0.0497  0.0576 0.141 
##  6  2020 0.0353  0.0306 0.0652
##  7  2021 0.0221  0.0290 0.0532
##  8  2022 0.00998 0.0141 0.0247
##  9  2023 0.0229  0.0250 0.0485
## 10  2024 0.0288  0.0268 0.0591

Bảng cuối cùng thể hiện đồng thời ba chỉ tiêu ROS, ROA và ROE theo từng năm, giúp so sánh hiệu quả tài chính ở các khía cạnh khác nhau: lợi nhuận theo doanh thu, theo tài sản và theo vốn chủ sở hữu. Quan sát bảng cho thấy cả ba chỉ tiêu đều có xu hướng biến động cùng chiều — khi ROS tăng, ROA và ROE cũng tăng theo, phản ánh sự nhất quán trong hiệu quả hoạt động và quản trị vốn của doanh nghiệp. Những năm có ba chỉ số đồng thời cao là giai đoạn doanh nghiệp đạt hiệu suất tổng thể tốt, trong khi những năm cả ba chỉ tiêu cùng giảm thể hiện giai đoạn hoạt động kém hiệu quả hơn.

2.6.4. Thống kê Biến lợi nhuận gộp

2.6.4.1. Thống kê sơ bộ

Phân tích giá trị trung bình (TB_LNG)

df_10bien %>% summarise(TB_LNG = mean(LoiNhuanGop))
## # A tibble: 1 × 1
##   TB_LNG
##    <dbl>
## 1   852.

Trong phép tính đầu tiên, hàm mean(LoiNhuanGop) được sử dụng để xác định giá trị trung bình của lợi nhuận gộp (LNG) trong toàn bộ giai đoạn quan sát. Kết quả cho thấy TB_LNG = 851.9653, nghĩa là trung bình mỗi năm doanh nghiệp đạt được khoảng 852 đơn vị lợi nhuận gộp. Đây là chỉ tiêu tổng quát phản ánh hiệu quả sản xuất – kinh doanh cốt lõi của doanh nghiệp, cho thấy khả năng tạo ra lợi nhuận từ hoạt động chính ở mức tương đối cao và ổn định trong chuỗi dữ liệu.

Phân tích giá trị lớn nhất (Max_LNG)

df_10bien %>% summarise(Max_LNG = max(LoiNhuanGop))
## # A tibble: 1 × 1
##   Max_LNG
##     <dbl>
## 1   1484.

Tiếp theo, phép tính max(LoiNhuanGop) cho kết quả Max_LNG = 1484.106, đây là mức lợi nhuận gộp cao nhất đạt được trong toàn bộ chu kỳ. Con số này cho thấy có ít nhất một năm doanh nghiệp tạo ra lợi nhuận gộp vượt gần gấp đôi mức trung bình, phản ánh khả năng tăng trưởng mạnh hoặc hiệu quả hoạt động vượt trội trong năm đó. Việc so sánh giữa giá trị lớn nhất và trung bình cũng cho thấy doanh nghiệp có thể đạt được mức sinh lợi rất cao trong điều kiện thuận lợi.

Phân tích độ lệch chuẩn (SD_LNG)

df_10bien %>% summarise(SD_LNG = sd(LoiNhuanGop))
## # A tibble: 1 × 1
##   SD_LNG
##    <dbl>
## 1   425.

Phép tính sd(LoiNhuanGop) cho ra SD_LNG = 424.5996, đại diện cho mức độ biến động trung bình của lợi nhuận gộp quanh giá trị trung bình. Nghĩa là các giá trị lợi nhuận gộp hàng năm lệch khỏi trung bình khoảng 425 đơn vị. Mức độ biến động này tương đối lớn so với trung bình (khoảng 50%), chứng tỏ lợi nhuận gộp giữa các năm không ổn định, có sự dao động đáng kể do ảnh hưởng của biến động chi phí, giá bán hoặc sản lượng tiêu thụ.

Phân tích hệ số biến thiên (CV_LNG)

df_10bien %>% summarise(CV_LNG = sd(LoiNhuanGop) / mean(LoiNhuanGop))
## # A tibble: 1 × 1
##   CV_LNG
##    <dbl>
## 1  0.498

Hệ số biến thiên được tính theo công thức sd(LoiNhuanGop) / mean(LoiNhuanGop), cho ra CV_LNG = 0.4983766, tương đương khoảng 49,8%. Chỉ tiêu này đo mức biến động tương đối của lợi nhuận so với giá trị trung bình. Với hệ số gần 0.5, ta có thể nhận định mức biến động lợi nhuận gộp là trung bình – cao, tức là gần bằng một nửa giá trị trung bình. Điều này cho thấy hiệu quả kinh doanh của doanh nghiệp có sự thay đổi đáng kể theo từng năm và chịu tác động mạnh của các yếu tố thị trường.

Phân tích khoảng tứ phân vị (IQR_LNG)

df_10bien %>% summarise(IQR_LNG = IQR(LoiNhuanGop))
## # A tibble: 1 × 1
##   IQR_LNG
##     <dbl>
## 1    522.

Sử dụng hàm IQR(LoiNhuanGop), kết quả thu được là IQR_LNG = 522.0571. Chỉ tiêu này thể hiện khoảng chênh lệch giữa tứ phân vị thứ ba (Q3) và thứ nhất (Q1), tức là phạm vi mà trong đó nằm 50% giá trị trung tâm của lợi nhuận gộp. Khoảng tứ phân vị khá lớn cho thấy lợi nhuận gộp phân tán mạnh, không tập trung chặt quanh giá trị trung bình. Điều này phản ánh sự khác biệt rõ rệt về hiệu quả sinh lời giữa các năm.

Phân tích tứ phân vị thứ ba (Q3_LNG)

df_10bien %>% summarise(Q3_LNG = quantile(LoiNhuanGop, 0.75))
## # A tibble: 1 × 1
##   Q3_LNG
##    <dbl>
## 1  1103.

Giá trị Q3_LNG = 1103.08, được tính bằng quantile(LoiNhuanGop, 0.75). Nghĩa là 75% các năm có lợi nhuận gộp thấp hơn hoặc bằng 1103, và chỉ 25% năm còn lại có lợi nhuận cao hơn mức này. Kết hợp với trung bình 852, ta có thể thấy phần lớn dữ liệu tập trung dưới mức 1100, trong khi một số năm đạt kết quả vượt trội hơn hẳn, góp phần kéo giá trị cực đại lên cao.

Phân tích độ lệch (Skewness_LNG)

df_10bien %>% summarise(Skewness_LNG = moments::skewness(LoiNhuanGop))
## # A tibble: 1 × 1
##   Skewness_LNG
##          <dbl>
## 1       -0.162

Cuối cùng, độ lệch được tính bằng moments::skewness(LoiNhuanGop) cho kết quả Skewness_LNG = -0.1617271. Đây là một giá trị âm nhỏ, thể hiện phân phối lợi nhuận gộp hơi lệch trái, tức là có xu hướng tập trung quanh các giá trị cao hơn trung bình, còn một vài năm có lợi nhuận thấp hơn kéo đuôi phân phối về phía trái. Nói cách khác, doanh nghiệp thường đạt lợi nhuận ở mức khá, chỉ có ít năm lợi nhuận giảm mạnh. Mức độ lệch nhẹ cho thấy dữ liệu phân bố gần đối xứng, phản ánh xu hướng hoạt động ổn định theo thời gian.

2.6.4.2. Phân Tích Tăng Trưởng và Biên Lợi Nhuận

Tính tốc độ tăng trưởng lợi nhuận gộp (TT_LNG)p

df_10bien %>% mutate(TT_LNG = (LoiNhuanGop / lag(LoiNhuanGop)) - 1)
## # A tibble: 10 × 21
##      nam  LNST DoanhThu LoiNhuanGop TSNganHan NoNganHan VonChuSoHuu TongTaiSan
##    <int> <dbl>    <dbl>       <dbl>     <dbl>     <dbl>       <dbl>      <dbl>
##  1  2015  40.0    1615.        190.     1072.      667.        819.      1955.
##  2  2016 142.     2144.        307.     1362.     1140.        955.      3078.
##  3  2017 223.     4070.        550.     2143.     1991.       1625.      4576.
##  4  2018 180.     8012.        673.     3989.     3206.       2980.      7529.
##  5  2019 460.     9258.       1042.     4971.     3237.       3255.      7987.
##  6  2020 262.     7429.        777.     4496.     3773.       4024.      8569.
##  7  2021 290.    13143.       1301.     5355.     3282.       5454.     10010.
##  8  2022 153.    15290.       1086.     5659.     3206.       6171.     10796.
##  9  2023 289.    12622.       1109.     5682.     3737.       5964.     11583.
## 10  2024 369.    12782.       1484.     6426.     4133.       6236.     13768.
## # ℹ 13 more variables: NoPhaiTra <dbl>, HangTonKho <dbl>, TienThuanHDKD <dbl>,
## #   GPM <dbl>, DE_Ratio <dbl>, CurrentRatio <dbl>, ton_kho_taisan <dbl>,
## #   cash_to_profit <dbl>, dot <chr>, loi_lo <chr>, TT_DT <dbl>, quy_mo <chr>,
## #   TT_LNG <dbl>

Đầu tiên, để phân tích xu hướng tăng trưởng của lợi nhuận gộp qua các năm, biến tốc độ tăng trưởng lợi nhuận gộp (TT_LNG) được tính theo công thức (LoiNhuanGop / lag(LoiNhuanGop)) - 1. Chỉ tiêu này thể hiện tỷ lệ thay đổi lợi nhuận gộp của năm hiện tại so với năm liền trước. Việc tính TT_LNG cho phép đánh giá mức độ tăng hoặc giảm của lợi nhuận gộp theo thời gian. Khi giá trị TT_LNG dương, lợi nhuận gộp tăng trưởng, còn khi âm, lợi nhuận gộp suy giảm. Quan sát các giá trị thu được, có thể nhận thấy lợi nhuận gộp của doanh nghiệp tăng tương đối mạnh ở những năm đầu chu kỳ, cho thấy hiệu quả kinh doanh được cải thiện rõ rệt, trong khi ở một số năm sau đó tốc độ tăng trưởng chậm lại hoặc có dấu hiệu giảm, phản ánh sự thay đổi của thị trường hoặc chi phí đầu vào.

Tính lợi nhuận gộp trung bình trượt 3 năm

df_10bien %>% arrange(nam) %>% mutate(LNG_TB_3Y = zoo::rollmean(LoiNhuanGop, k=3, fill=NA, align="right"))
## # A tibble: 10 × 21
##      nam  LNST DoanhThu LoiNhuanGop TSNganHan NoNganHan VonChuSoHuu TongTaiSan
##    <int> <dbl>    <dbl>       <dbl>     <dbl>     <dbl>       <dbl>      <dbl>
##  1  2015  40.0    1615.        190.     1072.      667.        819.      1955.
##  2  2016 142.     2144.        307.     1362.     1140.        955.      3078.
##  3  2017 223.     4070.        550.     2143.     1991.       1625.      4576.
##  4  2018 180.     8012.        673.     3989.     3206.       2980.      7529.
##  5  2019 460.     9258.       1042.     4971.     3237.       3255.      7987.
##  6  2020 262.     7429.        777.     4496.     3773.       4024.      8569.
##  7  2021 290.    13143.       1301.     5355.     3282.       5454.     10010.
##  8  2022 153.    15290.       1086.     5659.     3206.       6171.     10796.
##  9  2023 289.    12622.       1109.     5682.     3737.       5964.     11583.
## 10  2024 369.    12782.       1484.     6426.     4133.       6236.     13768.
## # ℹ 13 more variables: NoPhaiTra <dbl>, HangTonKho <dbl>, TienThuanHDKD <dbl>,
## #   GPM <dbl>, DE_Ratio <dbl>, CurrentRatio <dbl>, ton_kho_taisan <dbl>,
## #   cash_to_profit <dbl>, dot <chr>, loi_lo <chr>, TT_DT <dbl>, quy_mo <chr>,
## #   LNG_TB_3Y <dbl>

Để làm mượt dữ liệu và quan sát xu hướng trung hạn, biến LNG_TB_3Y được tạo ra bằng hàm zoo::rollmean(LoiNhuanGop, k=3), tính trung bình trượt 3 năm của lợi nhuận gộp. Chỉ tiêu này giúp loại bỏ các biến động ngắn hạn, tập trung thể hiện xu hướng ổn định của lợi nhuận gộp trong giai đoạn ba năm liên tiếp. Kết quả cho thấy lợi nhuận gộp trung bình ba năm có xu hướng tăng dần trong phần lớn thời kỳ, phản ánh rằng mặc dù có những dao động năm lẻ, doanh nghiệp vẫn duy trì được xu thế cải thiện về hiệu quả sản xuất – kinh doanh trong dài hạn.

Tính tỷ suất lợi nhuận gộp

df_10bien %>% mutate(GPM = LoiNhuanGop / DoanhThu)
## # A tibble: 10 × 20
##      nam  LNST DoanhThu LoiNhuanGop TSNganHan NoNganHan VonChuSoHuu TongTaiSan
##    <int> <dbl>    <dbl>       <dbl>     <dbl>     <dbl>       <dbl>      <dbl>
##  1  2015  40.0    1615.        190.     1072.      667.        819.      1955.
##  2  2016 142.     2144.        307.     1362.     1140.        955.      3078.
##  3  2017 223.     4070.        550.     2143.     1991.       1625.      4576.
##  4  2018 180.     8012.        673.     3989.     3206.       2980.      7529.
##  5  2019 460.     9258.       1042.     4971.     3237.       3255.      7987.
##  6  2020 262.     7429.        777.     4496.     3773.       4024.      8569.
##  7  2021 290.    13143.       1301.     5355.     3282.       5454.     10010.
##  8  2022 153.    15290.       1086.     5659.     3206.       6171.     10796.
##  9  2023 289.    12622.       1109.     5682.     3737.       5964.     11583.
## 10  2024 369.    12782.       1484.     6426.     4133.       6236.     13768.
## # ℹ 12 more variables: NoPhaiTra <dbl>, HangTonKho <dbl>, TienThuanHDKD <dbl>,
## #   GPM <dbl>, DE_Ratio <dbl>, CurrentRatio <dbl>, ton_kho_taisan <dbl>,
## #   cash_to_profit <dbl>, dot <chr>, loi_lo <chr>, TT_DT <dbl>, quy_mo <chr>

Kết quả GPM cho biết cứ 1 đồng doanh thu tạo ra bao nhiêu đồng lợi nhuận gộp. Đây là một thước đo quan trọng phản ánh hiệu quả kiểm soát chi phí sản xuất và khả năng định giá sản phẩm của doanh nghiệp. Nếu GPM cao, nghĩa là doanh nghiệp có khả năng giữ lại nhiều lợi nhuận từ doanh thu, thể hiện sức cạnh tranh tốt. Kết quả tính toán cho thấy tỷ suất lợi nhuận gộp duy trì ở mức ổn định trong hầu hết các năm, phản ánh khả năng quản trị chi phí tương đối hiệu quả và ổn định.

Đo lường độ biến động của tỷ suất lợi nhuận gộp

df_10bien %>% mutate(GPM = LoiNhuanGop / DoanhThu) %>% summarise(SD_GPM = sd(GPM))
## # A tibble: 1 × 1
##   SD_GPM
##    <dbl>
## 1 0.0226

Để đánh giá mức độ biến động của tỷ suất lợi nhuận gộp qua các năm, ta tính độ lệch chuẩn của GPM (SD_GPM) bằng công thức sd(GPM), kết quả thu được là 0.0226. Giá trị này thể hiện sự chênh lệch trung bình của tỷ suất lợi nhuận gộp so với mức trung bình chung, tức là GPM chỉ dao động khoảng 2,26 điểm phần trăm quanh giá trị trung bình. Điều đó cho thấy tỷ suất lợi nhuận gộp của doanh nghiệp có mức ổn định tương đối cao, ít biến động, phản ánh mô hình hoạt động kinh doanh ổn định và khả năng kiểm soát chi phí tốt trong giai đoạn quan sát.

Tính tốc độ tăng trưởng tỷ suất lợi nhuận gộp

df_10bien %>% mutate(GPM = LoiNhuanGop / DoanhThu) %>% mutate(TT_GPM = (GPM / lag(GPM)) - 1)
## # A tibble: 10 × 21
##      nam  LNST DoanhThu LoiNhuanGop TSNganHan NoNganHan VonChuSoHuu TongTaiSan
##    <int> <dbl>    <dbl>       <dbl>     <dbl>     <dbl>       <dbl>      <dbl>
##  1  2015  40.0    1615.        190.     1072.      667.        819.      1955.
##  2  2016 142.     2144.        307.     1362.     1140.        955.      3078.
##  3  2017 223.     4070.        550.     2143.     1991.       1625.      4576.
##  4  2018 180.     8012.        673.     3989.     3206.       2980.      7529.
##  5  2019 460.     9258.       1042.     4971.     3237.       3255.      7987.
##  6  2020 262.     7429.        777.     4496.     3773.       4024.      8569.
##  7  2021 290.    13143.       1301.     5355.     3282.       5454.     10010.
##  8  2022 153.    15290.       1086.     5659.     3206.       6171.     10796.
##  9  2023 289.    12622.       1109.     5682.     3737.       5964.     11583.
## 10  2024 369.    12782.       1484.     6426.     4133.       6236.     13768.
## # ℹ 13 more variables: NoPhaiTra <dbl>, HangTonKho <dbl>, TienThuanHDKD <dbl>,
## #   GPM <dbl>, DE_Ratio <dbl>, CurrentRatio <dbl>, ton_kho_taisan <dbl>,
## #   cash_to_profit <dbl>, dot <chr>, loi_lo <chr>, TT_DT <dbl>, quy_mo <chr>,
## #   TT_GPM <dbl>

Để đánh giá tốc độ biến động của tỷ suất lợi nhuận gộp theo thời gian, biến TT_GPM được tính theo công thức (GPM / lag(GPM)) - 1, thể hiện tốc độ tăng trưởng của tỷ suất lợi nhuận gộp giữa các năm. Nếu giá trị TT_GPM dương, doanh nghiệp đang cải thiện hiệu quả biên lợi nhuận; ngược lại, nếu âm, doanh nghiệp đang bị giảm hiệu quả sinh lợi trên doanh thu. Qua kết quả thu được, có thể nhận thấy tốc độ thay đổi của GPM giữa các năm tương đối nhỏ, chứng tỏ doanh nghiệp duy trì được sự ổn định về biên lợi nhuận trong dài hạn. Sự ổn định này là dấu hiệu tích cực, đặc biệt trong những ngành có chi phí đầu vào hoặc giá bán biến động mạnh, vì nó phản ánh khả năng thích ứng và duy trì hiệu quả hoạt động bền vững.

Phân tích các năm có tốc độ tăng trưởng biên lợi nhuận âm

df_10bien %>% mutate(GPM = LoiNhuanGop / DoanhThu, TT_GPM = (GPM / lag(GPM)) - 1) %>% filter(TT_GPM < 0)
## # A tibble: 5 × 21
##     nam  LNST DoanhThu LoiNhuanGop TSNganHan NoNganHan VonChuSoHuu TongTaiSan
##   <int> <dbl>    <dbl>       <dbl>     <dbl>     <dbl>       <dbl>      <dbl>
## 1  2017  223.    4070.        550.     2143.     1991.       1625.      4576.
## 2  2018  180.    8012.        673.     3989.     3206.       2980.      7529.
## 3  2020  262.    7429.        777.     4496.     3773.       4024.      8569.
## 4  2021  290.   13143.       1301.     5355.     3282.       5454.     10010.
## 5  2022  153.   15290.       1086.     5659.     3206.       6171.     10796.
## # ℹ 13 more variables: NoPhaiTra <dbl>, HangTonKho <dbl>, TienThuanHDKD <dbl>,
## #   GPM <dbl>, DE_Ratio <dbl>, CurrentRatio <dbl>, ton_kho_taisan <dbl>,
## #   cash_to_profit <dbl>, dot <chr>, loi_lo <chr>, TT_DT <dbl>, quy_mo <chr>,
## #   TT_GPM <dbl>

Đữ liệu được lọc bằng điều kiện filter(TT_GPM < 0) sau khi tính biến tốc độ tăng trưởng tỷ suất lợi nhuận gộp (TT_GPM) từ công thức (GPM / lag(GPM)) - 1. Mục tiêu của thao tác này là xác định những năm mà biên lợi nhuận gộp của doanh nghiệp bị suy giảm so với năm liền trước, tức là hiệu quả sinh lợi từ doanh thu giảm đi.

Kết quả bảng cho thấy các năm 2017, 2018, 2020, 2021 và 2022 là những giai đoạn có TT_GPM âm. Điều này hàm ý rằng trong các năm này, mặc dù doanh thu có thể tăng, nhưng tốc độ tăng chi phí giá vốn cao hơn tốc độ tăng doanh thu, khiến tỷ suất lợi nhuận gộp giảm. Đây là dấu hiệu cảnh báo doanh nghiệp đang chịu áp lực chi phí hoặc mất lợi thế cạnh tranh trong việc kiểm soát biên lợi nhuận. Đặc biệt, việc biên lợi nhuận gộp sụt giảm nhiều năm liền cho thấy mô hình kinh doanh đang chịu biến động mạnh, có thể do thay đổi cơ cấu sản phẩm hoặc ảnh hưởng từ thị trường đầu vào.

Phân tích tốc độ tăng trưởng logarit của lợi nhuận gộp

df_10bien %>% mutate(Log_Return_LNG = log(LoiNhuanGop / lag(LoiNhuanGop)))
## # A tibble: 10 × 21
##      nam  LNST DoanhThu LoiNhuanGop TSNganHan NoNganHan VonChuSoHuu TongTaiSan
##    <int> <dbl>    <dbl>       <dbl>     <dbl>     <dbl>       <dbl>      <dbl>
##  1  2015  40.0    1615.        190.     1072.      667.        819.      1955.
##  2  2016 142.     2144.        307.     1362.     1140.        955.      3078.
##  3  2017 223.     4070.        550.     2143.     1991.       1625.      4576.
##  4  2018 180.     8012.        673.     3989.     3206.       2980.      7529.
##  5  2019 460.     9258.       1042.     4971.     3237.       3255.      7987.
##  6  2020 262.     7429.        777.     4496.     3773.       4024.      8569.
##  7  2021 290.    13143.       1301.     5355.     3282.       5454.     10010.
##  8  2022 153.    15290.       1086.     5659.     3206.       6171.     10796.
##  9  2023 289.    12622.       1109.     5682.     3737.       5964.     11583.
## 10  2024 369.    12782.       1484.     6426.     4133.       6236.     13768.
## # ℹ 13 more variables: NoPhaiTra <dbl>, HangTonKho <dbl>, TienThuanHDKD <dbl>,
## #   GPM <dbl>, DE_Ratio <dbl>, CurrentRatio <dbl>, ton_kho_taisan <dbl>,
## #   cash_to_profit <dbl>, dot <chr>, loi_lo <chr>, TT_DT <dbl>, quy_mo <chr>,
## #   Log_Return_LNG <dbl>

Biến Log_Return_LNG được tạo ra theo công thức log(LoiNhuanGop / lag(LoiNhuanGop)). Đây là tốc độ tăng trưởng logarit của lợi nhuận gộp, một chỉ tiêu thường được dùng trong phân tích tài chính để đo mức thay đổi tương đối giữa hai kỳ theo thang logarit tự nhiên.

So với tốc độ tăng trưởng thông thường, log-return có ưu điểm là thể hiện tỷ lệ thay đổi đối xứng hơn, giúp loại bỏ ảnh hưởng của những biến động quá lớn giữa các năm và mô tả tốt hơn xu hướng trung bình của chuỗi dữ liệu. Giá trị dương của Log_Return_LNG cho thấy lợi nhuận gộp tăng trưởng, trong khi giá trị âm biểu thị lợi nhuận gộp giảm so với năm trước.

Quan sát bảng kết quả, ta nhận thấy Log_Return_LNG của doanh nghiệp dao động quanh mức dương trong hầu hết các năm, chỉ có một vài năm có giá trị thấp hơn 0. Điều này chứng tỏ rằng doanh nghiệp duy trì được xu hướng tăng trưởng lợi nhuận gộp ổn định, dù có những giai đoạn giảm nhẹ. Biến này rất hữu ích khi dùng để đo tốc độ tăng trưởng trung bình liên tục hoặc tính toán độ biến động (volatility) của lợi nhuận gộp trong các phân tích nâng cao sau này.

2.6.5. Thống Kê Suy Luận

Kiểm định Paired t-test giữa Lợi nhuận gộp (LNG) và Lợi nhuận sau thuế (LNST)

Mục tiêu: Mục tiêu của phép kiểm định này là so sánh trung bình của hai đại lượng — lợi nhuận gộp (LNG) và lợi nhuận sau thuế (LNST) — để xem chúng có sự khác biệt có ý nghĩa thống kê hay không. Vì hai biến này được đo trên cùng các năm, nên kiểm định Paired t-test được sử dụng, nhằm xem chênh lệch giữa chúng có khác 0 đáng kể hay không.

Giả thuyết kiểm định:

𝐻0: Không có sự khác biệt có ý nghĩa giữa trung bình lợi nhuận gộp và lợi nhuận sau thuế (μ₁ - μ₂ = 0).

𝐻1: Có sự khác biệt có ý nghĩa giữa trung bình lợi nhuận gộp và lợi nhuận sau thuế (μ₁ - μ₂ ≠ 0).

ttest_lng_lnst <- t.test(
  df_10bien$LoiNhuanGop,
  df_10bien$LNST,
  paired = TRUE,
  conf.level = 0.95
)

print("--- Kết quả Paired t-test (LNG vs. LNST) ---")
## [1] "--- Kết quả Paired t-test (LNG vs. LNST) ---"
print(ttest_lng_lnst)
## 
##  Paired t-test
## 
## data:  df_10bien$LoiNhuanGop and df_10bien$LNST
## t = 5.582, df = 9, p-value = 0.0003421
## alternative hypothesis: true mean difference is not equal to 0
## 95 percent confidence interval:
##  363.4182 858.6839
## sample estimates:
## mean difference 
##         611.051

Kết quả: Giá trị kiểm định t = 5.582, bậc tự do df = 9, và p-value = 0.0003421, nhỏ hơn 0.05. Khoảng tin cậy 95% cho chênh lệch trung bình nằm trong khoảng (363.4182 ; 858.6839), với chênh lệch trung bình mẫu là 611.051.

Kết luận: Vì p-value < 0.05, ta bác bỏ giả thuyết H₀, chấp nhận H₁. Điều này chứng tỏ có sự khác biệt có ý nghĩa thống kê giữa lợi nhuận gộp và lợi nhuận sau thuế. Trung bình lợi nhuận gộp lớn hơn đáng kể so với lợi nhuận sau thuế, điều này hoàn toàn hợp lý do lợi nhuận sau thuế đã bị khấu trừ chi phí và thuế thu nhập doanh nghiệp.

Kiểm định One-sample t-test cho Lợi nhuận sau thuế (LNST)

Mục tiêu: Phép kiểm định này nhằm đánh giá xem trung bình lợi nhuận sau thuế (LNST) của doanh nghiệp có cao hơn mức mục tiêu 200 hay không.

Giả thuyết kiểm định:

𝐻0: Trung bình LNST ≤ 200.

𝐻1: Trung bình LNST > 200.

t.test(df_10bien$LNST, mu = 200, alternative = "greater")
## 
##  One Sample t-test
## 
## data:  df_10bien$LNST
## t = 1.0697, df = 9, p-value = 0.1563
## alternative hypothesis: true mean is greater than 200
## 95 percent confidence interval:
##  170.7977      Inf
## sample estimates:
## mean of x 
##  240.9143

Kết quả: Giá trị kiểm định t = 1.0697, bậc tự do df = 9, và p-value = 0.1563, lớn hơn 0.05. Giá trị trung bình mẫu của LNST là 240.9143, với khoảng tin cậy 95% cho trung bình là (170.7977 ; +∞).

Kết luận: Do p-value > 0.05, ta không đủ bằng chứng để bác bỏ giả thuyết H₀. Nói cách khác, không có cơ sở thống kê để khẳng định rằng trung bình LNST lớn hơn 200. Dù trung bình mẫu cao hơn ngưỡng giả định, sự chênh lệch này chưa đủ mạnh để đạt mức ý nghĩa thống kê 5%.

Kiểm định One-sample t-test cho Doanh thu (DoanhThu)

Mục tiêu: Phép kiểm định này được thực hiện để xem trung bình doanh thu của doanh nghiệp có khác biệt đáng kể so với mức 10.000 hay không.

Giả thuyết kiểm định:

𝐻0: Trung bình DoanhThu = 10.000.

𝐻1: Trung bình DoanhThu ≠ 10.000.

t.test(df_10bien$DoanhThu, mu = 10000)
## 
##  One Sample t-test
## 
## data:  df_10bien$DoanhThu
## t = -0.88808, df = 9, p-value = 0.3976
## alternative hypothesis: true mean is not equal to 10000
## 95 percent confidence interval:
##   5162.725 12109.931
## sample estimates:
## mean of x 
##  8636.328

Kết quả: Giá trị kiểm định t = -0.88808, bậc tự do df = 9, và p-value = 0.3976, lớn hơn 0.05. Trung bình doanh thu mẫu là 8.636.328, với khoảng tin cậy 95% là (5.162.725 ; 12.109.931).

Kết luận: Do p-value > 0.05, ta chưa đủ bằng chứng để kết luận rằng trung bình doanh thu khác 10.000. Điều này có nghĩa rằng mức doanh thu trung bình của doanh nghiệp không khác đáng kể so với giá trị giả định, tức là quy mô doanh thu vẫn dao động quanh mức trung bình kỳ vọng.

Kiểm định Independent Two-sample t-test giữa hai nhóm doanh thu (Cao và Thấp)

Mục tiêu: Mục tiêu của phép kiểm định này là so sánh lợi nhuận sau thuế trung bình giữa hai nhóm doanh nghiệp — nhóm có doanh thu cao và nhóm có doanh thu thấp — để xem liệu quy mô doanh thu có ảnh hưởng đến lợi nhuận sau thuế hay không.

Giả thuyết kiểm định:

𝐻0: Không có sự khác biệt giữa trung bình LNST của hai nhóm (μ₁ = μ₂).

𝐻1: Có sự khác biệt giữa trung bình LNST của hai nhóm (μ₁ ≠ μ₂).

df_10bien$NhomDT <- ifelse(df_10bien$DoanhThu >= median(df_10bien$DoanhThu), "Cao", "Thap")
t.test(LNST ~ NhomDT, data = df_10bien)
## 
##  Welch Two Sample t-test
## 
## data:  LNST by NhomDT
## t = 2.2453, df = 7.4241, p-value = 0.05748
## alternative hypothesis: true difference in means between group Cao and group Thap is not equal to 0
## 95 percent confidence interval:
##   -5.86067 291.24147
## sample estimates:
##  mean in group Cao mean in group Thap 
##           312.2595           169.5691

Kết quả: Kết quả kiểm định Welch Two-sample t-test cho thấy giá trị t = 2.2453, bậc tự do df = 7.4241, và p-value = 0.05748. Trung bình LNST ở nhóm “Cao” là 312.2595, trong khi nhóm “Thấp” chỉ đạt 169.5691.

Kết luận: Với p-value ≈ 0.0575, chỉ hơi cao hơn ngưỡng 0.05, nên chưa đủ mạnh để bác bỏ giả thuyết H₀ ở mức ý nghĩa 5%, nhưng có thể xem là có xu hướng khác biệt giữa hai nhóm ở mức ý nghĩa 10%. Điều này cho thấy rằng doanh nghiệp có doanh thu cao thường có lợi nhuận sau thuế trung bình cao hơn, tuy nhiên mức độ khác biệt này chưa đủ lớn để khẳng định chắc chắn về mặt thống kê.

Phân tích phương sai một yếu tố (One-way ANOVA) giữa Doanh thu, Lợi nhuận gộp và Lợi nhuận sau thuế

ục tiêu: Mục tiêu của phép kiểm định ANOVA này là so sánh trung bình của ba chỉ tiêu tài chính chính — Doanh thu (DT), Lợi nhuận gộp (LNG) và Lợi nhuận sau thuế (LNST) — để xem liệu có sự khác biệt có ý nghĩa thống kê giữa các biến này hay không. Phép kiểm định được thực hiện sau khi chuyển dữ liệu từ dạng rộng sang dạng dài bằng hàm pivot_longer, giúp nhóm ba chỉ tiêu thành một biến định tính “ChiSo” và giá trị tương ứng “GiaTri”.

Giả thuyết kiểm định:

𝐻0: Không có sự khác biệt đáng kể giữa trung bình của ba nhóm (μ₁ = μ₂ = μ₃).

𝐻1: Có ít nhất một nhóm có trung bình khác biệt so với nhóm còn lại.

library(tidyr)
df_anova_3bien <- df_10bien %>%
  select(nam, DoanhThu, LoiNhuanGop, LNST) %>%
  pivot_longer(
    cols = c(DoanhThu, LoiNhuanGop, LNST),
    names_to = "ChiSo",
    values_to = "GiaTri"
  )

anova_3bien_model <- aov(GiaTri ~ ChiSo, data = df_anova_3bien)

print("--- Kết quả One-way ANOVA (So sánh DT, LNG, LNST) ---")
## [1] "--- Kết quả One-way ANOVA (So sánh DT, LNG, LNST) ---"
summary(anova_3bien_model)
##             Df    Sum Sq   Mean Sq F value   Pr(>F)    
## ChiSo        2 438175543 219087772   27.65 2.92e-07 ***
## Residuals   27 213960062   7924447                     
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1

Kết quả: Mô hình ANOVA được xây dựng với công thức GiaTri ~ ChiSo. Kết quả cho thấy giá trị F của mô hình rất lớn và p-value nhỏ hơn 0.05, chứng tỏ có sự khác biệt có ý nghĩa thống kê giữa các chỉ tiêu tài chính.

Kết luận: Do p-value < 0.05, ta bác bỏ giả thuyết H₀ và kết luận rằng các chỉ tiêu Doanh thu, Lợi nhuận gộp và Lợi nhuận sau thuế có trung bình khác biệt đáng kể. Điều này là hợp lý vì ba đại lượng này thể hiện các cấp độ khác nhau trong chuỗi giá trị doanh nghiệp — doanh thu là tổng thu nhập, lợi nhuận gộp phản ánh phần giữ lại sau giá vốn, còn lợi nhuận sau thuế là phần còn lại cuối cùng sau các chi phí.

Phân tích phương sai ANOVA theo nhóm doanh thu (Thấp, Trung bình, Cao)

Mục tiêu: Mục tiêu của phép kiểm định này là xem xét sự khác biệt về lợi nhuận sau thuế (LNST) giữa ba nhóm doanh nghiệp được chia theo mức doanh thu — “Thấp”, “Trung bình” và “Cao”. Việc nhóm hóa được thực hiện dựa trên các phân vị (quantiles) của biến Doanh thu, đảm bảo dữ liệu chia đều thành ba nhóm.

Giả thuyết kiểm định:

𝐻0: Trung bình lợi nhuận sau thuế của ba nhóm là bằng nhau (μ₁ = μ₂ = μ₃).

𝐻1: Có ít nhất một nhóm có trung bình khác biệt so với nhóm khác.

df_10bien$Nhom3DT <- cut(df_10bien$DoanhThu,
                         breaks = quantile(df_10bien$DoanhThu, probs = c(0, 0.33, 0.66, 1)),
                         labels = c("Thap", "TBinh", "Cao"))

anova_model <- aov(LNST ~ Nhom3DT, data = df_10bien)
summary(anova_model)
##             Df Sum Sq Mean Sq F value Pr(>F)
## Nhom3DT      2  17833    8916   0.775  0.502
## Residuals    6  68998   11500               
## 1 observation deleted due to missingness

Kết quả: Mô hình ANOVA với công thức LNST ~ Nhom3DT cho thấy giá trị F nhỏ và p-value > 0.05, nghĩa là không có bằng chứng thống kê cho thấy lợi nhuận sau thuế trung bình giữa các nhóm doanh thu khác nhau.

Kết luận: Do p-value > 0.05, ta chấp nhận giả thuyết H₀, kết luận rằng lợi nhuận sau thuế trung bình giữa các nhóm doanh thu thấp, trung bình và cao không có sự khác biệt đáng kể. Dù nhóm doanh thu cao thường có LNST tuyệt đối lớn hơn, sự khác biệt này không đủ mạnh để đạt ý nghĩa thống kê, cho thấy biên lợi nhuận và hiệu quả sử dụng vốn của các nhóm có thể tương đối tương đồng.

Kiểm định Levene về tính đồng nhất phương sai (Levene’s Test)

Mục tiêu: Trước khi kết luận từ ANOVA, cần kiểm tra giả định đồng nhất phương sai (homogeneity of variances) giữa các nhóm. Phép kiểm định Levene được dùng để kiểm tra xem phương sai của LNST có tương đồng giữa các nhóm doanh thu hay không.

Giả thuyết kiểm định:

𝐻0: Phương sai của LNST giữa các nhóm doanh thu là bằng nhau.

𝐻1: Có ít nhất một nhóm có phương sai khác biệt.

library(car)
leveneTest(LNST ~ NhomDT, data = df_10bien)
## Warning in leveneTest.default(y = y, group = group, ...): group coerced to
## factor.
## Levene's Test for Homogeneity of Variance (center = median)
##       Df F value Pr(>F)
## group  1  0.1575 0.7019
##        8

Kết quả: Kết quả Levene’s Test cho thấy giá trị F = 0.1575 và p-value = 0.7019, lớn hơn 0.05.

Kết luận: Vì p-value > 0.05, ta chấp nhận giả thuyết H₀, nghĩa là phương sai giữa các nhóm doanh thu là đồng nhất. Điều này đảm bảo rằng giả định cơ bản của ANOVA được thoả mãn, và các kết quả ANOVA ở trên là hợp lệ.

Kiểm định Chi-bình phương (Chi-squared Test) giữa nhóm Doanh thu và nhóm

Mục tiêu: Phép kiểm định Chi-squared được sử dụng để kiểm tra mối liên hệ giữa hai biến phân loại: nhóm doanh thu (NhomDT) và nhóm lợi nhuận sau thuế (NhomLNST). Mục tiêu là xác định xem mức doanh thu có ảnh hưởng đáng kể đến khả năng đạt mức LNST cao hay thấp hay không.

Giả thuyết kiểm định:

𝐻0: Không có mối liên hệ giữa nhóm doanh thu và nhóm LNST.

𝐻1: Có mối liên hệ giữa nhóm doanh thu và nhóm LNST.

df_10bien$NhomLNST <- ifelse(df_10bien$LNST >= median(df_10bien$LNST), "Cao", "Thap")
chisq.test(table(df_10bien$NhomDT, df_10bien$NhomLNST))
## Warning in stats::chisq.test(x, y, ...): Chi-squared approximation may be
## incorrect
## 
##  Pearson's Chi-squared test with Yates' continuity correction
## 
## data:  table(df_10bien$NhomDT, df_10bien$NhomLNST)
## X-squared = 1.6, df = 1, p-value = 0.2059

Kết quả: Kết quả kiểm định Pearson’s Chi-squared cho thấy giá trị X² = 1.6, với p-value = 0.2059, lớn hơn 0.05.

Kết luận: Vì p-value > 0.05, ta chấp nhận giả thuyết H₀, kết luận rằng không có mối liên hệ thống kê có ý nghĩa giữa nhóm doanh thu và nhóm lợi nhuận sau thuế. Nói cách khác, mức doanh thu không phải là yếu tố quyết định trực tiếp đến việc doanh nghiệp đạt mức LNST cao hay thấp, có thể do ảnh hưởng của các yếu tố khác như cơ cấu chi phí, biên lợi nhuận hoặc chi phí thuế.

Xác định khoảng tin cậy 95% cho log return trung bình của Doanh thu

Mục tiêu: Mục tiêu của thao tác này là ước lượng khoảng tin cậy 95% cho trung bình log-return của doanh thu — tức là tỷ lệ tăng trưởng trung bình (theo thang logarit tự nhiên) qua các năm. Việc dùng log-return giúp phản ánh tốc độ tăng trưởng tương đối, giảm ảnh hưởng của các biến động mạnh giữa các năm.

Phương pháp thực hiện: Biến log-return được tính bằng công thức log(DoanhThu / lag(DoanhThu)), sau đó loại bỏ các giá trị bị thiếu (NA). Tiếp theo, sử dụng hàm t.test() với mức tin cậy 0.95 để ước lượng khoảng tin cậy cho trung bình log-return của doanh thu.

df_log_return <- df_10bien %>%
  mutate(Log_Return_DT = log(DoanhThu / lag(DoanhThu))) %>%
  drop_na(Log_Return_DT)
ci_log_return_dt <- t.test(df_log_return$Log_Return_DT, conf.level = 0.95)$conf.int

print("--- Khoảng Tin Cậy 95% cho Log Return Trung bình của Doanh Thu ---")
## [1] "--- Khoảng Tin Cậy 95% cho Log Return Trung bình của Doanh Thu ---"
print(ci_log_return_dt)
## [1] -0.03207428  0.49185213
## attr(,"conf.level")
## [1] 0.95

Kết quả: Khoảng tin cậy 95% cho log-return trung bình của doanh thu nằm trong khoảng (-0.03207428 ; 0.49185213). Nghĩa là, với độ tin cậy 95%, tốc độ tăng trưởng trung bình của doanh thu hàng năm nằm trong khoảng từ -3.2% đến 49.2%.

Kết luận: Khoảng tin cậy này bao gồm cả giá trị 0, nên ta không thể khẳng định rằng tốc độ tăng trưởng trung bình của doanh thu chắc chắn dương (tức là có tăng trưởng rõ rệt). Tuy nhiên, cận trên khá cao cho thấy mức tăng trưởng doanh thu tiềm năng của doanh nghiệp có thể đạt gần 50%, phản ánh giai đoạn mở rộng mạnh về quy mô hoạt động, dù vẫn tồn tại rủi ro biến động hoặc giảm nhẹ ở một số năm.

Kiểm định ý nghĩa thống kê của mối tương quan giữa tăng trưởng Doanh thu (DT) và Lợi nhuận gộp (LNG)

Mục tiêu: Thao tác này nhằm kiểm tra xem tốc độ tăng trưởng của doanh thu và lợi nhuận gộp có mối quan hệ tuyến tính có ý nghĩa thống kê hay không. Việc sử dụng log-return của cả hai biến giúp phản ánh mối quan hệ động giữa hai chỉ tiêu tài chính theo thời gian.

Giả thuyết kiểm định:

H0: Không có mối tương quan tuyến tính giữa tăng trưởng doanh thu và tăng trưởng lợi nhuận gộp (r = 0).

H1: Có mối tương quan tuyến tính giữa tăng trưởng doanh thu và tăng trưởng lợi nhuận gộp (r ≠ 0).

Phương pháp: Sử dụng hàm cor.test() với phương pháp Pearson để kiểm tra mối quan hệ tuyến tính giữa hai biến Log_Return_DT và Log_Return_LNG.

df_returns <- df_10bien %>%
  mutate(
    Log_Return_DT = log(DoanhThu / lag(DoanhThu)),
    Log_Return_LNG = log(LoiNhuanGop / lag(LoiNhuanGop))
  ) %>%
  drop_na()
cor_test_result <- cor.test(
  df_returns$Log_Return_DT,
  df_returns$Log_Return_LNG,
  method = "pearson" # Kiểm tra mối quan hệ tuyến tính
)

print("--- Kiểm tra P-value cho Tương quan (Tăng trưởng DT vs. LNG) ---")
## [1] "--- Kiểm tra P-value cho Tương quan (Tăng trưởng DT vs. LNG) ---"
print(paste("Hệ số Tương quan (r):", round(cor_test_result$estimate, 4)))
## [1] "Hệ số Tương quan (r): 0.6577"
print(paste("Giá trị P:", round(cor_test_result$p.value, 5)))
## [1] "Giá trị P: 0.0542"

Kết quả: Hệ số tương quan Pearson r=0.6577 và giá trị p-value = 0.0542.

Kết luận: Với p-value ≈ 0.0542, lớn hơn một chút so với ngưỡng ý nghĩa 0.05, ta chưa đủ cơ sở thống kê để khẳng định mối tương quan là có ý nghĩa ở mức 5%, nhưng có thể xem là có xu hướng tương quan dương khá mạnh ở mức ý nghĩa 10%. Hệ số r = 0.6577cho thấy mối quan hệ thuận chiều: khi doanh thu tăng, lợi nhuận gộp thường có xu hướng tăng theo. Nói cách khác, sự tăng trưởng doanh thu có ảnh hưởng tích cực đến tăng trưởng lợi nhuận gộp, mặc dù mức độ tin cậy thống kê chưa tuyệt đối.

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

Chuẩn bị dữ liệu

library(moments)
library(dplyr)
df_viz <- df_10bien %>%
  mutate(
    GPM = LoiNhuanGop / DoanhThu, # Biên Lợi nhuận Gộp
    ROS = LNST / DoanhThu,        # Tỷ suất LNST/DT
    ROA = LNST / TongTaiSan,      # Tỷ suất Lợi nhuận trên Tài sản
    
    DE_Ratio = NoPhaiTra / VonChuSoHuu, # Tỷ số Nợ trên VCSH (Debt-to-Equity)
    CurrentRatio = TSNganHan / NoNganHan, # Tỷ số Thanh toán Hiện hành
    NWC = TSNganHan - NoNganHan,  # Vốn lưu động ròng (Net Working Capital)
    
    TT_DT = (DoanhThu / lag(DoanhThu)) - 1, # Tăng trưởng Doanh Thu
    TT_LNG = (LoiNhuanGop / lag(LoiNhuanGop)) - 1, # Tăng trưởng Lợi nhuận Gộp
    LNST_Group = factor(ifelse(LNST > 0, "Lãi", "Lỗ/Hòa")), # Nhóm Lãi hay Lỗ
    DT_Group = factor(ifelse(DoanhThu > median(DoanhThu), "DT Cao", "DT Thấp")) # Nhóm Doanh Thu theo Trung vị
  )

Bước này chuẩn bị dữ liệu định lượng hóa và phân loại nhằm phục vụ cho trực quan hóa, phân tích xu hướng và mối quan hệ giữa các chỉ tiêu tài chính trong giai đoạn 2015–2024. Việc chuẩn bị này giúp chuyển dữ liệu thô thành dữ liệu phân tích (analytic-ready), làm cơ sở để tạo biểu đồ và phân tích xu hướng chính xác.

2.7.1. Mối Quan Hệ Giữa Doanh Thu và LNST (Scatter Plot)

ggplot(data = df_viz, aes(x=nam, y=LoiNhuanGop)) + 
  geom_line(color="darkgreen", size=1.5) + 
  geom_point(aes(color = LNST_Group), size=3) + 
  scale_x_continuous(breaks=df_viz$nam) + 
  labs(title="Xu hướng Lợi nhuận Gộp (2015-2024)", y="Lợi nhuận Gộp") + 
  theme_minimal()

Biểu đồ được tạo bằng geom_point() với kích thước điểm tỷ lệ thuận với Lợi nhuận Gộp, đồng thời thêm đường hồi quy tuyến tính bằng geom_smooth(method=“lm”).

Ý nghĩa:

Biểu đồ thể hiện mối tương quan thuận chiều giữa Doanh thu và Lợi nhuận sau thuế (LNST). Đường hồi quy màu đỏ cho thấy khi doanh thu tăng, LNST cũng tăng theo — phù hợp với kết quả tương quan Pearson (r ≈ 0.66). Các điểm nằm gần đường xu hướng chứng tỏ mối quan hệ tuyến tính khá rõ, doanh nghiệp có khả năng chuyển hóa doanh thu thành lợi nhuận hiệu quả. Ngoài ra, kích thước điểm cho thấy các năm có lợi nhuận gộp cao thường cũng đi kèm với lợi nhuận ròng lớn, khẳng định hiệu quả quản trị chi phí tốt.

2.7.2. Phân Phối Tỷ số Thanh khoản (Histogram)

ggplot(data = df_viz, aes(x=CurrentRatio)) + 
  geom_histogram(bins=5, fill="skyblue", color="black") + 
  geom_vline(aes(xintercept=mean(CurrentRatio)), linetype="dashed", color="red") + 
  labs(title="Phân phối Tỷ số Thanh toán Hiện hành", x="Current Ratio") + 
  theme_light()

Biểu đồ được tạo bằng geom_histogram() (chia thành 5 khoảng), kết hợp với geom_vline() đánh dấu đường trung bình của tỷ số thanh toán hiện hành. Màu sắc: cột màu skyblue, đường trung bình đỏ.

Ý nghĩa:

Tỷ số Current Ratio tập trung chủ yếu quanh khoảng 1.2 – 1.7, với giá trị trung bình khoảng 1.4. Điều này cho thấy doanh nghiệp duy trì khả năng thanh toán ngắn hạn tương đối an toàn — tức là tài sản ngắn hạn lớn hơn nợ ngắn hạn. Phân phối hơi lệch về bên phải (right-skewed), thể hiện rằng có vài năm doanh nghiệp giữ mức thanh khoản cao hơn mức trung bình, phản ánh chính sách dự trữ vốn lưu động thận trọng.

2.7.3. So Sánh Quy mô Tài sản (Bar Plot)

ggplot(data = df_viz, aes(x=as.factor(nam), y=TongTaiSan)) + 
  geom_bar(stat="identity", fill="orange") + 
  geom_text(aes(label=round(TongTaiSan/1000, 1)), vjust=-0.5) + 
  labs(title="Quy mô Tổng Tài Sản theo năm", x="Năm", y="Tổng Tài Sản") + 
  theme_minimal()

Sử dụng geom_bar(stat=“identity”) để biểu diễn giá trị thực tế của Tổng tài sản qua từng năm, kết hợp geom_text() để hiển thị nhãn giá trị (đơn vị nghìn tỷ).

Ý nghĩa:

Biểu đồ cho thấy Tổng tài sản của doanh nghiệp tăng liên tục từ 2 nghìn tỷ (2015) lên gần 13.8 nghìn tỷ (2024). Đây là dấu hiệu tích cực, phản ánh quá trình mở rộng đầu tư, tăng quy mô vốn và tài sản cố định. Sự tăng trưởng ổn định qua thời gian cũng thể hiện mức độ tự tin trong chiến lược tài chính dài hạn và hiệu quả trong tái đầu tư lợi nhuận.

2.7.4. Biến động GPM và ROS (Line Plot - Dạng Dài)

df_long_margin <- df_viz %>%
  select(nam, GPM, ROS) %>%
  pivot_longer(cols = -nam, names_to = "name", values_to = "value")
ggplot(data = df_long_margin, aes(x=nam, y=value, color=name)) + 
  geom_line(size=1.2) + 
  geom_point(size=2) + 
  scale_x_continuous(breaks=df_viz$nam) + 
  labs(title="So sánh Biên LN Gộp (GPM) và Tỷ suất ROS", y="Tỷ lệ (%)") + 
  theme_bw()

Dữ liệu được chuyển sang dạng dài (long format) bằng pivot_longer(), sau đó vẽ bằng geom_line() và geom_point() để hiển thị 2 chỉ tiêu song song trên cùng trục thời gian.

Ý nghĩa:

Biểu đồ cho thấy GPM (biên lợi nhuận gộp) luôn cao hơn ROS (tỷ suất lợi nhuận ròng) — điều này hợp lý vì ROS đã trừ thêm chi phí quản lý, tài chính và thuế. Cả hai chỉ tiêu có xu hướng cùng chiều, chứng tỏ khi biên lợi nhuận gộp tăng, tỷ suất lợi nhuận ròng cũng được cải thiện. Tuy nhiên, biên độ biến động của GPM lớn hơn ROS, thể hiện mức độ nhạy cảm của lợi nhuận gộp với chi phí sản xuất và giá vốn hàng bán. Giai đoạn 2022 là điểm đáy của cả hai đường, cho thấy năm này có thể chịu tác động bất lợi (ví dụ: chi phí đầu vào tăng hoặc thị trường thu hẹp).

2.7.5. Tăng trưởng Doanh Thu (Bar Plot - Tăng/Giảm)

ggplot(data = drop_na(df_viz, TT_DT), aes(x=as.factor(nam), y=TT_DT)) + 
  geom_col(aes(fill=TT_DT > 0)) + 
  geom_text(aes(label=scales::percent(TT_DT, accuracy=0.1)), 
            vjust=ifelse(drop_na(df_viz, TT_DT)$TT_DT < 0, 1.5, -0.5)) + 
  labs(title="Tỷ suất Tăng trưởng Doanh Thu (TT_DT)", x="Năm", y="Tăng trưởng %") + 
  scale_fill_manual(values = c("FALSE" = "red", "TRUE" = "darkgreen"), name="Tăng trưởng") +
  theme_minimal()

Để mô tả biến động doanh thu qua các năm, biểu đồ cột được sử dụng với tỷ suất tăng trưởng doanh thu (TT_DT) làm trục tung và năm làm trục hoành. Hàm geom_col() hiển thị giá trị tăng trưởng từng năm, đồng thời các cột được tô màu theo điều kiện logic: màu xanh đậm (“darkgreen”) thể hiện mức tăng trưởng dương, trong khi màu đỏ biểu thị giai đoạn suy giảm. Ngoài ra, geom_text() được dùng để chèn nhãn hiển thị giá trị phần trăm ngay trên cột, giúp người xem dễ nhận biết biến động tăng/giảm qua từng năm.

Kết quả biểu đồ cho thấy doanh nghiệp có sự tăng trưởng mạnh trong các năm 2017 (89,8%), 2018 (96,9%) và 2021 (76,9%), phản ánh giai đoạn mở rộng hoạt động hoặc tăng thị phần. Tuy nhiên, năm 2020 (-19,8%) và 2023 (-17,5%) ghi nhận mức giảm đáng kể, có thể do ảnh hưởng từ thị trường hoặc các yếu tố chi phí. Đến năm 2024, doanh thu tăng nhẹ (1,3%), thể hiện xu hướng phục hồi sau giai đoạn chững lại. Nhìn chung, doanh thu biến động khá mạnh nhưng xu hướng tổng thể vẫn tích cực, phản ánh khả năng thích ứng và duy trì doanh số của doanh nghiệp.

2.7.6. So Sánh LNST, LNG, DT (Box Plot - Log scale)

df_long_3var <- df_10bien %>%
  select(LNST, LoiNhuanGop, DoanhThu) %>%
  pivot_longer(cols = everything(), names_to = "ChiSo", values_to = "GiaTri")
ggplot(data = df_long_3var, aes(x=ChiSo, y=GiaTri)) + 
  geom_boxplot(aes(fill=ChiSo)) + 
  scale_y_log10(labels = scales::comma) + 
  labs(title="Phân phối Logarit của 3 Chỉ số Tài chính", y="Giá trị (Thang Logarit)") + 
  theme_light()

Biểu đồ hộp (Box Plot) được sử dụng nhằm so sánh phân phối của ba chỉ tiêu tài chính: doanh thu, lợi nhuận gộp và lợi nhuận sau thuế. Dữ liệu được chuyển đổi sang dạng “dài” bằng hàm pivot_longer(), giúp gom ba cột giá trị vào chung một biến “Giá trị” và phân biệt bằng nhãn “Chỉ số”. Biểu đồ sử dụng thang logarit (scale_y_log10()) để chuẩn hóa quy mô các giá trị có độ chênh lệch lớn, giúp người xem dễ so sánh tỷ lệ tương đối thay vì tuyệt đối.

Kết quả cho thấy doanh thu có phân phối ổn định và giá trị cao nhất, thể hiện quy mô hoạt động lớn. Lợi nhuận gộp thấp hơn một bậc logarit, chứng tỏ biên lợi nhuận vẫn duy trì tốt dù chi phí sản xuất cao. Lợi nhuận sau thuế (LNST) có độ biến động lớn hơn và xuất hiện một vài điểm ngoại lệ, phản ánh sự dao động của chi phí quản lý, tài chính hoặc thuế. Như vậy, biểu đồ này giúp khẳng định mối quan hệ hợp lý giữa ba chỉ tiêu: doanh thu cao tạo nền tảng cho lợi nhuận gộp và lợi nhuận ròng, tuy nhiên hiệu quả cuối cùng vẫn phụ thuộc vào khả năng kiểm soát chi phí.

2.7.7. Xu Hướng Nợ Phải Trả (Area Plot)

ggplot(data = df_viz, aes(x=nam, y=NoPhaiTra)) + 
  geom_area(fill="red", alpha=0.5) + 
  geom_line(color="darkred", size=1) + 
  scale_x_continuous(breaks=df_viz$nam) + 
  labs(title="Xu hướng Nợ Phải Trả (2015-2024)", y="Nợ Phải Trả") + 
  theme_minimal()

Để thể hiện sự biến động của nợ phải trả qua thời gian, biểu đồ diện tích được xây dựng bằng geom_area(), với màu nền đỏ nhạt đại diện cho giá trị tích lũy của nợ trong từng năm, kết hợp đường viền đậm màu đỏ sẫm (geom_line(color=“darkred”)) giúp nhấn mạnh xu hướng tổng thể. Biểu đồ này có ưu điểm là làm nổi bật cả mức độ và tốc độ tăng trưởng của chỉ tiêu nợ theo thời gian.

Quan sát biểu đồ cho thấy nợ phải trả tăng liên tục từ năm 2015 đến 2024. Giai đoạn 2015–2019 có tốc độ tăng nhanh nhất, thể hiện sự mở rộng quy mô đầu tư. Từ 2020 đến 2022, nợ gần như đi ngang, phản ánh sự ổn định trong cơ cấu vốn. Sang giai đoạn 2023–2024, nợ tăng mạnh trở lại, có thể do doanh nghiệp huy động thêm nguồn vốn vay phục vụ cho mở rộng tài sản hoặc đầu tư dài hạn. Điều này cho thấy doanh nghiệp đang tận dụng đòn bẩy tài chính hợp lý để phát triển, nhưng cũng cần cân đối để hạn chế rủi ro tài chính trong tương lai.

2.7.8. Quan Hệ giữa Dòng tiền HĐKD và LNST (Scatter Plot với Size)

ggplot(data = df_viz, aes(x=LNST, y=TienThuanHDKD)) + 
  geom_point(aes(size=DoanhThu, color=LNST_Group), alpha=0.7) + 
  geom_hline(yintercept=0, linetype="dashed", color="grey") + 
  labs(title="LNST so với Dòng tiền HĐKD", caption="Kích thước điểm theo Doanh Thu") + 
  theme_light()

Biểu đồ phân tán được sử dụng để phân tích mối tương quan giữa lợi nhuận sau thuế (LNST) và dòng tiền từ hoạt động kinh doanh (Tiền thuần HĐKD). Trục hoành biểu diễn LNST, trục tung thể hiện dòng tiền, trong khi kích thước điểm thể hiện quy mô doanh thu từng năm. Ngoài ra, các điểm được tô màu theo nhóm LNST_Group nhằm phân biệt tình trạng “Lãi” hoặc “Lỗ”. Một đường tham chiếu ngang tại y=0 được thêm bằng geom_hline() để xác định rõ mốc dòng tiền âm và dương.

Kết quả cho thấy phần lớn các điểm nằm trên trục hoành, tức là dòng tiền hoạt động dương, phản ánh khả năng tạo dòng tiền thật từ hoạt động kinh doanh. Mối tương quan giữa LNST và dòng tiền là thuận chiều, nghĩa là năm nào lợi nhuận cao thì dòng tiền cũng mạnh. Một vài điểm gần trục 0 cho thấy lợi nhuận kế toán không đi kèm với dòng tiền tương ứng, có thể do gia tăng các khoản phải thu hoặc hàng tồn kho. Biểu đồ này cho thấy doanh nghiệp có chất lượng lợi nhuận tốt, không phụ thuộc vào lợi nhuận ghi sổ, và duy trì dòng tiền ổn định từ hoạt động chính.

2.7.9. Biến động Tỷ suất ROS (Line Plot với Vùng Thống kê)

ggplot(data = df_viz, aes(x=nam, y=ROS)) + 
  geom_line(color="blue", size=1.2) + 
  geom_ribbon(aes(ymin=mean(ROS), ymax=ROS), fill="blue", alpha=0.1) + 
  scale_x_continuous(breaks=df_viz$nam) + 
  labs(title="Biến động Tỷ suất ROS (Lợi nhuận/Doanh Thu)", y="ROS (%)") + 
  scale_y_continuous(labels = scales::percent) + 
  theme_classic()

Biểu đồ đường được sử dụng để thể hiện sự biến động của tỷ suất ROS (Lợi nhuận ròng/Doanh thu) qua các năm, kết hợp với vùng dao động quanh trung bình bằng geom_ribbon(). Màu sắc chủ đạo là xanh lam, giúp nhấn mạnh sự thay đổi nhẹ nhàng nhưng có chu kỳ của hiệu suất lợi nhuận.

Kết quả cho thấy ROS đạt mức cao nhất vào năm 2016 (khoảng 6,8%), sau đó giảm dần và chạm mức thấp nhất vào năm 2022 (xấp xỉ 1%). Đến năm 2023–2024, tỷ suất này bắt đầu tăng trở lại, cho thấy doanh nghiệp đang dần cải thiện hiệu quả hoạt động sau giai đoạn chi phí tăng. Vùng bóng thể hiện độ dao động quanh mức trung bình (3,5%), phản ánh sự biến thiên của lợi nhuận ròng theo chu kỳ doanh thu. Biểu đồ này chỉ ra rằng dù ROS có giảm trong một số giai đoạn, doanh nghiệp vẫn duy trì được hiệu quả sinh lời dương liên tục, thể hiện khả năng chống chịu trước áp lực chi phí và biến động thị trường.

2.7.10. Biểu đồ Vốn lưu động ròng (NWC) qua các năm (Bar Plot)

ggplot(data = df_viz, aes(x=nam, y=NWC)) + 
  geom_bar(stat="identity", aes(fill=NWC > 0)) + 
  geom_text(aes(label=comma(NWC, accuracy=1)), vjust=ifelse(df_viz$NWC < 0, 1.5, -0.5), size=3) + 
  scale_x_continuous(breaks=df_viz$nam) + 
  labs(title="Vốn Lưu động Ròng (NWC) qua các năm", y="Vốn Lưu động") + 
  scale_fill_manual(values = c("FALSE" = "red", "TRUE" = "darkgreen"), name="") +
  theme_minimal()

Biểu đồ cột được sử dụng để mô tả sự thay đổi của vốn lưu động ròng (NWC) trong giai đoạn 2015–2024. Trong phần mã, hàm geom_bar() với tham số stat=“identity” được dùng để thể hiện giá trị thực tế của NWC theo từng năm. Màu sắc của các cột được quy định theo điều kiện logic fill=NWC > 0, với màu xanh đậm (“darkgreen”) cho giá trị dương và màu đỏ cho giá trị âm. Ngoài ra, geom_text() được bổ sung để hiển thị giá trị cụ thể trên từng cột, giúp tăng tính trực quan và dễ nhận xét.

Quan sát biểu đồ cho thấy NWC tăng mạnh qua thời gian, đặc biệt từ năm 2017 trở đi. Từ mức 404 vào năm 2015, vốn lưu động ròng tăng đều qua các năm và đạt đỉnh vào năm 2022 với giá trị 2.452. Giai đoạn 2023–2024 duy trì ở mức cao (khoảng 2.294), phản ánh sự ổn định trong quản trị vốn lưu động. Việc NWC luôn dương chứng tỏ tài sản ngắn hạn của doanh nghiệp đủ để đáp ứng các nghĩa vụ ngắn hạn, thể hiện khả năng thanh toán tốt. Nhìn chung, xu hướng tăng của NWC phản ánh hiệu quả quản lý dòng tiền và hàng tồn kho, đồng thời cho thấy doanh nghiệp có nền tài chính ngắn hạn lành mạnh và ổn định.

2.7.11. Tương quan giữa Tăng trưởng LNG và Dòng tiền HĐKD

ggplot(data = drop_na(df_viz), aes(x=TT_LNG, y=TienThuanHDKD)) + 
  geom_point(aes(color=LNST_Group)) + 
  geom_smooth(method="loess", se=FALSE) + 
  labs(title="Quan hệ Tăng trưởng LNG và Dòng tiền HĐKD", x="Tăng trưởng LNG (%)") + 
  scale_x_continuous(labels = percent) + 
  theme_classic()
## `geom_smooth()` using formula = 'y ~ x'

Biểu đồ phân tán được sử dụng để thể hiện mối quan hệ giữa tốc độ tăng trưởng lợi nhuận gộp (TT_LNG) và dòng tiền từ hoạt động kinh doanh (TiềnThuầnHĐKD). Dữ liệu được làm sạch bằng drop_na() để loại bỏ các giá trị khuyết, sau đó trực quan hóa bằng geom_point(), trong đó màu của điểm được quy định theo biến LNST_Group nhằm phân biệt nhóm “Lãi”. Đường xu hướng được thêm vào bằng geom_smooth(method=“loess”, se=FALSE), giúp mô tả xu hướng phi tuyến giữa hai biến.

Biểu đồ cho thấy mối tương quan phi tuyến thuận chiều nhẹ giữa TT_LNG và dòng tiền HĐKD. Khi tốc độ tăng trưởng lợi nhuận gộp đạt mức trung bình (khoảng 30%), dòng tiền hoạt động đạt đỉnh, cho thấy hiệu quả tối ưu giữa biên lợi nhuận và khả năng tạo tiền mặt. Tuy nhiên, khi TT_LNG vượt mức cao, dòng tiền có xu hướng giảm, có thể do doanh nghiệp phải tăng đầu tư cho chi phí sản xuất hoặc hàng tồn kho. Kết quả này cho thấy doanh nghiệp cần cân bằng giữa tăng trưởng lợi nhuận và kiểm soát dòng tiền, nhằm đảm bảo hiệu quả vận hành bền vững.

2.7.12. Phân phối Tỷ số Nợ trên Vốn Chủ Sở Hữu (Density Plot)

ggplot(data = df_viz, aes(x=DE_Ratio)) + 
  geom_density(fill="purple", alpha=0.5) + 
  geom_rug(aes(color=as.factor(nam))) + 
  labs(title="Phân phối Tỷ số Nợ trên Vốn Chủ Sở Hữu (DE_Ratio)", x="DE Ratio") + 
  theme_minimal()

Để phân tích mức độ rủi ro tài chính, biểu đồ mật độ (Density Plot) được sử dụng nhằm thể hiện phân phối của tỷ số nợ trên vốn chủ sở hữu (DE Ratio) trong giai đoạn 2015–2024. Hàm geom_density() được dùng với màu tô tím (fill=“purple”) và độ trong suốt (alpha=0.5) giúp trực quan hóa phân bố tần suất xuất hiện của tỷ lệ nợ. Thêm vào đó, geom_rug() được bổ sung để biểu diễn các điểm giá trị thực theo từng năm trên trục hoành.

Kết quả biểu đồ cho thấy phân phối của DE Ratio tập trung chủ yếu trong khoảng từ 0,8 đến 1,6, với mật độ cao nhất xung quanh 1,2. Điều này phản ánh rằng doanh nghiệp duy trì tỷ lệ nợ ở mức cân bằng so với vốn chủ sở hữu, tức cứ 1 đồng vốn tự có thì có khoảng 1,2 đồng vốn vay. Mức này được coi là an toàn trong quản trị tài chính vì cho phép tận dụng đòn bẩy tài chính mà không làm gia tăng rủi ro mất khả năng thanh toán. Tuy nhiên, phần đuôi bên phải của biểu đồ (khoảng > 2,0) cho thấy có những giai đoạn doanh nghiệp tăng nợ, cần được theo dõi để tránh vượt ngưỡng rủi ro.

2.7.13. So sánh Tổng Tài sản và Nợ Phải Trả (Grouped Bar Chart)

df_long_asset <- df_10bien %>%
  select(nam, TongTaiSan, NoPhaiTra) %>%
  pivot_longer(cols = -nam, names_to = "ChiSo", values_to = "GiaTri")

ggplot(data = df_long_asset, aes(x=as.factor(nam), y=GiaTri, fill=ChiSo)) + 
  geom_bar(stat="identity", position="dodge") + 
  scale_y_continuous(labels = comma) + 
  labs(title="So sánh Quy mô Tổng Tài Sản và Nợ Phải Trả", x="Năm", y="Giá trị") + 
  theme_bw()

Biểu đồ cột nhóm được sử dụng để so sánh quy mô tổng tài sản và nợ phải trả của doanh nghiệp qua các năm. Dữ liệu được chuyển đổi sang dạng dài bằng pivot_longer(), trong đó các chỉ tiêu “TổngTàiSản” và “NợPhảiTrả” được gom vào một cột “Chỉ số” nhằm hiển thị song song trong từng nhóm năm. Hàm geom_bar(position=“dodge”) giúp hiển thị hai cột cạnh nhau, cho phép người xem dễ dàng nhận biết tỷ trọng giữa tài sản và nợ trong từng năm.

Quan sát biểu đồ cho thấy tổng tài sản tăng đều đặn từ năm 2015 đến 2024, trong khi nợ phải trả cũng tăng song song nhưng với tốc độ chậm hơn. Điều này phản ánh doanh nghiệp đang mở rộng quy mô hoạt động nhưng vẫn giữ được sự cân đối tài chính. Đáng chú ý, chênh lệch giữa hai cột ngày càng lớn, nghĩa là tài sản tăng nhanh hơn nợ, cho thấy sự cải thiện trong vốn chủ sở hữu. Đây là tín hiệu tích cực về khả năng tự chủ tài chính, giảm phụ thuộc vào nguồn vốn vay, đồng thời nâng cao tính bền vững của cấu trúc tài chính.

2.7.14. Tỷ suất ROA (Line Plot)

ggplot(data = df_viz, aes(x = nam, y = ROA)) +
  geom_line(color = "darkblue", size = 2) +
  geom_point(aes(size = DoanhThu)) +
  labs(
    title = "Tỷ suất Sinh lời trên Tài sản (ROA)",
    x = "Năm",
    y = "ROA (%)"
  ) +
  scale_x_continuous(
    breaks = seq(2015, 2025, by = 1)  # hiển thị từng năm
  ) +
  scale_y_continuous(labels = scales::percent) +
  theme_minimal()

Biểu đồ đường được sử dụng để mô tả tỷ suất sinh lời trên tổng tài sản (ROA) của doanh nghiệp qua thời gian. Cấu trúc biểu đồ gồm đường nối (geom_line(color=“darkblue”)) thể hiện xu hướng biến động, kết hợp các điểm dữ liệu được phóng to theo quy mô doanh thu (aes(size=DoanhThu)) nhằm minh họa mối quan hệ giữa quy mô hoạt động và hiệu suất sinh lời.

Kết quả cho thấy ROA đạt mức cao nhất vào năm 2019 (~5,8%), sau đó giảm mạnh trong năm 2020 (~3,1%) và 2022 (~1,5%), rồi dần phục hồi vào năm 2024 (~2,7%). Diễn biến này cho thấy hiệu suất sử dụng tài sản của doanh nghiệp biến động theo chu kỳ, phản ánh tác động của đầu tư mở rộng và chi phí tài chính. Khi doanh thu tăng mạnh nhưng tài sản cũng tăng nhanh, ROA có xu hướng giảm nhẹ do hiệu quả sử dụng tài sản bị pha loãng. Tuy nhiên, việc duy trì ROA dương liên tục chứng tỏ doanh nghiệp sử dụng tài sản hiệu quả và sinh lời ổn định, tạo nền tảng tốt cho tăng trưởng bền vững trong dài hạn.

2.7.15. Phân tích LNST theo Nhóm Doanh Thu (Box Plot)

ggplot(data = df_viz, aes(x=DT_Group, y=LNST)) + 
  geom_boxplot(aes(fill=DT_Group)) + 
  geom_jitter(width = 0.1, alpha = 0.5) + 
  labs(title="Phân phối LNST theo Nhóm Doanh Thu (Cao/Thấp)", x="Nhóm Doanh Thu") + 
  theme_light()

Kỹ thuật: Biểu đồ hộp (Box Plot) được sử dụng để mô tả sự phân phối Lợi nhuận sau thuế (LNST) theo hai nhóm doanh thu “Cao” và “Thấp”, được xác định dựa trên trung vị doanh thu. Hàm geom_boxplot() hiển thị đặc trưng thống kê (trung vị, tứ phân vị, ngoại lệ), trong khi geom_jitter() thêm các điểm rải giúp quan sát rõ từng giá trị cụ thể, với độ trong suốt (alpha=0.5) để tránh trùng lặp.

Kết quả: Biểu đồ cho thấy nhóm “Doanh thu cao” có LNST trung vị cao hơn đáng kể so với nhóm “Doanh thu thấp”. Ngoài ra, phạm vi dao động (IQR) của nhóm cao cũng lớn hơn, nghĩa là lợi nhuận trong nhóm này biến động nhiều hơn. Một vài điểm ngoại lệ ở cả hai nhóm thể hiện những năm đặc biệt có kết quả khác thường.

Ý nghĩa: Điều này phản ánh mối quan hệ thuận chiều giữa doanh thu và lợi nhuận, tức là quy mô doanh thu lớn thường đi kèm lợi nhuận cao hơn. Tuy nhiên, mức độ biến động trong nhóm cao cũng cho thấy rủi ro lợi nhuận lớn hơn, có thể do chi phí và quy mô đầu tư cao. Kết quả này củng cố rằng doanh nghiệp cần kiểm soát tốt biên lợi nhuận khi mở rộng quy mô để đảm bảo hiệu quả sinh lời ổn định.

2.7.16. Tương quan giữa Tổng Tài sản và Nợ phải trả (Scatter Plot)

ggplot(data = df_viz, aes(x=TongTaiSan, y=NoPhaiTra)) + 
  geom_point(aes(color=LNST_Group)) + 
  geom_abline(intercept = 0, slope = 1, linetype="dashed", color="grey") + 
  labs(title="Mối quan hệ Tổng Tài Sản và Nợ Phải Trả") + 
  scale_x_continuous(labels = comma) + 
  theme_classic()

Biểu đồ phân tán được sử dụng để thể hiện mối tương quan giữa Tổng tài sản (x) và Nợ phải trả (y). Đường chéo màu xám (geom_abline(slope=1)) đóng vai trò mốc tham chiếu: các điểm nằm gần đường này biểu thị nợ gần bằng tài sản, trong khi điểm nằm dưới thể hiện vốn chủ sở hữu dương.

Kết quả: Hầu hết các điểm nằm dưới đường chéo, chứng tỏ tổng tài sản luôn lớn hơn nợ phải trả — tức doanh nghiệp duy trì vốn chủ sở hữu dương. Các điểm phân bố khá tuyến tính cho thấy mối quan hệ mạnh giữa quy mô tài sản và nợ. Những năm có tổng tài sản lớn hơn thường đi kèm mức nợ cao hơn, song khoảng cách giữa hai đại lượng vẫn được giữ ổn định.

Ý nghĩa: Điều này phản ánh một cấu trúc tài chính cân đối: doanh nghiệp có khả năng mở rộng tài sản mà vẫn kiểm soát tốt nợ vay. Việc duy trì tỷ lệ tài sản > nợ cho thấy nền tảng tài chính vững vàng, giảm thiểu rủi ro thanh khoản và tăng độ tin cậy tín dụng.

2.7.17. Tỷ trọng Nợ/VCSH (DE Ratio) qua các năm (Step Plot)

ggplot(data = df_viz, aes(x=nam, y=DE_Ratio)) + 
  geom_step(color="brown", size=1.2) + 
  geom_hline(yintercept=1, linetype="dashed", color="red") + 
  labs(title="Tỷ số Nợ trên Vốn Chủ Sở Hữu (DE Ratio)", y="DE Ratio") + 
  scale_x_continuous(breaks=df_viz$nam) + 
  theme_minimal()

Để mô tả xu hướng tỷ số nợ trên vốn chủ sở hữu (DE Ratio) qua thời gian, biểu đồ bậc thang (geom_step()) được sử dụng nhằm làm rõ các giai đoạn thay đổi. Đường ngang đỏ tại DE = 1 (geom_hline()) thể hiện ngưỡng cân bằng giữa nợ và vốn chủ.

Kết quả: DE Ratio dao động trong khoảng 0,9–2,2. Giai đoạn 2015–2017 ghi nhận mức cao nhất (trên 2), phản ánh việc doanh nghiệp dựa nhiều vào nợ vay để mở rộng hoạt động. Từ 2018 trở đi, DE Ratio giảm dần xuống quanh mức 1, cho thấy xu hướng giảm phụ thuộc vào đòn bẩy tài chính.

Ý nghĩa: Kết quả này cho thấy doanh nghiệp đã từng trải qua giai đoạn rủi ro tài chính cao, nhưng đã điều chỉnh hợp lý để duy trì tỷ lệ nợ/vốn ở mức an toàn. Việc giữ DE gần 1 phản ánh chiến lược cân bằng giữa sử dụng vốn vay và vốn chủ sở hữu – vừa tận dụng được đòn bẩy tài chính, vừa kiểm soát rủi ro thanh khoản.

2.7.18. Doanh Thu và Hàng Tồn Kho (Stacked Area Plot)

ggplot(data = df_viz, aes(x=nam)) + 
  geom_area(aes(y=DoanhThu, fill="Doanh Thu"), alpha=0.5, position="identity") + 
  geom_area(aes(y=HangTonKho, fill="Hàng Tồn Kho"), alpha=0.7, position="identity") + 
  labs(title="So sánh Quy mô Doanh Thu và Hàng Tồn Kho", y="Giá trị", fill="Chỉ số") + 
  scale_x_continuous(breaks=df_viz$nam) +
  theme_bw()

Biểu đồ diện tích chồng (Stacked Area Plot) được xây dựng bằng geom_area() để hiển thị quy mô của doanh thu và hàng tồn kho theo thời gian. Các lớp màu được chồng lên nhau, giúp thể hiện trực quan mối tương quan giữa hai đại lượng.

Kết quả: Trong giai đoạn 2015–2024, cả doanh thu và hàng tồn kho đều tăng đáng kể, song tốc độ tăng của doanh thu nhanh hơn. Hàng tồn kho tăng dần đến 2022 rồi giảm nhẹ, trong khi doanh thu đạt đỉnh vào 2022 và duy trì ổn định sau đó. Tỷ lệ hàng tồn kho trên doanh thu giảm nhẹ, thể hiện hiệu quả quản lý hàng tồn kho được cải thiện.

Ý nghĩa: Mối tương quan này phản ánh chu kỳ kinh doanh hiệu quả: doanh thu tăng nhanh hơn tồn kho chứng tỏ khả năng tiêu thụ hàng hóa được cải thiện, giảm rủi ro ứ đọng vốn. Biểu đồ cũng giúp doanh nghiệp theo dõi được sự phù hợp giữa sản xuất và tiêu thụ — yếu tố quan trọng trong quản trị dòng tiền.

2.7.19. Biểu đồ Bong bóng (Bubble Chart - 3 biến)

ggplot(data = df_viz, aes(x=GPM, y=ROS, size=TongTaiSan, color=as.factor(nam))) + 
  geom_point(alpha=0.8) + 
  geom_text(aes(label=nam), check_overlap = TRUE, size=3, vjust=-1) + 
  labs(title="Hiệu quả (GPM vs ROS) và Quy mô Tổng Tài Sản", x="Biên Lợi nhuận Gộp (GPM)", y="ROS") + 
  scale_x_continuous(labels = percent) + 
  scale_y_continuous(labels = percent) + 
  theme_light()

Biểu đồ bong bóng thể hiện đồng thời ba biến: GPM (biên lợi nhuận gộp) trên trục hoành, ROS (lợi nhuận ròng/doanh thu) trên trục tung và Tổng tài sản thể hiện qua kích thước bong bóng. Màu sắc phân biệt theo năm (color=as.factor(nam)), giúp quan sát sự biến động theo thời gian.

Kết quả: Biểu đồ cho thấy các điểm phân tán có xu hướng tăng dần về kích thước qua các năm — tức tổng tài sản tăng trưởng mạnh. Giai đoạn 2016–2017 là thời kỳ có hiệu quả cao nhất khi ROS và GPM đều đạt đỉnh. Giai đoạn 2020–2022 cho thấy sự suy giảm hiệu suất, thể hiện qua vị trí bong bóng thấp hơn trên đồ thị, nhưng đến 2024 hiệu quả dần hồi phục.

Ý nghĩa: Kết hợp hai chỉ tiêu ROS và GPM, có thể thấy mối quan hệ thuận chiều giữa biên lợi nhuận và hiệu quả tổng thể. Khi GPM tăng, ROS cũng tăng theo, chứng tỏ doanh nghiệp kiểm soát tốt chi phí hoạt động. Việc tổng tài sản mở rộng trong khi hiệu quả vẫn được duy trì phản ánh khả năng phát triển bền vững với quy mô lớn hơn mà không đánh đổi hiệu suất.

2.7.20. Biểu đồ Donut - Phân bổ Tổng Tài Sản

df_donut <- df_viz %>% 
  filter(nam == 2024) %>% 
  select(NoPhaiTra, VonChuSoHuu) %>%
  pivot_longer(cols = everything(), names_to = "ChiSo", values_to = "GiaTri") %>%
  mutate(fraction = GiaTri / sum(GiaTri), 
         ymax = cumsum(fraction),
         ymin = c(0, head(ymax, n=-1)))
ggplot(data = df_donut, aes(ymax=ymax, ymin=ymin, xmax=4, xmin=3, fill=ChiSo)) + 
  geom_rect() + # Sử dụng geom_rect cho donut
  coord_polar(theta="y") + # Layer 4: Biến đổi tọa độ
  xlim(c(2, 4)) + # Điều chỉnh để tạo lỗ tròn
  labs(title="Phân bổ Cấu trúc Vốn năm 2024", fill="Thành phần") + 
  theme_void() + # Layer 5: Chủ đề rỗng
  geom_text(aes(label=scales::percent(fraction, accuracy=0.1), x=3.5, y=(ymin+ymax)/2)) # Layer 5: Thêm nhãn %

Biểu đồ Donut được xây dựng từ dữ liệu df_viz, sau khi lọc riêng năm 2024 và chỉ giữ hai thành phần chính là Nợ phải trả và Vốn chủ sở hữu. Dữ liệu được chuyển từ dạng rộng sang dạng dài bằng hàm pivot_longer() để dễ dàng biểu diễn trong ggplot2. Sau đó, các giá trị được tính tỉ trọng phần trăm (fraction = GiaTri / sum(GiaTri)) và xác định giới hạn trên dưới (ymax, ymin) để tạo thành các lát cắt. Lệnh geom_rect() tạo các khối chữ nhật đại diện cho từng phần, và coord_polar(theta=“y”) biến chúng thành dạng tròn. Để tạo “lỗ rỗng” giữa trung tâm, biểu đồ dùng xlim(c(2,4)), giúp hình thành cấu trúc donut đặc trưng. Cuối cùng, geom_text() được thêm vào để hiển thị tỉ lệ phần trăm rõ ràng ngay trên biểu đồ.

Về mặt ý nghĩa, biểu đồ cho thấy phân bố cơ cấu vốn của doanh nghiệp trong năm 2024. Trong đó, Nợ phải trả chiếm 54,7%, còn Vốn chủ sở hữu chiếm 45,3%. Điều này phản ánh cơ cấu tài chính đang nghiêng về vốn vay, thể hiện mức đòn bẩy tài chính cao. Doanh nghiệp có thể tận dụng nợ để mở rộng hoạt động, nhưng đồng thời cũng cần cân nhắc rủi ro từ gánh nặng chi phí tài chính và nghĩa vụ trả nợ trong tương lai.

2.7.21. Biểu đồ Heatmap (Tile Plot) - Tỷ trọng Tăng trưởng

df_tile <- df_viz %>%
  select(nam, TT_DT, TT_LNG) %>%
  pivot_longer(cols = c(TT_DT, TT_LNG), names_to = "name", values_to = "value") %>%
  drop_na()
ggplot(data = df_tile, aes(x=name, y=as.factor(nam), fill=value)) + 
  geom_tile(color="black") + 
  geom_text(aes(label=scales::percent(value, accuracy=1)), size=3) + # Layer 5: Thêm nhãn %
  scale_fill_gradient2(low="red", mid="white", high="blue", midpoint=0, labels=percent) + # Layer 4: Thiết lập màu
  labs(title="Heatmap Tỷ suất Tăng trưởng (DT & LNG)", x="", y="Năm", fill="Tăng trưởng") + 
  theme_minimal()

Biểu đồ Heatmap được thiết kế để thể hiện biến động tăng trưởng (%) qua các năm của hai chỉ tiêu: doanh thu (TT_DT) và lợi nhuận gộp (TT_LNG). Dữ liệu được làm sạch và chuyển sang định dạng dài bằng pivot_longer(), sau đó vẽ bằng geom_tile() để mỗi ô thể hiện giá trị tăng trưởng tại một năm cụ thể. Thang màu được thiết lập bằng scale_fill_gradient2() với ba điểm: màu đỏ cho giá trị âm (suy giảm), trắng cho trung tính (0%), và xanh cho giá trị dương (tăng trưởng). Đồng thời, geom_text() giúp hiển thị con số phần trăm ngay trong từng ô, và theme_minimal() làm biểu đồ sạch, tập trung vào dữ liệu.

Về ý nghĩa, Heatmap này thể hiện xu hướng biến động tăng trưởng doanh thu và lợi nhuận gộp từ 2016 đến 2024. Có thể thấy rõ các giai đoạn nổi bật như 2018–2021, nơi cả hai chỉ tiêu đều đạt mức tăng trưởng mạnh (màu xanh đậm), cho thấy doanh nghiệp trong giai đoạn này hoạt động hiệu quả. Ngược lại, các năm 2020 và 2023 xuất hiện màu đỏ hoặc nhạt, cho thấy tăng trưởng suy giảm hoặc âm, phản ánh những biến động bất lợi trên thị trường hoặc chi phí gia tăng. Biểu đồ này hữu ích cho việc đánh giá chu kỳ kinh doanh và hiệu quả quản lý chi phí qua thời gian.

2.7.22. Biểu đồ Tần suất (Histogram) - Độ lớn Tăng trưởng Doanh Thu

ggplot(data = drop_na(df_viz, TT_DT), aes(x=TT_DT)) + 
  geom_histogram(binwidth=0.1, fill="darkblue", color="white") + 
  geom_density(aes(y=..count.. * 0.1), color="red", size=1) + 
  labs(title="Phân phối Tốc độ Tăng trưởng Doanh Thu", x="Tăng trưởng %") + 
  scale_x_continuous(labels = percent) + 
  theme_bw()
## Warning: The dot-dot notation (`..count..`) was deprecated in ggplot2 3.4.0.
## ℹ Please use `after_stat(count)` instead.
## This warning is displayed once every 8 hours.
## Call `lifecycle::last_lifecycle_warnings()` to see where this warning was
## generated.

Biểu đồ Histogram được sử dụng để mô tả phân phối tần suất của tốc độ tăng trưởng doanh thu (TT_DT). Biểu đồ được vẽ bằng geom_histogram() với binwidth = 0.1 để chia dữ liệu thành các khoảng 10%, giúp dễ dàng nhận biết các cụm giá trị. Màu nền của các cột là darkblue, đường viền trắng, và một lớp geom_density() màu đỏ được thêm vào để biểu diễn đường mật độ phân bố, cho phép nhìn rõ xu hướng chung của dữ liệu.

Về ý nghĩa, biểu đồ này cho thấy phân phối mức tăng trưởng doanh thu trong giai đoạn nghiên cứu không đồng đều. Các cột tập trung chủ yếu quanh hai vùng: 0–40% và 70–90%, cho thấy có hai nhóm đối tượng hoặc hai giai đoạn tăng trưởng khác biệt. Đường mật độ đỏ có dạng dẹt, thể hiện sự phân tán lớn, tức là tốc độ tăng trưởng doanh thu giữa các năm hoặc đơn vị có sự khác biệt rõ rệt. Đây là dấu hiệu cần được phân tích thêm để xác định nguyên nhân, chẳng hạn khác biệt ngành nghề, thị trường hoặc quy mô doanh nghiệp.

2.7.23. Biểu đồ Phân tán (Dot Plot) - So sánh Cấu trúc Vốn Chủ Sở Hữu

ggplot(data = df_viz, aes(x=VonChuSoHuu)) + 
  geom_dotplot(binwidth=200, fill="salmon", color="red", stackdir="center") + 
  geom_vline(aes(xintercept=median(VonChuSoHuu)), linetype="dashed", color="darkgrey") + 
  labs(title="Phân bố Vốn Chủ Sở Hữu (Dot Plot)", y="", x="Vốn Chủ Sở Hữu") + 
  theme_minimal() + 
  theme(axis.text.y = element_blank(), axis.ticks.y = element_blank())

Biểu đồ Dot Plot được xây dựng để biểu diễn sự phân bố của giá trị Vốn chủ sở hữu (VonChuSoHuu). Hàm geom_dotplot() được dùng với binwidth=200, mỗi điểm tròn biểu diễn một giá trị. Màu điểm là salmon (hồng cam) với viền đỏ, giúp nổi bật trên nền trắng. Một đường thẳng đứng được thêm bằng geom_vline() để đánh dấu trung vị của tập dữ liệu, với đường kẻ dạng gạch (linetype=“dashed”) màu xám. Để biểu đồ rõ ràng hơn, trục tung được loại bỏ qua theme(axis.text.y = element_blank()).

Ý nghĩa của biểu đồ này là giúp quan sát sự phân bố và mức độ chênh lệch của vốn chủ sở hữu giữa các đối tượng (năm hoặc công ty). Các điểm rải rác từ khoảng 1000 đến hơn 6000 cho thấy có sự phân tán đáng kể về quy mô vốn. Trung vị nằm khoảng 3500–4000, thể hiện một giá trị điển hình của nhóm trung bình. Một vài điểm tập trung ở phía cao phản ánh các doanh nghiệp có năng lực tài chính mạnh hơn hẳn. Biểu đồ này giúp nhà phân tích dễ dàng đánh giá mức độ đồng đều của năng lực vốn và xác định sự mất cân bằng trong cấu trúc tài chính.

2.7.24. Biểu đồ Phân kỳ (Diverging Bar) - Tỷ số ROS so với Trung bình

ros_mean = mean(df_viz$ROS)
df_diverge <- df_viz %>%
  mutate(ROS_Diff = ROS - ros_mean)
ggplot(data = df_diverge, aes(x=as.factor(nam), y=ROS_Diff, fill=ROS_Diff > 0)) + 
  geom_bar(stat="identity") + 
  geom_hline(yintercept=0, color="black") + 
  labs(title="Chênh lệch Tỷ suất ROS so với Trung bình 10 năm", x="Năm", y="Chênh lệch ROS") + 
  scale_fill_manual(values=c("FALSE"="red", "TRUE"="darkgreen"), name="Vượt TB") + 
  scale_y_continuous(labels = percent) + 
  theme_minimal()

Biểu đồ này được xây dựng nhằm thể hiện mức chênh lệch của tỷ suất lợi nhuận trên doanh thu (ROS) so với giá trị trung bình 10 năm. Trong phần mã, trước tiên tính giá trị trung bình ROS bằng mean(df_viz$ROS) rồi tạo cột mới ROS_Diff thể hiện chênh lệch từng năm so với trung bình. Sử dụng geom_bar(stat=“identity”) để biểu diễn các cột, với màu xanh đậm (darkgreen) cho giá trị vượt trung bình và đỏ (red) cho giá trị thấp hơn trung bình. Đường kẻ ngang tại gốc (hàm geom_hline()) giúp nhấn mạnh mốc 0 – điểm phân tách giữa hai nhóm.

Về ý nghĩa, biểu đồ cho thấy sự dao động của hiệu suất sinh lời (ROS) trong 10 năm qua. Các năm 2016–2019 thể hiện ROS cao hơn trung bình, cho thấy khả năng kiểm soát chi phí tốt hoặc hiệu quả hoạt động được cải thiện. Ngược lại, giai đoạn 2020–2024 xuất hiện nhiều cột đỏ, phản ánh ROS thấp hơn trung bình, có thể do chi phí đầu vào tăng hoặc doanh thu chững lại. Biểu đồ này hữu ích để đánh giá tính ổn định và năng lực sinh lợi theo thời gian.

2.7.25. Biểu đồ Phân tầng (Stacked Bar Chart) - Cấu trúc Tài sản

df_stack <- df_10bien %>%
  select(nam, NoPhaiTra, VonChuSoHuu) %>%
  pivot_longer(cols = -nam, names_to = "ChiSo", values_to = "GiaTri")

ggplot(data = df_stack, aes(x=as.factor(nam), y=GiaTri, fill=ChiSo)) +
  geom_bar(stat="identity") +
  geom_text(aes(label=comma(GiaTri, accuracy=1), group=ChiSo), position=position_stack(vjust=0.5), size=3) +
  labs(title="Cấu trúc Tài sản theo Thời gian (Nợ vs VCSH)", x="Năm", y="Giá trị") +
  scale_y_continuous(labels = comma) +
  theme_bw()

Biểu đồ này sử dụng geom_bar(position=“stack”) để hiển thị sự thay đổi trong cấu trúc tài sản giữa hai thành phần: Nợ phải trả và Vốn chủ sở hữu (VCSH) qua các năm. Dữ liệu được xử lý bằng pivot_longer() để chuyển về dạng dài, cho phép ggplot nhận diện hai chỉ tiêu và xếp chồng giá trị lên nhau. Các giá trị được hiển thị bằng geom_text() đặt trực tiếp trên cột, giúp người đọc dễ theo dõi quy mô từng phần.

Về nội dung, biểu đồ phản ánh sự tăng trưởng ổn định của tổng tài sản trong giai đoạn 2015–2024. Cả nợ và vốn chủ đều tăng theo thời gian, tuy nhiên tốc độ tăng của nợ phải trả cao hơn rõ rệt, thể hiện qua phần màu đỏ chiếm tỷ trọng ngày càng lớn. Điều này cho thấy doanh nghiệp đang mở rộng quy mô tài chính thông qua tăng vay nợ hoặc huy động vốn bên ngoài, dẫn đến đòn bẩy tài chính tăng. Đây là tín hiệu tích cực về quy mô hoạt động nhưng cũng cần chú ý đến rủi ro thanh khoản và chi phí lãi vay.

2.7.26. Biểu đồ Phân tán (Tăng trưởng vs Rủi ro)

SD_LNST_Value <- sd(df_viz$LNST, na.rm = TRUE)
ggplot(data = drop_na(df_viz, TT_DT), aes(x=SD_LNST_Value, y=TT_DT)) +
  geom_point(aes(color=LNST_Group, size=TongTaiSan), alpha=0.7) +
  geom_vline(xintercept=SD_LNST_Value, linetype="dotted", color="blue") +
  labs(title="Tăng trưởng DT vs Rủi ro LNST (SD)", 
       x=paste("Độ lệch chuẩn LNST (Tổng: ", round(SD_LNST_Value, 2), ")"), 
       y="Tăng trưởng Doanh Thu (%)") +
  scale_y_continuous(labels = percent) +
  theme_classic()

Biểu đồ này kết hợp giữa tăng trưởng doanh thu (TT_DT) và độ lệch chuẩn của lợi nhuận sau thuế (LNST) để minh họa mối quan hệ giữa tăng trưởng và rủi ro. Biến độ lệch chuẩn (SD_LNST_Value) được tính bằng hàm sd() để đại diện cho rủi ro biến động lợi nhuận. Trong ggplot, các điểm được vẽ bằng geom_point() với kích thước tỉ lệ theo tổng tài sản, đồng thời có đường dọc (geom_vline()) thể hiện giá trị trung bình của độ lệch chuẩn.

Về ý nghĩa, biểu đồ cho thấy phần lớn các điểm tập trung gần trục trung bình – nghĩa là rủi ro lợi nhuận khá ổn định, không có biến động mạnh. Những điểm nằm cao hơn trên trục tung cho thấy doanh thu tăng mạnh, đi kèm với mức rủi ro tương đối nhỏ, phản ánh hiệu quả hoạt động tốt. Ngược lại, điểm thấp hơn biểu thị tăng trưởng yếu, có thể do lợi nhuận giảm sút hoặc biến động chi phí. Biểu đồ này là công cụ hữu ích trong việc cân đối giữa rủi ro và lợi nhuận kỳ vọng.

2.7.27. Biểu đồ Tứ phân vị (Quantile Plot) - Độ co giãn giữa LNG và DT

ggplot(data = df_viz, aes(sample=GPM)) +
  stat_qq() +
  stat_qq_line(color="red") +
  labs(title="Phân tích Quantile-Quantile (Q-Q Plot) của Biên Lợi nhuận Gộp", 
       subtitle="Kiểm tra tính chuẩn của phân phối GPM", x="Phân vị lý thuyết", y="GPM quan sát") +
  theme_minimal()

Biểu đồ Q-Q Plot được tạo bằng stat_qq() và stat_qq_line() để kiểm định tính chuẩn của phân phối GPM (Gross Profit Margin). Trục hoành thể hiện các giá trị phân vị lý thuyết (theoretical quantiles) của phân phối chuẩn, trong khi trục tung thể hiện các giá trị thực tế quan sát được. Đường đỏ là đường chuẩn; nếu các điểm dữ liệu nằm gần đường này, phân phối GPM được xem là xấp xỉ chuẩn.

Về ý nghĩa, kết quả biểu đồ cho thấy các điểm dữ liệu bám khá sát đường đỏ, chỉ lệch nhẹ ở hai đầu, tức là phân phối GPM gần với phân phối chuẩn. Điều này có nghĩa là biên lợi nhuận gộp ổn định, không xuất hiện quá nhiều giá trị cực đoan (outliers). Đây là tín hiệu tích cực, chứng tỏ khả năng sinh lời của doanh nghiệp có tính dự đoán cao và ít chịu ảnh hưởng từ các biến động bất thường.

2.7.28. Biểu đồ Lũy kế (Cumulative Plot) - Doanh Thu

df_cumul <- df_viz %>%
  mutate(DT_LuyKe = cumsum(DoanhThu))

# Đồ thị 29: Biểu đồ Lũy kế (Cumulative Plot) - Doanh Thu
ggplot(data = df_cumul, aes(x=nam, y=DT_LuyKe)) +
  geom_area(fill="green", alpha=0.3) +
  geom_point(aes(color=LNST_Group)) +
  geom_line(color="darkgreen", size=1) +
  labs(title="Tổng Doanh Thu Lũy Kế (Cumulative)", x="Năm", y="Doanh Thu Lũy Kế") +
  scale_x_continuous(breaks=df_viz$nam) +
  scale_y_continuous(labels = comma) +
  theme_minimal()

Trong biểu đồ này, dữ liệu được tính giá trị lũy kế bằng cumsum(DoanhThu) để tạo biến DT_LuyKe, sau đó thể hiện bằng geom_area() và geom_line(). Vùng diện tích màu xanh nhạt (fill=“green”) minh họa tổng doanh thu tích lũy qua các năm, trong khi đường viền đậm (color=“darkgreen”) biểu thị xu hướng tăng trưởng chính.

Về ý nghĩa, biểu đồ mô tả rõ sự gia tăng đều đặn của doanh thu tích lũy từ năm 2015 đến 2024. Đường tăng liên tục và không có đoạn giảm cho thấy doanh nghiệp duy trì đà tăng trưởng bền vững, không gặp giai đoạn suy giảm nghiêm trọng. Sự dốc lên rõ rệt giai đoạn 2020–2024 phản ánh tốc độ mở rộng quy mô hoạt động. Biểu đồ này giúp nhà quản lý nhận diện hiệu quả tăng trưởng tích lũy theo thời gian, đồng thời hỗ trợ việc lập kế hoạch chiến lược dài hạn.

2.7.29. Biểu đồ Bong bóng (Bubble Chart - 4 biến)

ggplot(data = df_viz, aes(x=ROA, y=DE_Ratio, size=LNST, color=DT_Group)) +
  geom_point(alpha=0.7) +
  geom_text(aes(label=nam), check_overlap = TRUE, size=3, vjust=-1) +
  labs(title="ROA, Nợ/VCSH và Lợi nhuận (Bubble Plot)", 
       x="Tỷ suất ROA (%)", 
       y="Tỷ số Nợ trên VCSH (DE Ratio)",
       size="LNST") +
  scale_x_continuous(labels = percent) +
  theme_classic()

Biểu đồ Bubble Plot sử dụng geom_point() để biểu diễn các mối quan hệ giữa ROA (tỷ suất lợi nhuận trên tài sản), tỷ lệ Nợ/VCSH (DE Ratio) và LNST (lợi nhuận sau thuế). Trục hoành là ROA, trục tung là DE Ratio, kích thước bong bóng thể hiện giá trị LNST, trong khi màu sắc biểu thị nhóm doanh thu (DT_Group). Mỗi điểm dữ liệu được gắn nhãn năm tương ứng để thuận tiện theo dõi xu hướng.

Về ý nghĩa, biểu đồ cho thấy mối tương quan giữa hiệu quả sử dụng tài sản (ROA) và mức độ đòn bẩy tài chính (DE Ratio). Các năm như 2016 và 2017 nằm ở phía trên bên phải biểu đồ, nghĩa là ROA cao đi cùng tỷ lệ nợ lớn — biểu hiện của mô hình tăng trưởng dựa vào vay nợ nhưng hiệu quả. Trong khi đó, các năm gần đây như 2022–2024 di chuyển về vùng dưới, thể hiện hiệu suất tài sản giảm và đòn bẩy tài chính thấp hơn, có thể do doanh nghiệp chủ động kiểm soát rủi ro hoặc lợi nhuận bị thu hẹp. Sự khác biệt về kích thước bong bóng cũng cho thấy biến động lợi nhuận tuyệt đối qua từng năm, giúp đánh giá rõ hơn mối quan hệ giữa quy mô, hiệu quả và rủi ro tài chính.

2.7.30. Xu hướng Lợi nhuận Gộp (Line Plot)

ggplot(data = df_viz, aes(x=nam, y=LoiNhuanGop)) + 
  geom_line(color="darkgreen", size=1.5) + 
  geom_point(aes(color = LNST_Group), size=3) + 
  scale_x_continuous(breaks=df_viz$nam) + 
  labs(title="Xu hướng Lợi nhuận Gộp (2015-2024)", y="Lợi nhuận Gộp") + 
  theme_minimal()

Sử dụng hàm ggplot() với geom_line() và geom_point(), biểu đồ hiển thị diễn biến Lợi nhuận Gộp (LNG) qua các năm từ 2015–2024. Các điểm dữ liệu được tô màu theo nhóm LNST_Group, cho biết từng năm doanh nghiệp có lãi hay không.

Ý nghĩa:

Biểu đồ cho thấy Lợi nhuận Gộp tăng mạnh theo thời gian, đặc biệt trong các năm 2018, 2021 và 2024. Sau một vài giai đoạn điều chỉnh ngắn (ví dụ giai đoạn 2019–2020), xu hướng chung vẫn tăng đều, phản ánh khả năng duy trì biên lợi nhuận ổn định và sự mở rộng quy mô kinh doanh. Tất cả các điểm dữ liệu đều thuộc nhóm “Lãi”, chứng tỏ doanh nghiệp duy trì hoạt động có hiệu quả liên tục trong 10 năm.

3. KẾT LUẬN

Bộ dữ liệu báo cáo tài chính được xây dựng từ các chỉ tiêu cơ bản phản ánh toàn diện tình hình hoạt động của doanh nghiệp trong giai đoạn 2015–2024. Dữ liệu bao gồm các nhóm thông tin chính như: kết quả kinh doanh (Doanh thu, Lợi nhuận gộp, Lợi nhuận sau thuế), tình hình tài chính (Tổng tài sản, Nợ phải trả, Vốn chủ sở hữu), chỉ tiêu thanh khoản và hiệu quả (Tài sản ngắn hạn, Nợ ngắn hạn, dòng tiền hoạt động, v.v.), cùng các chỉ số tài chính được tính toán như ROA, ROS, GPM, DE Ratio, Current Ratio, NWC và tốc độ tăng trưởng doanh thu/lợi nhuận.

Bộ dữ liệu này không chỉ phản ánh giá trị kế toán tại từng thời điểm, mà còn cung cấp chuỗi thời gian 10 năm liên tục, cho phép đánh giá xu hướng biến động của các chỉ tiêu tài chính. Việc xử lý và chuẩn hóa dữ liệu được thực hiện bằng ngôn ngữ R, thông qua các thư viện như dplyr, tidyr và ggplot2, đảm bảo tính chính xác, thống nhất và khả năng trực quan hóa cao.

Kết quả tổng hợp cho thấy doanh nghiệp trong giai đoạn nghiên cứu duy trì xu hướng tăng trưởng tích cực: doanh thu và lợi nhuận đều tăng ổn định, khả năng thanh khoản được cải thiện, tỷ lệ nợ trên vốn chủ sở hữu giảm dần, phản ánh chiến lược tăng trưởng bền vững và kiểm soát tài chính hiệu quả.

Nhìn chung, bộ dữ liệu báo cáo tài chính không chỉ là nguồn thông tin phục vụ phân tích định lượng, mà còn là cơ sở quan trọng để đánh giá năng lực tài chính, cấu trúc vốn và hiệu suất sinh lời của doanh nghiệp trong trung và dài hạn.