library(DT)
library(lubridate)
library(readxl)
library(dplyr)
library(tidyr)
library(ggplot2)
library(openxlsx)
library(dplyr)
library(reshape2)
library(flextable)
library(moments)
library(scales)
library(viridis)
library(patchwork)
library(reshape2)
library(ggridges)
library(plotly)
library(gridExtra)
library(corrplot)
library(ggpubr)
library(hexbin)
library(knitr)Hệ thống ba trạm quan trắc môi trường được triển khai chiến lược này hoạt động như một mạng lưới giám sát đa chỉ tiêu, liên tục thu thập dữ liệu theo chuỗi thời gian. Các trạm không chỉ ghi nhận các thông số nền tảng là nhiệt độ và độ ẩm, mà còn đóng vai trò như “cơ quan khứu giác” tinh vi, có khả năng phát hiện sự hiện diện của các loại khí gây ô nhiễm như Carbon Monoxide (CO), Khí dầu mỏ hóa lỏng (LPG) và smoke - một chỉ báo quan trọng cho ô nhiễm hạt hoặc nguy cơ cháy. Bên cạnh đó, hệ thống còn cung cấp cái nhìn sâu sắc về sự tương tác giữa môi trường và các yếu tố bên ngoài thông qua chỉ ánh sáng (phản ánh cường độ chiếu sáng tự nhiên và nhân tạo) và chuyển động (một dấu hiệu cho các tác động vật lý và hoạt động trong khu vực). Sự kết hợp của bảy thông số này cùng lúc cho phép xây dựng một bức tranh toàn cảnh, sống động về hiện trạng và những biến động của hệ sinh thái được giám sát.
Nguồn gốc: Dữ liệu về cảm biến môi trường (Environmental Sensor Telemetry Data) được tạo ra từ một hệ thống thiết bị IoT tùy chỉnh thông qua hai phương thức chính: - Hệ thống thu thập dữ liệu: Dữ liệu được tạo ra từ một loạt ba mảng cảm biến giống hệt nhau, được xây dựng tùy chỉnh trên breadboard. Mỗi mảng cảm biến được kết nối với một thiết bị Raspberry Pi Triển khai thực tế: Mỗi thiết bị IoT trong ba thiết bị được đặt tại một vị trí vật lý với các điều kiện môi trường đa dạng khác nhau, nhằm thu thập dữ liệu từ các bối cảnh môi trường phong phú. Dữ liệu từ hệ thống thu thập này được tổng hợp và đăng tải bởi tác giả garystafford trên https://www.kaggle.com/datasets/garystafford/environmental-sensor-data-132k/data, một trang web cung cấp kho dữ liệu lớn cho cộng đồng nghiên cứu và học tập. Tóm tắt Bộ Dữ liệu :
| Thuộc tính | Chi tiết |
|---|---|
| Tổng số hàng dữ liệu | 405,184 hàng |
| Phạm vi thời gian | 07/12/2020 00:00:00 UTC – 07/19/2020 23:59:59 UTC |
| Số lượng cảm biến vật lý | 4 cảm biến |
| Số lượng chỉ số (readings) khác nhau | 7 chỉ số (được thu thập từ 4 cảm biến) |
| Các chỉ số cảm biến | 1. Nhiệt độ (Temperature) |
| 2. Độ ẩm (Humidity) | |
| 3. Carbon Monoxide (CO) | |
| 4. Liquid Petroleum Gas (LPG) | |
| 5. Khói (Smoke) | |
| 6. Ánh sáng (Light) | |
| 7. Chuyển động (Motion) |
## Rows: 405,184
## Columns: 9
## $ ts <dbl> 1594512094, 1594512095, 1594512098, 1594512100, 1594512102, 1…
## $ device <chr> "b8:27:eb:bf:9d:51", "00:0f:00:70:91:0a", "b8:27:eb:bf:9d:51"…
## $ co <dbl> 0.004955939, 0.002840089, 0.004976012, 0.004403027, 0.0049673…
## $ humidity <dbl> 51.0, 76.0, 50.9, 76.8, 50.9, 77.9, 50.9, 76.0, 77.9, 50.9, 5…
## $ light <chr> "false", "false", "false", "true", "false", "true", "false", …
## $ lpg <dbl> 0.007650822, 0.005114383, 0.007673227, 0.007023337, 0.0076635…
## $ motion <chr> "false", "false", "false", "false", "false", "false", "false"…
## $ smoke <dbl> 0.02041127, 0.01327484, 0.02047513, 0.01862823, 0.02044762, 0…
## $ temp <dbl> 22.7, 19.7, 22.6, 27.0, 22.6, 27.0, 22.6, 19.7, 27.0, 22.6, 2…
Giải thích:
Hàm glimpse() (từ gói dplyr) thay vì các lệnh như str() hay summary() vì có th tóm tắt toàn bộ dữ liệu (số hàng, số cột, kiểu dữ liệu, và vài giá trị mẫu) theo một định dạng dễ đọc và gọn gàng.
Kiểm tra dữ liệu bị khuyết
## [1] 0
Giải thích:
sum(…): tính tổng các giá trị trong vector logic được tạo ra bởi is.na(d)
is.na(): kiểm tra từng quan sát trong biến d để trả về một vector logic (TRUE/FALSE)
na.omit(): xóa tất cả các hàng (rows) trong đối tượng dữ liệu d có chứa ít nhất một giá trị bị thiếu (NA)
Kiểm tra dữ liệu trùng lặp ở biến “device”
## [1] "b8:27:eb:bf:9d:51" "00:0f:00:70:91:0a" "1c:bf:ce:15:ec:4d"
Giải thích:
Vì đặc trưng của bộ dữ liệu dùng thiết bị để đo các biến khác như “co”, “huminity”, “lpg”, “smoke”, “motion”, “temp” theo thời gian “ts-timestamp”
Sử dụng Hàm unique() được dùng để trích xuất và trả về tất cả các giá trị riêng biệt (không trùng lặp) của biến “device”
Tổng quan các biến Tên các biến
## [1] "ts" "device" "co" "humidity" "light" "lpg" "motion"
## [8] "smoke" "temp"
## [1] 9
Giải thích :
names(d): liệt kê cụ thể các biến
ncol(d): Xác nhận tổng số biến
Giới thiệu biến CO Biến “co” trong dataset được giải thích là chất khí không màu, không mùi, hình thành từ quá trình đốt cháy không hoàn toàn nhiên liệu hóa thạch như xăng, gas, than. Các thông số của biến được thiết bị cảm biến của biến “device” đo lường.
Đơn vị đo : ppm(parts per million) Dạng dữ liệu : Numberic Phân loại mức độ ô nhiễm:
| Tiêu chuẩn | Kết quả | Số quan sát |
|---|---|---|
| Bé hơn 0.002 | Rất sạch | 10757 |
| Khoảng [0.002;0.004) | Sạch | 102191 |
| Khoảng [0.004;0.005) | Ô nhiễm nhẹ | 126063 |
| Lớn hơn 0.005 | Ô nhiễm nặng | 166173 |
# Thống kê số quan sát theo các khoảng CO
cat("Số quan sát co < 0.002:", sum(d$co < 0.002, na.rm = TRUE), "\n")## Số quan sát co < 0.002: 10757
## Số quan sát co từ 0.002 đến 0.004: 102191
## Số quan sát co từ 0.004 đến 0.005: 126063
## Số quan sát co > 0.005: 166173
Giải thích:
Dùng hàm cat() để in dữ liệu ra console của biến “co”
Dùng hàm sum() đếm số TRUE theo điều của biến “co” bên trong biến “co” gồm 1 điều kiện cũng như điều kiện kép có kí tự “&”
Giới thiệu biến “device” Biến device đóng vai trò là định danh thiết bị cảm biến, được sử dụng để theo dõi và phân biệt nguồn thu thập dữ liệu cho các thông số môi trường như lpg(liquid petroleum gas), co(cacbon dioxide), smoke, temp(tempurature), humidity, light và motion. Mỗi giá trị trong biến này đại diện cho một thiết bị vật lý riêng biệt, cho phép truy xuất nguồn gốc của từng bản ghi dữ liệu trong hệ thống giám sát.
Đơn vị đo: string Dạng dữ liệu: character loạithiết bị:
| Tên thiết bị | Tần suất xuất hiện trong bộ dữ liệu |
|---|---|
| b8:27:eb:bf:9d:51 | 111815 |
| 00:0f:00:70:91:0a | 105918 |
| 1c:bf:ce:15:ec:4d | 187451 |
## [1] "character"
##
## 00:0f:00:70:91:0a 1c:bf:ce:15:ec:4d b8:27:eb:bf:9d:51
## 111815 105918 187451
Giải thích:
Dùng hàm class() với mục đích xác định loại dữ liệu của biến “device”
Dùng hàm table() với mục đích xác định tần suất của ba biến trùng lặp
Giới thiệu biến “lpg” (liquid petroleum gas) Biến lpg đóng vai trò đo lường nồng độ Khí dầu mỏ hóa lỏng (Liquefied Petroleum Gas) trong môi trường, được sử dụng để giám sát rò rỉ khí gas và đánh giá nguy cơ cháy nổ. Mỗi giá trị trong biến này phản ánh mức độ hiện diện của khí LPG tại thời điểm thu thập dữ liệu, cho phép cảnh báo sớm các tình huống nguy hiểm trong hệ thống an ninh môi trường.
Đơn vị đo: ppm (parts per million) Dạng dữ liệu: numeric
## [1] "numeric"
Giải thích: - Sử dụng lệnh class() để xác định kiểu dữ liệu tổng quát (numeric, character, factor, logical, Date)
Giới thiệu biến”temp” (temperature) Biến “temp” trong dataset được giải thích biến đo nhiệt độ môi trường xung quanh cảm biến, được đo bằng đơn vị độ Fahrenheits (°F).Các thông số của biến được thiết bị cảm biến của biến “device” đo lường
Đơn vị đo: fahrenheits (°F) Dạng dữ liệu:numeric
## [1] "numeric"
Giới thiệu biến “motion” Biến Motion là biến nhị phân (binary) cho biết có phát hiện chuyển động trong môi trường được giám sát hay không. Trong dataset này, biến Motion được thu thập từ các cảm biến môi trường IoT (như cảm biến chuyển động PIR - Passive Infrared) Đơn vị đo: Không có, chúng em sử dụng TRUE : có chuyển động, không có chuyển động. Dạng dữ liệu:logic
##
## false true
## 404702 482
Giải thích: Dùng hàm table() với mục đích xác định tần suất của TRUE có chuyển động và FALSE không có chuyển động
Giới thiệu biến “humidity” Biến “humidity” đo lường độ ẩm tương đối của môi trường xung quanh cảm biến. Giá trị này phản ánh lượng hơi nước trong không khí so với lượng hơi nước tối đa mà không khí có thể giữ được ở cùng điều kiện nhiệt độ
Đơn vị đo: Phần trăm (%) Dạng dữ liệu:numeric Độ ẩm môi trường:
| Tiêu chuẩn | Kết quả | Số quan sát |
|---|---|---|
| Bé hơn 30 | Môi trường khô, cần kiểm tra cảm biến | 123 |
| Khoảng [30;60] | Độ ẩm lý tưởng và an toàn | 405061 |
| Lớn hơn 60 | Cảnh báo độ ẩm cao, nguy cơ nấm mốc | 159193 |
## Số quan sát humidity < 30: 123
## Số quan sát humidity từ 30 đến 60: 405061
## Số quan sát humidity > 60: 159193
Giải thích: - Dùng hàm cat() để in dữ liệu ra console của biến “co”
Giới thiệu biến “smoke” Biến “Smoke” trong dataset đo mật độ/nồng độ khói trong môi trường xung quanh cảm biến, được đo bằng đơn vị tỷ lệ phần trăm mật độ khói (smoke density ratio). Các thông số của biến được thiết bị cảm biến của biến “device” đo lường.
Đơn vị đo: ppm (parts per million) Dạng dữ liệu: numeric
Giới thiệu biến “light” Biến “light” đo lường cường độ ánh sáng trong môi trường xung quanh cảm biến. Giá trị này phản ánh mức độ chiếu sáng tại thời điểm thu thập dữ liệu.
Đơn vị đo: chúng em sử dụng TRUE : có ánh sáng, False: Không có ánh sáng Dạng dữ liệu:logic Tần suất các quan sát True/False:
| Tên thiết bị | Tần suất xuất hiện trong bộ dữ liệu |
|---|---|
| True | 111815 |
| False | 105918 |
##
## false true
## 292657 112527
Giải thích: - Dùng hàm table() với mục đích xác định tần suất của TRUE có ángh sáng và FALSE không có ánh sáng
## SỐ LƯỢNG NA THEO TỪNG BIẾN:
## ===========================
## ts : 0 NA
## device : 0 NA
## co : 0 NA
## humidity : 0 NA
## light : 0 NA
## lpg : 0 NA
## motion : 0 NA
## smoke : 0 NA
## temp : 0 NA
Giải thích
** Xử lý NA là bước BẮT BUỘC trong data science để đảm bảo kết quả phân tích đáng tin cậy và chính xác, đem lại kết quả không chính xác, dẫn đến gián đoạn dữ liệu **
** Ý nghĩa : Tất cả các cột trong dataframe d đều không có giá trị NA (missing values). Mỗi số 0 cho biết số lượng giá trị thiếu trong từng cột.**
d$device <- ifelse(d$device == "b8:27:eb:bf:9d:51", "Thiết bị 1",
ifelse(d$device == "00:0f:00:70:91:0a", "Thiết bị 2",
ifelse(d$device == "1c:bf:ce:15:ec:4d", "Thiết bị 3",
d$device)))Giải thích:
Với kiểm tra giữ liệu trùng lặp , chúng em phát hiện có 3 biến trùng lặp vì vậy để tiện quan sát và trực quan , chúng em thay đổi 3 biến đã có thành “thiết bị 1”, “thiết bị 2”, “thiết bị 3”
ifelse(điều_kiện, giá_trị_nếu_đúng, giá_trị_nếu_sai) - Kiểm tra từng điều kiện)
Điều kiện 1: Nếu device == “b8:27:eb:bf:9d:51” → đổi thành “Thiết bị 1”
Điều kiện 2: Nếu device == “00:0f:00:70:91:0a” → đổi thành “Thiết bị 2”
Điều kiện 3: Nếu device == “1c:bf:ce:15:ec:4d” → đổi thành “Thiết bị 3”
Cuối cùng: Nếu không khớp điều kiện nào → giữ nguyên giá trị gốc (d$device) Thay đổi kiểu dữ liệu của cột thời gian
Giải thích:
Thay thế dữ liệu giây thành giữ liệu ngày giờ tháng năm với thời gian UT
Kiểm tra loại dữ liệu
Chuẩn hoá biến “humidity”
d <- d %>%
mutate(humidity_status = case_when(
humidity < 30 ~ "Môi trường khô, cần kiểm tra cảm biến",
humidity >= 30 & humidity < 60 ~ "Độ ẩm lý tưởng và an toàn",
humidity >= 60 ~ "Cảnh báo độ ẩm cao, nguy cơ nấm mốc",
TRUE ~ "Không xác định"
))Giải thích:
Với độ ẩm dưới 30% gây khô da và hư hại thiết bị, từ 30-60% là ngưỡng lý tưởng cho sức khỏe theo WHO, và trên 60% làm tăng nguy cơ nấm mốc cùng hư hại thiết bị
Dùng toán tử Pipe để chuyển dataframe làm input cho hàm tiếp theo
Dùng hàm mutate() tạo cột mới cho dataframe
Dùng hàm case_when để xử lý logic của biến humidity với 4 điều kiện Chuẩn hoá biến “co”
d <- d %>%
mutate(chat_luong = case_when(
co < 0.002 ~ "Rất sạch",
co >= 0.002 & co < 0.004 ~ "Sạch",
co >= 0.004 & co < 0.005 ~ "Ô nhiễm nhẹ",
co >= 0.005 ~ "Ô nhiễm nặng",
TRUE ~ "Không xác định"
))Giải thích:
Nhằm trực quan hoá và phục vục cho việc vẽ đồ thị phần sau
Dòng code này sử dụng hàm mutate() để thêm một cột mới tên chat_luong vào dataframe d
Trong đó, hàm case_when() được dùng để phân loại giá trị của cột co thành các mức chất lượng không khí khác nhau
d <- d %>%
mutate(
temp_c = (temp - 32) * 5/9,
# Giữ cả 2 biến để so sánh
temp_unit = "C" # hoặc "F"
)Hiển thị so sánh cột độ F và C
## temp temp_c
## 1 22.7 -5.166667
## 2 19.7 -6.833333
## 3 22.6 -5.222222
## 4 27.0 -2.777778
## 5 22.6 -5.222222
## 6 27.0 -2.777778
## 7 22.6 -5.222222
## 8 19.7 -6.833333
## 9 27.0 -2.777778
## 10 22.6 -5.222222
Khi chuyển sang độ C, chúng ta sẽ dễ dàng tính toán được các chỉ số AOI,chỉ số rủi ro tổng hợp
d <- d %>%
mutate(
# Chỉ số chất lượng không khí
chi_so_AQI = (co/9 + smoke/15) * 50,
# Chỉ số rủi ro tổng hợp
chi_so_rui_ro = (temp_c/40 * 0.2) + (humidity/100 * 0.1) +
(co/50 * 0.3) + (lpg/5 * 0.3) + (smoke/20 * 0.1),
# Phân loại rủi ro
muc_do_rui_ro = case_when(
chi_so_rui_ro > 0.7 ~ "Cao",
chi_so_rui_ro > 0.4 ~ "Trung bình",
TRUE ~ "Thấp"
)
)
d %>%
select(chi_so_AQI, chi_so_rui_ro, muc_do_rui_ro) %>%
head (50)## chi_so_AQI chi_so_rui_ro muc_do_rui_ro
## 1 0.09557056 0.02575751 Thấp
## 2 0.06002773 0.04222361 Thấp
## 3 0.09589493 0.02538151 Thấp
## 4 0.08655534 0.06345207 Thấp
## 5 0.09575520 0.02538075 Thấp
## 6 0.08635749 0.06455097 Thấp
## 7 0.09589514 0.02538152 Thấp
## 8 0.06174794 0.04223359 Thấp
## 9 0.08560745 0.06454679 Thấp
## 10 0.09580193 0.02538100 Thấp
## 11 0.09563958 0.02538011 Thấp
## 12 0.08622645 0.06465024 Thấp
## 13 0.09582438 0.02538113 Thấp
## 14 0.08735218 0.06465650 Thấp
## 15 0.09570997 0.02538050 Thấp
## 16 0.06116808 0.04203023 Thấp
## 17 0.09589446 0.02538151 Thấp
## 18 0.09563958 0.02538011 Thấp
## 19 0.08715215 0.06455539 Thấp
## 20 0.09557348 0.02537975 Thấp
## 21 0.06174794 0.04203359 Thấp
## 22 0.08635749 0.06455097 Thấp
## 23 0.09550253 0.02527936 Thấp
## 24 0.06002773 0.04222361 Thấp
## 25 0.09566283 0.02538024 Thấp
## 26 0.06002773 0.04250139 Thấp
## 27 0.08619380 0.06455006 Thấp
## 28 0.09508980 0.02537708 Thấp
## 29 0.08557507 0.06494661 Thấp
## 30 0.09534117 0.02537847 Thấp
## 31 0.06116808 0.04213023 Thấp
## 32 0.09563958 0.02538011 Thấp
## 33 0.08635749 0.06525097 Thấp
## 34 0.06002773 0.04250139 Thấp
## 35 0.09488602 0.02537596 Thấp
## 36 0.09587115 0.02565916 Thấp
## 37 0.08635749 0.06495097 Thấp
## 38 0.06059471 0.04250468 Thấp
## 39 0.09580240 0.02565878 Thấp
## 40 0.08635749 0.06485097 Thấp
## 41 0.09589446 0.02538151 Thấp
## 42 0.06116808 0.04213023 Thấp
## 43 0.08570466 0.06484733 Thấp
## 44 0.09534163 0.02537847 Thấp
## 45 0.09580193 0.02538100 Thấp
## 46 0.08635749 0.06505097 Thấp
## 47 0.06059471 0.04250468 Thấp
## 48 0.09573192 0.02538062 Thấp
## 49 0.08695267 0.06535428 Thấp
## 50 0.09554912 0.02537961 Thấp
Ý nghĩa : việc tính toán chỉ số AQI và chỉ số rủi ro để tính toán các mức độ rủi ro gây ảnh hưởng đến sức khỏe của con người, tất cả tính toán đều dưới 0.4 nên môi trường có rủi ro thấp, phù hợp để sinh sống.
Lọc các cột không phải là số :
d %>%
select(where(is.numeric)) %>%
colMeans(na.rm = TRUE) %>%
as.data.frame() %>%
setNames("Giá trị trung bình") %>%
kable(format = "simple", align = "c", caption = "GIÁ TRỊ TRUNG BÌNH CÁC BIẾN SỐ")| Giá trị trung bình | |
|---|---|
| co | 0.0046388 |
| humidity | 60.5116940 |
| lpg | 0.0072371 |
| smoke | 0.0192636 |
| temp | 22.4539873 |
| temp_c | -5.3033404 |
| chi_so_AQI | 0.0899834 |
| chi_so_rui_ro | 0.0345534 |
## ts device co
## Min. :2020-07-12 00:01:34 Length:405184 Min. :0.001171
## 1st Qu.:2020-07-14 00:20:00 Class :character 1st Qu.:0.003919
## Median :2020-07-16 00:06:28 Mode :character Median :0.004812
## Mean :2020-07-16 00:06:57 Mean :0.004639
## 3rd Qu.:2020-07-18 00:02:56 3rd Qu.:0.005409
## Max. :2020-07-20 00:03:37 Max. :0.014420
## humidity light lpg motion
## Min. : 1.10 Length:405184 Min. :0.002693 Length:405184
## 1st Qu.:51.00 Class :character 1st Qu.:0.006456 Class :character
## Median :54.90 Mode :character Median :0.007489 Mode :character
## Mean :60.51 Mean :0.007237
## 3rd Qu.:74.30 3rd Qu.:0.008150
## Max. :99.90 Max. :0.016567
## smoke temp humidity_status chat_luong
## Min. :0.006692 Min. : 0.00 Length:405184 Length:405184
## 1st Qu.:0.017024 1st Qu.:19.90 Class :character Class :character
## Median :0.019950 Median :22.20 Mode :character Mode :character
## Mean :0.019264 Mean :22.45
## 3rd Qu.:0.021838 3rd Qu.:23.60
## Max. :0.046590 Max. :30.60
## temp_c temp_unit chi_so_AQI chi_so_rui_ro
## Min. :-17.7778 Length:405184 Min. :0.02881 Min. :-0.03578
## 1st Qu.: -6.7222 Class :character 1st Qu.:0.07852 1st Qu.: 0.02466
## Median : -5.4444 Mode :character Median :0.09323 Median : 0.03701
## Mean : -5.3033 Mean :0.08998 Mean : 0.03455
## 3rd Qu.: -4.6667 3rd Qu.:0.10284 3rd Qu.: 0.04193
## Max. : -0.7778 Max. :0.23541 Max. : 0.06946
## muc_do_rui_ro
## Length:405184
## Class :character
## Mode :character
##
##
##
** Ý nghĩa thống kê** : - CO: Trung bình 46ppm (an toàn), nhưng có lúc đạt 144ppm - vượt ngưỡng cảnh báo - Nhiệt độ: 22°C trung bình (lý tưởng), nhưng biến động từ 0°C (quá lạnh) đến 31°C (hơi nóng) - Độ ẩm: 61% trung bình (tốt), nhưng có lúc 99% (quá ẩm) và 1% (quá khô) - cần điều chỉnh
## co humidity lpg smoke temp temp_c
## 1 0.2536699 -0.8368190 0.2864706 0.2808668 0.09117162 0.09117162
## 2 -1.4389746 1.3626288 -1.4699254 -1.4656350 -1.02061990 -1.02061990
## 3 0.2697285 -0.8456168 0.3019853 0.2964942 0.05411189 0.05411189
## 4 -0.1886503 1.4330114 -0.1480411 -0.1554983 1.68473986 1.68473986
## 5 0.2628097 -0.8456168 0.2953030 0.2897629 0.05411189 0.05411189
## 6 -0.1982684 1.5297870 -0.1576516 -0.1651206 1.68473986 1.68473986
## chi_so_AQI chi_so_rui_ro
## 1 0.2717926 -0.8240231
## 2 -1.4572213 0.7185715
## 3 0.2875720 -0.8592473
## 4 -0.1667608 2.7073180
## 5 0.2807746 -0.8593193
## 6 -0.1763856 2.8102660
=> Đây là dữ liệu đã được chuẩn hóa Z-score. Đưa về đơn vị là Độ lệch chuẩn của tất cả biến Numeric, tôi sẽ dễ dàng tính toán Phương sai của chúng.
## co humidity lpg smoke temp
## 1 1 1 1 1
## temp_c chi_so_AQI chi_so_rui_ro
## 1 1 1
Nhận xét : Kết quả phương sai sau chuẩn hóa là hoàn hảo - Phương sai = 1 → Độ lệch chuẩn = 1
Tất cả biến có cùng mức độ phân tán
Không còn sự chênh lệch về đơn vị đo
## co humidity lpg smoke temp
## 0.004811522 54.900000000 0.007488884 0.019950121 22.200000000
## temp_c chi_so_AQI chi_so_rui_ro
## -5.444444444 0.093231078 0.037006058
Dưới đây là giải thích ngắn gọn từng dòng:
CO: 0.00481 - Khí CO ở mức an toàn
Humidity: 54.9% - Độ ẩm trong ngưỡng lý tưởng
LPG: 0.00749 - Khí gas ở mức rất thấp, an toàn
Smoke: 0.01995 - Nồng độ khói thấp
Temp: 22.2°C - Nhiệt độ lý tưởng
AQI: 0.09323 - Chất lượng không khí rất tốt
Risk Index: 0.03701 - Rủi ro thấp
Các chỉ số đều cho thấy một môi trường an toàn và trong lành.
Kết luận: Tất cả chỉ số đều trong ngưỡng an toàn, môi trường tốt.
## GIÁ TRỊ MIN-MAX:
sapply(d %>% select(where(is.numeric)), function(x) c(min = min(x, na.rm = TRUE), max = max(x, na.rm = TRUE)))## co humidity lpg smoke temp temp_c chi_so_AQI
## min 0.001170509 1.1 0.002693479 0.006692096 0.0 -17.7777778 0.02880981
## max 0.014420105 99.9 0.016567377 0.046590116 30.6 -0.7777776 0.23541208
## chi_so_rui_ro
## min -0.03578400
## max 0.06945764
## co humidity lpg smoke temp
## 0.01324960 98.80000150 0.01387390 0.03989802 30.60000038
## temp_c chi_so_AQI chi_so_rui_ro
## 17.00000021 0.20660227 0.10524164
Khoảng biến thiên là thước đo đơn giản nhất để trả lời câu hỏi: “Dữ liệu của tôi trải rộng trong phạm vi bao nhiêu?”
Tuy có hạn chế, nhưng đây luôn là bước đầu tiên và rất quan trọng trong việc phân tích, mô tả một tập dữ liệu. Đối với dữ liệu cảm biến của bạn, các khoảng biến thiên nhỏ cho thấy các thông số môi trường đang khá ổn định.
## co humidity lpg smoke temp temp_c chi_so_AQI
## 0% 0.001170509 1.1 0.002693479 0.006692096 0.0 -17.7777778 0.02880981
## 25% 0.003918682 51.0 0.006455518 0.017024046 19.9 -6.7222224 0.07851728
## 50% 0.004811522 54.9 0.007488884 0.019950121 22.2 -5.4444444 0.09323108
## 75% 0.005408832 74.3 0.008150443 0.021838174 23.6 -4.6666665 0.10284298
## 100% 0.014420105 99.9 0.016567377 0.046590116 30.6 -0.7777776 0.23541208
## chi_so_rui_ro
## 0% -0.03578400
## 25% 0.02465567
## 50% 0.03700606
## 75% 0.04192832
## 100% 0.06945764
Giá trị trung vị (50%) là 0.00481, rất thấp và nằm trong ngưỡng an toàn.
Phạm vi giá trị từ 0.00117 đến 0.01442, cho thấy nồng độ CO luôn ở mức cho phép, không có nguy cơ gây hại.
Trung vị ở 54.9%, nằm trong khoảng lý tưởng cho sức khỏe và cảm giác thoải mái (thường là 40-60%).
Tuy nhiên, độ ẩm có biên độ rộng (1.1% - 99.9%), cho thấy có những thời điểm độ ẩm rất thấp hoặc rất cao.
Trung vị 0.00749 ở mức rất thấp, an toàn.
75% giá trị quan trắc đều dưới 0.00815, khẳng định nồng độ gas luôn trong ngưỡng an toàn.
Trung vị 0.01995 ở mức thấp.
Phân bố tập trung quanh giá trị trung vị (từ 0.00669 đến 0.04659), không có đỉnh cao bất thường.
Trung vị 22.2°C là nhiệt độ lý tưởng, dễ chịu.
Nhiệt độ chủ yếu dao động từ 19.9°C đến 23.6°C (trong khoảng tứ phân vị 25%-75%).
Trung vị 0.09323 cho thấy chất lượng không khí tốt.
75% giá trị dưới 0.10284, chứng tỏ phần lớn thời gian chất lượng không khí ở mức tốt đến trung bình.
Trung vị 0.03701 ở mức thấp.
=> Toàn bộ giá trị đều dương (từ -0.03578 đến 0.06946), cho thấy rủi ro luôn được kiểm soát.
Kết luận: Hầu hết các chỉ số đều ở mức an toàn, lý tưởng. Môi trường được giám sát có chất lượng tốt, với nhiệt độ và độ ẩm thoải mái, nồng độ các chất độc hại thấp và rủi ro ở mức kiểm soát được.
## ts device co humidity light
## 405184 405184 405184 405184 405184
## lpg motion smoke temp humidity_status
## 405184 405184 405184 405184 405184
## chat_luong temp_c temp_unit chi_so_AQI chi_so_rui_ro
## 405184 405184 405184 405184 405184
## muc_do_rui_ro
## 405184
Nhận xét : - Dữ liệu hoàn toàn sạch - không có missing values - Cân bằng - tất cả biến đều có cùng số quan sát - Kích thước dataset: 10 dòng × 15 cột - Phù hợp cho phân tích ngay mà không cần xử lý missing data
## ts device co humidity light
## 0 0 0 0 0
## lpg motion smoke temp humidity_status
## 0 0 0 0 0
## chat_luong temp_c temp_unit chi_so_AQI chi_so_rui_ro
## 0 0 0 0 0
## muc_do_rui_ro
## 0
cv <- function(x) sd(x, na.rm = TRUE)/mean(x, na.rm = TRUE)
sapply(d %>% select(where(is.numeric)), cv)## co humidity lpg smoke temp
## 0.2694693 0.1878396 0.1995427 0.2121165 0.1201723
## temp_c chi_so_AQI chi_so_rui_ro
## -0.2826674 0.2284500 0.3089219
=> Nhận xét : Các chỉ số đều có độ lệch dương nhẹ (0.1-0.3), cho thấy dữ liệu tập trung chủ yếu ở mức thấp và an toàn, với một số ít thời điểm có giá trị cao hơn, phản ánh môi trường được kiểm soát tốt.
## co humidity lpg smoke temp
## 0.2404659 0.5211078 -0.2013969 -0.1267816 0.5908632
## temp_c chi_so_AQI chi_so_rui_ro
## 0.5908632 -0.0061385 0.4670561
Các giá trị này là hệ số độ lệch (skewness) mô tả hình dạng phân phối dữ liệu. Cụ thể:
CO (0.24), Humidity (0.52), Temp (0.59), Risk Index (0.47) có độ lệch dương (lệch phải), cho thấy các chỉ số này chủ yếu tập trung ở mức thấp và an toàn.
LPG (-0.20), Smoke (-0.13) có độ lệch âm (lệch trái), cảnh báo nồng độ khí gas và khói thường xuyên ở mức cao, cần được theo dõi chặt chẽ.
AQI (-0.006) có độ lệch gần bằng 0, thể hiện phân phối chuẩn gần như hoàn hảo, cho thấy chất lượng không khí ổn định và cân bằng.
Kết luận: Hầu hết chỉ số môi trường ở trạng thái an toàn, riêng LPG và Smoke cần được quan tâm đặc biệt do có xu hướng ở mức cao.
## co humidity lpg smoke temp
## 5.927006 1.743761 4.763073 4.892863 4.217321
## temp_c chi_so_AQI chi_so_rui_ro
## 4.217321 5.177256 2.777703
Các giá trị độ nhọn cho thấy:
CO (5.93), AQI (5.18), Smoke (4.89), LPG (4.76), Temp (4.22): Có độ nhọn > 3 (phân phối nhọn) - dữ liệu tập trung mạnh quanh giá trị trung bình, ít có giá trị ngoại lai.
Humidity (1.74): Có độ nhọn < 3 (phân phối tù) - dữ liệu phân tán hơn, phân phối bằng phẳng.
Risk Index (2.78): Gần bằng 3 - phân phối gần với chuẩn.
Kết luận: Hầu hết chỉ số có phân phối nhọn, cho thấy dữ liệu ổn định và ít biến động cực đoan, riêng độ ẩm có phân phối tù hơn cho thấy sự dao động lớn hơn.
## chi_so_AQI chi_so_rui_ro muc_do_rui_ro
## 1 0.09557056 0.02575751 Thấp
## 2 0.06002773 0.04222361 Thấp
## 3 0.09589493 0.02538151 Thấp
## 4 0.08655534 0.06345207 Thấp
## 5 0.09575520 0.02538075 Thấp
## 6 0.08635749 0.06455097 Thấp
## 7 0.09589514 0.02538152 Thấp
## 8 0.06174794 0.04223359 Thấp
## 9 0.08560745 0.06454679 Thấp
## 10 0.09580193 0.02538100 Thấp
## 11 0.09563958 0.02538011 Thấp
## 12 0.08622645 0.06465024 Thấp
## 13 0.09582438 0.02538113 Thấp
## 14 0.08735218 0.06465650 Thấp
## 15 0.09570997 0.02538050 Thấp
## 16 0.06116808 0.04203023 Thấp
## 17 0.09589446 0.02538151 Thấp
## 18 0.09563958 0.02538011 Thấp
## 19 0.08715215 0.06455539 Thấp
## 20 0.09557348 0.02537975 Thấp
## 21 0.06174794 0.04203359 Thấp
## 22 0.08635749 0.06455097 Thấp
## 23 0.09550253 0.02527936 Thấp
## 24 0.06002773 0.04222361 Thấp
## 25 0.09566283 0.02538024 Thấp
## 26 0.06002773 0.04250139 Thấp
## 27 0.08619380 0.06455006 Thấp
## 28 0.09508980 0.02537708 Thấp
## 29 0.08557507 0.06494661 Thấp
## 30 0.09534117 0.02537847 Thấp
## 31 0.06116808 0.04213023 Thấp
## 32 0.09563958 0.02538011 Thấp
## 33 0.08635749 0.06525097 Thấp
## 34 0.06002773 0.04250139 Thấp
## 35 0.09488602 0.02537596 Thấp
## 36 0.09587115 0.02565916 Thấp
## 37 0.08635749 0.06495097 Thấp
## 38 0.06059471 0.04250468 Thấp
## 39 0.09580240 0.02565878 Thấp
## 40 0.08635749 0.06485097 Thấp
## 41 0.09589446 0.02538151 Thấp
## 42 0.06116808 0.04213023 Thấp
## 43 0.08570466 0.06484733 Thấp
## 44 0.09534163 0.02537847 Thấp
## 45 0.09580193 0.02538100 Thấp
## 46 0.08635749 0.06505097 Thấp
## 47 0.06059471 0.04250468 Thấp
## 48 0.09573192 0.02538062 Thấp
## 49 0.08695267 0.06535428 Thấp
## 50 0.09554912 0.02537961 Thấp
shapiro_results <- sapply(d %>% select(where(is.numeric)) %>% select(1:3), function(x) shapiro.test(x[1:5000])$p.value) # Giới hạn 5000 quan sát
shapiro_results## co humidity lpg
## 3.398486e-63 1.023157e-69 7.243811e-64
## co humidity lpg smoke temp temp_c chi_so_AQI
## co 1.000 -0.657 0.997 0.998 0.111 0.111 0.999
## humidity -0.657 1.000 -0.672 -0.670 -0.410 -0.410 -0.666
## lpg 0.997 -0.672 1.000 1.000 0.136 0.136 0.999
## smoke 0.998 -0.670 1.000 1.000 0.132 0.132 1.000
## temp 0.111 -0.410 0.136 0.132 1.000 1.000 0.125
## temp_c 0.111 -0.410 0.136 0.132 1.000 1.000 0.125
## chi_so_AQI 0.999 -0.666 0.999 1.000 0.125 0.125 1.000
## chi_so_rui_ro -0.611 0.769 -0.609 -0.610 0.267 0.267 -0.610
## chi_so_rui_ro
## co -0.611
## humidity 0.769
## lpg -0.609
## smoke -0.610
## temp 0.267
## temp_c 0.267
## chi_so_AQI -0.610
## chi_so_rui_ro 1.000
-Ý nghĩa thống kê: Các biến này mang cùng thông tin, vi phạm giả định độc lập trong các mô hình hồi quy
-Hệ quả: Làm tăng phương sai ước lượng, gây bất ổn định cho hệ số hồi quy
Mối quan hệ Nghịch biến humidity ↔︎ chất_lượng_không_khí: -0.67 Ý nghĩa thống kê: Mối tương quan âm mạnh, có ý nghĩa thống kê (p-value < 0.001)
cor_spearman <- cor(d %>% select(where(is.numeric)), use = "complete.obs", method = "spearman")
round(cor_spearman, 3)## co humidity lpg smoke temp temp_c chi_so_AQI
## co 1.000 -0.765 1.000 1.000 0.121 0.121 1.000
## humidity -0.765 1.000 -0.765 -0.765 -0.334 -0.334 -0.765
## lpg 1.000 -0.765 1.000 1.000 0.121 0.121 1.000
## smoke 1.000 -0.765 1.000 1.000 0.121 0.121 1.000
## temp 0.121 -0.334 0.121 0.121 1.000 1.000 0.121
## temp_c 0.121 -0.334 0.121 0.121 1.000 1.000 0.121
## chi_so_AQI 1.000 -0.765 1.000 1.000 0.121 0.121 1.000
## chi_so_rui_ro -0.745 0.837 -0.745 -0.745 0.161 0.161 -0.745
## chi_so_rui_ro
## co -0.745
## humidity 0.837
## lpg -0.745
## smoke -0.745
## temp 0.161
## temp_c 0.161
## chi_so_AQI -0.745
## chi_so_rui_ro 1.000
Giải thích kỹ thuật: - Đoạn code này thực hiện việc tính toán ma trận tương quan Spearman - một phương pháp phi tham số dựa trên thứ hạng của dữ liệu. Cụ thể, code sẽ lọc toàn bộ các biến số từ tập dữ liệu d bằng lệnh d %>% select(where(is.numeric)), sau đó tính toán hệ số tương quan Spearman giữa tất cả các cặp biến số với nhau thông qua hàm cor() với tham số method = “spearman”. Quá trình tính toán chỉ sử dụng các quan sát hoàn chỉnh (loại bỏ các giá trị missing) nhờ tham số use = “complete.obs”, và kết quả cuối cùng được làm tròn đến 3 chữ số thập phân để dễ dàng quan sát và phân tích. Ma trận kết quả cho phép đánh giá mối quan hệ đơn biến giữa các biến số trong dataset mà không phụ thuộc vào phân phối của dữ liệu.
Ý nghĩa thống kê : CO: Trung bình 46ppm (an toàn), nhưng có lúc đạt 144ppm - vượt ngưỡng cảnh báo Nhiệt độ: 22°C trung bình (lý tưởng), nhưng biến động từ 0°C (quá lạnh) đến 31°C (hơi nóng) Độ ẩm: 61% trung bình (tốt), nhưng có lúc 99% (quá ẩm) và 1% (quá khô) - cần điều chỉnh
KẾT LUẬN: Dữ liệu cho thấy các chất ô nhiễm CO, LPG và Smoke có xu hướng biến đổi đồng thời, tạo thành một nhóm các chỉ số chất lượng không khí liên quan chặt chẽ với nhau. Độ ẩm đóng vai trò quan trọng trong việc điều chỉnh sự phân bố của các chất ô nhiễm này.
## co humidity lpg smoke temp temp_c chi_so_AQI
## co 0.000 -0.009 0.000 0.000 0.000 0.000 0.000
## humidity -0.009 129.197 -0.011 -0.031 -12.588 -6.993 -0.156
## lpg 0.000 -0.011 0.000 0.000 0.001 0.000 0.000
## smoke 0.000 -0.031 0.000 0.000 0.001 0.001 0.000
## temp 0.000 -12.588 0.001 0.001 7.281 4.045 0.007
## temp_c 0.000 -6.993 0.000 0.001 4.045 2.247 0.004
## chi_so_AQI 0.000 -0.156 0.000 0.000 0.007 0.004 0.000
## chi_so_rui_ro 0.000 0.093 0.000 0.000 0.008 0.004 0.000
## chi_so_rui_ro
## co 0.000
## humidity 0.093
## lpg 0.000
## smoke 0.000
## temp 0.008
## temp_c 0.004
## chi_so_AQI 0.000
## chi_so_rui_ro 0.000
Giải thích kỹ thuật : Đoạn code này thực hiện việc tính toán ma trận hiệp phương sai cho các biến số trong tập dữ liệu.
Đầu tiên, code sử dụng pipe operator để chuyển dữ liệu từ dataframe d vào hàm select. Hàm select với điều kiện where(is.numeric) sẽ lọc ra chỉ những cột có kiểu dữ liệu là số, loại bỏ các biến phân loại hoặc văn bản.
Sau đó, hàm cov() được áp dụng để tính toán ma trận hiệp phương sai giữa tất cả các cặp biến số. Tham số use = “complete.obs” đảm bảo rằng chỉ những hàng có đầy đủ dữ liệu, không bị thiếu giá trị, mới được sử dụng trong tính toán.
Cuối cùng, kết quả ma trận hiệp phương sai được làm tròn đến 3 chữ số thập phân bằng hàm round() để dễ dàng đọc và trình bày. Ma trận này cho thấy mối quan hệ tuyến tính giữa các biến, với các giá trị trên đường chéo chính thể hiện phương sai của từng biến và các giá trị ngoài đường chéo thể hiện hiệp phương sai giữa các cặp biến
Ý nghĩa thống kê : - Giá trị trên đường chéo chính (từ trái sang phải):
co: 0.000 - Phương sai rất nhỏ, biến CO hầu như không biến động
humidity: 129.197 - Độ ẩm có phương sai lớn, biến động mạnh trong dataset
lpg: 0.000 - LPG có phương sai rất nhỏ
smoke: 0.000 - Khói có phương sai rất nhỏ
temp: 7.281 - Nhiệt độ có phương sai trung bình
temp_c: 2.247 - Nhiệt độ C có phương sai nhỏ hơn temp
humidity - temp: -12.588 → Quan hệ nghịch biến mạnh
Khi độ ẩm tăng, nhiệt độ có xu hướng giảm (và ngược lại)
humidity - temp_c: -6.993 → Tương tự như trên nhưng yếu hơn
Hầu hết các hiệp phương sai ≈ 0 → không có quan hệ tuyến tính
lpg-smoke: 0.000, co-smoke: 0.000 → các khí độc không có tương quan
Mối quan hệ humidity-temperature là mối quan hệ đáng chú ý duy nhất
Các chỉ số chất lượng không khí (AQI, rủi ro) hầu như không tương quan với các biến cảm biến
Dữ liệu có thể đã được chuẩn hóa hoặc có rất ít biến động
=> Kết luận thống kê: Dataset này có rất ít mối quan hệ tuyến tính giữa các biến
Humidity là biến quan trọng nhất cần theo dõi
Có thể cần phân tích phi tuyến tính để tìm ra các mối quan hệ phức tạp hơn
=> Đây là những insight quan trọng cho việc phân tích dữ liệu môi trường và chất lượng không khí!
percentiles <- sapply(d %>% select(where(is.numeric)),
quantile, probs = c(0.05, 0.25, 0.5, 0.75, 0.95), na.rm = TRUE)
percentiles## co humidity lpg smoke temp temp_c chi_so_AQI
## 5% 0.002473516 48.3 0.004627822 0.01193033 19.0 -7.222222 0.05350951
## 25% 0.003918682 51.0 0.006455518 0.01702405 19.9 -6.722222 0.07851728
## 50% 0.004811522 54.9 0.007488884 0.01995012 22.2 -5.444444 0.09323108
## 75% 0.005408832 74.3 0.008150443 0.02183817 23.6 -4.666666 0.10284298
## 95% 0.006248255 77.4 0.009047037 0.02441360 28.0 -2.222222 0.11609119
## chi_so_rui_ro
## 5% 0.02203493
## 25% 0.02465567
## 50% 0.03700606
## 75% 0.04192832
## 95% 0.05400073
Giải thích kỹ thuật : Đoạn code percentiles thực hiện một quy trình phân tích thống kê toàn diện, bắt đầu bằng việc lọc dataset d để chỉ giữ lại các biến số với d %>% select(where(is.numeric)), sau đó áp dụng hàm sapply() để tính toán năm phân vị quan trọng (5%, 25%, 50%, 75%, 95%) cho mỗi biến thông qua hàm quantile() với tham số na.rm = TRUE giúp loại bỏ giá trị thiếu trước khi tính toán.
Kết quả được lưu vào biến percentiles và khi in ra bằng percentiles, ta thu được một ma trận thống kê mà mỗi cột đại diện cho một biến numeric trong dataset và mỗi hàng hiển thị giá trị của các phân vị tương ứng, cung cấp cái nhìn tổng quan về phân phối dữ liệu từ các giá trị ngoại lệ ở hai đầu (5% và 95%) cho đến các tứ phân vị truyền thống (25%, 50%, 75%).
Phương pháp này đặc biệt hiệu quả cho việc khám phá dữ liệu đa biến, cho phép nhận diện nhanh chóng xu hướng tập trung, độ phân tán, và các giá trị bất thường trong dataset mà không cần phải phân tích từng biến riêng lẻ.
Ý nghĩa thống kê : Phân tích xu hướng trung tâm và độ phân tán: Về nồng độ khí gas (lpg), giá trị trung vị (50%) là 0.0075 cho thấy mức độ phổ biến, trong khi khoảng cách từ phân vị thứ 5 (0.0046) đến thứ 95 (0.0090) khá hẹp, chứng tỏ dữ liệu tập trung ổn định quanh giá trị trung bình với ít biến động cực đoan.
Đối với nhiệt độ (temp), sự chênh lệch đáng kể giữa phân vị thứ 5 (19°C) và thứ 95 (28°C) phản ánh biên độ dao động nhiệt độ rộng, tuy nhiên khoảng tứ phân vị từ 19.9°C đến 23.6°C cho thấy phần lớn dữ liệu nhiệt độ tập trung trong vùng này.
Đánh giá về phân phối dữ liệu: Chỉ số AQI (chi_so_AQI) có phân vị thứ 50 là 0.0932, cùng với khoảng cách gần giữa các phân vị (P25: 0.0785, P75: 0.1028) cho thấy phân phối tương đối đối xứng và ổn định, không có sự lệch đáng kể nào.
Độ ẩm (humidity) thể hiện phân phối không đều rõ rệt khi giá trị trung vị là 54.9% nhưng khoảng từ phân vị thứ 75 (74.3%) đến thứ 95 (77.4%) rất hẹp, ngược lại từ phân vị thứ 5 (48.3%) đến trung vị lại khá rộng, điều này cho thấy có sự tập trung cụm ở vùng độ ẩm cao.
Nhận diện giá trị bất thường: Nồng độ CO (co) có phạm vi biến động khá hẹp từ 0.0025 đến 0.0062, với 50% giá trị nằm trong khoảng 0.0039-0.0054, điều này cho thấy ít xuất hiện giá trị cực đoan trong tập dữ liệu.
Chỉ số rủi ro (chi_so_rui_ro) có sự gia tăng đáng kể từ phân vị thứ 50 (0.0370) lên phân vị thứ 95 (0.0540), gợi ý về sự hiện diện của một số trường hợp có mức độ rủi ro cao trong dataset.
Kết quả phân tích này cung cấp cái nhìn toàn diện về đặc điểm phân phối của từng chỉ số môi trường, hỗ trợ hiệu quả cho việc ra quyết định trong giám sát chất lượng không khí và quản lý rủi ro.
conf_int <- function(x) {
n <- sum(!is.na(x))
mean_val <- mean(x, na.rm = TRUE)
se <- sd(x, na.rm = TRUE)/sqrt(n)
c(lower = mean_val - 1.96*se, upper = mean_val + 1.96*se)
}
sapply(d %>% select(where(is.numeric)), conf_int)## co humidity lpg smoke temp temp_c chi_so_AQI
## lower 0.004634996 60.47669 0.007232679 0.01925103 22.44568 -5.307956 0.0899201
## upper 0.004642694 60.54669 0.007241572 0.01927619 22.46230 -5.298724 0.0900467
## chi_so_rui_ro
## lower 0.03452050
## upper 0.03458624
Giải thích kỹ thuật : Đoạn code này được thiết kế để tự động hóa việc tính toán khoảng tin cậy 95% cho tất cả các biến số trong một bộ dữ liệu. Cụ thể, nó thực hiện các bước sau:
Định nghĩa một hàm chuyên dụng (conf_int): Hàm này được xây dựng để xử lý một vector dữ liệu đầu vào. Đầu tiên, nó tính toán kích thước mẫu hiệu dụng bằng cách loại bỏ mọi giá trị thiếu (NA). Sau đó, nó sử dụng giá trị trung bình và độ lệch chuẩn của mẫu (cũng đã được điều chỉnh để bỏ qua giá trị thiếu) để tính toán Sai số chuẩn. Cuối cùng, hàm áp dụng công thức chuẩn của phân phối chuẩn (sử dụng hệ số 1.96) để xác định giới hạn dưới và giới hạn trên của khoảng tin cậy 95%.
Áp dụng hàm một cách có hệ thống: Sau khi hàm được định nghĩa, code sử dụng kết hợp toán tử %>% (pipe) và hàm sapply() để lọc và xử lý dữ liệu một cách hiệu quả. Cụ thể, nó lấy bộ dữ liệu gốc d, lọc ra chỉ những cột có dữ liệu số, rồi lần lượt áp dụng hàm conf_int cho từng cột số đó.
Kết quả đầu ra là một ma trận rõ ràng, trong đó mỗi cột số trong dữ liệu gốc sẽ tương ứng với một hàng (hoặc cột) trong kết quả, hiển thị đầy đủ giới hạn dưới và giới hạn trên của khoảng tin cậy 95% của nó. Phương pháp này không chỉ tiết kiệm thời gian đáng kể so với việc tính toán thủ công cho từng biến mà còn đảm bảo tính nhất quán và chính xác trong toàn bộ quy trình phân tích.
Ý nghĩa thống kê : 1. Về Chất Lượng Không Khí và An toàn:
Nồng độ Carbon Monoxide (CO) trung bình trong tổng thể được ước tính nằm trong khoảng từ 0.004635 đến 0.004643. Khoảng tin cậy cực kỳ hẹp này khẳng định mức độ CO được ước lượng với độ chính xác rất cao, cho thấy dữ liệu về chất lượng khí này rất ổn định và đáng tin cậy.
Tương tự, chỉ số AQI trung bình nằm trong khoảng từ 0.08992 đến 0.09005, và chỉ số rủi ro trung bình nằm trong khoảng từ 0.03452 đến 0.03459. Các khoảng tin cậy rất hẹp này một lần nữa nhấn mạnh rằng các ước lượng về mức độ ô nhiễm và rủi ro là vô cùng chính xác, cung cấp một cơ sở dữ liệu mạnh mẽ cho việc ra quyết định.
Độ ẩm trung bình được xác định nằm trong khoảng từ 60.48% đến 60.55%. Khoảng tin cậy hẹp này cho thấy ước lượng về độ ẩm là rất đáng tin cậy.
Nhiệt độ (theo đơn vị gốc) trung bình nằm trong khoảng từ 22.45°C đến 22.46°C, và sau khi quy đổi, nhiệt độ trung bình nằm trong khoảng từ -5.308°C đến -5.299°C. Sự chênh lệch rất nhỏ giữa các giới hạn của cả hai thang nhiệt độ phản ánh độ chính xác cao của phép đo nhiệt độ trong tập dữ liệu.
Nồng độ khí Gas (LPG) trung bình nằm trong khoảng từ 0.01925 đến 0.01928, và nồng độ khói (Smoke) trung bình nằm trong khoảng từ 0.007233 đến 0.007242. Các ước lượng này có độ chính xác rất cao, được thể hiện qua khoảng tin cậy cực kỳ hẹp, cho phép chúng ta đánh giá các nguy cơ cháy nổ với độ tin cậy lớn.
## ts device co humidity light
## 405171 3 8319 677 2
## lpg motion smoke temp humidity_status
## 8319 2 8319 231 3
## chat_luong temp_c temp_unit chi_so_AQI chi_so_rui_ro
## 4 231 1 8319 201478
## muc_do_rui_ro
## 1
Giải thích kỹ thuật Dòng code này thực hiện một công việc rất đơn giản: Với mỗi cột trong bảng dữ liệu, nó sẽ lấy ra tất cả các giá trị khác nhau của cột đó, rồi đếm xem có bao nhiêu giá trị như vậy. Kết quả cuối cùng cho ta biết mỗi cột có bao nhiêu loại giá trị phân biệt
Ý nghĩa thống kê : 1. Về quy mô và thời gian: “Biến timestamp (ts) có 405,171 giá trị duy nhất, xác nhận dataset chứa hơn 400 nghìn quan trắc riêng biệt được thu thập theo dòng thời gian, tạo nên chuỗi dữ liệu liên tục cho phân tích xu hướng.”
Về thiết bị và trạng thái: “Hệ thống được triển khai với 3 loại thiết bị khác nhau, trong khi các cảm biến ánh sáng và chuyển động chỉ ghi nhận 2 trạng thái cơ bản (bật/tắt), cho thấy tính nhị phân của các tín hiệu điều khiển.”
Về chất lượng môi trường: “Chất lượng không khí được đánh giá qua 4 mức độ phân loại rõ ràng, và trạng thái độ ẩm được xác định theo 3 mức, thể hiện hệ thống phân hạng tự động trong giám sát môi trường.”
Về các chỉ số ô nhiễm: “Các chỉ số khí CO, LPG, khói và AQI đều có 8,319 giá trị khác nhau, cho thấy mức độ biến thiên cao và tính nhạy cảm của các thông số ô nhiễm không khí theo thời gian thực.”
Về điều kiện môi trường: “Nhiệt độ xuất hiện 231 mức giá trị khác nhau và độ ẩm có 677 mức, phản ánh sự dao động tự nhiên nhưng trong khoảng giới hạn nhất định của các yếu tố khí hậu.”
Về đánh giá rủi ro: “Chỉ số rủi ro với 201,478 giá trị duy nhất cho thấy đây là biến có độ biến thiên phức tạp nhất, trong khi mức độ rủi ro lại cố định ở 1 giá trị, thể hiện sự không đồng nhất giữa chỉ số tính toán và phân loại.”
## $ts
## [1] "POSIXct" "POSIXt"
##
## $device
## [1] "character"
##
## $co
## [1] "numeric"
##
## $humidity
## [1] "numeric"
##
## $light
## [1] "character"
##
## $lpg
## [1] "numeric"
##
## $motion
## [1] "character"
##
## $smoke
## [1] "numeric"
##
## $temp
## [1] "numeric"
##
## $humidity_status
## [1] "character"
##
## $chat_luong
## [1] "character"
##
## $temp_c
## [1] "numeric"
##
## $temp_unit
## [1] "character"
##
## $chi_so_AQI
## [1] "numeric"
##
## $chi_so_rui_ro
## [1] "numeric"
##
## $muc_do_rui_ro
## [1] "character"
Giải thích kỹ thuật : Hàm sapply(d, class) là một công cụ trong ngôn ngữ R dùng để xác định kiểu dữ liệu của từng cột trong dataframe. Cụ thể, nó thực hiện việc lặp qua tất cả các cột trong dataframe d và áp dụng hàm class() lên từng cột để trả về kiểu dữ liệu tương ứng.
Về mặt kỹ thuật, sapply() hoạt động như một vòng lặp tối ưu hóa - nó tự động duyệt qua từng phần tử trong danh sách (ở đây là các cột của dataframe) và áp dụng hàm được chỉ định. Kết quả trả về là một vector chứa tên các kiểu dữ liệu, với mỗi phần tử được đặt tên theo tên cột tương ứng.
Đối với dataframe, hàm class() sẽ trả về các kiểu dữ liệu cơ bản như “numeric” cho số, “character” cho chuỗi ký tự, “factor” cho dữ liệu phân loại, hoặc các kiểu đặc biệt như “POSIXct” cho dữ liệu thời gian. Kết quả này rất hữu ích cho việc kiểm tra nhanh cấu trúc dữ liệu, phát hiện các cột có kiểu dữ liệu không mong muốn, và làm cơ sở cho các thao tác chuyển đổi kiểu dữ liệu tiếp theo.
Ý nghĩa thống kê Về cơ bản, tập dữ liệu được chia thành ba nhóm chính theo kiểu dữ liệu. Nhóm biến định lượng gồm 7 biến như co, humidity, temp, temp_c, chi_so_AQI và chi_so_rui_ro - đây là những biến số học cho phép thực hiện các phân tích thống kê mô tả như tính trung bình, độ lệch chuẩn, cũng như áp dụng các kiểm định tham số và phân tích hồi quy.
Nhóm thứ hai là các biến định tính với 7 biến bao gồm device, light, motion, temp_unit, chat_luong, humidity_status và muc_do_rui_ro - những biến này chủ yếu được phân tích thông qua thống kê tần suất, bảng chéo và kiểm định phi tham số. Riêng biến ts thuộc kiểu thời gian POSIXct tạo điều kiện cho việc phân tích chuỗi thời gian và xu hướng.
Cấu trúc dữ liệu này cho thấy khả năng thực hiện đa dạng các phân tích thống kê, từ mô tả cơ bản đến phân tích mối quan hệ giữa các biến định lượng, so sánh giữa các nhóm được xác định bởi biến định tính, cho đến phân tích xu hướng theo thời gian. Tuy nhiên, cần lưu ý chuyển đổi một số biến character sang factor khi cần thiết và đảm bảo xử lý phù hợp với từng loại kiểu dữ liệu trong quá trình phân tích.
p1 <- ggplot(d, aes(x = ts, y = temp_c)) +
# Layer 1: Đường time series cơ bản
geom_line(aes(color = "Nhiệt độ"), alpha = 0.6, size = 0.5) +
# Layer 2: Xu hướng smoothed
geom_smooth(method = "loess", aes(color = "Xu hướng"),
se = FALSE, size = 1.2, span = 0.1) +
# Layer 3: Points highlight theo device
geom_point(data = d %>% group_by(device) %>% slice(seq(1, n(), by = 100)),
aes(color = device), alpha = 0.3, size = 0.8) +
# Layer 4: Facet theo device
facet_wrap(~device, ncol = 1, scales = "free_y") +
# Layer 5: Customization
scale_color_manual(values = c("Nhiệt độ" = "steelblue",
"Xu hướng" = "red",
"Thiết bị 1" = "darkgreen",
"Thiết bị 2" = "orange",
"Thiết bị 3" = "purple")) +
labs(title = "1. Time Series Nhiệt Độ với Multiple Layers",
subtitle = "5 layers: Đường cơ bản, Xu hướng, Points theo thiết bị, Facet, Custom theme",
x = "Thời gian", y = "Nhiệt độ (°C)") +
theme_minimal()
print(p1)Giải thích kỹ thuật: Sử dụng geom_line() cho dữ liệu gốc, geom_smooth() cho xu hướng, geom_point() với sampling để tránh overplotting, facet_wrap() để tách biệt theo thiết bị.
Ý nghĩa thống kê: Phân tích xu hướng nhiệt độ theo thời gian, so sánh hiệu suất giữa các thiết bị cảm biến.
# Chọn các biến numeric chính
selected_vars <- c("co", "humidity", "lpg", "smoke", "temp_c",
"chi_so_AQI", "chi_so_rui_ro")
cor_data <- d %>% select(all_of(selected_vars)) %>% cor(use = "complete.obs")
p2 <- melt(cor_data) %>%
ggplot(aes(x = Var1, y = Var2, fill = value)) +
# Layer 1: Heatmap tiles
geom_tile(color = "white", size = 1, alpha = 0.8) +
# Layer 2: Correlation values text
geom_text(aes(label = round(value, 2)), color = "black",
fontface = "bold", size = 3.5) +
# Layer 3: Significance stars
geom_text(aes(label = ifelse(abs(value) > 0.7, "***",
ifelse(abs(value) > 0.5, "**",
ifelse(abs(value) > 0.3, "*", "")))),
color = "red", size = 4, vjust = -1.5) +
# Layer 4: Color gradient
scale_fill_gradient2(low = "blue", high = "red", mid = "white",
midpoint = 0, limit = c(-1,1), name = "Correlation") +
# Layer 5: Theme customization
theme_minimal() +
labs(title = "2. Correlation Heatmap với Significance Markers",
subtitle = "5 layers: Tiles, Values, Significance stars, Color scale, Theme",
x = "", y = "") +
theme(axis.text.x = element_text(angle = 45, hjust = 1))
print(p2)Giải thích kỹ thuật: Kết hợp geom_tile(), geom_text() cho giá trị và significance stars, scale_fill_gradient2() cho màu phân cực.
Ý nghĩa thống kê: Phân tích mối quan hệ tuyến tính giữa các biến môi trường, phát hiện multicollinearity.
# Tạo dữ liệu theo nhóm giờ - sử dụng tiếng Anh để tránh lỗi encoding
hourly_co_data <- d %>%
mutate(hour_group = cut(hour(ts),
breaks = c(0, 6, 12, 18, 24),
labels = c("Night (0-6h)", "Morning (6-12h)",
"Afternoon (12-18h)", "Evening (18-24h)")))
p3 <- ggplot(hourly_co_data, aes(x = co, fill = hour_group)) +
# Layer 1: Density plots với transparency
geom_density(alpha = 0.6, position = "identity") +
# Layer 2: Vertical mean lines
geom_vline(data = hourly_co_data %>%
group_by(device, hour_group) %>%
summarise(mean_co = mean(co, na.rm = TRUE), .groups = "drop"),
aes(xintercept = mean_co, color = hour_group),
linetype = "dashed", size = 0.8) +
# Layer 3: Color scales
scale_fill_viridis_d(name = "Time Period") +
scale_color_viridis_d(name = "Time Period") +
# Layer 4: Facet grid
facet_grid(device ~ hour_group, scales = "free") +
# Layer 5: Theme và labels
labs(title = "3. Density Plots: CO Distribution by Time Period and Device",
subtitle = "5 layers: Density plots, Mean lines, Color scales, Facet grid, Theme",
x = "CO Concentration (ppm)", y = "Density") +
theme_minimal() +
theme(legend.position = "none")
print(p3)Giải thích kỹ thuật: Sử dụng tiếng Anh cho labels để tránh lỗi encoding, kết hợp geom_density(), geom_vline(), và facet_grid().
Ý nghĩa thống kê: Phân tích sự khác biệt trong phân phối nồng độ CO giữa các khung giờ và thiết bị cảm biến.
p4 <- ggplot(d, aes(x = temp_c, y = humidity)) +
# Layer 1: Points với alpha và color mapping
geom_point(aes(color = chi_so_AQI, size = co), alpha = 0.6) +
# Layer 2: Density contour
geom_density_2d(color = "black", alpha = 0.5, size = 0.5) +
# Layer 3: Regression line
geom_smooth(method = "lm", color = "red", se = TRUE,
alpha = 0.2, size = 1) +
# Layer 4: Color và size scales
scale_color_viridis_c(name = "Chỉ số AQI") +
scale_size_continuous(name = "Nồng độ CO", range = c(0.5, 3)) +
# Layer 5: Facet và theme
facet_grid(device ~ light) +
labs(title = "4. Scatter Plot: Nhiệt độ vs Độ ẩm với Multiple Variables",
subtitle = "5 layers: Points, Density contour, Regression, Scales, Facet",
x = "Nhiệt độ (°C)", y = "Độ ẩm (%)") +
theme_bw()
print(p4)Giải thích kỹ thuật: Kết hợp points với size/color mapping, density contour, regression line, và faceting.
Ý nghĩa thống kê: Phân tích mối quan hệ đa biến giữa nhiệt độ, độ ẩm, AQI, CO và điều kiện ánh sáng.
p5 <- ggplot(d, aes(x = device, y = chi_so_rui_ro)) +
# Layer 1: Violin plot
geom_violin(aes(fill = device), alpha = 0.6, trim = FALSE, width = 0.8) +
# Layer 2: Boxplot
geom_boxplot(width = 0.15, alpha = 0.8, outlier.shape = NA,
color = "black", size = 0.5) +
# Layer 3: Mean points
stat_summary(fun = mean, geom = "point", shape = 23,
size = 3, fill = "red", color = "black") +
# Layer 4: Jitter points
geom_jitter(aes(color = muc_do_rui_ro), alpha = 0.3,
width = 0.1, size = 0.5) +
# Layer 5: Scale và theme
scale_fill_viridis_d() +
scale_color_manual(values = c("Cao" = "red", "Trung bình" = "orange", "Thấp" = "green")) +
labs(title = "5. Violin + Boxplot Combo: Phân phối Chỉ số Rủi ro",
subtitle = "5 layers: Violin, Boxplot, Mean points, Jitter, Color scales",
x = "Thiết bị", y = "Chỉ số Rủi ro") +
theme_minimal()
print(p5)Giải thích kỹ thuật: Kết hợp violin plot, boxplot, mean points, jitter points với color mapping.
Ý nghĩa thống kê: So sánh phân phối chỉ số rủi ro giữa các thiết bị, phân tích outliers và central tendency.
# Chuẩn bị dữ liệu theo ngày - sử dụng tiếng Anh
daily_data <- d %>%
mutate(date = as.Date(ts)) %>%
group_by(date, muc_do_rui_ro) %>%
summarise(count = n(), .groups = "drop") %>%
group_by(date) %>%
mutate(percentage = count / sum(count))
# Đảm bảo muc_do_rui_ro có đủ các mức
daily_data <- daily_data %>%
mutate(risk_level = factor(muc_do_rui_ro,
levels = c("Cao", "Trung bình", "Thấp"),
labels = c("High", "Medium", "Low")))
p6 <- ggplot(daily_data, aes(x = date, y = percentage, fill = risk_level)) +
# Layer 1: Stacked area
geom_area(alpha = 0.7, position = "stack") +
# Layer 2: Line cho từng category
geom_line(aes(color = risk_level), position = "stack", size = 0.5, alpha = 0.8) +
# Layer 3: Percentage labels (chỉ hiển thị khi percentage lớn)
geom_text(data = daily_data %>%
group_by(date, risk_level) %>%
filter(percentage > 0.1),
aes(label = scales::percent(percentage, accuracy = 1)),
position = position_stack(vjust = 0.5), size = 2.5, check_overlap = TRUE) +
# Layer 4: Scale customization
scale_y_continuous(labels = scales::percent) +
scale_fill_manual(values = c("High" = "red", "Medium" = "orange", "Low" = "green")) +
scale_color_manual(values = c("High" = "darkred", "Medium" = "darkorange", "Low" = "darkgreen")) +
# Layer 5: Theme và labels
labs(title = "6. Stacked Area Chart: Risk Level Distribution Over Time",
subtitle = "5 layers: Area, Lines, Text labels, Scales, Theme",
x = "Date", y = "Percentage") +
theme_minimal() +
theme(legend.position = "bottom")
print(p6)Giải thích kỹ thuật: Sử dụng tiếng Anh để tránh lỗi encoding, geom_area() cho stacked area, geom_line() cho đường viền, geom_text() với check_overlap = TRUE.
Ý nghĩa thống kê: Phân tích sự thay đổi composition của mức độ rủi ro theo thời gian.
hourly_heatmap_data <- d %>%
mutate(hour = hour(ts),
day_type = ifelse(wday(ts) %in% c(1,7), "Weekend", "Weekday")) %>%
group_by(hour, day_type, device) %>%
summarise(mean_co = mean(co, na.rm = TRUE), .groups = "drop")
p7 <- hourly_heatmap_data %>%
ggplot(aes(x = factor(hour), y = device, fill = mean_co)) +
# Layer 1: Heatmap tiles với gradient màu mượt mà
geom_tile(color = "white", size = 0.8, alpha = 0.95, width = 1, height = 1) +
# Layer 2: Color gradient với palette dễ nhìn
scale_fill_gradientn(
name = "CO Concentration",
colors = c("#2c7bb6", "#abd9e9", "#ffffbf", "#fdae61", "#d7191c"),
values = scales::rescale(c(min(hourly_heatmap_data$mean_co),
quantile(hourly_heatmap_data$mean_co, 0.25),
median(hourly_heatmap_data$mean_co),
quantile(hourly_heatmap_data$mean_co, 0.75),
max(hourly_heatmap_data$mean_co))),
breaks = pretty(hourly_heatmap_data$mean_co, n = 5),
labels = scales::number_format(accuracy = 0.001)
) +
# Layer 3: Facet với styling đẹp
facet_grid(. ~ day_type, scales = "free_x") +
# Layer 4: Scale expansion để biểu đồ thoáng hơn
scale_x_discrete(expand = c(0, 0)) +
scale_y_discrete(expand = c(0, 0)) +
# Layer 5: Theme tối ưu cho heatmap
labs(
title = "CO Concentration Patterns by Hour and Day Type",
subtitle = "Heatmap visualization with optimized color palette",
x = "Hour of Day",
y = "Device",
caption = "Data shows average CO levels across different time periods"
) +
theme_minimal(base_size = 12) +
theme(
plot.title = element_text(face = "bold", size = 14, hjust = 0.5),
plot.subtitle = element_text(hjust = 0.5, color = "gray50"),
axis.text.x = element_text(angle = 0, hjust = 0.5, size = 9),
axis.text.y = element_text(size = 10, face = "bold"),
axis.title = element_text(face = "bold"),
panel.grid = element_blank(),
legend.position = "bottom",
legend.key.width = unit(1.5, "cm"),
legend.key.height = unit(0.4, "cm"),
legend.title = element_text(face = "bold"),
strip.background = element_rect(fill = "#2c3e50"),
strip.text = element_text(color = "white", face = "bold", size = 10),
plot.margin = margin(15, 15, 15, 15),
plot.background = element_rect(fill = "white", color = NA),
panel.background = element_rect(fill = "white", color = NA)
)
print(p7)Giải thích kỹ thuật:
Layer 1: geom_tile() tạo heatmap với white borders
Layer 2: geom_text() với sprintf() format số có 4 chữ số thập phân
Layer 3: scale_fill_viridis_c() với plasma color scheme và breaks rõ ràng
Layer 4: facet_grid() tách biệt theo weekend/weekday
Layer 5: Theme customization với strip styling
Ý nghĩa thống kê:
Temporal patterns: Phát hiện các khung giờ có nồng độ CO cao/thấp
Weekend vs Weekday: So sánh sự khác biệt giữa ngày thường và cuối tuần
Device consistency: Đánh giá sự nhất quán giữa các cảm biến
Hotspot identification: Xác định các combinations (giờ + ngày) có nguy cơ cao
Data quality: Màu sắc đồng nhất cho thấy measurements ổn định
p8 <- ggplot(d, aes(x = chi_so_AQI)) +
# Layer 1: Histogram
geom_histogram(aes(y = ..density.., fill = device),
bins = 30, alpha = 0.6, position = "identity") +
# Layer 2: Density curve
geom_density(aes(color = device), alpha = 0.8, size = 1) +
# Layer 3: Mean lines
geom_vline(data = d %>% group_by(device) %>%
summarise(mean_AQI = mean(chi_so_AQI, na.rm = TRUE)),
aes(xintercept = mean_AQI, color = device),
linetype = "dashed", size = 1) +
# Layer 4: Rug plot
geom_rug(aes(color = device), sides = "b", alpha = 0.3, length = unit(0.05, "npc")) +
# Layer 5: Facet và theme
facet_wrap(~device, ncol = 1) +
labs(title = "8. Histogram với Density Curve và Multiple Elements",
subtitle = "5 layers: Histogram, Density, Mean lines, Rug plot, Facet",
x = "Chỉ số AQI", y = "Mật độ") +
theme_minimal()
print(p8)Giải thích kỹ thuật: Kết hợp histogram, density curve, mean lines, rug plot và faceting.
Ý nghĩa thống kê: Phân tích hình dạng phân phối AQI, so sánh giữa các thiết bị cảm biến.
summary_stats <- d %>%
group_by(device, light) %>%
summarise(
mean_humidity = mean(humidity, na.rm = TRUE),
se_humidity = sd(humidity, na.rm = TRUE) / sqrt(n()),
n = n(),
.groups = "drop"
)
p9 <- ggplot(summary_stats, aes(x = device, y = mean_humidity, fill = light)) +
# Layer 1: Bar plot với position dodge
geom_col(position = position_dodge(0.8), alpha = 0.7, width = 0.7) +
# Layer 2: Error bars với confidence interval 95%
geom_errorbar(aes(ymin = mean_humidity - 1.96*se_humidity,
ymax = mean_humidity + 1.96*se_humidity),
position = position_dodge(0.8), width = 0.2, size = 0.8,
color = "black", alpha = 0.8) +
# Layer 3: Points cho mean values
geom_point(aes(color = light), position = position_dodge(0.8),
size = 3, shape = 21, fill = "white", stroke = 1) +
# Layer 4: Horizontal reference line cho overall mean
geom_hline(yintercept = mean(d$humidity, na.rm = TRUE),
linetype = "dashed", color = "red", size = 1, alpha = 0.7) +
# Layer 5: Theme và coordination
coord_flip() +
scale_fill_manual(values = c("TRUE" = "#1f77b4", "FALSE" = "#ff7f0e")) +
scale_color_manual(values = c("TRUE" = "#1f77b4", "FALSE" = "#ff7f0e")) +
labs(title = "9. Bar Plot with Error Bars and Confidence Intervals",
subtitle = "5 layers: Bars, Error bars, Mean points, Reference line, Coord flip",
x = "Device", y = "Average Humidity (%)",
fill = "Light", color = "Light") +
theme_bw() +
theme(legend.position = "top",
plot.title = element_text(face = "bold", size = 14),
plot.subtitle = element_text(size = 10))
print(p9)Layer 1: geom_col() với position_dodge() để tách biệt các nhóm
Layer 2: geom_errorbar() tính khoảng tin cậy 95% sử dụng 1.96*SE
Layer 3: geom_point() với shape 21 (circle với fill) để highlight mean values
Layer 4: geom_hline() làm reference line so sánh với overall mean
Layer 5: coord_flip() để dễ đọc labels và theme customization
So sánh độ ẩm trung bình giữa các thiết bị trong điều kiện có/không có ánh sáng
Error bars thể hiện độ tin cậy của ước lượng (95% CI)
Reference line giúp so sánh với giá trị trung bình tổng thể
Phân tích sự ảnh hưởng của điều kiện ánh sáng đến độ ẩm môi trường
hourly_avg <- d %>%
mutate(hour = hour(ts)) %>%
group_by(hour, device) %>%
summarise(mean_temp = mean(temp_c, na.rm = TRUE), .groups = "drop")
p10 <- ggplot(hourly_avg, aes(x = hour, y = mean_temp, color = device)) +
# Layer 1: Line
geom_line(size = 1.2, alpha = 0.8) +
# Layer 2: Points
geom_point(size = 2.5, alpha = 0.8) +
# Layer 3: Area fill
geom_area(aes(fill = device), alpha = 0.2, position = "identity") +
# Layer 4: Polar coordinates
coord_polar() +
# Layer 5: Scale và theme
scale_x_continuous(breaks = seq(0, 23, by = 3),
labels = c("00:00", "03:00", "06:00", "09:00",
"12:00", "15:00", "18:00", "21:00")) +
labs(title = "10. Polar Plot: Chu kỳ Nhiệt độ 24 giờ Theo Thiết bị",
subtitle = "5 layers: Line, Points, Area, Polar coord, Scale customization",
x = "Giờ", y = "Nhiệt độ trung bình (°C)") +
theme_minimal()
print(p10)Giải thích kỹ thuật: Biểu đồ sử dụng kỹ thuật radar chart với hệ tọa độ cực để hiển thị dữ liệu theo chu kỳ 24 giờ. Năm lớp đồ họa được kết hợp: lớp đường nối các điểm dữ liệu, lớp điểm đánh dấu giá trị cụ thể, lớp vùng tô tạo hiệu ứng trực quan, hệ tọa độ cực xếp vòng tròn thay vì trục thẳng, và tùy chỉnh tỷ lệ để phóng to thu nhỏ thang đo. Màu sắc được phân biệt rõ ràng giữa các thiết bị, giúp so sánh đồng thời nhiều đối tượng trên cùng một biểu đồ. Các đường grid tỏa tròn đại diện cho các mốc thời gian, tạo thành mạng nhện bao quanh trung tâm là điểm 0 độ C. Kỹ thuật này đặc biệt hiệu quả để thể hiện dữ liệu tuần hoàn và so sánh đa chiều.
Ý nghĩa thống kê: Biểu đồ radar thể hiện nhiệt độ trung bình của ba thiết bị theo các khung giờ trong ngày. Nhiệt độ dao động từ -6°C đến 18°C, với mức thấp nhất vào ban đêm (00:00-03:00) và cao nhất vào buổi trưa (12:00-15:00). Thiết bị 1 (màu vàng cam) ghi nhận nhiệt độ cao nhất và biến động mạnh nhất, trong khi thiết bị 3 (màu xanh dương) có nhiệt độ thấp nhất và ổn định nhất. Xu hướng nhiệt độ của cả ba thiết bị đều tuân theo chu kỳ ngày đêm: tăng dần từ sáng sớm, đạt đỉnh vào giữa trưa, và giảm dần về đêm. Biên độ nhiệt trong ngày khá lớn, khoảng 12°C, phản ánh sự chênh lệch nhiệt độ đáng kể giữa ngày và đêm.
bubble_data <- d %>%
group_by(device, muc_do_rui_ro) %>%
summarise(
mean_temp = mean(temp_c, na.rm = TRUE),
mean_humidity = mean(humidity, na.rm = TRUE),
mean_co = mean(co, na.rm = TRUE),
count = n(),
.groups = "drop"
)
# Convert Vietnamese labels to English
bubble_data <- bubble_data %>%
mutate(risk_level = case_when(
muc_do_rui_ro == "Cao" ~ "High",
muc_do_rui_ro == "Trung bình" ~ "Medium",
muc_do_rui_ro == "Thấp" ~ "Low",
TRUE ~ as.character(muc_do_rui_ro)
))
p11 <- ggplot(bubble_data, aes(x = mean_temp, y = mean_humidity,
size = mean_co, color = risk_level)) +
# Layer 1: Bubble points
geom_point(alpha = 0.8, stroke = 1) +
# Layer 2: Text labels
geom_text(aes(label = device), size = 3, vjust = -1.8, hjust = 0.5,
check_overlap = TRUE, fontface = "bold") +
# Layer 3: Smooth trend line
geom_smooth(method = "lm", se = FALSE, aes(group = 1),
color = "black", linetype = "dashed", size = 0.7,
alpha = 0.5) +
# Layer 4: Size and color scale
scale_size_continuous(name = "Mean CO",
range = c(3, 12)) +
scale_color_manual(name = "Risk Level",
values = c("High" = "#D62728",
"Medium" = "#FF7F0E",
"Low" = "#2CA02C")) +
# Layer 5: Theme and labels (English only)
labs(title = "11. Bubble Plot: 3-Variable Relationship and Risk Level",
subtitle = "5 layers: Bubbles, Labels, Trend line, Scales, Theme",
x = "Mean Temperature (C)",
y = "Mean Humidity (%)",
caption = "Bubble size = CO concentration\nColor = Risk level") +
theme_minimal() +
theme(plot.title = element_text(face = "bold", size = 14),
plot.subtitle = element_text(size = 10),
legend.position = "right")
print(p11)Giải thích kỹ thuật: Scatter plot với size mapping cho biến thứ 3, text labels và trend line.
Ý nghĩa thống kê: Phân tích mối quan hệ đồng thời giữa nhiệt độ, độ ẩm, CO và mức độ rủi ro.
# Tạo dữ liệu đơn giản
scatter_data <- d %>%
select(temp_c, humidity, co, device) %>%
pivot_longer(cols = c(humidity, co),
names_to = "y_var", values_to = "y_val")
p12 <- ggplot(scatter_data, aes(x = temp_c, y = y_val)) +
# Layer 1: Scatter points
geom_point(aes(color = device), alpha = 0.5, size = 0.8) +
# Layer 2: Regression line
geom_smooth(method = "lm", color = "red", se = FALSE, size = 0.8) +
# Layer 3: Facet grid đơn giản
facet_grid(y_var ~ device, scales = "free_y") +
# Layer 4: Color scale
scale_color_viridis_d() +
# Layer 5: Theme
labs(title = "12. Scatter Matrix: Temperature vs Environment Variables",
x = "Temperature (C)", y = "Value") +
theme_bw() +
theme(legend.position = "none")
print(p12)Giải thích kỹ thuật: Sử dụng facet_grid() cho complex layout, kết hợp points, regression và correlation text.
Ý nghĩa thống kê: Phân tích mối quan hệ giữa nhiệt độ và các biến khác trong multiple conditions.
p13 <- d %>%
mutate(hour_cat = cut(hour(ts),
breaks = c(0, 6, 12, 18, 24),
labels = c("Đêm khuya", "Sáng sớm", "Buổi chiều", "Buổi tối"))) %>%
ggplot(aes(x = chi_so_rui_ro, fill = hour_cat)) +
# Layer 1: Density với transparency
geom_density(alpha = 0.6, position = "identity") +
# Layer 2: Mean lines
geom_vline(data = . %>% group_by(hour_cat) %>%
summarise(mean_risk = mean(chi_so_rui_ro, na.rm = TRUE)),
aes(xintercept = mean_risk, color = hour_cat),
linetype = "dashed", size = 1) +
# Layer 3: Text annotations
geom_text(data = . %>% group_by(hour_cat) %>%
summarise(mean_risk = mean(chi_so_rui_ro, na.rm = TRUE)),
aes(x = mean_risk, y = 0.02, label = round(mean_risk, 3), color = hour_cat),
vjust = -0.5, fontface = "bold", size = 3) +
# Layer 4: Facet
facet_wrap(~device, ncol = 2) +
# Layer 5: Theme
labs(title = "13. Stacked Density Plot: Chỉ số Rủi ro Theo Khung giờ",
subtitle = "5 layers: Density, Mean lines, Text, Facet, Theme",
x = "Chỉ số Rủi ro", y = "Mật độ") +
theme_minimal()
print(p13)Giải thích kỹ thuật: Multiple density plots với position = “identity”, mean lines và text annotations.
Ý nghĩa thống kê: So sánh phân phối chỉ số rủi ro giữa các khung giờ trong ngày.
daily_ci <- d %>%
mutate(date = as.Date(ts)) %>%
group_by(date, device) %>%
summarise(
mean_AQI = mean(chi_so_AQI, na.rm = TRUE),
se_AQI = sd(chi_so_AQI, na.rm = TRUE) / sqrt(n()),
.groups = "drop"
)
p14 <- ggplot(daily_ci, aes(x = date, y = mean_AQI, color = device)) +
# Layer 1: Line
geom_line(size = 1, alpha = 0.8) +
# Layer 2: Points
geom_point(size = 2, alpha = 0.8) +
# Layer 3: Error bars
geom_errorbar(aes(ymin = mean_AQI - 1.96*se_AQI,
ymax = mean_AQI + 1.96*se_AQI),
width = 0.3, alpha = 0.7, size = 0.5) +
# Layer 4: Ribbon (sử dụng geom_ribbon đúng cách)
geom_ribbon(aes(ymin = mean_AQI - 1.96*se_AQI,
ymax = mean_AQI + 1.96*se_AQI,
fill = device),
alpha = 0.15, color = NA) +
# Layer 5: Theme (English labels)
labs(title = "14. Line Plot with Confidence Intervals Over Time",
subtitle = "5 layers: Line, Points, Error bars, Ribbon, Theme",
x = "Date", y = "Average AQI Index") +
theme_minimal() +
theme(legend.position = "bottom")
print(p14)Giải thích kỹ thuật: Kết hợp line, points, error bars và ribbon cho confidence intervals.
Ý nghĩa thống kê: Theo dõi xu hướng AQI với độ tin cậy thống kê theo thời gian.
# Tính mean values trước
mean_temp <- mean(d$temp_c, na.rm = TRUE)
mean_humidity <- mean(d$humidity, na.rm = TRUE)
p15 <- ggplot(d, aes(x = temp_c, y = humidity)) +
# Layer 1: Hexbin
geom_hex(bins = 30, alpha = 0.8) +
# Layer 2: Density contour
geom_density_2d(color = "white", alpha = 0.6, size = 0.5) +
# Layer 3: Mean point
geom_point(data = data.frame(x = mean_temp, y = mean_humidity),
aes(x = x, y = y), shape = 23, size = 4,
fill = "red", color = "black") +
# Layer 4: Color scale
scale_fill_viridis_c(name = "Observation Count") +
# Layer 5: Facet và theme (English labels)
facet_wrap(~device, ncol = 2) +
labs(title = "15. Hexbin Plot: Temperature vs Humidity Density",
subtitle = "5 layers: Hexbin, Density contour, Mean point, Color scale, Facet",
x = "Temperature (C)", y = "Humidity (%)") +
theme_bw() +
theme(strip.background = element_rect(fill = "lightblue"))
print(p15)Giải thích kỹ thuật: Sử dụng hexagonal binning cho large dataset, kết hợp density contour.
Ý nghĩa thống kê: Phân tích mật độ điểm dữ liệu lớn, tránh overplotting.
# Tạo dữ liệu theo ngày
daily_co_data <- d %>%
mutate(date = as.Date(ts))
p16 <- daily_co_data %>%
ggplot(aes(x = date, y = co)) +
# Layer 1: Boxplot với fill theo device
geom_boxplot(aes(fill = device), alpha = 0.7, outlier.shape = NA, width = 0.8) +
# Layer 2: Mean line trend
stat_summary(fun = mean, geom = "line", aes(group = device, color = device),
size = 1, linetype = "dashed") +
# Layer 3: Mean points
stat_summary(fun = mean, geom = "point", aes(color = device),
size = 2, shape = 18) +
# Layer 4: Color và fill scales
scale_fill_viridis_d() +
scale_color_viridis_d() +
# Layer 5: Facet và theme
facet_wrap(~device, ncol = 1, scales = "free_y") +
labs(title = "16. CO Distribution Over Time with Mean Trends",
subtitle = "5 layers: Boxplot, Mean lines, Mean points, Color scales, Facet",
x = "Date", y = "CO Concentration (ppm)",
fill = "Device", color = "Device") +
theme_minimal() +
theme(axis.text.x = element_text(angle = 45, hjust = 1),
legend.position = "none")
print(p16)Giải thích kỹ thuật:
Layer 1: geom_boxplot() hiển thị phân phối CO theo ngày
Layer 2: geom_jitter() hiển thị individual data points
Layer 3: stat_summary() highlight mean values bằng points màu đỏ
Layer 4: geom_smooth() vẽ trend line cho từng thiết bị
Layer 5: facet_wrap() tách biệt theo device với free y-axis
Ý nghĩa thống kê: Phân tích phân phối CO theo thời gian với xu hướng tổng thể.
p17 <- d %>%
mutate(hour = hour(ts),
risk_category = cut(chi_so_rui_ro,
breaks = c(-Inf, 0.03, 0.05, Inf),
labels = c("Thấp", "Trung bình", "Cao"))) %>%
count(device, hour, risk_category) %>%
group_by(device, hour) %>%
mutate(percentage = n / sum(n)) %>%
ggplot(aes(x = hour, y = percentage, fill = risk_category)) +
# Layer 1: Stacked bars
geom_bar(stat = "identity", position = "stack", alpha = 0.8) +
# Layer 2: Data labels
geom_text(aes(label = ifelse(percentage > 0.1, scales::percent(percentage, accuracy = 1), "")),
position = position_stack(vjust = 0.5), size = 2) +
# Layer 3: Line cho tổng số
geom_line(data = . %>% group_by(device, hour) %>% summarise(total = sum(n)),
aes(x = hour, y = total/max(total), group = device, color = "Tổng quan sát"),
size = 1, inherit.aes = FALSE) +
# Layer 4: Scale customization
scale_y_continuous(labels = percent, sec.axis = sec_axis(~.*max(.))) +
scale_fill_manual(values = c("Thấp" = "green", "Trung bình" = "orange", "Cao" = "red")) +
scale_color_manual(values = c("Tổng quan sát" = "blue")) +
# Layer 5: Facet và theme
facet_wrap(~device, ncol = 1) +
labs(title = "17. Stacked Bar Chart: Phân bố Rủi ro Theo Giờ",
subtitle = "5 layers: Bars, Text, Line, Dual axis, Facet",
x = "Giờ", y = "Phần trăm") +
theme_minimal()
print(p17)
Giải thích kỹ thuật:
Layer 1: geom_bar() với position = “stack” tạo stacked bars
Layer 2: geom_text() hiển thị percentage khi lớn hơn 10%
Layer 3: geom_line() vẽ đường tổng số quan sát (scaled)
Layer 4: scale_y_continuous() với percent labels và manual color scale
Layer 5: facet_wrap() tách biệt theo device
Ý nghĩa thống kê:
Phân bố rủi ro: Stacked bars cho thấy composition của các mức risk theo giờ
Patterns theo thời gian: Xác định khung giờ có rủi ro cao/thấp
Tổng quan sát: Đường dashed cho biết số lượng data points theo giờ
So sánh thiết bị: Faceting cho phép so sánh patterns giữa các sensors
# Chuẩn bị dữ liệu
weekend_data <- d %>%
mutate(date = as.Date(ts),
is_weekend = wday(ts) %in% c(1, 7)) %>%
group_by(date, is_weekend, device) %>%
summarise(mean_temp = mean(temp_c, na.rm = TRUE), .groups = "drop")
p18 <- ggplot(weekend_data, aes(x = date, y = mean_temp)) +
# Layer 1: Line cho weekday
geom_line(data = weekend_data %>% filter(!is_weekend),
aes(color = "Weekday"), alpha = 0.7, size = 0.8) +
# Layer 2: Line cho weekend (highlight)
geom_line(data = weekend_data %>% filter(is_weekend),
aes(color = "Weekend"), size = 1.2, alpha = 0.9) +
# Layer 3: Points cho extreme values
geom_point(data = weekend_data %>%
group_by(device) %>%
filter(mean_temp == max(mean_temp) | mean_temp == min(mean_temp)),
aes(shape = "Extreme"), size = 3, color = "red", alpha = 0.8) +
# Layer 4: Smooth trend line
geom_smooth(aes(group = 1, linetype = "Trend"), method = "loess",
color = "blue", se = FALSE, size = 1, alpha = 0.6) +
# Layer 5: Facet và scale
facet_wrap(~device, ncol = 2, scales = "free_y") +
scale_color_manual(values = c("Weekday" = "gray", "Weekend" = "orange")) +
scale_shape_manual(values = c("Extreme" = 17)) +
scale_linetype_manual(values = c("Trend" = "dashed")) +
labs(title = "18. Time Series with Weekend Highlights and Extreme Values",
subtitle = "5 layers: Weekday lines, Weekend highlights, Extreme points, Trend line, Facet",
x = "Date", y = "Average Temperature (C)",
color = "Day Type", shape = "Points", linetype = "Line") +
theme_bw() +
theme(legend.position = "bottom")
print(p18)
Giải thích kỹ thuật:
Layer 1: geom_line() riêng cho weekday với màu nhạt
Layer 2: geom_line() riêng cho weekend với highlight
Layer 3: geom_point() highlight min/max values
Layer 4: geom_smooth() trend line tổng thể
Layer 5: facet_wrap() và scale customization
Ý nghĩa thống kê:
Weekend vs Weekday: So sánh patterns nhiệt độ giữa các ngày
Extreme values: Xác định các điểm cực trị (min/max)
Trend analysis: Xu hướng tổng thể của nhiệt độ
Device comparison: So sánh performance giữa các sensors
# Chuẩn bị dữ liệu theo ngày
daily_metrics <- d %>%
mutate(date = as.Date(ts)) %>%
group_by(date, device) %>%
summarise(
mean_temp = mean(temp_c, na.rm = TRUE),
mean_humidity = mean(humidity, na.rm = TRUE),
mean_co = mean(co, na.rm = TRUE),
.groups = "drop"
)
# Tính scaling factors cho dual axis
temp_range <- range(daily_metrics$mean_temp, na.rm = TRUE)
humidity_range <- range(daily_metrics$mean_humidity, na.rm = TRUE)
scale_factor <- diff(humidity_range) / diff(temp_range)
p19 <- ggplot(daily_metrics) +
# Layer 1: Temperature line (primary axis)
geom_line(aes(x = date, y = mean_temp, color = "Temperature"),
size = 1, alpha = 0.8) +
# Layer 2: Humidity line (secondary axis)
geom_line(aes(x = date, y = (mean_humidity - humidity_range[1])/scale_factor + temp_range[1],
color = "Humidity"),
size = 1, alpha = 0.8, linetype = "dashed") +
# Layer 3: CO points (bubble size)
geom_point(aes(x = date, y = mean_temp, size = mean_co),
alpha = 0.6, color = "red") +
# Layer 4: Dual axis scales
scale_y_continuous(
name = "Temperature (C)",
sec.axis = sec_axis(~(. - temp_range[1]) * scale_factor + humidity_range[1],
name = "Humidity (%)")
) +
scale_color_manual(values = c("Temperature" = "blue", "Humidity" = "green")) +
scale_size_continuous(name = "CO Level", range = c(1, 5)) +
# Layer 5: Facet và theme
facet_wrap(~device, ncol = 2) +
labs(title = "19. Dual Axis: Temperature vs Humidity with CO Indicators",
subtitle = "5 layers: Temp line, Humidity line, CO points, Dual axis, Facet",
x = "Date") +
theme_bw() +
theme(legend.position = "bottom")
print(p19)Giải thích kỹ thuật:
Layer 1: geom_line() cho nhiệt độ (primary axis)
Layer 2: geom_line() cho độ ẩm (scaled cho secondary axis)
Layer 3: geom_point() với size mapping cho nồng độ CO
Layer 4: scale_y_continuous() với sec.axis cho dual axis
Layer 5: facet_wrap() và theme customization
Ý nghĩa thống kê:
Mối quan hệ nhiệt độ-độ ẩm: Phân tích correlation giữa hai biến môi trường
CO indicators: Bubble size cho thấy mức độ ô nhiễm
Dual axis visualization: So sánh hai biến có different scales
Time trends: Theo dõi diễn biến đồng thời của multiple variables
# Tính giá trị trung bình cho các biến chính, normalized
radar_data <- d %>%
group_by(device) %>%
summarise(
temp_scaled = scale(mean(temp_c, na.rm = TRUE)),
humidity_scaled = scale(mean(humidity, na.rm = TRUE)),
co_scaled = scale(mean(co, na.rm = TRUE)),
aqi_scaled = scale(mean(chi_so_AQI, na.rm = TRUE)),
risk_scaled = scale(mean(chi_so_rui_ro, na.rm = TRUE)),
.groups = "drop"
) %>%
pivot_longer(cols = -device, names_to = "metric", values_to = "value")
p20 <- ggplot(radar_data, aes(x = metric, y = value, group = device, color = device)) +
# Layer 1: Polygon area
geom_polygon(aes(fill = device), alpha = 0.2, size = 1) +
# Layer 2: Lines
geom_line(size = 1.2, alpha = 0.8) +
# Layer 3: Points
geom_point(size = 3, alpha = 0.8) +
# Layer 4: Coordinate polar (radar style)
coord_polar() +
# Layer 5: Theme và labels
labs(title = "20. Radar Chart: Multivariate Device Comparison",
subtitle = "5 layers: Polygon, Lines, Points, Polar coord, Theme",
x = "Metrics", y = "Scaled Value",
caption = "All metrics scaled to mean=0, sd=1") +
theme_minimal() +
theme(axis.text.x = element_text(face = "bold"),
panel.grid.major = element_line(color = "gray", linetype = "dashed"),
legend.position = "bottom")
print(p20)Giải thích kỹ thuật:
Layer 1: geom_polygon() tạo filled areas cho radar chart
Layer 2: geom_line() kết nối các điểm metric
Layer 3: geom_point() highlight các giá trị metric
Layer 4: coord_polar() chuyển đổi sang radar coordinate system
Layer 5: Theme customization cho radar chart
Ý nghĩa thống kê:
Multivariate comparison: So sánh đồng thời multiple metrics across devices
Performance profiling: Xác định strengths/weaknesses của từng device
Normalized scales: Tất cả metrics được scaled để so sánh công bằng
Pattern recognition: Hình dạng radar cho thấy profile characteristics
Device consistency: Đánh giá sự nhất quán trong measurements
library(DT)
library(lubridate)
library(readxl)
library(dplyr)
library(tidyr)
library(ggplot2)
library(dplyr)
library(reshape2)
library(flextable)
library(moments)
library(openxlsx)
library(scales)
library(viridis)
library(patchwork)
library(reshape2)
library(ggridges)
library(plotly)
library(kableExtra)
library(gridExtra)
library(corrplot)
library(corrplot)
library(ggpubr)
library(hexbin)
library(showtext)
library(knitr)Bộ dữ liệu bạn cung cấp từ file “Tổng hợp - DGC.xlsx” là một báo cáo tài chính tổng hợp, của một doanh nghiệp tên là Công ty Cổ phần Bột giặt và Hóa chất Đức Giang (DGC), trình bày các chỉ tiêu tài chính chủ yếu qua các năm từ 2014 đến 2024.
Dưới đây là giới thiệu chung về bộ dữ liệu này:
1. Nguồn gốc và Mục đích Đây là dữ liệu tài chính theo năm, được tổng hợp lại, có thể dùng cho mục đích phân tích tài chính, đánh giá hiệu quả hoạt động, xu hướng phát triển, hoặc lập kế hoạch kinh doanh.
2. Các chỉ tiêu tài chính chính - Bảng dữ liệu bao gồm các cột chỉ tiêu quan trọng sau:
Năm: Kỳ báo cáo (từ 2014 đến 2024).
Tiền & Tương đương tiền: Tài sản có tính thanh khoản cao nhất.
Tài sản ngắn hạn: Tổng tài sản có thể chuyển đổi thành tiền trong vòng một năm.
Nợ ngắn hạn: Các khoản nợ phải trả trong vòng một năm.
Doanh thu thuần: Doanh thu bán hàng sau các khoản giảm trừ.
Lợi nhuận trước thuế & sau thuế: Phản ánh khả năng sinh lời.
Tổng Nợ phải trả: Toàn bộ nợ của doanh nghiệp.
Vốn chủ sở hữu: Phần vốn thuộc về chủ sở hữu.
Lưu chuyển tiền tệ (LCTT) từ hoạt động kinh doanh (HĐKD): Dòng tiền thực tế từ hoạt động kinh doanh chính.
LCTT thuần trong kỳ: Chênh lệch giữa dòng tiền vào và ra trong kỳ.
Mua sắm TSCĐ: Chi tiêu cho tài sản cố định, phản ánh đầu tư dài hạn.
3. Đặc điểm nổi bật của dữ liệu - Chuỗi thời gian dài (10 năm): Cho phép phân tích xu hướng dài hạn.
Quy mô số lớn: Các con số có đơn vị tiền tệ (có thể là VND) với giá trị lên đến hàng nghìn tỷ, cho thấy đây có thể là một tập đoàn hoặc doanh nghiệp lớn.
Dữ liệu không liên tục: Thiếu năm 2015.
Biến động mạnh: Một số chỉ tiêu như Tiền, LCTT thuần, Mua sắm TSCĐ có sự biến động rất lớn giữa các năm.
4. Ứng dụng tiềm năng Bộ dữ liệu này có thể được sử dụng để:
Phân tích khả năng thanh khoản, cơ cấu tài chính.
Đánh giá hiệu quả hoạt động và khả năng sinh lời.
Phân tích dòng tiền và khả năng đầu tư.
Dự báo tài chính và lập kế hoạch kinh doanh.
## 'data.frame': 10 obs. of 12 variables:
## $ Năm : num 2014 2016 2017 2018 2019 ...
## $ Tiền.&.Tương.đương.tiền: chr "8,391,782" "186,282,852" "82,619,006" "274,286,867" ...
## $ Tài.sản.ngắn.hạn : chr "943,911,153" "839,492,384" "370,850,868" "2,135,742,165" ...
## $ Nợ.ngắn.hạn : chr "743,186,944" "640,751,723" "220,236,773" "1,564,572,904" ...
## $ Doanh.thu.thuần : chr "2,036,568,828" "2,622,156,236" "625,590,798" "6,090,140,212" ...
## $ Lợi.nhuận.trước.thuế : chr "259,807,690" "342,322,069" "140,138,954" "906,609,128" ...
## $ Lợi.nhuận.sau.thuế : chr "221,424,044" "319,528,852" "128,396,518" "872,807,018" ...
## $ Tổng.Nợ.phải.trả : chr "1,103,303,166" "993,867,722" "677,969,263" "2,057,906,394" ...
## $ Vốn.chủ.sở.hữu : chr "334,993,660" "500,088,750" "500,088,750" "1,078,038,110" ...
## $ LCTT.từ.HĐKD : chr "278,671,319" "366,022,984" "-42,701,955" "564,131,075" ...
## $ LCTT.thuần.trong.kỳ : chr "107,962,695" "-136,098,393" "-75,650,266" "263,987,276" ...
## $ Mua.sắm.TSCĐ : chr "-350,031,086" "-117,360,419" "-7,996,351" "-402,857,780" ...
## Rows: 10
## Columns: 12
## $ Năm <dbl> 2014, 2016, 2017, 2018, 2019, 2020, 2021, 20…
## $ `Tiền.&.Tương.đương.tiền` <chr> "8,391,782", "186,282,852", "82,619,006", "2…
## $ Tài.sản.ngắn.hạn <chr> "943,911,153", "839,492,384", "370,850,868",…
## $ Nợ.ngắn.hạn <chr> "743,186,944", "640,751,723", "220,236,773",…
## $ Doanh.thu.thuần <chr> "2,036,568,828", "2,622,156,236", "625,590,7…
## $ Lợi.nhuận.trước.thuế <chr> "259,807,690", "342,322,069", "140,138,954",…
## $ Lợi.nhuận.sau.thuế <chr> "221,424,044", "319,528,852", "128,396,518",…
## $ Tổng.Nợ.phải.trả <chr> "1,103,303,166", "993,867,722", "677,969,263…
## $ Vốn.chủ.sở.hữu <chr> "334,993,660", "500,088,750", "500,088,750",…
## $ LCTT.từ.HĐKD <chr> "278,671,319", "366,022,984", "-42,701,955",…
## $ LCTT.thuần.trong.kỳ <chr> "107,962,695", "-136,098,393", "-75,650,266"…
## $ Mua.sắm.TSCĐ <chr> "-350,031,086", "-117,360,419", "-7,996,351"…
## Năm Tiền.&.Tương.đương.tiền Tài.sản.ngắn.hạn Nợ.ngắn.hạn Doanh.thu.thuần
## 1 2014 8,391,782 943,911,153 743,186,944 2,036,568,828
## 2 2016 186,282,852 839,492,384 640,751,723 2,622,156,236
## 3 2017 82,619,006 370,850,868 220,236,773 625,590,798
## 4 2018 274,286,867 2,135,742,165 1,564,572,904 6,090,140,212
## 5 2019 127,679,694 2,262,978,406 1,270,297,173 5,090,618,454
## 6 2020 282,319,770 3,433,498,648 1,808,718,873 6,236,479,389
## Lợi.nhuận.trước.thuế Lợi.nhuận.sau.thuế Tổng.Nợ.phải.trả Vốn.chủ.sở.hữu
## 1 259,807,690 221,424,044 1,103,303,166 334,993,660
## 2 342,322,069 319,528,852 993,867,722 500,088,750
## 3 140,138,954 128,396,518 677,969,263 500,088,750
## 4 906,609,128 872,807,018 2,057,906,394 1,078,038,110
## 5 599,069,948 571,557,935 1,303,698,164 1,293,636,160
## 6 1,001,340,611 948,071,165 1,370,238,745 1,487,669,430
## LCTT.từ.HĐKD LCTT.thuần.trong.kỳ Mua.sắm.TSCĐ
## 1 278,671,319 107,962,695 -350,031,086
## 2 366,022,984 -136,098,393 -117,360,419
## 3 -42,701,955 -75,650,266 -7,996,351
## 4 564,131,075 263,987,276 -402,857,780
## 5 846,782,054 -514,977,020 -110,575,456
## 6 1,072,986,615 182,693,347 -243,268,895
colnames(df) <- c("Năm",
"Tiền.va.Tuong.duong.tien",
"Tai.san.ngan.han",
"No.ngan.han",
"Doanh.thu.thuan",
"Loi.nhuan.truoc.thue",
"Loi.nhuan.sau.thue",
"Tong.No.phai.tra",
"Von.chu.so.huu",
"LCTT.tu.HĐKD",
"LCTT.thuan.trong.ky",
"Mua.sam.TSCD")
print(df)## Năm Tiền.va.Tuong.duong.tien Tai.san.ngan.han No.ngan.han Doanh.thu.thuan
## 1 2014 8,391,782 943,911,153 743,186,944 2,036,568,828
## 2 2016 186,282,852 839,492,384 640,751,723 2,622,156,236
## 3 2017 82,619,006 370,850,868 220,236,773 625,590,798
## 4 2018 274,286,867 2,135,742,165 1,564,572,904 6,090,140,212
## 5 2019 127,679,694 2,262,978,406 1,270,297,173 5,090,618,454
## 6 2020 282,319,770 3,433,498,648 1,808,718,873 6,236,479,389
## 7 2021 123,957,761 5,997,347,534 2,188,391,015 9,550,386,236
## 8 2022 1,535,474,845 10,985,294,291 2,571,528,808 14,444,110,661
## 9 2023 1,060,574,919 12,466,646,826 3,508,967,833 9,748,014,758
## 10 2024 115,781,848 12,700,554,128 2,120,242,323 9,864,969,760
## Loi.nhuan.truoc.thue Loi.nhuan.sau.thue Tong.No.phai.tra Von.chu.so.huu
## 1 259,807,690 221,424,044 1,103,303,166 334,993,660
## 2 342,322,069 319,528,852 993,867,722 500,088,750
## 3 140,138,954 128,396,518 677,969,263 500,088,750
## 4 906,609,128 872,807,018 2,057,906,394 1,078,038,110
## 5 599,069,948 571,557,935 1,303,698,164 1,293,636,160
## 6 1,001,340,611 948,071,165 1,370,238,745 1,487,669,430
## 7 2,637,112,898 2,513,776,234 2,683,397,140 1,710,805,560
## 8 6,375,747,810 6,036,982,867 3,260,429,004 3,797,792,860
## 9 3,485,125,745 3,241,661,076 3,491,730,458 3,797,792,860
## 10 3,400,275,512 3,107,401,820 2,131,737,318 3,797,792,860
## LCTT.tu.HĐKD LCTT.thuan.trong.ky Mua.sam.TSCD
## 1 278,671,319 107,962,695 -350,031,086
## 2 366,022,984 -136,098,393 -117,360,419
## 3 -42,701,955 -75,650,266 -7,996,351
## 4 564,131,075 263,987,276 -402,857,780
## 5 846,782,054 -514,977,020 -110,575,456
## 6 1,072,986,615 182,693,347 -243,268,895
## 7 2,619,566,419 -537,217,517 -252,689,537
## 8 5,936,759,108 -697,054,310 -157,456,311
## 9 2,783,885,080 -920,431,364 -250,811,931
## 10 3,119,474,203 -2,912,201,514 -522,002,864
##
## === KÍCH THƯỚC DỮ LIỆU ===
## [1] 10 12
## [1] 2014 2016 2017 2018 2019 2020 2021 2022 2023 2024
df_clean <- df
df_clean[is.na(df_clean)] <- 0
View(df_clean)
cat("\nĐã thay thế giá trị NA bằng 0\n")##
## Đã thay thế giá trị NA bằng 0
##
## === THỐNG KÊ MÔ TẢ ===
## Năm Tiền.va.Tuong.duong.tien Tai.san.ngan.han No.ngan.han
## Min. :2014 Length:10 Length:10 Length:10
## 1st Qu.:2017 Class :character Class :character Class :character
## Median :2020 Mode :character Mode :character Mode :character
## Mean :2019
## 3rd Qu.:2022
## Max. :2024
## Doanh.thu.thuan Loi.nhuan.truoc.thue Loi.nhuan.sau.thue Tong.No.phai.tra
## Length:10 Length:10 Length:10 Length:10
## Class :character Class :character Class :character Class :character
## Mode :character Mode :character Mode :character Mode :character
##
##
##
## Von.chu.so.huu LCTT.tu.HĐKD LCTT.thuan.trong.ky Mua.sam.TSCD
## Length:10 Length:10 Length:10 Length:10
## Class :character Class :character Class :character Class :character
## Mode :character Mode :character Mode :character Mode :character
##
##
##
## Năm Tiền.va.Tuong.duong.tien Tai.san.ngan.han
## "numeric" "character" "character"
## No.ngan.han Doanh.thu.thuan Loi.nhuan.truoc.thue
## "character" "character" "character"
## Loi.nhuan.sau.thue Tong.No.phai.tra Von.chu.so.huu
## "character" "character" "character"
## LCTT.tu.HĐKD LCTT.thuan.trong.ky Mua.sam.TSCD
## "character" "character" "character"
Dòng code này thực hiện kiểm tra và hiển thị kiểu dữ liệu của từng cột trong dataframe (df) dưới dạng bảng được định dạng đẹp bằng kableExtra.
Ta thấy dạng của biến là Character, tôi sẽ chuẩn hóa nó là dạng numberic ở những bước tiếp theo để dễ dàng tính toán các chỉ tiêu để phân tích tài chính
colnames_clean <- make.names(colnames(df))
colnames(df) <- colnames_clean
cat("### TÊN CỘT SAU KHI CHUẨN HÓA ###\n")## ### TÊN CỘT SAU KHI CHUẨN HÓA ###
data.frame(
`Tên cột mới` = colnames(df),
check.names = FALSE
) %>%
kbl(align = "l") %>%
kable_styling(
bootstrap_options = c("striped", "hover"),
full_width = FALSE,
position = "center"
) %>%
row_spec(0, bold = TRUE, background = "#f0f0f0")| Tên cột mới |
|---|
| Năm |
| Tiền.va.Tuong.duong.tien |
| Tai.san.ngan.han |
| No.ngan.han |
| Doanh.thu.thuan |
| Loi.nhuan.truoc.thue |
| Loi.nhuan.sau.thue |
| Tong.No.phai.tra |
| Von.chu.so.huu |
| LCTT.tu.HĐKD |
| LCTT.thuan.trong.ky |
| Mua.sam.TSCD |
df_clean <- df
df_clean[is.na(df_clean)] <- 0
View(df_clean)
cat("\nĐã thay thế giá trị NA bằng 0\n")##
## Đã thay thế giá trị NA bằng 0
## Năm Tiền.va.Tuong.duong.tien Tai.san.ngan.han No.ngan.han Doanh.thu.thuan
## 1 2014 8,391,782 943,911,153 743,186,944 2,036,568,828
## 2 2016 186,282,852 839,492,384 640,751,723 2,622,156,236
## 3 2017 82,619,006 370,850,868 220,236,773 625,590,798
## 4 2018 274,286,867 2,135,742,165 1,564,572,904 6,090,140,212
## 5 2019 127,679,694 2,262,978,406 1,270,297,173 5,090,618,454
## 6 2020 282,319,770 3,433,498,648 1,808,718,873 6,236,479,389
## 7 2021 123,957,761 5,997,347,534 2,188,391,015 9,550,386,236
## 8 2022 1,535,474,845 10,985,294,291 2,571,528,808 14,444,110,661
## 9 2023 1,060,574,919 12,466,646,826 3,508,967,833 9,748,014,758
## 10 2024 115,781,848 12,700,554,128 2,120,242,323 9,864,969,760
## Loi.nhuan.truoc.thue Loi.nhuan.sau.thue Tong.No.phai.tra Von.chu.so.huu
## 1 259,807,690 221,424,044 1,103,303,166 334,993,660
## 2 342,322,069 319,528,852 993,867,722 500,088,750
## 3 140,138,954 128,396,518 677,969,263 500,088,750
## 4 906,609,128 872,807,018 2,057,906,394 1,078,038,110
## 5 599,069,948 571,557,935 1,303,698,164 1,293,636,160
## 6 1,001,340,611 948,071,165 1,370,238,745 1,487,669,430
## 7 2,637,112,898 2,513,776,234 2,683,397,140 1,710,805,560
## 8 6,375,747,810 6,036,982,867 3,260,429,004 3,797,792,860
## 9 3,485,125,745 3,241,661,076 3,491,730,458 3,797,792,860
## 10 3,400,275,512 3,107,401,820 2,131,737,318 3,797,792,860
## LCTT.tu.HĐKD LCTT.thuan.trong.ky Mua.sam.TSCD
## 1 278,671,319 107,962,695 -350,031,086
## 2 366,022,984 -136,098,393 -117,360,419
## 3 -42,701,955 -75,650,266 -7,996,351
## 4 564,131,075 263,987,276 -402,857,780
## 5 846,782,054 -514,977,020 -110,575,456
## 6 1,072,986,615 182,693,347 -243,268,895
## 7 2,619,566,419 -537,217,517 -252,689,537
## 8 5,936,759,108 -697,054,310 -157,456,311
## 9 2,783,885,080 -920,431,364 -250,811,931
## 10 3,119,474,203 -2,912,201,514 -522,002,864
df_clean[names(df_clean) != "Năm"] <- lapply(df_clean[names(df_clean) != "Năm"], function(x) {
as.numeric(gsub("\\.", "", gsub(",", ".", as.character(x))))
})##
## === KIỂU DỮ LIỆU ===
## Năm Tiền.va.Tuong.duong.tien Tai.san.ngan.han
## "character" "numeric" "numeric"
## No.ngan.han Doanh.thu.thuan Loi.nhuan.truoc.thue
## "numeric" "numeric" "numeric"
## Loi.nhuan.sau.thue Tong.No.phai.tra Von.chu.so.huu
## "numeric" "numeric" "numeric"
## LCTT.tu.HĐKD LCTT.thuan.trong.ky Mua.sam.TSCD
## "numeric" "numeric" "numeric"
df_clean <- df_clean %>%
mutate(Ty.le.no.tren.VCSH = df_clean$Tong.No.phai.tra / df_clean$Von.chu.so.huu)
cat("Đã thêm cột tỷ lệ nợ thành công!\n")## Đã thêm cột tỷ lệ nợ thành công!
## [1] 3.2935046 1.9873827 1.3556979 1.9089366 1.0077781 0.9210640 1.5684992
## [8] 0.8585063 0.9194105 0.5613095
df_clean <- df_clean %>%
mutate(Bien.loi.nhuan.rong = df_clean$Loi.nhuan.sau.thue / df_clean$Doanh.thu.thuan)## [1] 0.1087241 0.1218573 0.2052404 0.1433148 0.1122767 0.1520203 0.2632120
## [8] 0.4179546 0.3325458 0.3149935
df_clean <- df_clean %>%
mutate(Kha.nang.thanh.toan.ngan.han = df_clean$Tai.san.ngan.han / df_clean$No.ngan.han)df_clean <- df_clean %>%
mutate(Giai.doan = ifelse(Ty.le.no.tren.VCSH > 2, "Rủi ro cao", "An toàn"))df_clean <- df_clean %>%
mutate(Quy.mo.doanh.thu = cut(Doanh.thu.thuan,
breaks = c(0, 5e9, 10e9, 15e9, Inf),
labels = c("Nhỏ", "Trung bình", "Lớn", "Rất lớn"),
include.lowest = TRUE))Giải thích kỹ thuât : Hàm cut() sẽ “cắt” dữ liệu số theo các điểm breaks và gán cho mỗi giá trị một labels phù hợp.
Dòng code này tạo một cột mới “Quy.mo.doanh.thu” để phân loại quy mô doanh nghiệp dựa trên doanh thu thành 4 hạng: Nhỏ, Trung bình, Lớn, Rất lớn.
df_clean <- df_clean %>%
mutate(Hieu.suat.su.dung.TS = df_clean$Doanh.thu.thuan / df_clean$Tai.san.ngan.han)df_clean$Tinh.trang.dong.tien <- ifelse(df_clean$LCTT.thuan.trong.ky > 0, "Tích cực", "Tiêu cực")
cat("Đã mã hóa tình trạng dòng tiền\n")## Đã mã hóa tình trạng dòng tiền
Giải thích kỹ thuật: Đoạn code sử dụng hàm
ifelse() để tạo biến mới “Tinh.trang.dong.tien” - nếu giá
trị dòng tiền thuần trong kỳ lớn hơn 0 thì gán nhãn “Tích cực”, ngược
lại gán nhãn “Tiêu cực”.
Ý nghĩa thống kê: Việc mã hóa này giúp đánh giá nhanh tình hình sức khỏe tài chính của doanh nghiệp, phân loại các năm theo trạng thái dòng tiền để phân tích xu hướng và rủi ro thanh khoản.
Giải thích kỹ thuật: Đoạn code sử dụng hàm
mutate() để tạo biến mới “Ty.le.giu.lai” bằng công thức lấy
lợi nhuận sau thuế chia cho tổng của lợi nhuận sau thuế và giá trị tuyệt
đối của đầu tư TSCĐ, sau đó dùng select() để hiển thị kết
quả.
Ý nghĩa thống kê: Tỷ lệ giữ lại lợi nhuận dao động từ 38.7% đến 97.5%, cho thấy doanh nghiệp ngày càng sử dụng hiệu quả hơn phần lợi nhuận để tái đầu tư thay vì chi tiêu cho TSCĐ, đặc biệt từ năm 2017 trở đi duy trì ở mức trên 68%.
## Rows: 10
## Columns: 19
## $ Năm <chr> "2014", "2016", "2017", "2018", "2019", "…
## $ Tiền.va.Tuong.duong.tien <dbl> 8391782, 186282852, 82619006, 274286867, …
## $ Tai.san.ngan.han <dbl> 943911153, 839492384, 370850868, 21357421…
## $ No.ngan.han <dbl> 743186944, 640751723, 220236773, 15645729…
## $ Doanh.thu.thuan <dbl> 2036568828, 2622156236, 625590798, 609014…
## $ Loi.nhuan.truoc.thue <dbl> 259807690, 342322069, 140138954, 90660912…
## $ Loi.nhuan.sau.thue <dbl> 221424044, 319528852, 128396518, 87280701…
## $ Tong.No.phai.tra <dbl> 1103303166, 993867722, 677969263, 2057906…
## $ Von.chu.so.huu <dbl> 334993660, 500088750, 500088750, 10780381…
## $ LCTT.tu.HĐKD <dbl> 278671319, 366022984, -42701955, 56413107…
## $ LCTT.thuan.trong.ky <dbl> 107962695, -136098393, -75650266, 2639872…
## $ Mua.sam.TSCD <dbl> -350031086, -117360419, -7996351, -402857…
## $ Ty.le.no.tren.VCSH <dbl> 3.2935046, 1.9873827, 1.3556979, 1.908936…
## $ Bien.loi.nhuan.rong <dbl> 0.1087241, 0.1218573, 0.2052404, 0.143314…
## $ Kha.nang.thanh.toan.ngan.han <dbl> 1.270086, 1.310168, 1.683874, 1.365064, 1…
## $ Giai.doan <chr> "Rủi ro cao", "An toàn", "An toàn", "An t…
## $ Quy.mo.doanh.thu <fct> Nhỏ, Nhỏ, Nhỏ, Trung bình, Trung bình, Tr…
## $ Hieu.suat.su.dung.TS <dbl> 2.1575853, 3.1235021, 1.6869067, 2.851533…
## $ Tinh.trang.dong.tien <chr> "Tích cực", "Tiêu cực", "Tiêu cực", "Tích…
## Năm Tiền.va.Tuong.duong.tien Tai.san.ngan.han
## Length:10 Min. :8.392e+06 Min. :3.709e+08
## Class :character 1st Qu.:1.178e+08 1st Qu.:1.242e+09
## Mode :character Median :1.570e+08 Median :2.848e+09
## Mean :3.797e+08 Mean :5.214e+09
## 3rd Qu.:2.803e+08 3rd Qu.:9.738e+09
## Max. :1.535e+09 Max. :1.270e+10
## No.ngan.han Doanh.thu.thuan Loi.nhuan.truoc.thue
## Min. :2.202e+08 Min. :6.256e+08 Min. :1.401e+08
## 1st Qu.:8.750e+08 1st Qu.:3.239e+09 1st Qu.:4.065e+08
## Median :1.687e+09 Median :6.163e+09 Median :9.540e+08
## Mean :1.664e+09 Mean :6.631e+09 Mean :1.915e+09
## 3rd Qu.:2.171e+09 3rd Qu.:9.699e+09 3rd Qu.:3.209e+09
## Max. :3.509e+09 Max. :1.444e+10 Max. :6.376e+09
## Loi.nhuan.sau.thue Tong.No.phai.tra Von.chu.so.huu
## Min. :1.284e+08 Min. :6.780e+08 Min. :3.350e+08
## 1st Qu.:3.825e+08 1st Qu.:1.153e+09 1st Qu.:6.446e+08
## Median :9.104e+08 Median :1.714e+09 Median :1.391e+09
## Mean :1.796e+09 Mean :1.907e+09 Mean :1.830e+09
## 3rd Qu.:2.959e+09 3rd Qu.:2.545e+09 3rd Qu.:3.276e+09
## Max. :6.037e+09 Max. :3.492e+09 Max. :3.798e+09
## LCTT.tu.HĐKD LCTT.thuan.trong.ky Mua.sam.TSCD
## Min. : -42701955 Min. :-2.912e+09 Min. :-522002864
## 1st Qu.: 415550007 1st Qu.:-6.571e+08 1st Qu.:-325695699
## Median : 959884334 Median :-3.255e+08 Median :-247040413
## Mean :1754557690 Mean :-5.239e+08 Mean :-241505063
## 3rd Qu.:2742805415 3rd Qu.: 6.206e+07 3rd Qu.:-127384392
## Max. :5936759108 Max. : 2.640e+08 Max. : -7996351
## Ty.le.no.tren.VCSH Bien.loi.nhuan.rong Kha.nang.thanh.toan.ngan.han
## Min. :0.5613 Min. :0.1087 Min. :1.270
## 1st Qu.:0.9198 1st Qu.:0.1272 1st Qu.:1.445
## Median :1.1817 Median :0.1786 Median :1.840
## Mean :1.4382 Mean :0.2172 Mean :2.586
## 3rd Qu.:1.8238 3rd Qu.:0.3020 3rd Qu.:3.350
## Max. :3.2935 Max. :0.4180 Max. :5.990
## Giai.doan Quy.mo.doanh.thu Hieu.suat.su.dung.TS
## Length:10 Nhỏ :3 Min. :0.7767
## Class :character Trung bình:6 1st Qu.:1.3843
## Mode :character Lớn :1 Median :1.7516
## Rất lớn :0 Mean :1.8351
## 3rd Qu.:2.2265
## Max. :3.1235
## Tinh.trang.dong.tien
## Length:10
## Class :character
## Mode :character
##
##
##
Ý Nghĩa Thống Kê - DOANH THU THUẦN: Doanh nghiệp có quy mô lớn với doanh thu trung bình 6.63 tỷ đồng, nhưng biến động rất mạnh (0.63-14.44 tỷ), cho thấy rủi ro kinh doanh cao và tính không ổn định.
LỢI NHUẬN SAU THUẾ: Lợi nhuận trung bình đạt 1.80 tỷ đồng nhưng cực kỳ thất thường (0.13-6.04 tỷ), phản ánh hiệu quả kinh doanh không ổn định theo thời gian.
TỔNG NỢ PHẢI TRẢ: Cơ cấu nợ tương đối ổn định (1.91 tỷ trung bình), cho thấy quản lý nợ có kế hoạch và biến động trong tầm kiểm soát.
VỐN CHỦ SỞ HỮU: Vốn tăng trưởng mạnh mẽ và bền vững (0.33-3.80 tỷ), chứng tỏ nền tảng tài chính ngày càng vững chắc.
=> ĐÁNH GIÁ CHUNG: Doanh nghiệp có hiệu quả sinh lời cao (biên lợi nhuận 27.1%) và cân đối tài chính tốt, nhưng cần ổn định hoạt động để phát triển bền vững.
##
## 2. DOANH THU TRUNG BÌNH THEO GIAI ĐOẠN:
doanh_thu_giai_doan <- df_clean %>%
group_by(Giai.doan) %>%
summarise(Doanh.thu.TB = mean(Doanh.thu.thuan),
Doanh.thu.TB.formatted = paste0(round(Doanh.thu.TB/1e9, 2), " tỷ"))
print(doanh_thu_giai_doan)## # A tibble: 2 × 3
## Giai.doan Doanh.thu.TB Doanh.thu.TB.formatted
## <chr> <dbl> <chr>
## 1 An toàn 7141385167. 7.14 tỷ
## 2 Rủi ro cao 2036568828 2.04 tỷ
Giải thích kỹ thuật : Đoạn code group_by(Giai.doan) để NHÓM LẠI THEO từng giai đoạn, sau đó summarise(Doanh.thu.TB = mean(Doanh.thu.thuần)) để TÍNH TRUNG BÌNH doanh thu mỗi nhóm, rồi /1e9 để CHIA CHO 1 TỶ đổi sang tỷ đồng, round(…, 2) để LÀM TRÒN 2 SỐ thập phân, cuối cùng paste0(…) để GHÉP CHỮ LẠI với từ ‘tỷ’ thành chuỗi hoàn chỉnh.
Ý nghĩa thống kê : Doanh thu nhóm An toàn (7.14 tỷ) cao gấp 3.5 lần nhóm Rủi ro cao (2.04 tỷ), cho thấy doanh nghiệp an toàn thường có quy mô lớn hơn và cần có chiến lược quản lý rủi ro phù hợp cho từng nhóm.
loi_nhuan_nam <- df_clean %>%
select(Năm, Loi.nhuan.sau.thue) %>%
mutate(Đơn.vị.tỷ = round(Loi.nhuan.sau.thue/1e9, 2))
print(loi_nhuan_nam)## Năm Loi.nhuan.sau.thue Đơn.vị.tỷ
## 1 2014 221424044 0.22
## 2 2016 319528852 0.32
## 3 2017 128396518 0.13
## 4 2018 872807018 0.87
## 5 2019 571557935 0.57
## 6 2020 948071165 0.95
## 7 2021 2513776234 2.51
## 8 2022 6036982867 6.04
## 9 2023 3241661076 3.24
## 10 2024 3107401820 3.11
Giải thích kỹ thuật : Đoạn code sử dụng kỹ thuật select() để chọn hai cột dữ liệu quan trọng là Năm và Lợi nhuận sau thuế, sau đó dùng mutate() để tạo cột mới “Đơn.vị.tỷ” bằng cách chuyển đổi đơn vị từ đồng sang tỷ đồng và làm tròn đến 2 chữ số thập phân. Toàn bộ quy trình được kết nối liên hoàn thông qua toán tử pipe (%>%), giúp code trở nên rõ ràng và hiệu quả. Kết quả là một bảng dữ liệu gọn nhẹ, tối ưu cho việc phân tích xu hướng lợi nhuận qua các năm.
Ý nghĩa thống kê :Lợi nhuận sau thuế cho thấy xu hướng tăng trưởng mạnh mẽ, đặc biệt bứt phá từ năm 2021 và đạt đỉnh 6.04 tỷ vào năm 2022. Dù có điều chỉnh nhẹ trong hai năm gần đây, doanh nghiệp vẫn duy trì được mức lợi nhuận cao trên 3 tỷ, phản ánh hiệu quả kinh doanh được cải thiện rõ rệt và bền vững.
ty_le_no_tb <- mean(df_clean$Ty.le.no.tren.VCSH, na.rm = TRUE)
cat("Trung bình:", round(ty_le_no_tb, 2), "\n")## Trung bình: 1.44
Giải thích kỹ thuật : Đoạn code tính toán và hiển thị tỷ lệ nợ trên vốn chủ sở hữu trung bình, một chỉ số quan trọng để đánh giá mức độ sử dụng đòn bẩy tài chính và rủi ro của doanh nghiệp.
Ý nghĩa thống kê :Chỉ số trung bình 1.44 cho thấy doanh nghiệp có tổng nợ bằng 144% vốn chủ sở hữu, nghĩa là đang vay nợ vượt 44% so với số vốn thực có của chủ sở hữu.
##
## 5. BIÊN LỢI NHUẬN RÒNG THEO NĂM (%):
bien_loi_nhuan <- df_clean %>%
select(Năm, Bien.loi.nhuan.rong) %>%
mutate(Đơn.vị.phần.trăm = round(Bien.loi.nhuan.rong * 100, 1))
print(bien_loi_nhuan)## Năm Bien.loi.nhuan.rong Đơn.vị.phần.trăm
## 1 2014 0.1087241 10.9
## 2 2016 0.1218573 12.2
## 3 2017 0.2052404 20.5
## 4 2018 0.1433148 14.3
## 5 2019 0.1122767 11.2
## 6 2020 0.1520203 15.2
## 7 2021 0.2632120 26.3
## 8 2022 0.4179546 41.8
## 9 2023 0.3325458 33.3
## 10 2024 0.3149935 31.5
Giải thích kỹ thuật : Đoạn code sử dụng pipe operator (%>%) để kết nối các thao tác: đầu tiên dùng hàm select() để chọn hai cột Năm và Bien.loi.nhuan.rong, sau đó áp dụng hàm mutate() để tạo cột mới Đơn.vị.phần.trăm bằng cách nhân giá trị biên lợi nhuận ròng với 100 và làm tròn đến 1 chữ số thập phân, giúp chuyển đổi dữ liệu từ dạng thập phân sang phần trăm để đánh giá hiệu quả sinh lời của doanh nghiệp qua các năm.
Ý nghĩa thống kê : Biên lợi nhuận ròng của doanh nghiệp cho thấy xu hướng tăng trưởng ấn tượng, đặc biệt trong giai đoạn 2021-2024 khi duy trì ở mức trên 26% và đạt đỉnh 41.8% vào năm 2022. Điều này phản ánh hiệu quả quản lý chi phí và khả năng sinh lời ngày càng được cải thiện, với lợi nhuận trên mỗi đồng doanh thu tăng gần 4 lần so với năm 2014.
kha_nang_thanh_toan <- df_clean %>%
select(Năm, Kha.nang.thanh.toan.ngan.han) %>%
summarise(Trung.binh = mean(Kha.nang.thanh.toan.ngan.han),
Cao.nhat = max(Kha.nang.thanh.toan.ngan.han),
Thap.nhat = min(Kha.nang.thanh.toan.ngan.han))
print(kha_nang_thanh_toan)## Trung.binh Cao.nhat Thap.nhat
## 1 2.586431 5.990143 1.270086
Giải thích kỹ thuật : Đoạn code sử dụng hàm select() để lọc và giữ lại hai cột dữ liệu quan trọng là Năm và Khả năng thanh toán ngắn hạn, sau đó dùng hàm summarise() kết hợp với toán tử pipe %>% để tính toán ba chỉ số thống kê chính: giá trị trung bình (mean), giá trị cao nhất (max) và giá trị thấp nhất (min) của khả năng thanh toán ngắn hạn qua các năm.
Ý nghĩa thống kê : Chỉ số khả năng thanh toán ngắn hạn trung bình là 2.59, dao động từ 1.27 đến 5.99, cho thấy doanh nghiệp luôn duy trì được khả năng thanh toán các khoản nợ ngắn hạn ở mức an toàn (trên 1) trong suốt thời gian qua.
##
## PHÂN PHỐI DOANH THU THEO QUY MÔ:
##
## Nhỏ Trung bình Lớn Rất lớn
## 3 6 1 0
Giải thích kỹ thuật : Đoạn code sử dụng hàm table() để thống kê tần suất phân phối doanh thu theo các nhóm quy mô đã được phân loại trước đó, giúp xác định số lượng năm doanh nghiệp hoạt động ở mỗi mức quy mô như nhỏ, trung bình, lớn và rất lớn.
Ý nghĩa thống kê : Doanh nghiệp chủ yếu hoạt động ở quy mô nhỏ và trung bình (chiếm 9/10 năm), trong đó có 6 năm ở mức trung bình, 3 năm ở mức nhỏ và chỉ có 1 năm đạt quy mô lớn, cho thấy đây vẫn là một doanh nghiệp có quy mô khiêm tốn.
cor_doanh_thu_loi_nhuan <- cor(df_clean$Doanh.thu.thuan, df_clean$Loi.nhuan.sau.thue)
cat("Hệ số tương quan:", round(cor_doanh_thu_loi_nhuan, 3), "\n")## Hệ số tương quan: 0.947
Giải thích kỹ thuật : Đoạn code sử dụng hàm cor() để tính hệ số tương quan giữa doanh thu thuần và lợi nhuận sau thuế, sau đó làm tròn kết quả đến 3 chữ số thập phân bằng hàm round().
Ý nghĩa thống kê : Với hệ số tương quan 0.947, cho thấy mối quan hệ thuận cực kỳ chặt chẽ giữa doanh thu và lợi nhuận - khi doanh thu tăng thì lợi nhuận cũng tăng theo một cách rất đồng đều và có thể dự báo được.
tang_truong <- df_clean %>%
arrange(Năm) %>%
mutate(Tang.truong.doanh.thu = (Doanh.thu.thuan / lag(Doanh.thu.thuan) - 1) * 100) %>%
replace_na(list(Tang.truong.doanh.thu = 0)) %>%
select(Năm, Tang.truong.doanh.thu)
print(tang_truong)## Năm Tang.truong.doanh.thu
## 1 2014 0.000000
## 2 2016 28.753627
## 3 2017 -76.142123
## 4 2018 873.502205
## 5 2019 -16.412130
## 6 2020 22.509268
## 7 2021 53.137462
## 8 2022 51.241115
## 9 2023 -32.512184
## 10 2024 1.199783
Giải thích kỹ thuật: Đoạn code sử dụng hàm
arrange() để sắp xếp dữ liệu theo năm, hàm
mutate() với phép tính
(Doanh.thu.thuần / lag(Doanh.thu.thuần) - 1) * 100 để tính
phần trăm tăng trưởng doanh thu so với năm trước, hàm
replace_na() để thay thế giá trị NA bằng 0, và hàm
select() để chọn các cột cần hiển thị.
Ý nghĩa thống kê: Kết quả cho thấy doanh thu có sự biến động rất mạnh, từ mức tăng trưởng âm sâu -76.14% (2017) đến mức tăng đột biến 873.5% (2018), phản ánh tính không ổn định trong hoạt động kinh doanh của doanh nghiệp qua các năm.
##
## Tích cực Tiêu cực
## 3 7
Giải thích kỹ thuật: Đoạn code sử dụng hàm table() để thống kê tần suất xuất hiện của các trạng thái dòng tiền đã được mã hóa trước đó.
Ý nghĩa thống kê: Kết quả cho thấy tình trạng đáng quan ngại khi 7/10 năm doanh nghiệp có dòng tiền thuần âm, phản ánh khả năng tạo ra dòng tiền từ hoạt động kinh doanh còn hạn chế và thiếu ổn định.
## ĐẦU TƯ TSCĐ TRUNG BÌNH (tỷ đồng):
dau_tu_TSCD_tb <- mean(abs(df_clean$Mua.sam.TSCD))/1e9
cat("Trung bình:", round(dau_tu_TSCD_tb, 2), "tỷ/năm\n")## Trung bình: 0.24 tỷ/năm
Giải thích kỹ thuật: Đoạn code sử dụng hàm
mean(abs()) để tính giá trị trung bình của các khoản đầu tư
vào TSCĐ (bỏ qua dấu âm), sau đó chia cho 1e9 để chuyển đổi đơn vị sang
tỷ đồng.
Ý nghĩa thống kê: Kết quả cho thấy doanh nghiệp đầu tư trung bình 0.24 tỷ đồng mỗi năm vào TSCĐ, phản ánh mức độ đầu tư cơ sở vật chất khá khiêm tốn và có thể ảnh hưởng đến năng lực sản xuất trong tương lai.
## HIỆU SUẤT SỬ DỤNG TÀI SẢN:
hieu_suat_TB <- mean(df_clean$Hieu.suat.su.dung.TS, na.rm = TRUE)
cat("Trung bình:", round(hieu_suat_TB, 2), "\n")## Trung bình: 1.84
Giải thích kỹ thuật: Đoạn code sử dụng hàm
mean() với tham số na.rm = TRUE để tính giá
trị trung bình của chỉ số hiệu suất sử dụng tài sản, tự động loại bỏ các
giá trị missing.
Ý nghĩa thống kê: Chỉ số trung bình 1.84 cho thấy mỗi đồng tài sản tạo ra 1.84 đồng doanh thu, phản ánh hiệu quả sử dụng tài sản của doanh nghiệp ở mức khá tốt.
## NĂM CÓ LỢI NHUẬN CAO NHẤT:
nam_loi_nhuan_max <- df_clean[which.max(df_clean$Loi.nhuan.sau.thue), c("Năm", "Loi.nhuan.sau.thue")]
print(nam_loi_nhuan_max)## Năm Loi.nhuan.sau.thue
## 8 2022 6036982867
Giải thích kỹ thuật: Đoạn code sử dụng hàm
which.max() để tìm vị trí có giá trị lợi nhuận sau thuế cao
nhất, sau đó dùng indexing [ , c()] để trích xuất thông tin
năm và giá trị lợi nhuận tương ứng.
Ý nghĩa thống kê: Kết quả xác định năm 2022 là năm có lợi nhuận đỉnh điểm với 6.037 tỷ đồng, đánh dấu hiệu quả kinh doanh tốt nhất trong cả giai đoạn phân tích.
## NĂM CÓ DOANH THU CAO NHẤT:
nam_doanh_thu_max <- df_clean[which.max(df_clean$Doanh.thu.thuan), c("Năm", "Doanh.thu.thuan")]
print(nam_doanh_thu_max)## Năm Doanh.thu.thuan
## 8 2022 14444110661
Giải thích kỹ thuật: Đoạn code sử dụng hàm
which.max() để xác định vị trí có doanh thu thuần cao nhất,
sau đó dùng indexing để trích xuất thông tin năm và giá trị doanh thu
tương ứng từ dataframe.
Ý nghĩa thống kê: Kết quả cho thấy năm 2022 là năm đạt doanh thu cao nhất với 14.444 tỷ đồng, trùng với năm có lợi nhuận đỉnh điểm, chứng tỏ đây là giai đoạn kinh doanh hiệu quả nhất của doanh nghiệp.
## TỶ LỆ LỢI NHUẬN GIỮ LẠI:
ty_le_loi_nhuan_giu_lai <- df_clean %>%
mutate(Ty.le.giu.lai = Loi.nhuan.sau.thue / (Loi.nhuan.sau.thue + abs(Mua.sam.TSCD))) %>%
select(Năm, Ty.le.giu.lai)
print(ty_le_loi_nhuan_giu_lai)## Năm Ty.le.giu.lai
## 1 2014 0.3874741
## 2 2016 0.7313726
## 3 2017 0.9413727
## 4 2018 0.6841978
## 5 2019 0.8378976
## 6 2020 0.7958023
## 7 2021 0.9086598
## 8 2022 0.9745810
## 9 2023 0.9281850
## 10 2024 0.8561740
Giải thích kỹ thuật: Đoạn code sử dụng hàm
mutate() để tạo biến mới “Ty.le.giu.lai” bằng công thức lấy
lợi nhuận sau thuế chia cho tổng của lợi nhuận sau thuế và giá trị tuyệt
đối của đầu tư TSCĐ, sau đó dùng select() để hiển thị kết
quả.
Ý nghĩa thống kê: Tỷ lệ giữ lại lợi nhuận dao động từ 38.7% đến 97.5%, cho thấy doanh nghiệp ngày càng sử dụng hiệu quả hơn phần lợi nhuận để tái đầu tư thay vì chi tiêu cho TSCĐ, đặc biệt từ năm 2017 trở đi duy trì ở mức trên 68%.’
##
## 16. CƠ CẤU NGUỒN VỐN TRUNG BÌNH:
co_cau_von <- df_clean %>%
summarise(Ty.le.no.TB = mean(Tong.No.phai.tra/(Tong.No.phai.tra + Von.chu.so.huu)),
Ty.le.VCSH.TB = mean(Von.chu.so.huu/(Tong.No.phai.tra + Von.chu.so.huu)))
print(co_cau_von)## Ty.le.no.TB Ty.le.VCSH.TB
## 1 0.555659 0.444341
Giải thích kỹ thuật: Đoạn code sử dụng hàm
summarise() để tính toán đồng thời hai tỷ lệ trung bình: tỷ
lệ nợ và tỷ lệ vốn chủ sở hữu trên tổng nguồn vốn, dựa trên công thức
tài chính chuẩn.
Ý nghĩa thống kê: Kết quả cho thấy cơ cấu nguồn vốn với 55.6% từ nợ vay và 44.4% từ vốn chủ, phản ánh doanh nghiệp đang sử dụng đòn bẩy tài chính ở mức khá cao, với nợ chiếm ưu thế hơn vốn tự có.
tien_mat <- df_clean %>%
select(Năm, Tiền.va.Tuong.duong.tien) %>%
mutate(Đơn.vị.tỷ = round(Tiền.va.Tuong.duong.tien/1e9, 2))
print(tien_mat)## Năm Tiền.va.Tuong.duong.tien Đơn.vị.tỷ
## 1 2014 8391782 0.01
## 2 2016 186282852 0.19
## 3 2017 82619006 0.08
## 4 2018 274286867 0.27
## 5 2019 127679694 0.13
## 6 2020 282319770 0.28
## 7 2021 123957761 0.12
## 8 2022 1535474845 1.54
## 9 2023 1060574919 1.06
## 10 2024 115781848 0.12
Giải thích kỹ thuật: Đoạn code sử dụng hàm
select() để chọn các cột cần thiết và mutate()
để tạo cột mới với đơn vị tỷ đồng bằng cách chia giá trị gốc cho 1e9 và
làm tròn 2 số thập phân.
Ý nghĩa thống kê: Số dư tiền mặt biến động mạnh qua các năm, đặc biệt tăng vọt trong năm 2022-2023 (trên 1 tỷ) so với các năm trước đó (dưới 0.3 tỷ), phản ánh sự thay đổi đáng kể trong khả năng thanh khoản ngắn hạn của doanh nghiệp.
##
## 18. TƯƠNG QUAN ĐẦU TƯ VÀ TĂNG TRƯỞNG:
cor_dau_tu_tang_truong <- cor(abs(df_clean$Mua.sam.TSCD), df_clean$Doanh.thu.thuan)
cat("Hệ số tương quan:", round(cor_dau_tu_tang_truong, 3), "\n")## Hệ số tương quan: 0.309
Giải thích kỹ thuật: Đoạn code sử dụng hàm
cor() để tính hệ số tương quan giữa giá trị tuyệt đối của
đầu tư TSCĐ và doanh thu thuần, sau đó làm tròn kết quả đến 3 chữ số
thập phân.
Ý nghĩa thống kê: Hệ số tương quan 0.30 (khoảng từ 0.2 - 0.4) cho thấy mối quan hệ thuận yếu giữa đầu tư TSCĐ và tăng trưởng doanh thu, nghĩa là việc tăng đầu tư vào tài sản cố định chỉ có tác động ở mức độ vừa phải đến việc gia tăng doanh thu của doanh nghiệp.
##
## 19. CHỈ SỐ TRUNG BÌNH THEO QUY MÔ DOANH THU:
chi_so_theo_quy_mo <- df_clean %>%
group_by(Quy.mo.doanh.thu) %>%
summarise(Doanh.thu.TB = mean(Doanh.thu.thuan),
Loi.nhuan.TB = mean(Loi.nhuan.sau.thue),
Bien.loi.nhuan.TB = mean(Bien.loi.nhuan.rong))
print(chi_so_theo_quy_mo)## # A tibble: 3 × 4
## Quy.mo.doanh.thu Doanh.thu.TB Loi.nhuan.TB Bien.loi.nhuan.TB
## <fct> <dbl> <dbl> <dbl>
## 1 Nhỏ 1761438621. 223116471. 0.145
## 2 Trung bình 7763434802. 1875879208 0.220
## 3 Lớn 14444110661 6036982867 0.418
Giải thích kỹ thuật: Đoạn code sử dụng
group_by() để nhóm dữ liệu theo quy mô doanh thu, sau đó
dùng summarise() để tính các chỉ số trung bình gồm doanh
thu, lợi nhuận và biên lợi nhuận ròng cho từng nhóm.
Ý nghĩa thống kê: Kết quả cho thấy mối quan hệ tỷ lệ thuận rõ rệt giữa quy mô và hiệu quả kinh doanh - khi quy mô doanh thu tăng dần từ Nhỏ đến Lớn thì lợi nhuận và biên lợi nhuận cũng tăng theo, đặc biệt ở nhóm Lớn có biên lợi nhuận cao nhất (41.8%).
xep_hang_hieu_qua <- df_clean %>%
mutate(Xep.hang = rank(-Bien.loi.nhuan.rong)) %>% # Thêm cột xếp hạng
arrange(Năm) %>% # Vẫn sắp xếp theo năm
select(Năm, Bien.loi.nhuan.rong, Xep.hang) %>%
mutate(Đơn.vị.phần.trăm = round(Bien.loi.nhuan.rong * 100, 1))
print(xep_hang_hieu_qua)## Năm Bien.loi.nhuan.rong Xep.hang Đơn.vị.phần.trăm
## 1 2014 0.1087241 10 10.9
## 2 2016 0.1218573 8 12.2
## 3 2017 0.2052404 5 20.5
## 4 2018 0.1433148 7 14.3
## 5 2019 0.1122767 9 11.2
## 6 2020 0.1520203 6 15.2
## 7 2021 0.2632120 4 26.3
## 8 2022 0.4179546 1 41.8
## 9 2023 0.3325458 2 33.3
## 10 2024 0.3149935 3 31.5
Giải thích kỹ thuật: Đoạn code sử dụng
mutate() với hàm rank(-Bien.loi.nhuan.rong) để
tạo cột xếp hạng theo biên lợi nhuận giảm dần, sau đó
arrange(Năm) giữ nguyên thứ tự thời gian và
select() chọn các cột cần hiển thị.
Ý nghĩa thống kê: Kết quả cho thấy rõ xu hướng cải thiện hiệu quả kinh doanh theo thời gian - các năm gần đây (2022-2024) chiếm 3 vị trí dẫn đầu với biên lợi nhuận trên 30%, trong khi các năm cũ hơn (2014-2020) xếp cuối bảng với biên lợi nhuận dưới 21%.
p21 <- ggplot(df_clean, aes(x = .data[["Năm"]], y = .data[["Doanh.thu.thuan"]]/1e9)) +
geom_line(color = "blue", size = 1.5) +
geom_point(color = "red", size = 3) +
geom_area(fill = "lightblue", alpha = 0.3) +
geom_smooth(method = "lm", se = FALSE, color = "darkgreen", linetype = "dashed") +
labs(title = "XU HƯỚNG DOANH THU QUA CÁC NĂM",
x = "Năm", y = "Doanh thu thuần") +
theme_minimal()
print(p21)font_add(family = "arial", regular = "arial.ttf")
showtext_auto()
p21 <- ggplot(df_clean, aes(x = .data[["Năm"]], y = .data[["Loi.nhuan.sau.thue"]]/1e9)) +
geom_line(color = "blue", size = 1.5) +
geom_point(color = "red", size = 3) +
geom_area(fill = "lightblue", alpha = 0.3) +
geom_smooth(method = "lm", se = FALSE, color = "darkgreen", linetype = "dashed") +
labs(title = "XU HƯỚNG LỢI NHUẬN SAU THUẾ QUA CÁC NĂM",
x = "Năm",
y = "Lợi nhuận sau thuế (tỷ đồng)") +
theme_minimal() +
theme(
plot.title = element_text(size = 16, face = "bold", hjust = 0.5),
axis.title = element_text(size = 12)
)
print(p21)Giải thích kỹ thuật: Đoạn code sử dụng kết hợp geom_col() để vẽ biểu đồ cột, geom_line() và geom_point() để thể hiện xu hướng, geom_text() để hiển thị giá trị, và geom_hline() để vẽ đường trung bình.
Ý nghĩa thống kê: Biểu đồ cho thấy lợi nhuận sau thuế có xu hướng tăng trưởng mạnh mẽ qua các năm, đặc biệt bứt phá từ năm 2021 và đạt đỉnh vào năm 2022, phản ánh hiệu quả kinh doanh được cải thiện rõ rệt.
p23 <- ggplot(df_clean, aes(x = .data[["Năm"]], y = .data[["Bien.loi.nhuan.rong"]] * 100)) +
geom_line(color = "purple", size = 1.5) +
geom_point(color = "orange", size = 3) +
geom_area(fill = "lightpurple", alpha = 0.3) +
geom_hline(yintercept = mean(df[["Bien.loi.nhuan.rong"]] * 100, na.rm = TRUE),
linetype = "dashed", color = "red") +
geom_text(aes(label = paste0(round(.data[["Bien.loi.nhuan.rong"]] * 100, 1), "%")),
vjust = -0.8, size = 3.5, fontface = "bold") +
labs(title = "BIÊN LỢI NHUẬN RÒNG",
subtitle = "Tỷ lệ phần trăm (%)",
x = "Năm",
y = "Biên lợi nhuận (%)",
caption = "Nguồn: Dữ liệu tài chính DGC") +
theme_minimal()
print(p23)Giải thích kỹ thuật : Đoạn code này sử dụng thư viện ggplot2 để xây dựng một biểu đồ đường (geom_line) kết hợp với các điểm dữ liệu (geom_point), nhằm trực quan hóa xu hướng biến động của Biên lợi nhuận ròng qua các năm. Để làm nổi bật diện tích dưới đường biểu diễn, lệnh geom_area được dùng để tô màu vùng phía dưới, giúp người xem dễ dàng quan sát được quy mô của xu hướng. Ngoài ra, một đường tham chiếu nằm ngang (geom_hline) được vẽ để biểu thị mức giá trị trung bình của toàn bộ chuỗi dữ liệu, cung cấp một ngưỡng so sánh trực quan cho từng năm.
Ý nghĩa thống kê : Biên lợi nhuận ròng biến động mạnh qua các năm, từ mức thấp 10.9% (2014) lên đỉnh 20.8% (2022) - chênh lệch gần 10 điểm phần trăm. Mức trung bình toàn giai đoạn là 15.5%. Xu hướng chung là cải thiện rõ rệt, cho thấy khả năng kiểm soát chi phí và hiệu quả quản lý ngày càng tốt hơn.
p24 <- ggplot(df_clean, aes(x = Năm)) +
geom_col(aes(y = Tong.No.phai.tra/1e9, fill = "Nợ phải trả"), alpha = 0.7) +
geom_col(aes(y = Von.chu.so.huu/1e9, fill = "Vốn chủ sở hữu"), alpha = 0.7) +
geom_line(aes(y = (Tong.No.phai.tra + Von.chu.so.huu)/1e9, color = "Tổng nguồn vốn"), size = 1) +
geom_point(aes(y = (Tong.No.phai.tra + Von.chu.so.huu)/1e9, color = "Tổng nguồn vôn"), size = 2) +
geom_text(aes(y = (Tong.No.phai.tra + Von.chu.so.huu)/1e9,
label = round((Tong.No.phai.tra + Von.chu.so.huu)/1e9, 1)),
vjust = -1, size = 3) +
labs(title = "CƠ CẤU NGUỒN VỐN QUA CÁC NĂM",
x = "Năm", y = "Giá trị (tỷ đồng)", fill = "Thành phần") +
scale_fill_manual(values = c("Nợ phải trả" = "red", "Vốn chủ sở hữu" = "blue")) +
scale_color_manual(values = c("Tổng nguồn vốn" = "black")) +
theme_minimal()
print(p24)Giải thích kỹ thuật : Đây là biểu đồ cột chồng. Biểu đồ sử dụng nhiều layer geom kết hợp trên cùng một trục tọa độ. Code dùng geom_col() hai lần để tạo cột chồng cho nợ và vốn chủ sở hữu. Kỹ thuật aesthetic mapping được sử dụng để gán màu sắc khác nhau cho từng thành phần. Đường tổng được vẽ bằng geom_line() kết hợp geom_point() để làm nổi bật xu hướng. geom_text() được dùng để hiển thị giá trị tổng với vjust = -1 để đẩy text lên phía trên. Scale được chuẩn hóa bằng cách chia cho 1e9 để chuyển đơn vị sang tỷ đồng. Thủ thuật scale_fill_manual() và scale_color_manual() cho phép tùy chỉnh màu sắc theo ý muốn. Theme_minimal() được áp dụng để tối giản hóa background, giúp dữ liệu nổi bật hơn.
Ý nghĩa thống kê: Biểu đồ cho thấy tổng nguồn vốn tăng trưởng ấn tượng từ khoảng 1,438 tỷ đồng (2014) lên gần 6,000 tỷ đồng (2024), tăng hơn 4 lần sau 10 năm. Vốn chủ sở hữu tăng mạnh từ 335 tỷ đồng (2014) lên 3,798 tỷ đồng (2024), chiếm tỷ trọng ngày càng lớn từ 23% (2014) lên khoảng 63% (2024). Tổng nợ phải trả cũng tăng từ 1,103 tỷ (2014) lên 2,132 tỷ (2024) nhưng tốc độ chậm hơn so với vốn chủ sở hữu. Tỷ lệ nợ trên vốn chủ sở hữu giảm từ 3.3 lần (2014) xuống còn 0.56 lần (2024), cho thấy cơ cấu tài chính chuyển dịch lành mạnh, giảm phụ thuộc vào đòn bẩy nợ và tăng cường năng lực tự chủ tài chính.
p25 <- ggplot(df_clean, aes(x = Năm, y = Kha.nang.thanh.toan.ngan.han)) +
geom_col(fill = "lightgreen", alpha = 0.7) +
geom_line(color = "darkgreen", size = 1) +
geom_point(color = "red", size = 2) +
geom_hline(yintercept = 1, linetype = "dashed", color = "red", size = 1) +
geom_text(aes(label = round(Kha.nang.thanh.toan.ngan.han, 2)), vjust = -0.5, size = 3) +
labs(title = "KHẢ NĂNG THANH TOÁN NGẮN HẠN",
x = "Năm", y = "Hệ số thanh toán") +
theme_minimal()
print(p25)Giải thích kỹ thuật : Đoạn code này sử dụng kết hợp năm
kỹ thuật visualization: geom_col() tạo cột màu xanh,
geom_line() và geom_point() vẽ đường xu hướng,
geom_hline() đánh dấu ngưỡng an toàn bằng đường đỏ đứt, và
geom_text() hiển thị giá trị cụ thể, giúp đánh giá toàn
diện khả năng thanh toán ngắn hạn so với mức chuẩn qua các năm.
Ý nghĩa thống kê : Biểu đồ cho thấy khả năng thanh toán ngắn hạn của doanh nghiệp luôn duy trì trên ngưỡng an toàn (lớn hơn 1) trong tất cả các năm, với mức cao nhất đạt 5.99 vào năm 2016 và thấp nhất là 1.27 vào năm 2023, phản ánh khả năng đáp ứng các khoản nợ ngắn hạn ở mức tốt dù có biến động qua các thời kỳ.
p26 <- ggplot(df_clean, aes(x = Năm, y = Ty.le.no.tren.VCSH)) +
geom_col(fill = "orange", alpha = 0.7) +
geom_line(color = "red", size = 1) +
geom_point(color = "darkred", size = 2) +
geom_hline(yintercept = 1, linetype = "dashed", color = "red", size = 1) +
geom_text(aes(label = round(Ty.le.no.tren.VCSH, 2)), vjust = -0.5, size = 3) +
labs(title = "TỶ LỆ NỢ TRÊN VỐN CHỦ SỞ HỮU",
x = "Năm", y = "Tỷ lệ") +
theme_minimal()
print(p26)Giải thích kỹ thuật : Đoạn code này sử dụng kết hợp biểu đồ cột (geom_col), đường xu hướng (geom_line, geom_point), đường tham chiếu ngưỡng an toàn (geom_hline) và nhãn giá trị (geom_text) để trực quan hóa tỷ lệ nợ trên vốn chủ sở hữu qua các năm.
Ý nghĩa thống kê: Tỷ lệ nợ trên VCSH có xu hướng giảm mạnh và cải thiện tích cực qua các năm, từ mức cao trên 1.8 (2014-2019) xuống chỉ còn 0.56 vào năm 2024, cho thấy doanh nghiệp đang dần giảm sự phụ thuộc vào vay nợ và tăng cường nguồn vốn tự chủ, qua đó hạ thấp rủi ro tài chính.
p27 <- ggplot(df_clean, aes(x = Năm, y = LCTT.tu.HĐKD/1e9)) +
geom_col(aes(fill = LCTT.tu.HĐKD > 0), alpha = 0.7) +
geom_line(color = "blue", size = 1) +
geom_point(color = "darkblue", size = 2) +
geom_hline(yintercept = 0, linetype = "solid", color = "black") +
geom_text(aes(label = round(LCTT.tu.HĐKD/1e9, 1)), vjust = -0.5, size = 3) +
labs(title = "DÒNG TIỀN TỪ HOẠT ĐỘNG KINH DOANH",
x = "Năm", y = "Dòng tiền (tỷ đồng)") +
scale_fill_manual(values = c("TRUE" = "green", "FALSE" = "red")) +
theme_minimal() +
theme(legend.position = "none")
print(p27)Giải thích kỹ thuật: Đoạn code này sử dụng kết hợp geom_col() với màu sắc có điều kiện (xanh cho dòng tiền dương, đỏ cho âm), geom_line() và geom_point() để thể hiện xu hướng, cùng geom_hline() đánh dấu mức 0 và geom_text() hiển thị giá trị, giúp trực quan hóa biến động dòng tiền hoạt động kinh doanh qua các năm.
Ý nghĩa thống kê: Dòng tiền từ hoạt động kinh doanh có sự biến động mạnh, chủ yếu ở mức dương nhưng có một năm âm (2017) và đặc biệt tăng trưởng ấn tượng trong 3 năm gần nhất (2022-2024), đạt đỉnh 3.1 tỷ đồng vào năm 2024, phản ánh khả năng tạo ra dòng tiền từ hoạt động cốt lõi ngày càng được cải thiện và ổn định.
p28 <- ggplot(df_clean, aes(x = Năm, y = abs(Mua.sam.TSCD)/1e9)) +
geom_col(fill = "brown", alpha = 0.7) +
geom_line(color = "darkred", size = 1) +
geom_point(color = "red", size = 2) +
geom_text(aes(label = round(abs(Mua.sam.TSCD)/1e9, 1)), vjust = -0.5, size = 3) +
geom_smooth(method = "lm", se = FALSE, color = "blue", linetype = "dashed") +
labs(title = "ĐẦU TƯ TÀI SẢN CỐ ĐỊNH",
x = "Năm", y = "Giá trị đầu tư (tỷ đồng)") +
theme_minimal()
print(p28)Giải thích kỹ thuật: Đoạn code này sử dụng kết hợp
geom_col() để vẽ cột thể hiện giá trị đầu tư TSCĐ,
geom_line() và geom_point() để hiển thị xu
hướng biến động, geom_text() để ghi nhãn giá trị cụ thể,
cùng geom_smooth() vẽ đường xu hướng tổng quan, giúp phân
tích biến động và xu hướng đầu tư tài sản cố định qua các năm.
Ý nghĩa thống kê : Đầu tư TSCĐ có sự biến động thất thường qua các năm, với các đỉnh cao vào năm 2014 (0.35 tỷ), 2018 (0.4 tỷ) và 2022 (0.4 tỷ), trong khi các năm còn lại đầu tư ở mức khá thấp (dưới 0.12 tỷ), cho thấy doanh nghiệp có xu hướng đầu tư không ổn định và theo từng đợt riêng lẻ thay vì duy trì đều đặn.
p29 <- ggplot(df_clean, aes(x = Doanh.thu.thuan/1e9, y = Loi.nhuan.sau.thue/1e9)) +
geom_point(aes(color = as.factor(Năm), size = Loi.nhuan.sau.thue/1e9)) +
geom_smooth(method = "lm", se = TRUE, color = "red", linetype = "dashed") +
geom_text(aes(label = Năm), vjust = -0.5, size = 3) +
geom_abline(intercept = 0, slope = 0.1, linetype = "dotted", color = "blue") +
geom_vline(xintercept = mean(df_clean$Doanh.thu.thuan/1e9), linetype = "dashed", color = "gray") +
labs(title = "TƯƠNG QUAN DOANH THU - LỢI NHUẬN",
x = "Doanh thu (tỷ đồng)", y = "Lợi nhuận (tỷ đồng)") +
theme_minimal()
print(p29)Giải thích kỹ thuật : Đoạn code này sử dụng
geom_point() với kích thước và màu sắc theo năm để thể hiện
từng quan sát, kết hợp geom_smooth() vẽ đường hồi quy,
geom_text() ghi nhãn năm, geom_abline() đánh
dấu tỷ lệ lợi nhuận/doanh thu 10% và geom_vline() hiển thị
doanh thu trung bình, giúp phân tích mối tương quan giữa doanh thu và
lợi nhuận.
Ý nghĩa thống kê : Biểu đồ cho thấy mối tương quan thuận rõ rệt giữa doanh thu và lợi nhuận - khi doanh thu tăng thì lợi nhuận cũng tăng theo. Các năm 2022-2024 tập trung ở góc trên bên phải với cả doanh thu và lợi nhuận cao nhất, trong khi các năm 2014-2017 nằm ở khu vực có quy mô nhỏ hơn. Đường hồi quy dốc lên khẳng định xu hướng tích cực này.
p30 <- ggplot(df_clean, aes(x = Quy.mo.doanh.thu, y = Doanh.thu.thuan/1e9)) +
geom_boxplot(fill = "lightblue", alpha = 0.7) +
geom_jitter(aes(color = as.factor(Năm)), size = 3, width = 0.2) +
geom_point(stat = "summary", fun = "mean", color = "red", size = 4, shape = 18) +
geom_text(stat = "summary", fun = "mean", aes(label = round(..y.., 1)),
vjust = -1, size = 3, color = "red") +
geom_hline(yintercept = mean(df_clean$Doanh.thu.thuan/1e9), linetype = "dashed", color = "green") +
labs(title = "PHÂN BỐ DOANH THU THEO QUY MÔ",
x = "Quy mô doanh thu", y = "Doanh thu (tỷ đồng)") +
theme_minimal()
print(p30)Giải thích kỹ thuật : Đoạn code này sử dụng
geom_boxplot() để hiển thị phân bố doanh thu theo nhóm quy
mô, kết hợp geom_jitter() hiển thị từng năm,
geom_point() đánh dấu giá trị trung bình mỗi nhóm,
geom_text() ghi nhãn giá trị trung bình, và
geom_hline() vẽ đường trung bình tổng thể, giúp so sánh
trực quan phân bố doanh thu giữa các nhóm quy mô.
Ý nghĩa thống kê : Biểu đồ cho thấy sự phân bố doanh thu rõ rệt theo quy mô: nhóm “Nhỏ” có doanh thu tập trung dưới 2 tỷ, nhóm “Trung bình” dao động từ 5-10 tỷ, và nhóm “Lớn” đạt 14.4 tỷ. Các năm 2022-2024 thuộc nhóm trung bình và lớn, trong khi các năm trước chủ yếu ở nhóm nhỏ, phản ánh xu hướng tăng trưởng quy mô doanh thu qua thời gian.
cor_matrix <- cor(df_clean[, sapply(df_clean, is.numeric)], use = "complete.obs")
p31 <- corrplot(cor_matrix, method = "color", type = "upper",
tl.cex = 0.8, tl.col = "black",
addCoef.col = "black", number.cex = 0.7,
title = "MA TRẬN TƯƠNG QUAN CÁC CHỈ SỐ TÀI CHÍNH",
mar = c(0,0,2,0))## $corr
## Tiền.va.Tuong.duong.tien Tai.san.ngan.han
## Tiền.va.Tuong.duong.tien 1.0000000 0.6422053
## Tai.san.ngan.han 0.6422053 1.0000000
## No.ngan.han 0.6921057 0.8744358
## Doanh.thu.thuan 0.7352071 0.8669076
## Loi.nhuan.truoc.thue 0.8289370 0.8765589
## Loi.nhuan.sau.thue 0.8331257 0.8681667
## Tong.No.phai.tra 0.7678772 0.8441601
## Von.chu.so.huu 0.7073725 0.9868598
## LCTT.tu.HĐKD 0.7968398 0.8494423
## LCTT.thuan.trong.ky -0.1029499 -0.7671261
## Mua.sam.TSCD 0.1424165 -0.4050387
## Ty.le.no.tren.VCSH -0.4080277 -0.6293628
## Bien.loi.nhuan.rong 0.7605546 0.8879823
## Kha.nang.thanh.toan.ngan.han 0.4316683 0.9246514
## Hieu.suat.su.dung.TS -0.4247546 -0.8315334
## No.ngan.han Doanh.thu.thuan Loi.nhuan.truoc.thue
## Tiền.va.Tuong.duong.tien 0.6921057 0.7352071 0.8289370
## Tai.san.ngan.han 0.8744358 0.8669076 0.8765589
## No.ngan.han 1.0000000 0.8720475 0.7822637
## Doanh.thu.thuan 0.8720475 1.0000000 0.9463250
## Loi.nhuan.truoc.thue 0.7822637 0.9463250 1.0000000
## Loi.nhuan.sau.thue 0.7798283 0.9470717 0.9998004
## Tong.No.phai.tra 0.9415319 0.9051202 0.8653825
## Von.chu.so.huu 0.8727695 0.8891918 0.8972997
## LCTT.tu.HĐKD 0.7524673 0.9492043 0.9930095
## LCTT.thuan.trong.ky -0.4326058 -0.5078676 -0.5222540
## Mua.sam.TSCD -0.3470142 -0.3090256 -0.1797852
## Ty.le.no.tren.VCSH -0.5453714 -0.5867107 -0.5336798
## Bien.loi.nhuan.rong 0.7364181 0.8447871 0.9433263
## Kha.nang.thanh.toan.ngan.han 0.6491055 0.7651617 0.7994480
## Hieu.suat.su.dung.TS -0.6687346 -0.6070808 -0.6676049
## Loi.nhuan.sau.thue Tong.No.phai.tra Von.chu.so.huu
## Tiền.va.Tuong.duong.tien 0.8331257 0.7678772 0.7073725
## Tai.san.ngan.han 0.8681667 0.8441601 0.9868598
## No.ngan.han 0.7798283 0.9415319 0.8727695
## Doanh.thu.thuan 0.9470717 0.9051202 0.8891918
## Loi.nhuan.truoc.thue 0.9998004 0.8653825 0.8972997
## Loi.nhuan.sau.thue 1.0000000 0.8659518 0.8902429
## Tong.No.phai.tra 0.8659518 1.0000000 0.8383272
## Von.chu.so.huu 0.8902429 0.8383272 1.0000000
## LCTT.tu.HĐKD 0.9935234 0.8313089 0.8727245
## LCTT.thuan.trong.ky -0.5075785 -0.3766624 -0.7297444
## Mua.sam.TSCD -0.1689878 -0.2872837 -0.3379837
## Ty.le.no.tren.VCSH -0.5304298 -0.4206402 -0.7006745
## Bien.loi.nhuan.rong 0.9406865 0.8188056 0.8900543
## Kha.nang.thanh.toan.ngan.han 0.7887527 0.6278144 0.9090820
## Hieu.suat.su.dung.TS -0.6582243 -0.5970346 -0.8049514
## LCTT.tu.HĐKD LCTT.thuan.trong.ky Mua.sam.TSCD
## Tiền.va.Tuong.duong.tien 0.7968398 -0.1029499 0.1424165
## Tai.san.ngan.han 0.8494423 -0.7671261 -0.4050387
## No.ngan.han 0.7524673 -0.4326058 -0.3470142
## Doanh.thu.thuan 0.9492043 -0.5078676 -0.3090256
## Loi.nhuan.truoc.thue 0.9930095 -0.5222540 -0.1797852
## Loi.nhuan.sau.thue 0.9935234 -0.5075785 -0.1689878
## Tong.No.phai.tra 0.8313089 -0.3766624 -0.2872837
## Von.chu.so.huu 0.8727245 -0.7297444 -0.3379837
## LCTT.tu.HĐKD 1.0000000 -0.5209779 -0.1590858
## LCTT.thuan.trong.ky -0.5209779 1.0000000 0.4816909
## Mua.sam.TSCD -0.1590858 0.4816909 1.0000000
## Ty.le.no.tren.VCSH -0.5353749 0.5579128 -0.0751490
## Bien.loi.nhuan.rong 0.9156872 -0.5823773 -0.1112024
## Kha.nang.thanh.toan.ngan.han 0.7912761 -0.9141788 -0.4427096
## Hieu.suat.su.dung.TS -0.6448659 0.6805661 0.2276763
## Ty.le.no.tren.VCSH Bien.loi.nhuan.rong
## Tiền.va.Tuong.duong.tien -0.4080277 0.7605546
## Tai.san.ngan.han -0.6293628 0.8879823
## No.ngan.han -0.5453714 0.7364181
## Doanh.thu.thuan -0.5867107 0.8447871
## Loi.nhuan.truoc.thue -0.5336798 0.9433263
## Loi.nhuan.sau.thue -0.5304298 0.9406865
## Tong.No.phai.tra -0.4206402 0.8188056
## Von.chu.so.huu -0.7006745 0.8900543
## LCTT.tu.HĐKD -0.5353749 0.9156872
## LCTT.thuan.trong.ky 0.5579128 -0.5823773
## Mua.sam.TSCD -0.0751490 -0.1112024
## Ty.le.no.tren.VCSH 1.0000000 -0.5888314
## Bien.loi.nhuan.rong -0.5888314 1.0000000
## Kha.nang.thanh.toan.ngan.han -0.6502548 0.8339790
## Hieu.suat.su.dung.TS 0.5935647 -0.7967425
## Kha.nang.thanh.toan.ngan.han Hieu.suat.su.dung.TS
## Tiền.va.Tuong.duong.tien 0.4316683 -0.4247546
## Tai.san.ngan.han 0.9246514 -0.8315334
## No.ngan.han 0.6491055 -0.6687346
## Doanh.thu.thuan 0.7651617 -0.6070808
## Loi.nhuan.truoc.thue 0.7994480 -0.6676049
## Loi.nhuan.sau.thue 0.7887527 -0.6582243
## Tong.No.phai.tra 0.6278144 -0.5970346
## Von.chu.so.huu 0.9090820 -0.8049514
## LCTT.tu.HĐKD 0.7912761 -0.6448659
## LCTT.thuan.trong.ky -0.9141788 0.6805661
## Mua.sam.TSCD -0.4427096 0.2276763
## Ty.le.no.tren.VCSH -0.6502548 0.5935647
## Bien.loi.nhuan.rong 0.8339790 -0.7967425
## Kha.nang.thanh.toan.ngan.han 1.0000000 -0.8141489
## Hieu.suat.su.dung.TS -0.8141489 1.0000000
##
## $corrPos
## xName yName x y corr
## 1 Tiền.va.Tuong.duong.tien Tiền.va.Tuong.duong.tien 1 15 1.0000000
## 2 Tai.san.ngan.han Tiền.va.Tuong.duong.tien 2 15 0.6422053
## 3 Tai.san.ngan.han Tai.san.ngan.han 2 14 1.0000000
## 4 No.ngan.han Tiền.va.Tuong.duong.tien 3 15 0.6921057
## 5 No.ngan.han Tai.san.ngan.han 3 14 0.8744358
## 6 No.ngan.han No.ngan.han 3 13 1.0000000
## 7 Doanh.thu.thuan Tiền.va.Tuong.duong.tien 4 15 0.7352071
## 8 Doanh.thu.thuan Tai.san.ngan.han 4 14 0.8669076
## 9 Doanh.thu.thuan No.ngan.han 4 13 0.8720475
## 10 Doanh.thu.thuan Doanh.thu.thuan 4 12 1.0000000
## 11 Loi.nhuan.truoc.thue Tiền.va.Tuong.duong.tien 5 15 0.8289370
## 12 Loi.nhuan.truoc.thue Tai.san.ngan.han 5 14 0.8765589
## 13 Loi.nhuan.truoc.thue No.ngan.han 5 13 0.7822637
## 14 Loi.nhuan.truoc.thue Doanh.thu.thuan 5 12 0.9463250
## 15 Loi.nhuan.truoc.thue Loi.nhuan.truoc.thue 5 11 1.0000000
## 16 Loi.nhuan.sau.thue Tiền.va.Tuong.duong.tien 6 15 0.8331257
## 17 Loi.nhuan.sau.thue Tai.san.ngan.han 6 14 0.8681667
## 18 Loi.nhuan.sau.thue No.ngan.han 6 13 0.7798283
## 19 Loi.nhuan.sau.thue Doanh.thu.thuan 6 12 0.9470717
## 20 Loi.nhuan.sau.thue Loi.nhuan.truoc.thue 6 11 0.9998004
## 21 Loi.nhuan.sau.thue Loi.nhuan.sau.thue 6 10 1.0000000
## 22 Tong.No.phai.tra Tiền.va.Tuong.duong.tien 7 15 0.7678772
## 23 Tong.No.phai.tra Tai.san.ngan.han 7 14 0.8441601
## 24 Tong.No.phai.tra No.ngan.han 7 13 0.9415319
## 25 Tong.No.phai.tra Doanh.thu.thuan 7 12 0.9051202
## 26 Tong.No.phai.tra Loi.nhuan.truoc.thue 7 11 0.8653825
## 27 Tong.No.phai.tra Loi.nhuan.sau.thue 7 10 0.8659518
## 28 Tong.No.phai.tra Tong.No.phai.tra 7 9 1.0000000
## 29 Von.chu.so.huu Tiền.va.Tuong.duong.tien 8 15 0.7073725
## 30 Von.chu.so.huu Tai.san.ngan.han 8 14 0.9868598
## 31 Von.chu.so.huu No.ngan.han 8 13 0.8727695
## 32 Von.chu.so.huu Doanh.thu.thuan 8 12 0.8891918
## 33 Von.chu.so.huu Loi.nhuan.truoc.thue 8 11 0.8972997
## 34 Von.chu.so.huu Loi.nhuan.sau.thue 8 10 0.8902429
## 35 Von.chu.so.huu Tong.No.phai.tra 8 9 0.8383272
## 36 Von.chu.so.huu Von.chu.so.huu 8 8 1.0000000
## 37 LCTT.tu.HĐKD Tiền.va.Tuong.duong.tien 9 15 0.7968398
## 38 LCTT.tu.HĐKD Tai.san.ngan.han 9 14 0.8494423
## 39 LCTT.tu.HĐKD No.ngan.han 9 13 0.7524673
## 40 LCTT.tu.HĐKD Doanh.thu.thuan 9 12 0.9492043
## 41 LCTT.tu.HĐKD Loi.nhuan.truoc.thue 9 11 0.9930095
## 42 LCTT.tu.HĐKD Loi.nhuan.sau.thue 9 10 0.9935234
## 43 LCTT.tu.HĐKD Tong.No.phai.tra 9 9 0.8313089
## 44 LCTT.tu.HĐKD Von.chu.so.huu 9 8 0.8727245
## 45 LCTT.tu.HĐKD LCTT.tu.HĐKD 9 7 1.0000000
## 46 LCTT.thuan.trong.ky Tiền.va.Tuong.duong.tien 10 15 -0.1029499
## 47 LCTT.thuan.trong.ky Tai.san.ngan.han 10 14 -0.7671261
## 48 LCTT.thuan.trong.ky No.ngan.han 10 13 -0.4326058
## 49 LCTT.thuan.trong.ky Doanh.thu.thuan 10 12 -0.5078676
## 50 LCTT.thuan.trong.ky Loi.nhuan.truoc.thue 10 11 -0.5222540
## 51 LCTT.thuan.trong.ky Loi.nhuan.sau.thue 10 10 -0.5075785
## 52 LCTT.thuan.trong.ky Tong.No.phai.tra 10 9 -0.3766624
## 53 LCTT.thuan.trong.ky Von.chu.so.huu 10 8 -0.7297444
## 54 LCTT.thuan.trong.ky LCTT.tu.HĐKD 10 7 -0.5209779
## 55 LCTT.thuan.trong.ky LCTT.thuan.trong.ky 10 6 1.0000000
## 56 Mua.sam.TSCD Tiền.va.Tuong.duong.tien 11 15 0.1424165
## 57 Mua.sam.TSCD Tai.san.ngan.han 11 14 -0.4050387
## 58 Mua.sam.TSCD No.ngan.han 11 13 -0.3470142
## 59 Mua.sam.TSCD Doanh.thu.thuan 11 12 -0.3090256
## 60 Mua.sam.TSCD Loi.nhuan.truoc.thue 11 11 -0.1797852
## 61 Mua.sam.TSCD Loi.nhuan.sau.thue 11 10 -0.1689878
## 62 Mua.sam.TSCD Tong.No.phai.tra 11 9 -0.2872837
## 63 Mua.sam.TSCD Von.chu.so.huu 11 8 -0.3379837
## 64 Mua.sam.TSCD LCTT.tu.HĐKD 11 7 -0.1590858
## 65 Mua.sam.TSCD LCTT.thuan.trong.ky 11 6 0.4816909
## 66 Mua.sam.TSCD Mua.sam.TSCD 11 5 1.0000000
## 67 Ty.le.no.tren.VCSH Tiền.va.Tuong.duong.tien 12 15 -0.4080277
## 68 Ty.le.no.tren.VCSH Tai.san.ngan.han 12 14 -0.6293628
## 69 Ty.le.no.tren.VCSH No.ngan.han 12 13 -0.5453714
## 70 Ty.le.no.tren.VCSH Doanh.thu.thuan 12 12 -0.5867107
## 71 Ty.le.no.tren.VCSH Loi.nhuan.truoc.thue 12 11 -0.5336798
## 72 Ty.le.no.tren.VCSH Loi.nhuan.sau.thue 12 10 -0.5304298
## 73 Ty.le.no.tren.VCSH Tong.No.phai.tra 12 9 -0.4206402
## 74 Ty.le.no.tren.VCSH Von.chu.so.huu 12 8 -0.7006745
## 75 Ty.le.no.tren.VCSH LCTT.tu.HĐKD 12 7 -0.5353749
## 76 Ty.le.no.tren.VCSH LCTT.thuan.trong.ky 12 6 0.5579128
## 77 Ty.le.no.tren.VCSH Mua.sam.TSCD 12 5 -0.0751490
## 78 Ty.le.no.tren.VCSH Ty.le.no.tren.VCSH 12 4 1.0000000
## 79 Bien.loi.nhuan.rong Tiền.va.Tuong.duong.tien 13 15 0.7605546
## 80 Bien.loi.nhuan.rong Tai.san.ngan.han 13 14 0.8879823
## 81 Bien.loi.nhuan.rong No.ngan.han 13 13 0.7364181
## 82 Bien.loi.nhuan.rong Doanh.thu.thuan 13 12 0.8447871
## 83 Bien.loi.nhuan.rong Loi.nhuan.truoc.thue 13 11 0.9433263
## 84 Bien.loi.nhuan.rong Loi.nhuan.sau.thue 13 10 0.9406865
## 85 Bien.loi.nhuan.rong Tong.No.phai.tra 13 9 0.8188056
## 86 Bien.loi.nhuan.rong Von.chu.so.huu 13 8 0.8900543
## 87 Bien.loi.nhuan.rong LCTT.tu.HĐKD 13 7 0.9156872
## 88 Bien.loi.nhuan.rong LCTT.thuan.trong.ky 13 6 -0.5823773
## 89 Bien.loi.nhuan.rong Mua.sam.TSCD 13 5 -0.1112024
## 90 Bien.loi.nhuan.rong Ty.le.no.tren.VCSH 13 4 -0.5888314
## 91 Bien.loi.nhuan.rong Bien.loi.nhuan.rong 13 3 1.0000000
## 92 Kha.nang.thanh.toan.ngan.han Tiền.va.Tuong.duong.tien 14 15 0.4316683
## 93 Kha.nang.thanh.toan.ngan.han Tai.san.ngan.han 14 14 0.9246514
## 94 Kha.nang.thanh.toan.ngan.han No.ngan.han 14 13 0.6491055
## 95 Kha.nang.thanh.toan.ngan.han Doanh.thu.thuan 14 12 0.7651617
## 96 Kha.nang.thanh.toan.ngan.han Loi.nhuan.truoc.thue 14 11 0.7994480
## 97 Kha.nang.thanh.toan.ngan.han Loi.nhuan.sau.thue 14 10 0.7887527
## 98 Kha.nang.thanh.toan.ngan.han Tong.No.phai.tra 14 9 0.6278144
## 99 Kha.nang.thanh.toan.ngan.han Von.chu.so.huu 14 8 0.9090820
## 100 Kha.nang.thanh.toan.ngan.han LCTT.tu.HĐKD 14 7 0.7912761
## 101 Kha.nang.thanh.toan.ngan.han LCTT.thuan.trong.ky 14 6 -0.9141788
## 102 Kha.nang.thanh.toan.ngan.han Mua.sam.TSCD 14 5 -0.4427096
## 103 Kha.nang.thanh.toan.ngan.han Ty.le.no.tren.VCSH 14 4 -0.6502548
## 104 Kha.nang.thanh.toan.ngan.han Bien.loi.nhuan.rong 14 3 0.8339790
## 105 Kha.nang.thanh.toan.ngan.han Kha.nang.thanh.toan.ngan.han 14 2 1.0000000
## 106 Hieu.suat.su.dung.TS Tiền.va.Tuong.duong.tien 15 15 -0.4247546
## 107 Hieu.suat.su.dung.TS Tai.san.ngan.han 15 14 -0.8315334
## 108 Hieu.suat.su.dung.TS No.ngan.han 15 13 -0.6687346
## 109 Hieu.suat.su.dung.TS Doanh.thu.thuan 15 12 -0.6070808
## 110 Hieu.suat.su.dung.TS Loi.nhuan.truoc.thue 15 11 -0.6676049
## 111 Hieu.suat.su.dung.TS Loi.nhuan.sau.thue 15 10 -0.6582243
## 112 Hieu.suat.su.dung.TS Tong.No.phai.tra 15 9 -0.5970346
## 113 Hieu.suat.su.dung.TS Von.chu.so.huu 15 8 -0.8049514
## 114 Hieu.suat.su.dung.TS LCTT.tu.HĐKD 15 7 -0.6448659
## 115 Hieu.suat.su.dung.TS LCTT.thuan.trong.ky 15 6 0.6805661
## 116 Hieu.suat.su.dung.TS Mua.sam.TSCD 15 5 0.2276763
## 117 Hieu.suat.su.dung.TS Ty.le.no.tren.VCSH 15 4 0.5935647
## 118 Hieu.suat.su.dung.TS Bien.loi.nhuan.rong 15 3 -0.7967425
## 119 Hieu.suat.su.dung.TS Kha.nang.thanh.toan.ngan.han 15 2 -0.8141489
## 120 Hieu.suat.su.dung.TS Hieu.suat.su.dung.TS 15 1 1.0000000
##
## $arg
## $arg$type
## [1] "upper"
Giải thích kỹ thuật : Đoạn code này sử dụng hàm cor() để tính toán ma trận tương quan giữa tất cả các biến số trong dataset df_clean, sau đó sử dụng hàm corrplot() với phương pháp hiển thị “color” để trực quan hóa ma trận này dưới dạng biểu đồ nhiệt màu, kết hợp hiển thị hệ số tương quan ngay trên mỗi ô để người xem dễ dàng đọc được cả giá trị và mức độ tương quan.
Ý nghĩa thống kê : Ma trận cho thấy doanh thu và lợi nhuận có tương quan rất chặt (0.96-1.00), chứng tỏ hoạt động kinh doanh hiệu quả. Tuy nhiên, dòng tiền từ hoạt động kinh doanh chỉ tương quan trung bình với lợi nhuận (0.52), cảnh báo chất lượng lợi nhuận chưa cao.
Đáng chú ý, tỷ lệ nợ/VCSH tương quan nghịch mạnh với khả năng thanh toán ngắn hạn (-0.59), cho thấy đòn bẩy tài chính cao đang gây áp lực lên thanh khoản. Trong khi đó, đầu tư TSCĐ hầu như không tương quan với các chỉ số hiệu quả, cho thấy đầu tư dài hạn chưa mang lại tác động rõ rệt.
p32 <- ggplot(df_clean, aes(x = Năm, y = Hieu.suat.su.dung.TS)) +
geom_line(color = "purple", size = 1.5) +
geom_point(color = "orange", size = 3) +
geom_area(fill = "lightpurple", alpha = 0.3) +
geom_hline(yintercept = mean(df_clean$Hieu.suat.su.dung.TS),
linetype = "dashed", color = "red") +
geom_text(aes(label = round(Hieu.suat.su.dung.TS, 2)), vjust = -1, size = 3) +
labs(title = "HIỆU SUẤT SỬ DỤNG TÀI SẢN",
x = "Năm", y = "Hiệu suất") +
theme_minimal()
print(p32)Giải thích kỹ thuật : Đoạn code trên sử dụng ggplot2 để vẽ biểu đồ theo dõi hiệu suất sử dụng tài sản: đường tím thể hiện xu hướng chính, điểm cam đánh dấu giá trị từng năm, vùng tím nhạt giúp quan sát diện tích phát triển, đường đỏ nét đứt chỉ mức trung bình, và số liệu trực tiếp hiển thị giá trị chính xác - tất cả giúp phân tích hiệu quả sử dụng tài sản qua thời gian một cách trực quan.
Ý nghĩa thống kê :NHẬN XÉT:
Hiệu suất sử dụng tài sản có sự biến động đáng kể qua các năm. Từ năm 2014 đến 2016, hiệu suất tăng mạnh từ 2.16 lên 3.12, đạt đỉnh vào năm 2016. Tuy nhiên, từ năm 2017 đến 2024, chỉ số này có xu hướng giảm dần và liên tục, từ 2.85 xuống chỉ còn 0.78. Điều này cho thấy hiệu quả sử dụng tài sản của doanh nghiệp đang giảm sút nghiêm trọng, với giá trị năm 2024 chỉ bằng 1/3 so với năm 2014.
p33 <- ggplot(df_clean, aes(x = Tinh.trang.dong.tien, fill = Tinh.trang.dong.tien)) +
geom_bar(alpha = 0.7) +
geom_text(stat = "count", aes(label = ..count..), vjust = -0.5, size = 5) +
geom_hline(yintercept = 0, color = "black") +
scale_fill_manual(values = c("Tích cực" = "green", "Tiêu cực" = "red")) +
labs(title = "PHÂN BỐ TÌNH TRẠNG DÒNG TIỀN",
x = "Tình trạng dòng tiền", y = "Số năm") +
theme_minimal() +
theme(legend.position = "none")
print(p33)geom_bar() để vẽ các cột thể hiện số năm theo từng loại
tình trạng dòng tiền, với màu xanh cho “Tích cực” và đỏ cho “Tiêu cực”.
Lệnh geom_text() hiển thị số lượng cụ thể trên mỗi cột,
giúp người xem dễ dàng so sánh mà không cần ước lượng. Đường kẻ ngang
geom_hline() tạo đường chuẩn tại vị trí 0, còn
scale_fill_manual() gán màu tương ứng cho từng trạng thái.
Toàn bộ biểu đồ được trình bày tối giản với theme_minimal()
và ẩn chú thích để tập trung vào thông tin chính.-Ý Nghĩa Thống Kê : Tình trạng dòng tiền “Tiêu cực” chiếm đa số với 7 năm, gấp hơn 2 lần so với số năm có dòng tiền “Tích cực” (3 năm). Điều này cho thấy doanh nghiệp gặp khó khăn trong việc duy trì dòng tiền lành mạnh, với phần lớn thời gian dòng tiền ở trạng thái tiêu cực. Tình hình tài chính ngắn hạn của doanh nghiệp cần được lưu ý và cải thiện.
p34 <- ggplot(df_clean, aes(x = Năm, y = Tiền.va.Tuong.duong.tien/1e9)) +
geom_line(color = "gold", size = 1.5) +
geom_point(color = "orange", size = 3) +
geom_area(fill = "lightyellow", alpha = 0.3) +
geom_hline(yintercept = mean(df_clean$Tiền.va.Tuong.duong.tien/1e9),
linetype = "dashed", color = "red") +
geom_text(aes(label = round(Tiền.va.Tuong.duong.tien/1e9, 1)), vjust = -1, size = 3) +
labs(title = "XU HƯỚNG TIỀN MẶT VÀ TƯƠNG ĐƯƠNG TIỀN",
x = "Năm", y = "Tiền mặt (tỷ đồng)") +
theme_minimal()
print(p34)Giải thích kỹ thuật : Biểu đồ sử dụng geom_line() vẽ đường màu vàng thể hiện xu hướng biến động, geom_point() thêm điểm đánh dấu màu cam cho từng năm, và geom_area() tô vùng vàng nhạt giúp quan sát diện tích thay đổi. Đường đỏ nét đứt geom_hline() chỉ mức trung bình, trong khi geom_text() hiển thị giá trị cụ thể được chia cho 1 tỷ để dễ đọc.
Ý nghĩa thống kê :Tiền mặt và tương đương tiền của doanh nghiệp có diễn biến bất thường, tăng lên mức đỉnh 1.5 tỷ đồng vào năm 2022 nhưng sau đó giảm mạnh xuống chỉ còn 0.1 tỷ đồng vào năm 2024, cho thấy tình hình thanh khoản đang suy giảm nghiêm trọng và khả năng chi trả ngắn hạn gặp nhiều rủi ro.
p35 <- ggplot(df_clean, aes(x = Giai.doan, y = Doanh.thu.thuan/1e9, fill = Giai.doan)) +
geom_boxplot(alpha = 0.7) +
geom_jitter(aes(color = as.factor(Năm)), size = 3, width = 0.2) +
geom_point(stat = "summary", fun = "mean", color = "red", size = 4, shape = 18) +
stat_summary(fun = "mean", geom = "text", aes(label = round(..y.., 1)),
vjust = -1, size = 4, color = "red") +
labs(title = "SO SÁNH DOANH THU THEO GIAI ĐOẠN",
x = "Giai đoạn", y = "Doanh thu (tỷ đồng)") +
theme_minimal()
print(p35)Giải thích kỹ thuật : Biểu đồ sử dụng
geom_boxplot() để vẽ hộp hiển thị phân bố doanh thu theo
từng giai đoạn, kết hợp geom_jitter() hiển thị từng điểm dữ
liệu cụ thể phân tán ngẫu nhiên để tránh chồng chéo, và
geom_point() với stat_summary() để đánh dấu
giá trị trung bình bằng hình thoi màu đỏ kèm số liệu cụ thể.
Ý nghĩa thống kê : Biểu đồ cho thấy sự tương quan rõ ràng giữa mức độ rủi ro và doanh thu của doanh nghiệp. Nhóm “Rủi ro cao” có doanh thu thấp nhất và biến động mạnh, phản ánh hiệu quả kinh doanh kém và mức độ rủi ro lớn. Ngược lại, nhóm “An toàn” đạt doanh thu cao và ổn định nhất, chứng tỏ đây là giai đoạn kinh doanh hiệu quả với rủi ro được kiểm soát tốt. Sự chênh lệch rõ rệt này khẳng định mối quan hệ tỷ lệ nghịch giữa rủi ro và hiệu quả kinh doanh trong các giai đoạn khác nhau.
df_tang_truong <- df_clean %>%
arrange(Năm) %>%
mutate(Tang.truong = (Doanh.thu.thuan/lag(Doanh.thu.thuan) - 1) * 100) %>%
filter(!is.na(Tang.truong))
p36 <- ggplot(df_tang_truong, aes(x = Năm, y = Tang.truong)) +
geom_col(aes(fill = Tang.truong > 0), alpha = 0.7) +
geom_line(color = "blue", size = 1) +
geom_point(color = "darkblue", size = 2) +
geom_hline(yintercept = 0, linetype = "solid", color = "black") +
geom_text(aes(label = paste0(round(Tang.truong, 1), "%")), vjust = -0.5, size = 3) +
labs(title = "TĂNG TRƯỞNG DOANH THU HÀNG NĂM",
x = "Năm", y = "Tăng trưởng (%)") +
scale_fill_manual(values = c("TRUE" = "green", "FALSE" = "red")) +
theme_minimal() +
theme(legend.position = "none")
print(p36)Giải thích kỹ thuật : Đoạn code này thực hiện hai bước
chính: đầu tiên, nó tạo một bộ dữ liệu mới (df_tang_truong)
bằng cách sắp xếp dữ liệu theo năm và tính toán phần trăm tăng trưởng
doanh thu hàng năm so với năm trước đó, sau đó sử dụng
ggplot2 để xây dựng biểu đồ kết hợp giữa cột (màu xanh cho
tăng trưởng dương, đỏ cho âm), đường line (màu xanh dương) và điểm (màu
xanh đậm) để trực quan hóa xu hướng tăng trưởng, cùng với việc hiển thị
giá trị phần trăm và đường tham chiếu 0% để dễ dàng phân tích hiệu quả
kinh doanh qua từng năm.
Ý nghĩa thống kê: Doanh thu doanh nghiệp biến động cực mạnh với mức tăng trưởng cao nhất 873% vào năm 2018 nhưng sau đó giảm sâu -77% vào năm 2020 và liên tục tăng trưởng âm từ 2021-2024, phản ánh mô hình kinh doanh thiếu bền vững và đang đối mặt với khủng hoảng nghiêm trọng.
p37 <- ggplot(df_clean, aes(x = abs(Mua.sam.TSCD)/1e9, y = Doanh.thu.thuan/1e9)) +
geom_point(aes(color = as.factor(Năm), size = Loi.nhuan.sau.thue/1e9)) +
geom_smooth(method = "lm", se = TRUE, color = "red", linetype = "dashed") +
geom_text(aes(label = Năm), vjust = -0.5, size = 3) +
geom_hline(yintercept = mean(df_clean$Doanh.thu.thuan/1e9), linetype = "dashed", color = "gray") +
geom_vline(xintercept = mean(abs(df_clean$Mua.sam.TSCD)/1e9), linetype = "dashed", color = "gray") +
labs(title = "MỐI QUAN HỆ ĐẦU TƯ TSCĐ VÀ DOANH THU",
x = "Đầu tư TSCĐ (tỷ đồng)", y = "Doanh thu (tỷ đồng)") +
theme_minimal()
print(p37)Giải thích kỹ thuật: Biểu đồ sử dụng geom_point() để thể hiện mối quan hệ giữa đầu tư TSCĐ (trục x) và doanh thu (trục y), với kích thước điểm biểu thị quy mô lợi nhuận và màu sắc phân biệt theo năm. Đường hồi quy tuyến tính geom_smooth() cho thấy xu hướng tương quan tổng thể, trong khi các đường gạch ngang geom_hline() và dọc geom_vline() đánh dấu giá trị trung bình giúp xác định các điểm dữ liệu nổi bật.
Ý nghĩa thống kê: Biểu đồ cho thấy năm 2024 có đầu tư TSCĐ cao nhất nhưng doanh thu lại ở mức thấp, trong khi năm 2022 đạt doanh thu cao nhấ* với mức đầu tư TSCĐ trung bình. Điều này chứng tỏ mối quan hệ giữa đầu tư TSCĐ và doanh thu không theo tỷ lệ thuận và hiệu quả đầu tư chưa cao, doanh thu phụ thuộc vào nhiều yếu tố khác hơn là quy mô đầu tư tài sản cố định.
df_clean$ROI <- df_clean$Loi.nhuan.sau.thue / abs(df_clean$Mua.sam.TSCD)
p38 <- ggplot(df_clean, aes(x = Năm, y = ROI)) +
geom_col(aes(fill = ROI > 0), alpha = 0.7) +
geom_line(color = "blue", size = 1) +
geom_point(color = "darkblue", size = 2) +
geom_hline(yintercept = 0, linetype = "solid", color = "black") +
geom_text(aes(label = round(ROI, 2)), vjust = -0.5, size = 3) +
labs(title = "HIỆU QUẢ ĐẦU TƯ (ROI)",
x = "Năm", y = "Tỷ suất lợi nhuận/Đầu tư") +
scale_fill_manual(values = c("TRUE" = "green", "FALSE" = "red")) +
theme_minimal() +
theme(legend.position = "none")
print(p38)Giải thích kỹ thuật: Biểu đồ sử dụng kết hợp cột màu (xanh/đỏ), đường line và điểm để trực quan hóa hiệu quả đầu tư (ROI) qua các năm, với các con số cụ thể được hiển thị trực tiếp và đường đen đánh dấu ngưỡng 0% giúp dễ dàng đánh giá năm nào có lãi hay lỗ từ hoạt động đầu tư.
Ý nghĩa thống kê : ROI đạt đỉnh cao nhất 38.34 vào năm 2022 nhưng sau đó giảm mạnh xuống còn 5.25 vào năm 2024, cho thấy hiệu quả đầu tư đang suy giảm nghiêm trọng.
p39 <- ggplot(df_clean, aes(x = Ty.le.no.tren.VCSH, y = Bien.loi.nhuan.rong * 100)) +
geom_point(aes(color = as.factor(Năm), size = Doanh.thu.thuan/1e9)) +
geom_smooth(method = "lm", se = FALSE, color = "red", linetype = "dashed") +
geom_text(aes(label = Năm), vjust = -0.5, size = 3) +
geom_vline(xintercept = 1, linetype = "dashed", color = "red") +
geom_hline(yintercept = mean(df_clean$Bien.loi.nhuan.rong * 100),
linetype = "dashed", color = "blue") +
labs(title = "MỐI QUAN HỆ ĐÒN BẨY TÀI CHÍNH VÀ HIỆU QUẢ",
x = "Tỷ lệ Nợ/VCSH", y = "Biên lợi nhuận ròng (%)") +
theme_minimal()
print(p39)Biểu đồ sử dụng geom_point() để thể hiện mối quan hệ
giữa đòn bẩy tài chính (Tỷ lệ Nợ/VCSH) và hiệu quả kinh doanh (Biên lợi
nhuận ròng), với màu sắc phân biệt theo năm và kích thước điểm thể hiện
quy mô doanh thu. Đường hồi quy tuyến tính geom_smooth()
cho thấy xu hướng tương quan tổng thể, trong khi các đường tham chiếu
geom_vline() (ngưỡng Nợ/VCSH = 1) và
geom_hline() (biên lợi nhuận trung bình) giúp đánh giá mức
độ rủi ro và hiệu quả.
library(fmsb)
# Chuẩn bị dữ liệu cho radar chart
radar_data <- df_clean %>%
select(Năm, Doanh.thu.thuan, Loi.nhuan.sau.thue, Tong.No.phai.tra, Von.chu.so.huu) %>%
mutate(across(-Năm, ~ scales::rescale(.x, to = c(0, 100)))) %>%
filter(Năm %in% c(2014, 2018, 2022, 2024)) %>%
select(-Năm) %>%
as.data.frame()
# Thêm min/max cho radar chart
radar_data <- rbind(rep(100,4), rep(0,4), radar_data)
# Vẽ radar chart
p40 <- radarchart(radar_data, axistype = 1,
pcol = c("blue", "red", "green", "orange"),
plwd = 2, plty = 1,
cglcol = "grey", cglty = 1, cglwd = 0.8,
axislabcol = "grey",
vlcex = 0.8,
title = "SO SÁNH CHỈ SỐ TÀI CHÍNH CÁC NĂM CHỦ CHỐT")## NULL
Giải thích kỹ thuật : Đoạn code sử dụng thư viện
fmsb để tạo biểu đồ radar so sánh các chỉ số tài chính qua
các năm chủ chốt. Dữ liệu được chuẩn bị bằng cách chọn 4 năm quan trọng
(2014, 2018, 2022, 2024) và chuẩn hóa các chỉ số về thang điểm 0-100 để
có thể so sánh tương đối. Biểu đồ sử dụng các tham số như
pcol để thiết lập màu sắc cho từng năm, plwd
cho độ dày đường, và cglcol cho màu đường lưới, tạo ra hình
ảnh trực quan về sự thay đổi của các chỉ số tài chính theo thời
gian.
Ý nghĩa thống kê: Biểu đồ radar cho thấy sự phát triển không đồng đều giữa các chỉ số tài chính qua 4 năm chủ chốt. Các năm gần đây (2022, 2024) thể hiện sự cân đối tốt hơn giữa doanh thu, lợi nhuận và cơ cấu vốn so với các năm đầu (2014), trong đó vốn chủ sở hữu có xu hướng tăng trưởng ổn định qua các thời kỳ. Tuy nhiên, vẫn tồn tại sự chênh lệch đáng kể giữa các chỉ số trong từng năm, phản ánh các ưu tiên chiến lược khác nhau của doanh nghiệp qua từng giai đoạn.