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..
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.
Đề 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.
Đố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ả.
Đề 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.
## 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
## Warning: package 'readr' was built under R version 4.5.1
## Warning: package 'psych' was built under R version 4.5.1
## 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.
## 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.
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.
## [1] 1000000
## [1] 20
## [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.
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).
| 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.
## # 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.
## 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).
## [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ả).
## [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.
## Số dòng: 1000000
## 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.
## # 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.
## # 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
## 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ý.
## TÓM TẮT DỮ LIỆU
## =================
## Số dòng: 1000000
## Số cột: 20
## Các biến bao gồm:
## - 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.
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.
## # 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.
## 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 đủ.
## [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.
## [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.
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.
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.
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ô.
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.
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.
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.
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.
## # 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.
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.
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.
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.
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.
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.
## [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.
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.
## 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.
## 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.
## 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á.
## 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.
## 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ũ.
## 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.
## 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.
## 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á.
##
## 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.
##
## 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
##
## 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).
##
## 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.
##
## 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.
##
## 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.
##
## 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.
##
## 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.
##
## 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).
##
## 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.
##
## 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.
##
## 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.
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.
## [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.
## [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.
## [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ế.
## [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.
## [1] 1500
## [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.
## [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.
## 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.
## 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.
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
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)
## # 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
## # 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ô.
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á.
## # 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.
## # 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).
## # 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.
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ổ.
##
## 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).
## # 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.
## # 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.
## # 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.
## # 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).
## # 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í”.
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.
## # 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.
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).
## # 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ũ.
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.
## # 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.
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.
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.
## # 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).
## # 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.
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.
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).
## # 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ù.
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.
## # 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.
Tương quan Tuổi & Giá: Tính Tương quan giữa age và 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.
## # 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.
## # 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).
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.
## # 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.
## # 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.
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.
## # 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)).
## # 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.
## # 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.
## # 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.
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ũ.
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á.
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.
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.
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á.
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ũ.
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
#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
#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ử.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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ẽ.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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ơ.
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
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ể.
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.
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.
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.
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ơ.
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ể.
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.
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.
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.
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.
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).
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.
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.
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.
Để 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.
Đố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.
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.
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).
Để 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.
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:
## 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
## Warning: package 'skimr' was built under R version 4.5.1
## 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
## Warning: package 'corrplot' was built under R version 4.5.1
## corrplot 0.95 loaded
## 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
## 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
## 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:
## 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`
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:
## [1] 10
## [1] 134
## [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ố.
## 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 (
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à
## # 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.
## 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.
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)
Đầ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)
## [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))
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
## [1] 141
## 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)
## 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
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ệ.
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
)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
## 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
## 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
## [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
## [1] 10 11
## [1] 10
## [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
## [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
## # 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
## # 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.
Chuyển đổi kiểu dữ liệu
## # 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)
## [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
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
## # 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.
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.
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ế.
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.
## # 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.
Các năm có LNST dương.
## # 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.
## # 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).
## # 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.
## # 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.
## # 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.
## # 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.
## # 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ị).
## # 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
## # 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.
## # 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..
## # 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.
Sắp xếp theo Tỷ suất Thanh toán Hiện hành (TSNH/NoNganHan) giảm dần.
## # 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.
## # 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.
## # 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.
## # 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.
Biến 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
## 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
## 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
## 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
## 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
## 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
## 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ả
## 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
## 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
## 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á.
Giá trị Trung bình (Mean) của 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.
## # 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).
## # 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).
## # A tibble: 1 × 1
## min_dt
## <dbl>
## 1 1615.
## # A tibble: 1 × 1
## max_dt
## <dbl>
## 1 15290.
## # 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).
## [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
## # 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
## # 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)
## # 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
## # 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
## # 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)
## # A tibble: 1 × 1
## Q1
## <dbl>
## 1 4909.
Quartile 2 (Q2 - median)
## # A tibble: 1 × 1
## Q2
## <dbl>
## 1 8635.
Quartile 3 (Q3)
## # 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
## # 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
## # 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).
## [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.
## [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
## [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
## [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).
## # 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.
Tính Tốc độ tăng trưởng hàng năm kép (CAGR) cục bộ 3 năm (Rolling CAGR).
## # 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.
## # 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.
## # 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.
## # 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.
Phân tích giá trị trung bình (TB_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)
## # 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)
## # 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)
## # 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)
## # 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)
## # 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)
## # 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.
Phân tích cột TT_LNST – Tốc độ tăng trưởng 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>,
## # 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
## # 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
## # 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.
Phân tích các chỉ tiêu
## # 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
## # 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
## # 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
## [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.
## # 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.
Phân tích giá trị trung bình (TB_LNG)
## # 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)
## # 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)
## # 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)
## # 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)
## # 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)
## # 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)
## # 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.
Tính tốc độ tăng trưởng lợi nhuận gộp (TT_LNG)p
## # 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
## # 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
## # 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
## # 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
## # 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.
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) ---"
##
## 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.
##
## 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.
##
## 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) ---"
## 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.
## 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 ---"
## [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) ---"
## [1] "Hệ số Tương quan (r): 0.6577"
## [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.
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.
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.
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.
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.
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).
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.
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í.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.