library(readxl)
## Warning: package 'readxl' was built under R version 4.5.1
Data <- read_excel("D:/NNLT/Data.xlsx")
Câu lệnh này giúp nhập toàn bộ bộ dữ liệu nhân sự (thông tin như lương, tuổi, giới tính, phòng ban, điểm hài lòng, v.v.) vào R để bắt đầu phân tích.
head(Data)
## # A tibble: 6 × 20
## Employee_ID Department Gender Age Job_Title Hire_Date Years_At_Company
## <dbl> <chr> <chr> <dbl> <chr> <chr> <dbl>
## 1 1 IT Male 55 Speciali… 2022-01-… 2
## 2 2 Finance Male 29 Developer 2024-04-… 0
## 3 3 Finance Male 55 Speciali… 2015-10-… 8
## 4 4 Customer Support Female 48 Analyst 2016-10-… 7
## 5 5 Engineering Female 36 Analyst 2021-07-… 3
## 6 6 IT Male 43 Manager 2016-08-… 8
## # ℹ 13 more variables: Education_Level <chr>, Performance_Score <dbl>,
## # Monthly_Salary <chr>, Work_Hours_Per_Week <dbl>, Projects_Handled <dbl>,
## # Overtime_Hours <dbl>, Sick_Days <dbl>, Remote_Work_Frequency <dbl>,
## # Team_Size <dbl>, Training_Hours <dbl>, Promotions <dbl>,
## # Employee_Satisfaction_Score <chr>, Resigned <lgl>
Lệnh head(Data) giúp nhanh chóng kiểm tra dữ liệu nhập có đúng hay chưa, đồng thời hình dung cấu trúc tổng quan của bộ dữ liệu nhân viên trước khi bắt đầu các bước xử lý tiếp theo.
dim(Data)
## [1] 100000 20
Dữ liệu thô có 100000 quan sát và 20 biến.
names(Data)
## [1] "Employee_ID" "Department"
## [3] "Gender" "Age"
## [5] "Job_Title" "Hire_Date"
## [7] "Years_At_Company" "Education_Level"
## [9] "Performance_Score" "Monthly_Salary"
## [11] "Work_Hours_Per_Week" "Projects_Handled"
## [13] "Overtime_Hours" "Sick_Days"
## [15] "Remote_Work_Frequency" "Team_Size"
## [17] "Training_Hours" "Promotions"
## [19] "Employee_Satisfaction_Score" "Resigned"
Lệnh names(Data) giúp xác định rõ các biến có trong bộ dữ liệu nhân sự, là bước quan trọng để hiểu cấu trúc dữ liệu và định hướng các phân tích tiếp theo.
variable_meaning <- data.frame(
Variable = c(
"Employee_ID",
"Department",
"Gender",
"Age",
"Job_Title",
"Hire_Date",
"Years_At_Company",
"Education_Level",
"Performance_Score",
"Monthly_Salary",
"Work_Hours_Per_Week",
"Projects_Handled",
"Overtime_Hours",
"Sick_Days",
"Remote_Work_Frequency",
"Team_Size",
"Training_Hours",
"Promotions",
"Employee_Satisfaction_Score",
"Resigned"
),
Meaning = c(
"Mã định danh duy nhất của mỗi nhân viên",
"Phòng ban mà nhân viên đang làm việc (như IT, HR, Sales,...)",
"Giới tính của nhân viên (Nam/Nữ)",
"Tuổi của nhân viên (tính bằng năm)",
"Chức danh công việc hiện tại của nhân viên",
"Ngày bắt đầu làm việc tại công ty",
"Số năm nhân viên đã làm việc tại công ty",
"Trình độ học vấn cao nhất của nhân viên (Cao đẳng, Đại học, Sau đại học,...)",
"Điểm đánh giá hiệu suất làm việc (từ 1 đến 5)",
"Mức lương hàng tháng của nhân viên",
"Số giờ làm việc trung bình mỗi tuần của nhân viên",
"Số dự án mà nhân viên đã hoặc đang phụ trách",
"Số giờ làm thêm (overtime) trung bình mỗi tháng",
"Số ngày nghỉ ốm của nhân viên trong năm",
"Tần suất làm việc từ xa",
"Quy mô nhóm hoặc đội mà nhân viên tham gia",
"Tổng số giờ tham gia các khóa đào tạo",
"Số lần được thăng chức của nhân viên",
"Mức độ hài lòng của nhân viên (từ 0 đến 5)",
"Trạng thái nghỉ việc của nhân viên (TRUE = đã nghỉ, FALSE = còn làm)"
),
stringsAsFactors = FALSE
)
# Hiển thị bảng
library(knitr)
kable(variable_meaning, booktabs = TRUE, caption = "Giải thích ý nghĩa các biến trong bộ dữ liệu nhân sự")
| Variable | Meaning |
|---|---|
| Employee_ID | Mã định danh duy nhất của mỗi nhân viên |
| Department | Phòng ban mà nhân viên đang làm việc (như IT, HR, Sales,…) |
| Gender | Giới tính của nhân viên (Nam/Nữ) |
| Age | Tuổi của nhân viên (tính bằng năm) |
| Job_Title | Chức danh công việc hiện tại của nhân viên |
| Hire_Date | Ngày bắt đầu làm việc tại công ty |
| Years_At_Company | Số năm nhân viên đã làm việc tại công ty |
| Education_Level | Trình độ học vấn cao nhất của nhân viên (Cao đẳng, Đại học, Sau đại học,…) |
| Performance_Score | Điểm đánh giá hiệu suất làm việc (từ 1 đến 5) |
| Monthly_Salary | Mức lương hàng tháng của nhân viên |
| Work_Hours_Per_Week | Số giờ làm việc trung bình mỗi tuần của nhân viên |
| Projects_Handled | Số dự án mà nhân viên đã hoặc đang phụ trách |
| Overtime_Hours | Số giờ làm thêm (overtime) trung bình mỗi tháng |
| Sick_Days | Số ngày nghỉ ốm của nhân viên trong năm |
| Remote_Work_Frequency | Tần suất làm việc từ xa |
| Team_Size | Quy mô nhóm hoặc đội mà nhân viên tham gia |
| Training_Hours | Tổng số giờ tham gia các khóa đào tạo |
| Promotions | Số lần được thăng chức của nhân viên |
| Employee_Satisfaction_Score | Mức độ hài lòng của nhân viên (từ 0 đến 5) |
| Resigned | Trạng thái nghỉ việc của nhân viên (TRUE = đã nghỉ, FALSE = còn làm) |
Đoạn mã này giúp hệ thống hóa toàn bộ thông tin về các biến trong bộ dữ liệu nhân sự.
str(Data)
## tibble [100,000 × 20] (S3: tbl_df/tbl/data.frame)
## $ Employee_ID : num [1:100000] 1 2 3 4 5 6 7 8 9 10 ...
## $ Department : chr [1:100000] "IT" "Finance" "Finance" "Customer Support" ...
## $ Gender : chr [1:100000] "Male" "Male" "Male" "Female" ...
## $ Age : num [1:100000] 55 29 55 48 36 43 37 55 55 45 ...
## $ Job_Title : chr [1:100000] "Specialist" "Developer" "Specialist" "Analyst" ...
## $ Hire_Date : chr [1:100000] "2022-01-19 08:03:05.556036" "2024-04-18 08:03:05.556036" "2015-10-26 08:03:05.556036" "2016-10-22 08:03:05.556036" ...
## $ Years_At_Company : num [1:100000] 2 0 8 7 3 8 1 9 1 7 ...
## $ Education_Level : chr [1:100000] "High School" "High School" "High School" "Bachelor" ...
## $ Performance_Score : num [1:100000] 5 5 3 2 2 3 5 2 2 1 ...
## $ Monthly_Salary : chr [1:100000] "6750.0" "7500.0" "5850.0" "4800.0" ...
## $ Work_Hours_Per_Week : num [1:100000] 33 34 37 52 38 46 55 42 51 41 ...
## $ Projects_Handled : num [1:100000] 32 34 27 10 11 31 20 46 23 33 ...
## $ Overtime_Hours : num [1:100000] 22 13 6 28 29 8 29 7 21 2 ...
## $ Sick_Days : num [1:100000] 2 14 3 12 13 0 2 8 14 6 ...
## $ Remote_Work_Frequency : num [1:100000] 0 100 50 100 100 100 0 100 0 75 ...
## $ Team_Size : num [1:100000] 14 12 10 10 15 15 16 7 1 4 ...
## $ Training_Hours : num [1:100000] 66 61 1 0 9 95 27 64 0 53 ...
## $ Promotions : num [1:100000] 0 2 0 1 1 0 0 0 1 2 ...
## $ Employee_Satisfaction_Score: chr [1:100000] "2.63" "1.72" "3.17" "1.86" ...
## $ Resigned : logi [1:100000] FALSE FALSE FALSE FALSE FALSE FALSE ...
Lệnh str(Data) cho ta cái nhìn tổng quan về cấu trúc và kiểu dữ liệu của bộ nhân sự.
colSums(is.na(Data))
## Employee_ID Department
## 0 0
## Gender Age
## 0 0
## Job_Title Hire_Date
## 0 0
## Years_At_Company Education_Level
## 0 0
## Performance_Score Monthly_Salary
## 0 0
## Work_Hours_Per_Week Projects_Handled
## 0 0
## Overtime_Hours Sick_Days
## 0 0
## Remote_Work_Frequency Team_Size
## 0 0
## Training_Hours Promotions
## 0 0
## Employee_Satisfaction_Score Resigned
## 0 0
Lệnh colSums(is.na(Data)) giúp bạn phát hiện dữ liệu bị thiếu trong từng biến.
sum(duplicated(Data))
## [1] 0
Lệnh sum(duplicated(Data)) cho biết có bao nhiêu quan sát bị trùng lặp trong dữ liệu. Kết quả = 0 → bộ dữ liệu nhân sự sạch, không trùng lặp.
summary(Data)
## Employee_ID Department Gender Age
## Min. : 1 Length:100000 Length:100000 Min. :22.00
## 1st Qu.: 25001 Class :character Class :character 1st Qu.:31.00
## Median : 50001 Mode :character Mode :character Median :41.00
## Mean : 50001 Mean :41.03
## 3rd Qu.: 75000 3rd Qu.:51.00
## Max. :100000 Max. :60.00
## Job_Title Hire_Date Years_At_Company Education_Level
## Length:100000 Length:100000 Min. : 0.000 Length:100000
## Class :character Class :character 1st Qu.: 2.000 Class :character
## Mode :character Mode :character Median : 4.000 Mode :character
## Mean : 4.476
## 3rd Qu.: 7.000
## Max. :10.000
## Performance_Score Monthly_Salary Work_Hours_Per_Week Projects_Handled
## Min. :1.000 Length:100000 Min. :30.00 Min. : 0.00
## 1st Qu.:2.000 Class :character 1st Qu.:37.00 1st Qu.:12.00
## Median :3.000 Mode :character Median :45.00 Median :24.00
## Mean :2.995 Mean :44.96 Mean :24.43
## 3rd Qu.:4.000 3rd Qu.:53.00 3rd Qu.:37.00
## Max. :5.000 Max. :60.00 Max. :49.00
## Overtime_Hours Sick_Days Remote_Work_Frequency Team_Size
## Min. : 0.00 Min. : 0.000 Min. : 0.00 Min. : 1.00
## 1st Qu.: 7.00 1st Qu.: 3.000 1st Qu.: 25.00 1st Qu.: 5.00
## Median :15.00 Median : 7.000 Median : 50.00 Median :10.00
## Mean :14.51 Mean : 7.009 Mean : 50.09 Mean :10.01
## 3rd Qu.:22.00 3rd Qu.:11.000 3rd Qu.: 75.00 3rd Qu.:15.00
## Max. :29.00 Max. :14.000 Max. :100.00 Max. :19.00
## Training_Hours Promotions Employee_Satisfaction_Score Resigned
## Min. : 0.00 Min. :0.0000 Length:100000 Mode :logical
## 1st Qu.:25.00 1st Qu.:0.0000 Class :character FALSE:89990
## Median :49.00 Median :1.0000 Mode :character TRUE :10010
## Mean :49.51 Mean :0.9997
## 3rd Qu.:75.00 3rd Qu.:2.0000
## Max. :99.00 Max. :2.0000
Lệnh summary(Data) giúp hiểu rõ cấu trúc và đặc điểm chung của toàn bộ bộ dữ liệu nhân sự. Biến Age Kết quả: Min = 22, Median = 41, Mean = 41.03, Max = 60 cho thấy Biến số (numeric), giá trị trung bình và trung vị gần bằng nhau → phân bố tuổi khá đều, không bị lệch nhiều.Đa phần nhân viên trong công ty nằm ở độ tuổi trung niên (30–50 tuổi), là nhóm có kinh nghiệm và ổn định nghề nghiệp. Ít nhân viên ở độ tuổi rất trẻ (<25) hoặc gần nghỉ hưu (>60).
library(dplyr)
library(psych)
## Warning: package 'psych' was built under R version 4.5.1
library(moments)
# --- XÁC ĐỊNH DANH SÁCH BIẾN SỐ ---
num_vars <- names(Data)[sapply(Data, is.numeric)]
# --- HÀM THỐNG KÊ MÔ TẢ CHO 1 BIẾN ---
describe_one_var <- function(x) {
x_no_na <- na.omit(x)
data.frame(
Min = min(x_no_na),
Max = max(x_no_na),
Mean = mean(x_no_na),
Median = median(x_no_na),
SD = sd(x_no_na),
Variance = var(x_no_na),
Skewness = skewness(x_no_na),
Kurtosis = kurtosis(x_no_na)
)
}
# --- TẠO DANH SÁCH BẢNG THỐNG KÊ CHO TỪNG BIẾN ---
desc_list <- lapply(num_vars, function(var) {
stats <- describe_one_var(Data[[var]])
list(Variable = var, Summary = stats)
})
# --- IN RA MỖI BẢNG RIÊNG ---
for (item in desc_list) {
cat("\n====================================\n")
cat("Biến:", item$Variable, "\n")
print(item$Summary)
}
##
## ====================================
## Biến: Employee_ID
## Min Max Mean Median SD Variance Skewness Kurtosis
## 1 1 1e+05 50000.5 50000.5 28867.66 833341667 0 1.8
##
## ====================================
## Biến: Age
## Min Max Mean Median SD Variance Skewness Kurtosis
## 1 22 60 41.02941 41 11.24412 126.4302 -0.006169566 1.796472
##
## ====================================
## Biến: Years_At_Company
## Min Max Mean Median SD Variance Skewness Kurtosis
## 1 0 10 4.47607 4 2.869336 8.23309 0.01121056 1.778282
##
## ====================================
## Biến: Performance_Score
## Min Max Mean Median SD Variance Skewness Kurtosis
## 1 1 5 2.99543 3 1.414726 2.001449 0.004008424 1.699362
##
## ====================================
## Biến: Work_Hours_Per_Week
## Min Max Mean Median SD Variance Skewness Kurtosis
## 1 30 60 44.95695 45 8.942003 79.95942 0.009620887 1.795712
##
## ====================================
## Biến: Projects_Handled
## Min Max Mean Median SD Variance Skewness Kurtosis
## 1 0 49 24.43117 24 14.46958 209.3689 0.009681863 1.791757
##
## ====================================
## Biến: Overtime_Hours
## Min Max Mean Median SD Variance Skewness Kurtosis
## 1 0 29 14.51493 15 8.664026 75.06535 -0.001166502 1.796839
##
## ====================================
## Biến: Sick_Days
## Min Max Mean Median SD Variance Skewness Kurtosis
## 1 0 14 7.00855 7 4.331591 18.76268 -0.003320354 1.783845
##
## ====================================
## Biến: Remote_Work_Frequency
## Min Max Mean Median SD Variance Skewness Kurtosis
## 1 0 100 50.0905 50 35.35116 1249.704 -0.001900944 1.697277
##
## ====================================
## Biến: Team_Size
## Min Max Mean Median SD Variance Skewness Kurtosis
## 1 1 19 10.01356 10 5.495405 30.19948 -0.0005922356 1.788459
##
## ====================================
## Biến: Training_Hours
## Min Max Mean Median SD Variance Skewness Kurtosis
## 1 0 99 49.50606 49 28.89038 834.6542 -0.0006484809 1.800442
##
## ====================================
## Biến: Promotions
## Min Max Mean Median SD Variance Skewness Kurtosis
## 1 0 2 0.99972 1 0.8158717 0.6656466 0.0005139954 1.502314
Sau khi thực hiện thống kê mô tả cho các biến định lượng trong bộ dữ liệu nhân sự, ta thu được các chỉ tiêu như giá trị trung bình, độ lệch chuẩn, độ lệch và độ nhọn. Kết quả cho thấy phần lớn các biến như tuổi, số năm làm việc, điểm hiệu suất, số giờ làm việc mỗi tuần có phân bố tương đối cân đối quanh giá trị trung bình (Skewness ≈ 0), chứng tỏ dữ liệu có độ ổn định cao. Một số biến như lương và giờ làm thêm có Skewness dương, cho thấy có một nhóm nhỏ nhân viên có giá trị cao hơn trung bình đáng kể — thường là nhóm có hiệu suất hoặc vị trí cao hơn.
#Chuyển đổi 2 biến từ character → numeric
Data$Monthly_Salary <- as.numeric(Data$Monthly_Salary)
Data$Employee_Satisfaction_Score <- as.numeric(Data$Employee_Satisfaction_Score)
str(Data$Monthly_Salary)
## num [1:100000] 6750 7500 5850 4800 4800 7800 5250 7200 4200 6050 ...
str(Data$Employee_Satisfaction_Score)
## num [1:100000] 2.63 1.72 3.17 1.86 1.25 2.77 4.46 2.09 1.44 2.93 ...
# Chuyển đổi biến thành dạng date
Data$Hire_Date <- as.Date(Data$Hire_Date)
# Đếm số biến định lượng
num_vars <- sapply(Data, is.numeric)
sum(num_vars)
## [1] 14
# Đếm số biến định tính
cat_vars <- sapply(Data, function(x) is.character(x) | is.factor(x))
sum(cat_vars)
## [1] 4
# Đếm số biến thời gian
date_vars <- sapply(Data, function(x) inherits(x, "Date") | inherits(x, "POSIXct"))
sum(date_vars)
## [1] 1
# Liệt kê tên biến theo loại
names(Data)[num_vars] # Định lượng
## [1] "Employee_ID" "Age"
## [3] "Years_At_Company" "Performance_Score"
## [5] "Monthly_Salary" "Work_Hours_Per_Week"
## [7] "Projects_Handled" "Overtime_Hours"
## [9] "Sick_Days" "Remote_Work_Frequency"
## [11] "Team_Size" "Training_Hours"
## [13] "Promotions" "Employee_Satisfaction_Score"
names(Data)[cat_vars] # Định tính
## [1] "Department" "Gender" "Job_Title" "Education_Level"
names(Data)[date_vars] # Kiểu thời gian
## [1] "Hire_Date"
Sau khi thực hiện phân loại kiểu dữ liệu, ta xác định được: Các biến định lượng gồm các thông tin có thể đo lường bằng số như: tuổi, lương, số năm làm việc, điểm hiệu suất, số giờ làm việc mỗi tuần,… Các biến định tính gồm các thông tin dạng phân loại như: giới tính, phòng ban, trình độ học vấn, chức danh công việc,… Biến thời gian gồm Hire_Date – ngày bắt đầu làm việc. Việc phân loại này giúp lựa chọn phương pháp xử lý và biểu đồ phù hợp cho từng biến, đảm bảo phân tích đúng bản chất dữ liệu nhân sự.
library(dplyr)
Data %>%
group_by(Department) %>%
summarise(
Mean_Salary = mean(Monthly_Salary),
Mean_Performance = mean(Performance_Score)
)
## # A tibble: 9 × 3
## Department Mean_Salary Mean_Performance
## <chr> <dbl> <dbl>
## 1 Customer Support 6404. 3.00
## 2 Engineering 6417. 3.02
## 3 Finance 6399. 2.98
## 4 HR 6400. 3.00
## 5 IT 6415. 3
## 6 Legal 6391. 2.98
## 7 Marketing 6378. 2.98
## 8 Operations 6412. 3.01
## 9 Sales 6413. 2.99
Lệnh group_by(Department) nhóm dữ liệu theo từng phòng ban. Hàm summarise() sau đó tính giá trị trung bình (mean) của hai biến định lượng là Monthly_Salary (lương trung bình) và Performance_Score (điểm hiệu suất trung bình) trong từng nhóm. Kết quả hiển thị dạng bảng tóm tắt (tibble), gồm 3 cột: Department: tên phòng ban. Mean_Salary: lương trung bình của nhân viên trong phòng ban đó. Mean_Performance: điểm hiệu suất trung bình của phòng ban. Bảng này cho thấy mức lương trung bình và hiệu suất làm việc trung bình của từng phòng ban trong công ty. Ví dụ: phòng Engineering có Mean_Salary và Mean_Performance cao hơn một chút, cho thấy nhân viên ở đây được trả lương tốt và có năng suất cao hơn mức trung bình. Ngược lại, các phòng như Marketing hay Finance có giá trị thấp hơn một chút, có thể phản ánh tính chất công việc hoặc chính sách đãi ngộ khác nhau giữa các bộ phận.
Data$Department <- as.factor(Data$Department)
Data$Gender <- as.factor(Data$Gender)
Trong quá trình xử lý dữ liệu, hai biến Department (phòng ban) và Gender (giới tính) ban đầu có kiểu dữ liệu character. Để đảm bảo việc phân tích nhóm và trực quan hóa dữ liệu được chính xác, hai biến này được chuyển đổi sang kiểu factor bằng hàm as.factor() trong R. Biến Department thể hiện phòng ban làm việc của nhân viên (như IT, HR, Sales, Finance,…), là cơ sở để so sánh các chỉ tiêu như lương, hiệu suất giữa các phòng ban. Biến Gender biểu thị giới tính nhân viên (Nam/Nữ), hỗ trợ phân tích sự khác biệt về lương, mức độ hài lòng giữa hai giới.
library(stringr)
Data$Job_Title <- stringr::str_to_title(Data$Job_Title)
Data$Department <- stringr::str_replace_all(Data$Department, "Dept\\.|Department", "")
Việc chuẩn hóa này đảm bảo các giá trị trong biến Department và Job_Title được đồng nhất, từ đó tránh trùng lặp khi phân tích, giúp cho các thống kê về mức lương, hiệu suất hoặc sự hài lòng theo chức danh/phòng ban trở nên chính xác và đáng tin cậy hơn.
library(ggplot2)
## Warning: package 'ggplot2' was built under R version 4.5.1
##
## Attaching package: 'ggplot2'
## The following objects are masked from 'package:psych':
##
## %+%, alpha
# Chọn một vài biến định lượng chính để kiểm tra
numeric_vars <- c("Monthly_Salary", "Work_Hours_Per_Week", "Projects_Handled",
"Overtime_Hours", "Training_Hours")
# Vẽ biểu đồ boxplot cho từng biến
for (var in numeric_vars) {
p <- ggplot(Data, aes_string(y = var)) +
geom_boxplot(fill = "steelblue", outlier.color = "red", outlier.size = 2) +
labs(title = paste("Phát hiện giá trị ngoại lai -", var),
y = var) +
theme_minimal()
print(p)
}
## Warning: `aes_string()` was deprecated in ggplot2 3.0.0.
## ℹ Please use tidy evaluation idioms with `aes()`.
## ℹ See also `vignette("ggplot2-in-packages")` for more information.
## This warning is displayed once every 8 hours.
## Call `lifecycle::last_lifecycle_warnings()` to see where this warning was
## generated.
Hàm geom_boxplot() trong ggplot2 giúp trực quan hóa phân bố dữ liệu và
xác định giá trị ngoại lai (outlier) thông qua các điểm màu đỏ nằm ngoài
khoảng tứ phân vị (IQR). aes_string(y = var) cho phép lặp tự động qua
nhiều biến, tiết kiệm thời gian và tăng tính linh hoạt. Các điểm
outlier.color = “red” biểu thị những giá trị nằm ngoài phạm vi thông
thường của biến. Việc phát hiện ngoại lai giúp xác định các trường hợp
bất thường trong dữ liệu nhân sự, ví dụ: Mức lương cao đột biến có thể
là nhân viên cấp quản lý hoặc lỗi nhập liệu. Giờ làm thêm
(Overtime_Hours) quá cao có thể phản ánh áp lực công việc hoặc phân bổ
nguồn lực chưa hợp lý. Số giờ đào tạo quá lớn có thể là chương trình
huấn luyện đặc biệt hoặc lỗi ghi nhận dữ liệu. Bước này giúp đảm bảo độ
tin cậy và tính hợp lý của dữ liệu đầu vào
for (var in numeric_vars) {
Q1 <- quantile(Data[[var]], 0.25, na.rm = TRUE)
Q3 <- quantile(Data[[var]], 0.75, na.rm = TRUE)
IQR_value <- Q3 - Q1
outliers <- Data %>%
filter(Data[[var]] > (Q3 + 1.5 * IQR_value) | Data[[var]] < (Q1 - 1.5 * IQR_value))
cat("Biến:", var, "- Số lượng giá trị ngoại lai:", nrow(outliers), "\n")
}
## Biến: Monthly_Salary - Số lượng giá trị ngoại lai: 0
## Biến: Work_Hours_Per_Week - Số lượng giá trị ngoại lai: 0
## Biến: Projects_Handled - Số lượng giá trị ngoại lai: 0
## Biến: Overtime_Hours - Số lượng giá trị ngoại lai: 0
## Biến: Training_Hours - Số lượng giá trị ngoại lai: 0
Mục đích: Trong quá trình phân tích dữ liệu, việc phát hiện các giá trị ngoại lai (outliers) giúp đảm bảo độ tin cậy của các phép thống kê và mô hình dự đoán. Các giá trị bất thường có thể làm sai lệch kết quả hoặc phản ánh các trường hợp đặc biệt (ví dụ: nhân viên có lương quá cao, làm việc quá giờ,…). Mỗi biến được kiểm tra dựa trên khoảng tứ phân vị (IQR): Giá trị nằm ngoài khoảng [Q1 - 1.5×IQR, Q3 + 1.5×IQR] được xem là ngoại lai. Kết quả cho thấy tất cả 5 biến định lượng chính đều không có giá trị nằm ngoài khoảng này. Điều đó chứng tỏ dữ liệu sạch, ổn định, không có điểm bất thường trong các biến về lương, giờ làm việc, dự án, làm thêm, hay đào tạo. Các biến phản ánh hiệu suất và điều kiện làm việc của nhân viên có sự phân bố hợp lý — ví dụ: Không có nhân viên nào có mức lương hay giờ làm vượt trội bất thường. Số lượng dự án, giờ đào tạo và làm thêm đều nằm trong giới hạn bình thường. Điều này giúp đảm bảo rằng khi phân tích hiệu suất làm việc, mức độ hài lòng, hoặc dự đoán nghỉ việc, kết quả sẽ không bị ảnh hưởng bởi giá trị cực đoan. Bộ dữ liệu nhân sự được xây dựng khá hoàn chỉnh, không tồn tại giá trị ngoại lai đáng kể. Do đó, không cần thực hiện bước loại bỏ hoặc xử lý ngoại lai, có thể chuyển sang bước tiếp theo (chuẩn hóa và mã hóa dữ liệu).
Data$Gender_Code <- ifelse(Data$Gender == "Male", 1, ifelse(Data$Gender == "Female", 0, 2))
Data$Income_per_Hour <- Data$Monthly_Salary / (4 * Data$Work_Hours_Per_Week)
Data$Tenure_Years <- as.numeric(difftime(Sys.Date(), Data$Hire_Date, units = "days")) / 365
Data$Monthly_Salary_Scaled <- scale(Data$Monthly_Salary)
Data$Age_Group <- cut(Data$Age, breaks=c(20,30,40,50,60), labels=c("20-30","31-40","41-50","51-60"))
summary(Data$Age)
## Min. 1st Qu. Median Mean 3rd Qu. Max.
## 22.00 31.00 41.00 41.03 51.00 60.00
Data %>% filter(Age < 18 | Age > 65)
## # A tibble: 0 × 25
## # ℹ 25 variables: Employee_ID <dbl>, Department <chr>, Gender <fct>, Age <dbl>,
## # Job_Title <chr>, Hire_Date <date>, Years_At_Company <dbl>,
## # Education_Level <chr>, Performance_Score <dbl>, Monthly_Salary <dbl>,
## # Work_Hours_Per_Week <dbl>, Projects_Handled <dbl>, Overtime_Hours <dbl>,
## # Sick_Days <dbl>, Remote_Work_Frequency <dbl>, Team_Size <dbl>,
## # Training_Hours <dbl>, Promotions <dbl>, Employee_Satisfaction_Score <dbl>,
## # Resigned <lgl>, Gender_Code <dbl>, Income_per_Hour <dbl>, …
library(corrplot)
## Warning: package 'corrplot' was built under R version 4.5.1
## corrplot 0.95 loaded
corr_data <- Data %>%
select(Monthly_Salary, Performance_Score, Age, Years_At_Company, Training_Hours)
corrplot(cor(corr_data), method = "circle")
### 2.10. Mã hóa thứ bậc cho trình độ học vấn
Data$Education_Level <- factor(Data$Education_Level,
levels = c("High School", "Bachelor", "Master", "PhD"),
ordered = TRUE)
Data$Education_Code <- as.numeric(Data$Education_Level)
Data$Salary_log <- log(Data$Monthly_Salary)
Data$Resigned_Label <- ifelse(Data$Resigned == TRUE, "Đã nghỉ việc", "Còn làm việc")
Data$Performance_Level <- cut(Data$Performance_Score,
breaks = c(0,2,3.5,5),
labels = c("Thấp", "Trung bình", "Cao"))
z_salary <- scale(Data$Monthly_Salary)
Data$outlier_flag <- ifelse(abs(z_salary) > 3, 1, 0)
table(Data$outlier_flag)
##
## 0
## 100000
Data$Monthly_Salary <- round(Data$Monthly_Salary, 0)
Data$Performance_Score <- round(Data$Performance_Score, 1)
install.packages("skimr")
## Installing package into 'C:/Users/Admin/AppData/Local/R/win-library/4.5'
## (as 'lib' is unspecified)
## package 'skimr' successfully unpacked and MD5 sums checked
##
## The downloaded binary packages are in
## C:\Users\Admin\AppData\Local\Temp\RtmpKYkmzk\downloaded_packages
install.packages("corrplot")
## Warning: package 'corrplot' is in use and will not be installed
library(dplyr)
library(ggplot2)
library(psych)
library(skimr)
## Warning: package 'skimr' was built under R version 4.5.1
library(corrplot)
describe(Data)
## Warning in FUN(newX[, i], ...): no non-missing arguments to min; returning Inf
## Warning in FUN(newX[, i], ...): no non-missing arguments to min; returning Inf
## Warning in FUN(newX[, i], ...): no non-missing arguments to max; returning -Inf
## Warning in FUN(newX[, i], ...): no non-missing arguments to max; returning -Inf
## vars n mean sd median trimmed
## Employee_ID 1 1e+05 50000.50 28867.66 50000.50 50000.50
## Department* 2 1e+05 5.01 2.58 5.00 5.01
## Gender* 3 1e+05 1.56 0.57 2.00 1.52
## Age 4 1e+05 41.03 11.24 41.00 41.04
## Job_Title* 5 1e+05 4.01 2.00 4.00 4.01
## Hire_Date 6 1e+05 NaN NA NA NaN
## Years_At_Company 7 1e+05 4.48 2.87 4.00 4.47
## Education_Level* 8 1e+05 1.95 0.81 2.00 1.87
## Performance_Score 9 1e+05 3.00 1.41 3.00 2.99
## Monthly_Salary 10 1e+05 6403.21 1372.51 6500.00 6385.86
## Work_Hours_Per_Week 11 1e+05 44.96 8.94 45.00 44.95
## Projects_Handled 12 1e+05 24.43 14.47 24.00 24.41
## Overtime_Hours 13 1e+05 14.51 8.66 15.00 14.52
## Sick_Days 14 1e+05 7.01 4.33 7.00 7.01
## Remote_Work_Frequency 15 1e+05 50.09 35.35 50.00 50.11
## Team_Size 16 1e+05 10.01 5.50 10.00 10.01
## Training_Hours 17 1e+05 49.51 28.89 49.00 49.51
## Promotions 18 1e+05 1.00 0.82 1.00 1.00
## Employee_Satisfaction_Score 19 1e+05 3.00 1.15 3.00 3.00
## Resigned 20 1e+05 NaN NA NA NaN
## Gender_Code 21 1e+05 0.56 0.57 1.00 0.52
## Income_per_Hour 22 1e+05 37.13 11.25 35.55 36.30
## Tenure_Years 23 1e+05 6.12 2.88 6.10 6.12
## Monthly_Salary_Scaled 24 1e+05 0.00 1.00 0.07 -0.01
## Age_Group* 25 1e+05 2.54 1.11 3.00 2.55
## Education_Code 26 1e+05 1.95 0.81 2.00 1.87
## Salary_log 27 1e+05 8.74 0.22 8.78 8.75
## Resigned_Label* 28 1e+05 1.10 0.30 1.00 1.00
## Performance_Level* 29 1e+05 2.00 0.89 2.00 2.00
## outlier_flag 30 1e+05 0.00 0.00 0.00 0.00
## mad min max range skew kurtosis
## Employee_ID 37065.00 1.00 100000.00 99999.00 0.00 -1.20
## Department* 2.97 1.00 9.00 8.00 -0.01 -1.23
## Gender* 1.48 1.00 3.00 2.00 0.41 -0.78
## Age 14.83 22.00 60.00 38.00 -0.01 -1.20
## Job_Title* 2.97 1.00 7.00 6.00 -0.01 -1.25
## Hire_Date NA Inf -Inf -Inf NA NA
## Years_At_Company 2.97 0.00 10.00 10.00 0.01 -1.22
## Education_Level* 0.00 1.00 4.00 3.00 0.67 0.13
## Performance_Score 1.48 1.00 5.00 4.00 0.00 -1.30
## Monthly_Salary 1630.86 3850.00 9000.00 5150.00 0.10 -0.88
## Work_Hours_Per_Week 11.86 30.00 60.00 30.00 0.01 -1.20
## Projects_Handled 19.27 0.00 49.00 49.00 0.01 -1.21
## Overtime_Hours 11.86 0.00 29.00 29.00 0.00 -1.20
## Sick_Days 5.93 0.00 14.00 14.00 0.00 -1.22
## Remote_Work_Frequency 37.06 0.00 100.00 100.00 0.00 -1.30
## Team_Size 7.41 1.00 19.00 18.00 0.00 -1.21
## Training_Hours 37.06 0.00 99.00 99.00 0.00 -1.20
## Promotions 1.48 0.00 2.00 2.00 0.00 -1.50
## Employee_Satisfaction_Score 1.47 1.00 5.00 4.00 0.00 -1.19
## Resigned NA Inf -Inf -Inf NA NA
## Gender_Code 1.48 0.00 2.00 2.00 0.41 -0.78
## Income_per_Hour 11.00 16.04 75.00 58.96 0.66 0.10
## Tenure_Years 3.70 1.15 11.15 10.00 0.01 -1.20
## Monthly_Salary_Scaled 1.19 -1.86 1.89 3.75 0.10 -0.88
## Age_Group* 1.48 1.00 4.00 3.00 -0.04 -1.33
## Education_Code 0.00 1.00 4.00 3.00 0.67 0.13
## Salary_log 0.25 8.26 9.10 0.85 -0.27 -0.76
## Resigned_Label* 0.00 1.00 2.00 1.00 2.66 5.10
## Performance_Level* 1.48 1.00 3.00 2.00 0.01 -1.75
## outlier_flag 0.00 0.00 0.00 0.00 NaN NaN
## se
## Employee_ID 91.29
## Department* 0.01
## Gender* 0.00
## Age 0.04
## Job_Title* 0.01
## Hire_Date NA
## Years_At_Company 0.01
## Education_Level* 0.00
## Performance_Score 0.00
## Monthly_Salary 4.34
## Work_Hours_Per_Week 0.03
## Projects_Handled 0.05
## Overtime_Hours 0.03
## Sick_Days 0.01
## Remote_Work_Frequency 0.11
## Team_Size 0.02
## Training_Hours 0.09
## Promotions 0.00
## Employee_Satisfaction_Score 0.00
## Resigned NA
## Gender_Code 0.00
## Income_per_Hour 0.04
## Tenure_Years 0.01
## Monthly_Salary_Scaled 0.00
## Age_Group* 0.00
## Education_Code 0.00
## Salary_log 0.00
## Resigned_Label* 0.00
## Performance_Level* 0.00
## outlier_flag 0.00
skim(Data)
| Name | Data |
| Number of rows | 100000 |
| Number of columns | 30 |
| _______________________ | |
| Column type frequency: | |
| character | 3 |
| Date | 1 |
| factor | 4 |
| logical | 1 |
| numeric | 21 |
| ________________________ | |
| Group variables | None |
Variable type: character
| skim_variable | n_missing | complete_rate | min | max | empty | n_unique | whitespace |
|---|---|---|---|---|---|---|---|
| Department | 0 | 1 | 2 | 16 | 0 | 9 | 0 |
| Job_Title | 0 | 1 | 7 | 10 | 0 | 7 | 0 |
| Resigned_Label | 0 | 1 | 12 | 12 | 0 | 2 | 0 |
Variable type: Date
| skim_variable | n_missing | complete_rate | min | max | median | n_unique |
|---|---|---|---|---|---|---|
| Hire_Date | 0 | 1 | 2014-09-07 | 2024-09-03 | 2019-09-21 | 3650 |
Variable type: factor
| skim_variable | n_missing | complete_rate | ordered | n_unique | top_counts |
|---|---|---|---|---|---|
| Gender | 0 | 1 | FALSE | 3 | Mal: 48031, Fem: 48001, Oth: 3968 |
| Education_Level | 0 | 1 | TRUE | 4 | Bac: 50041, Hig: 30004, Mas: 14904, PhD: 5051 |
| Age_Group | 0 | 1 | FALSE | 4 | 41-: 25721, 51-: 25713, 31-: 25535, 20-: 23031 |
| Performance_Level | 0 | 1 | FALSE | 3 | Thấ: 40133, Cao: 39868, Tru: 19999 |
Variable type: logical
| skim_variable | n_missing | complete_rate | mean | count |
|---|---|---|---|---|
| Resigned | 0 | 1 | 0.1 | FAL: 89990, TRU: 10010 |
Variable type: numeric
| skim_variable | n_missing | complete_rate | mean | sd | p0 | p25 | p50 | p75 | p100 | hist |
|---|---|---|---|---|---|---|---|---|---|---|
| Employee_ID | 0 | 1 | 50000.50 | 28867.66 | 1.00 | 25000.75 | 50000.50 | 75000.25 | 100000.00 | ▇▇▇▇▇ |
| Age | 0 | 1 | 41.03 | 11.24 | 22.00 | 31.00 | 41.00 | 51.00 | 60.00 | ▇▇▇▇▇ |
| Years_At_Company | 0 | 1 | 4.48 | 2.87 | 0.00 | 2.00 | 4.00 | 7.00 | 10.00 | ▇▅▅▅▂ |
| Performance_Score | 0 | 1 | 3.00 | 1.41 | 1.00 | 2.00 | 3.00 | 4.00 | 5.00 | ▇▇▇▇▇ |
| Monthly_Salary | 0 | 1 | 6403.21 | 1372.51 | 3850.00 | 5250.00 | 6500.00 | 7500.00 | 9000.00 | ▅▇▇▇▅ |
| Work_Hours_Per_Week | 0 | 1 | 44.96 | 8.94 | 30.00 | 37.00 | 45.00 | 53.00 | 60.00 | ▇▇▇▇▇ |
| Projects_Handled | 0 | 1 | 24.43 | 14.47 | 0.00 | 12.00 | 24.00 | 37.00 | 49.00 | ▇▇▇▇▇ |
| Overtime_Hours | 0 | 1 | 14.51 | 8.66 | 0.00 | 7.00 | 15.00 | 22.00 | 29.00 | ▇▇▇▇▇ |
| Sick_Days | 0 | 1 | 7.01 | 4.33 | 0.00 | 3.00 | 7.00 | 11.00 | 14.00 | ▇▇▇▇▇ |
| Remote_Work_Frequency | 0 | 1 | 50.09 | 35.35 | 0.00 | 25.00 | 50.00 | 75.00 | 100.00 | ▇▇▇▇▇ |
| Team_Size | 0 | 1 | 10.01 | 5.50 | 1.00 | 5.00 | 10.00 | 15.00 | 19.00 | ▇▇▆▇▇ |
| Training_Hours | 0 | 1 | 49.51 | 28.89 | 0.00 | 25.00 | 49.00 | 75.00 | 99.00 | ▇▇▇▇▇ |
| Promotions | 0 | 1 | 1.00 | 0.82 | 0.00 | 0.00 | 1.00 | 2.00 | 2.00 | ▇▁▇▁▇ |
| Employee_Satisfaction_Score | 0 | 1 | 3.00 | 1.15 | 1.00 | 2.01 | 3.00 | 3.99 | 5.00 | ▇▇▇▇▇ |
| Gender_Code | 0 | 1 | 0.56 | 0.57 | 0.00 | 0.00 | 1.00 | 1.00 | 2.00 | ▇▁▇▁▁ |
| Income_per_Hour | 0 | 1 | 37.13 | 11.25 | 16.04 | 28.68 | 35.55 | 43.88 | 75.00 | ▅▇▅▂▁ |
| Tenure_Years | 0 | 1 | 6.12 | 2.88 | 1.15 | 3.62 | 6.10 | 8.61 | 11.15 | ▇▇▇▇▇ |
| Monthly_Salary_Scaled | 0 | 1 | 0.00 | 1.00 | -1.86 | -0.84 | 0.07 | 0.80 | 1.89 | ▅▇▇▇▅ |
| Education_Code | 0 | 1 | 1.95 | 0.81 | 1.00 | 1.00 | 2.00 | 2.00 | 4.00 | ▅▇▁▂▁ |
| Salary_log | 0 | 1 | 8.74 | 0.22 | 8.26 | 8.57 | 8.78 | 8.92 | 9.10 | ▃▅▆▇▆ |
| outlier_flag | 0 | 1 | 0.00 | 0.00 | 0.00 | 0.00 | 0.00 | 0.00 | 0.00 | ▁▁▇▁▁ |
Data %>%
summarise(across(where(is.numeric),
list(mean = mean, min = min, max = max), na.rm = TRUE))
## Warning: There was 1 warning in `summarise()`.
## ℹ In argument: `across(...)`.
## Caused by warning:
## ! The `...` argument of `across()` is deprecated as of dplyr 1.1.0.
## Supply arguments directly to `.fns` through an anonymous function instead.
##
## # Previously
## across(a:b, mean, na.rm = TRUE)
##
## # Now
## across(a:b, \(x) mean(x, na.rm = TRUE))
## # A tibble: 1 × 63
## Employee_ID_mean Employee_ID_min Employee_ID_max Age_mean Age_min Age_max
## <dbl> <dbl> <dbl> <dbl> <dbl> <dbl>
## 1 50000. 1 100000 41.0 22 60
## # ℹ 57 more variables: Years_At_Company_mean <dbl>, Years_At_Company_min <dbl>,
## # Years_At_Company_max <dbl>, Performance_Score_mean <dbl>,
## # Performance_Score_min <dbl>, Performance_Score_max <dbl>,
## # Monthly_Salary_mean <dbl>, Monthly_Salary_min <dbl>,
## # Monthly_Salary_max <dbl>, Work_Hours_Per_Week_mean <dbl>,
## # Work_Hours_Per_Week_min <dbl>, Work_Hours_Per_Week_max <dbl>,
## # Projects_Handled_mean <dbl>, Projects_Handled_min <dbl>, …
Data %>%
count(Department, name = "SoLuong") %>%
arrange(desc(SoLuong))
## # A tibble: 9 × 2
## Department SoLuong
## <chr> <int>
## 1 Marketing 11216
## 2 Finance 11200
## 3 Operations 11181
## 4 IT 11131
## 5 Sales 11122
## 6 Legal 11118
## 7 Customer Support 11116
## 8 HR 10960
## 9 Engineering 10956
Data %>%
count(Gender) %>%
mutate(Percent = round(n / sum(n) * 100, 2))
## # A tibble: 3 × 3
## Gender n Percent
## <fct> <int> <dbl>
## 1 Female 48001 48
## 2 Male 48031 48.0
## 3 Other 3968 3.97
Data <- Data %>%
mutate(
Nhom_Tuoi = case_when(
Age < 30 ~ "Dưới 30",
Age >= 30 & Age < 40 ~ "30-39",
Age >= 40 & Age < 50 ~ "40-49",
Age >= 50 ~ "Từ 50 trở lên"
)
)
Data %>%
group_by(Nhom_Tuoi, Gender) %>%
summarise(LuongTB = mean(Monthly_Salary, na.rm = TRUE)) %>%
arrange(Nhom_Tuoi)
## `summarise()` has grouped output by 'Nhom_Tuoi'. You can override using the
## `.groups` argument.
## # A tibble: 12 × 3
## # Groups: Nhom_Tuoi [4]
## Nhom_Tuoi Gender LuongTB
## <chr> <fct> <dbl>
## 1 30-39 Female 6400.
## 2 30-39 Male 6399.
## 3 30-39 Other 6414.
## 4 40-49 Female 6414.
## 5 40-49 Male 6394.
## 6 40-49 Other 6427.
## 7 Dưới 30 Female 6403.
## 8 Dưới 30 Male 6398.
## 9 Dưới 30 Other 6392.
## 10 Từ 50 trở lên Female 6403.
## 11 Từ 50 trở lên Male 6410.
## 12 Từ 50 trở lên Other 6421.
Data <- Data %>%
mutate(Nhom_Tuoi = case_when(
Age < 25 ~ "Dưới 25",
Age >= 25 & Age < 35 ~ "25–34",
Age >= 35 & Age < 45 ~ "35–44",
Age >= 45 ~ "Trên 45"
))
table(Data$Nhom_Tuoi)
##
## 25–34 35–44 Dưới 25 Trên 45
## 25607 25597 7608 41188
Data %>%
group_by(Department) %>%
summarise(LuongTB = mean(Monthly_Salary, na.rm = TRUE)) %>%
mutate(XepHang = rank(-LuongTB))
## # A tibble: 9 × 3
## Department LuongTB XepHang
## <chr> <dbl> <dbl>
## 1 Customer Support 6404. 5
## 2 Engineering 6417. 1
## 3 Finance 6399. 7
## 4 HR 6400. 6
## 5 IT 6415. 2
## 6 Legal 6391. 8
## 7 Marketing 6378. 9
## 8 Operations 6412. 4
## 9 Sales 6413. 3
Data %>%
group_by(Education_Level) %>%
summarise(
Min = min(Monthly_Salary, na.rm = TRUE),
Q1 = quantile(Monthly_Salary, 0.25, na.rm = TRUE),
Median = median(Monthly_Salary, na.rm = TRUE),
Q3 = quantile(Monthly_Salary, 0.75, na.rm = TRUE),
Max = max(Monthly_Salary, na.rm = TRUE)
)
## # A tibble: 4 × 6
## Education_Level Min Q1 Median Q3 Max
## <ord> <dbl> <dbl> <dbl> <dbl> <dbl>
## 1 High School 3850 5250 6500 7500 9000
## 2 Bachelor 3850 5250 6500 7500 9000
## 3 Master 3850 5250 6500 7500 9000
## 4 PhD 3850 5400 6500 7500 9000
num_vars <- Data %>% select(where(is.numeric))
cor_matrix <- cor(num_vars, use = "complete.obs")
## Warning in cor(num_vars, use = "complete.obs"): the standard deviation is zero
cor_matrix
## Employee_ID Age Years_At_Company
## Employee_ID 1.0000000000 4.010169e-03 -7.175044e-03
## Age 0.0040101693 1.000000e+00 7.807067e-05
## Years_At_Company -0.0071750437 7.807067e-05 1.000000e+00
## Performance_Score -0.0020774164 1.597668e-03 1.597730e-03
## Monthly_Salary -0.0020502697 2.756751e-03 -6.446329e-04
## Work_Hours_Per_Week -0.0009682099 -3.049750e-03 2.577616e-03
## Projects_Handled -0.0007055068 -1.726106e-03 2.962663e-03
## Overtime_Hours -0.0052544207 1.875477e-03 1.964914e-03
## Sick_Days 0.0007453207 6.981262e-03 -4.371378e-03
## Remote_Work_Frequency -0.0003470926 -4.671609e-03 -2.443322e-03
## Team_Size 0.0020271653 -3.411191e-03 3.249903e-03
## Training_Hours -0.0029659719 2.044696e-03 2.696411e-03
## Promotions -0.0007783032 -2.887805e-03 -2.736752e-03
## Employee_Satisfaction_Score -0.0015949690 -1.242389e-04 -3.180180e-03
## Gender_Code 0.0009785420 -7.307428e-04 -3.676997e-03
## Income_per_Hour -0.0006911393 3.882076e-03 -1.511366e-03
## Tenure_Years -0.0069117415 3.607415e-04 9.949547e-01
## Monthly_Salary_Scaled -0.0020502697 2.756751e-03 -6.446329e-04
## Education_Code -0.0018789701 3.824126e-03 -9.113552e-04
## Salary_log -0.0017915120 2.933448e-03 -9.981241e-04
## outlier_flag NA NA NA
## Performance_Score Monthly_Salary
## Employee_ID -0.0020774164 -0.0020502697
## Age 0.0015976678 0.0027567514
## Years_At_Company 0.0015977303 -0.0006446329
## Performance_Score 1.0000000000 0.5100348076
## Monthly_Salary 0.5100348076 1.0000000000
## Work_Hours_Per_Week -0.0056272519 -0.0023471937
## Projects_Handled 0.0006404622 -0.0019249034
## Overtime_Hours -0.0013116293 -0.0030286716
## Sick_Days 0.0029943235 0.0036103835
## Remote_Work_Frequency 0.0017328664 -0.0004640546
## Team_Size -0.0051744134 0.0029715225
## Training_Hours 0.0023579401 -0.0010876011
## Promotions -0.0035012983 -0.0019402037
## Employee_Satisfaction_Score 0.0016962790 0.0010827334
## Gender_Code 0.0033283897 -0.0005024205
## Income_per_Hour 0.3652205329 0.7095713299
## Tenure_Years 0.0013313701 -0.0011698334
## Monthly_Salary_Scaled 0.5100348076 1.0000000000
## Education_Code 0.0018269621 0.0055555788
## Salary_log 0.4984682532 0.9931557833
## outlier_flag NA NA
## Work_Hours_Per_Week Projects_Handled Overtime_Hours
## Employee_ID -0.0009682099 -0.0007055068 -0.005254421
## Age -0.0030497497 -0.0017261058 0.001875477
## Years_At_Company 0.0025776162 0.0029626628 0.001964914
## Performance_Score -0.0056272519 0.0006404622 -0.001311629
## Monthly_Salary -0.0023471937 -0.0019249034 -0.003028672
## Work_Hours_Per_Week 1.0000000000 -0.0041829031 0.005787021
## Projects_Handled -0.0041829031 1.0000000000 0.004106915
## Overtime_Hours 0.0057870213 0.0041069149 1.000000000
## Sick_Days -0.0008383590 -0.0049951817 0.004254812
## Remote_Work_Frequency -0.0046182275 0.0004843081 -0.004349288
## Team_Size 0.0007902768 0.0038130125 0.002174617
## Training_Hours 0.0012871484 0.0022111028 0.002939398
## Promotions 0.0002382231 -0.0023438196 -0.002537371
## Employee_Satisfaction_Score 0.0005299660 0.0061258039 0.001052243
## Gender_Code 0.0030297598 0.0020483138 -0.003142553
## Income_per_Hour -0.6788761210 0.0011201122 -0.005860099
## Tenure_Years 0.0033883197 0.0024509233 0.001749499
## Monthly_Salary_Scaled -0.0023471937 -0.0019249034 -0.003028672
## Education_Code -0.0018123271 -0.0015197491 0.007493310
## Salary_log -0.0019864042 -0.0022188744 -0.002688654
## outlier_flag NA NA NA
## Sick_Days Remote_Work_Frequency Team_Size
## Employee_ID 0.0007453207 -0.0003470926 0.0020271653
## Age 0.0069812624 -0.0046716085 -0.0034111911
## Years_At_Company -0.0043713776 -0.0024433223 0.0032499029
## Performance_Score 0.0029943235 0.0017328664 -0.0051744134
## Monthly_Salary 0.0036103835 -0.0004640546 0.0029715225
## Work_Hours_Per_Week -0.0008383590 -0.0046182275 0.0007902768
## Projects_Handled -0.0049951817 0.0004843081 0.0038130125
## Overtime_Hours 0.0042548124 -0.0043492880 0.0021746169
## Sick_Days 1.0000000000 0.0004782113 0.0001493077
## Remote_Work_Frequency 0.0004782113 1.0000000000 -0.0006677778
## Team_Size 0.0001493077 -0.0006677778 1.0000000000
## Training_Hours 0.0003468368 0.0052273677 0.0027358291
## Promotions -0.0030440420 -0.0005365374 0.0006476629
## Employee_Satisfaction_Score -0.0008929077 -0.0014080411 0.0009435061
## Gender_Code 0.0019069739 0.0014421629 -0.0035767307
## Income_per_Hour 0.0030818680 0.0029304538 0.0015846071
## Tenure_Years -0.0044099108 -0.0026209039 0.0034104045
## Monthly_Salary_Scaled 0.0036103835 -0.0004640546 0.0029715225
## Education_Code -0.0026007225 0.0023716776 0.0011924871
## Salary_log 0.0033390196 -0.0004589593 0.0031194449
## outlier_flag NA NA NA
## Training_Hours Promotions
## Employee_ID -0.0029659719 -0.0007783032
## Age 0.0020446964 -0.0028878052
## Years_At_Company 0.0026964107 -0.0027367522
## Performance_Score 0.0023579401 -0.0035012983
## Monthly_Salary -0.0010876011 -0.0019402037
## Work_Hours_Per_Week 0.0012871484 0.0002382231
## Projects_Handled 0.0022111028 -0.0023438196
## Overtime_Hours 0.0029393975 -0.0025373710
## Sick_Days 0.0003468368 -0.0030440420
## Remote_Work_Frequency 0.0052273677 -0.0005365374
## Team_Size 0.0027358291 0.0006476629
## Training_Hours 1.0000000000 0.0009325892
## Promotions 0.0009325892 1.0000000000
## Employee_Satisfaction_Score -0.0014892218 0.0002268193
## Gender_Code -0.0045291464 0.0016893454
## Income_per_Hour -0.0023492786 -0.0015630480
## Tenure_Years 0.0028224575 -0.0027728045
## Monthly_Salary_Scaled -0.0010876011 -0.0019402037
## Education_Code -0.0008259264 0.0007700870
## Salary_log -0.0013740890 -0.0017717160
## outlier_flag NA NA
## Employee_Satisfaction_Score Gender_Code
## Employee_ID -1.594969e-03 0.0009785420
## Age -1.242389e-04 -0.0007307428
## Years_At_Company -3.180180e-03 -0.0036769971
## Performance_Score 1.696279e-03 0.0033283897
## Monthly_Salary 1.082733e-03 -0.0005024205
## Work_Hours_Per_Week 5.299660e-04 0.0030297598
## Projects_Handled 6.125804e-03 0.0020483138
## Overtime_Hours 1.052243e-03 -0.0031425532
## Sick_Days -8.929077e-04 0.0019069739
## Remote_Work_Frequency -1.408041e-03 0.0014421629
## Team_Size 9.435061e-04 -0.0035767307
## Training_Hours -1.489222e-03 -0.0045291464
## Promotions 2.268193e-04 0.0016893454
## Employee_Satisfaction_Score 1.000000e+00 -0.0047025556
## Gender_Code -4.702556e-03 1.0000000000
## Income_per_Hour 9.901409e-06 -0.0021507012
## Tenure_Years -3.000590e-03 -0.0034907672
## Monthly_Salary_Scaled 1.082733e-03 -0.0005024205
## Education_Code -3.167152e-03 -0.0025618943
## Salary_log 1.237863e-03 -0.0008487764
## outlier_flag NA NA
## Income_per_Hour Tenure_Years Monthly_Salary_Scaled
## Employee_ID -6.911393e-04 -0.0069117415 -0.0020502697
## Age 3.882076e-03 0.0003607415 0.0027567514
## Years_At_Company -1.511366e-03 0.9949547064 -0.0006446329
## Performance_Score 3.652205e-01 0.0013313701 0.5100348076
## Monthly_Salary 7.095713e-01 -0.0011698334 1.0000000000
## Work_Hours_Per_Week -6.788761e-01 0.0033883197 -0.0023471937
## Projects_Handled 1.120112e-03 0.0024509233 -0.0019249034
## Overtime_Hours -5.860099e-03 0.0017494988 -0.0030286716
## Sick_Days 3.081868e-03 -0.0044099108 0.0036103835
## Remote_Work_Frequency 2.930454e-03 -0.0026209039 -0.0004640546
## Team_Size 1.584607e-03 0.0034104045 0.0029715225
## Training_Hours -2.349279e-03 0.0028224575 -0.0010876011
## Promotions -1.563048e-03 -0.0027728045 -0.0019402037
## Employee_Satisfaction_Score 9.901409e-06 -0.0030005904 0.0010827334
## Gender_Code -2.150701e-03 -0.0034907672 -0.0005024205
## Income_per_Hour 1.000000e+00 -0.0025908506 0.7095713299
## Tenure_Years -2.590851e-03 1.0000000000 -0.0011698334
## Monthly_Salary_Scaled 7.095713e-01 -0.0011698334 1.0000000000
## Education_Code 4.468437e-03 -0.0007234356 0.0055555788
## Salary_log 7.044228e-01 -0.0015312002 0.9931557833
## outlier_flag NA NA NA
## Education_Code Salary_log outlier_flag
## Employee_ID -0.0018789701 -0.0017915120 NA
## Age 0.0038241263 0.0029334479 NA
## Years_At_Company -0.0009113552 -0.0009981241 NA
## Performance_Score 0.0018269621 0.4984682532 NA
## Monthly_Salary 0.0055555788 0.9931557833 NA
## Work_Hours_Per_Week -0.0018123271 -0.0019864042 NA
## Projects_Handled -0.0015197491 -0.0022188744 NA
## Overtime_Hours 0.0074933096 -0.0026886542 NA
## Sick_Days -0.0026007225 0.0033390196 NA
## Remote_Work_Frequency 0.0023716776 -0.0004589593 NA
## Team_Size 0.0011924871 0.0031194449 NA
## Training_Hours -0.0008259264 -0.0013740890 NA
## Promotions 0.0007700870 -0.0017717160 NA
## Employee_Satisfaction_Score -0.0031671522 0.0012378629 NA
## Gender_Code -0.0025618943 -0.0008487764 NA
## Income_per_Hour 0.0044684368 0.7044228497 NA
## Tenure_Years -0.0007234356 -0.0015312002 NA
## Monthly_Salary_Scaled 0.0055555788 0.9931557833 NA
## Education_Code 1.0000000000 0.0058748496 NA
## Salary_log 0.0058748496 1.0000000000 NA
## outlier_flag NA NA 1
Data %>%
summarise(TyLeNghiViec = mean(Resigned) * 100)
## # A tibble: 1 × 1
## TyLeNghiViec
## <dbl>
## 1 10.0
Data %>%
mutate(CV_Luong = sd(Monthly_Salary, na.rm = TRUE) / mean(Monthly_Salary, na.rm = TRUE) * 100)
## # A tibble: 100,000 × 32
## Employee_ID Department Gender Age Job_Title Hire_Date Years_At_Company
## <dbl> <chr> <fct> <dbl> <chr> <date> <dbl>
## 1 1 IT Male 55 Speciali… 2022-01-19 2
## 2 2 Finance Male 29 Developer 2024-04-18 0
## 3 3 Finance Male 55 Speciali… 2015-10-26 8
## 4 4 Customer Supp… Female 48 Analyst 2016-10-22 7
## 5 5 Engineering Female 36 Analyst 2021-07-23 3
## 6 6 IT Male 43 Manager 2016-08-14 8
## 7 7 IT Male 37 Technici… 2023-08-28 1
## 8 8 Engineering Female 55 Engineer 2014-10-27 9
## 9 9 Marketing Female 55 Technici… 2023-06-29 1
## 10 10 Engineering Female 45 Consulta… 2016-12-23 7
## # ℹ 99,990 more rows
## # ℹ 25 more variables: Education_Level <ord>, Performance_Score <dbl>,
## # Monthly_Salary <dbl>, Work_Hours_Per_Week <dbl>, Projects_Handled <dbl>,
## # Overtime_Hours <dbl>, Sick_Days <dbl>, Remote_Work_Frequency <dbl>,
## # Team_Size <dbl>, Training_Hours <dbl>, Promotions <dbl>,
## # Employee_Satisfaction_Score <dbl>, Resigned <lgl>, Gender_Code <dbl>,
## # Income_per_Hour <dbl>, Tenure_Years <dbl>, …
Data %>%
group_by(Resigned) %>%
summarise(DiemHaiLongTB = mean(Employee_Satisfaction_Score, na.rm = TRUE))
## # A tibble: 2 × 2
## Resigned DiemHaiLongTB
## <lgl> <dbl>
## 1 FALSE 3.00
## 2 TRUE 2.99
Data %>%
group_by(Education_Level) %>%
summarise(
LuongTB = mean(Monthly_Salary, na.rm = TRUE),
TuoiTB = mean(Age, na.rm = TRUE)
)
## # A tibble: 4 × 3
## Education_Level LuongTB TuoiTB
## <ord> <dbl> <dbl>
## 1 High School 6399. 41.0
## 2 Bachelor 6398. 41.0
## 3 Master 6417. 41.0
## 4 PhD 6432. 41.3
table(Data$Gender, Data$Education_Level)
##
## High School Bachelor Master PhD
## Female 14299 24138 7127 2437
## Male 14516 23902 7195 2418
## Other 1189 2001 582 196
cor(Data$Monthly_Salary, Data$Employee_Satisfaction_Score)
## [1] 0.001082733
Data %>%
group_by(Job_Title) %>%
summarise(DuAnTB = mean(Projects_Handled, na.rm = TRUE))
## # A tibble: 7 × 2
## Job_Title DuAnTB
## <chr> <dbl>
## 1 Analyst 24.4
## 2 Consultant 24.4
## 3 Developer 24.4
## 4 Engineer 24.5
## 5 Manager 24.3
## 6 Specialist 24.5
## 7 Technician 24.5
# Tạo biến nhóm tuổi (phân tổ theo khoảng)
Data <- Data %>%
mutate(Nhom_tuoi = cut(Age,
breaks = c(20, 30, 40, 50, 60),
labels = c("20-29", "30-39", "40-49", "50-59"),
right = FALSE)) # khoảng trái đóng, phải mở
# Phân tổ theo giới tính và nhóm tuổi
bang_phan_to <- Data %>%
group_by(Gender, Nhom_tuoi) %>%
summarise(
So_luong = n(),
Luong_TB = mean(as.numeric(Monthly_Salary), na.rm = TRUE),
Diem_HL_TB = mean(as.numeric(Employee_Satisfaction_Score), na.rm = TRUE)
) %>%
arrange(Gender, Nhom_tuoi)
## `summarise()` has grouped output by 'Gender'. You can override using the
## `.groups` argument.
# In kết quả ra màn hình
print(bang_phan_to)
## # A tibble: 15 × 5
## # Groups: Gender [3]
## Gender Nhom_tuoi So_luong Luong_TB Diem_HL_TB
## <fct> <fct> <int> <dbl> <dbl>
## 1 Female 20-29 9722 6403. 3.00
## 2 Female 30-39 12403 6400. 3.01
## 3 Female 40-49 12333 6414. 3.00
## 4 Female 50-59 12331 6400. 3.00
## 5 Female <NA> 1212 6434. 3.06
## 6 Male 20-29 9946 6398. 2.99
## 7 Male 30-39 12056 6399. 3.00
## 8 Male 40-49 12357 6394. 2.99
## 9 Male 50-59 12462 6404. 2.99
## 10 Male <NA> 1210 6469. 3.03
## 11 Other 20-29 824 6392. 2.94
## 12 Other 30-39 1006 6414. 3.00
## 13 Other 40-49 1020 6427. 3.00
## 14 Other 50-59 1005 6423. 3.00
## 15 Other <NA> 113 6405. 3.10
Data %>%
group_by(Department) %>%
summarise(
LuongTB = mean(Monthly_Salary, na.rm = TRUE),
DoLechChuan = sd(Monthly_Salary, na.rm = TRUE)
) %>%
arrange(desc(LuongTB))
## # A tibble: 9 × 3
## Department LuongTB DoLechChuan
## <chr> <dbl> <dbl>
## 1 Engineering 6417. 1365.
## 2 IT 6415. 1378.
## 3 Sales 6413. 1365.
## 4 Operations 6412. 1380.
## 5 Customer Support 6404. 1372.
## 6 HR 6400. 1369.
## 7 Finance 6399. 1364.
## 8 Legal 6391. 1376.
## 9 Marketing 6378. 1383.
# Lọc dữ liệu theo tiêu chí học vấn, hiệu suất và số ngày ốm
df_filtered2 <- Data %>%
filter(
Job_Title == "Developer",
Education_Level == "Master",
Performance_Score < 2,
Sick_Days > 5
)
print(df_filtered2)
## # A tibble: 252 × 32
## Employee_ID Department Gender Age Job_Title Hire_Date Years_At_Company
## <dbl> <chr> <fct> <dbl> <chr> <date> <dbl>
## 1 338 Operations Female 55 Developer 2017-02-07 7
## 2 670 Legal Male 47 Developer 2019-04-29 5
## 3 811 Sales Female 24 Developer 2018-06-20 6
## 4 986 IT Female 56 Developer 2020-07-31 4
## 5 1774 Finance Male 45 Developer 2022-03-27 2
## 6 2191 Legal Female 39 Developer 2016-05-06 8
## 7 2437 IT Female 36 Developer 2014-12-23 9
## 8 2783 Finance Female 43 Developer 2016-03-28 8
## 9 2847 Legal Other 53 Developer 2017-09-13 6
## 10 3119 HR Female 58 Developer 2015-09-17 8
## # ℹ 242 more rows
## # ℹ 25 more variables: Education_Level <ord>, Performance_Score <dbl>,
## # Monthly_Salary <dbl>, Work_Hours_Per_Week <dbl>, Projects_Handled <dbl>,
## # Overtime_Hours <dbl>, Sick_Days <dbl>, Remote_Work_Frequency <dbl>,
## # Team_Size <dbl>, Training_Hours <dbl>, Promotions <dbl>,
## # Employee_Satisfaction_Score <dbl>, Resigned <lgl>, Gender_Code <dbl>,
## # Income_per_Hour <dbl>, Tenure_Years <dbl>, …
library(dplyr)
library(ggplot2)
data_bar <- Data %>%
group_by(Department) %>%
summarise(n = n())
ggplot(data_bar, aes(x = Department, y = n, fill = Department)) +
geom_col() +
geom_text(aes(label = n), vjust = -0.3, color = "black", size = 4) +
labs(title = "Số lượng nhân viên theo phòng ban",
x = "Phòng ban", y = "Số lượng nhân viên") +
theme_minimal() +
theme(axis.text.x = element_text(angle = 30, hjust = 1))
### Biểu đồ 2-Cột nhóm (Gender+Department)
data_group <- Data %>%
group_by(Department, Gender) %>%
summarise(n = n())
## `summarise()` has grouped output by 'Department'. You can override using the
## `.groups` argument.
ggplot(data_group, aes(x = Department, y = n, fill = Gender)) +
geom_col(position = "dodge") +
geom_text(aes(label = n), position = position_dodge(0.9), vjust = -0.3) +
labs(title = "Số lượng nhân viên theo phòng ban và giới tính",
x = "Phòng ban", y = "Số lượng") +
theme_classic()
### Biểu đồ 3 - Boxplot: Phân bố lương theo phòng
ban
ggplot(Data, aes(x = Department, y = Monthly_Salary, fill = Department)) +
geom_boxplot() +
labs(title = "Phân bố lương theo phòng ban",
x = "Phòng ban", y = "Mức lương") +
theme_minimal() +
coord_flip()
### Biểu đồ 4 - Scatter plot: Mối quan hệ giữa tuổi và
lương
ggplot(Data, aes(x = Age, y = Monthly_Salary, color = Gender)) +
geom_point(alpha = 0.6) +
geom_smooth(method = "lm", se = FALSE, color = "black") +
labs(title = "Mối quan hệ giữa tuổi và lương",
x = "Tuổi", y = "Lương trung bình") +
theme_minimal()
## `geom_smooth()` using formula = 'y ~ x'
### Biểu đồ 5 - Density plot: Phân bố điểm hài lòng theo giới
tính
ggplot(Data, aes(x = Employee_Satisfaction_Score, fill = Gender)) +
geom_density(alpha = 0.5) +
labs(title = "Phân bố điểm hài lòng theo giới tính",
x = "Điểm hài lòng", y = "Mật độ") +
theme_light()
### Biểu đồ 6 - Histogram: Phân bố tuổi nhân viên
ggplot(Data, aes(x = Age)) +
geom_histogram(fill = "skyblue", color = "black", bins = 20) +
labs(title = "Phân bố độ tuổi nhân viên",
x = "Tuổi", y = "Số lượng") +
theme_minimal()
### Biểu đồ 7 - Pie chart: Trình độ học vấn
data_pie <- Data %>%
group_by(Education_Level) %>%
summarise(n = n())
ggplot(data_pie, aes(x = "", y = n, fill = Education_Level)) +
geom_col(width = 1) +
coord_polar(theta = "y") +
geom_text(aes(label = paste0(round(n/sum(n)*100, 1), "%")),
position = position_stack(vjust = 0.5)) +
labs(title = "Tỷ lệ trình độ học vấn của nhân viên") +
theme_void()
### Biểu đồ 8 - Line chart: Lương trung bình theo thâm
niên
data_line <- Data %>%
group_by(Years_At_Company) %>%
summarise(LuongTB = mean(Monthly_Salary, na.rm = TRUE))
ggplot(data_line, aes(x = Years_At_Company, y = LuongTB)) +
geom_line(color = "blue", linewidth = 1.2) +
geom_point(size = 2, color = "red") +
labs(title = "Lương trung bình theo thâm niên làm việc",
x = "Số năm làm việc", y = "Lương trung bình") +
theme_minimal()
### Biểu đồ 9 - Facet: Chia biểu đồ theo giới tính
ggplot(Data, aes(x = Department, y = Monthly_Salary, fill = Department)) +
geom_boxplot() +
facet_wrap(~Gender) +
labs(title = "Phân bố lương theo phòng ban và giới tính") +
theme_minimal()
### Biểu đồ 10 - Heatmap: Trung bình điểm hài lòng theo phòng
ban và giới tính
data_heat <- Data %>%
group_by(Department, Gender) %>%
summarise(SatMean = mean(Employee_Satisfaction_Score, na.rm = TRUE))
## `summarise()` has grouped output by 'Department'. You can override using the
## `.groups` argument.
ggplot(data_heat, aes(x = Department, y = Gender, fill = SatMean)) +
geom_tile() +
geom_text(aes(label = round(SatMean, 2)), color = "white") +
labs(title = "Điểm hài lòng trung bình theo phòng ban & giới tính",
x = "Phòng ban", y = "Giới tính") +
theme_minimal()
### Biểu đồ 11 - Violin Plot: Lương theo trình độ học
vấn
ggplot(Data, aes(x = Education_Level, y = Monthly_Salary, fill = Education_Level)) +
geom_violin(trim = FALSE, alpha = 0.7) +
geom_boxplot(width = 0.1, fill = "white", outlier.color = "red") +
labs(title = "Phân bố lương theo trình độ học vấn",
x = "Trình độ học vấn", y = "Mức lương") +
theme_minimal() +
theme(axis.text.x = element_text(angle = 20, hjust = 1))
### Biểu đồ 12 - Bar chart có Facet theo giới tính
Data %>%
group_by(Gender, Department) %>%
summarise(n = n()) %>%
ggplot(aes(x = Department, y = n, fill = Department)) +
geom_col() +
geom_text(aes(label = n), vjust = -0.3) +
facet_wrap(~Gender) +
labs(title = "Số lượng nhân viên theo phòng ban và giới tính",
x = "Phòng ban", y = "Số lượng") +
theme_classic()
## `summarise()` has grouped output by 'Gender'. You can override using the
## `.groups` argument.
### Biểu đồ 13 - Scatter Plot có Regression Line
ggplot(Data, aes(x = Projects_Handled, y = Performance_Score, color = Department)) +
geom_point(alpha = 0.6) +
geom_smooth(method = "lm", se = FALSE, color = "black") +
labs(title = "Mối quan hệ giữa số dự án và điểm hiệu suất làm việc",
x = "Số dự án phụ trách", y = "Điểm hiệu suất") +
theme_minimal()
## `geom_smooth()` using formula = 'y ~ x'
### Biểu đồ 14 - Histogram với đường Density
Overlay
ggplot(Data, aes(x = Work_Hours_Per_Week)) +
geom_histogram(aes(y = ..density..), bins = 20, fill = "lightblue", color = "black") +
geom_density(color = "red", linewidth = 1) +
labs(title = "Phân bố số giờ làm việc mỗi tuần",
x = "Số giờ làm việc", y = "Mật độ") +
theme_light()
## Warning: The dot-dot notation (`..density..`) was deprecated in ggplot2 3.4.0.
## ℹ Please use `after_stat(density)` instead.
## This warning is displayed once every 8 hours.
## Call `lifecycle::last_lifecycle_warnings()` to see where this warning was
## generated.
### Biểu đồ 15 - Stacked Bar: Tỷ lệ nhân viên gắn bó theo trình
độ học vấn
Data %>%
group_by(Education_Level, Stay = ifelse(Resigned == 0, "Còn làm", "Nghỉ việc")) %>%
summarise(SL = n()) %>%
ggplot(aes(x = Education_Level, y = SL, fill = Stay)) +
geom_col(position = "fill") +
geom_text(aes(label = paste0(round(100 * SL / sum(SL), 1), "%")),
position = position_fill(vjust = 0.5), color = "white", size = 3) +
scale_y_continuous(labels = scales::percent) +
labs(title = "Tỷ lệ nhân viên còn làm & nghỉ việc theo trình độ học vấn",
x = "Trình độ học vấn", y = "Tỷ lệ (%)") +
theme_minimal()
## `summarise()` has grouped output by 'Education_Level'. You can override using
## the `.groups` argument.
install.packages(“ggridges”) library(ggridges) ### Biểu đồ 16 -
Ridgeline Plot: Phân bố hiệu suất theo phòng ban
ggplot(Data, aes(x = Performance_Score, y = Department, fill = Department)) +
geom_density_ridges(alpha = 0.7) +
labs(title = "Phân bố điểm hiệu suất theo phòng ban",
x = "Điểm hiệu suất", y = "Phòng ban") +
theme_minimal() +
theme(legend.position = "none")
## Picking joint bandwidth of 0.198
### Biểu đồ 17 - Heatmap Lương trung bình theo Giới tính &
Trình độ
Data %>%
group_by(Gender, Education_Level) %>%
summarise(LuongTB = mean(Monthly_Salary, na.rm = TRUE)) %>%
ggplot(aes(x = Education_Level, y = Gender, fill = LuongTB)) +
geom_tile() +
geom_text(aes(label = round(LuongTB, 1)), color = "white") +
scale_fill_gradient(low = "skyblue", high = "darkblue") +
labs(title = "Lương trung bình theo giới tính và trình độ học vấn",
x = "Trình độ học vấn", y = "Giới tính") +
theme_minimal()
## `summarise()` has grouped output by 'Gender'. You can override using the
## `.groups` argument.
### Biểu đồ 18 – Line Chart: Điểm hài lòng trung bình theo năm
thâm niên
Data %>%
group_by(Years_At_Company) %>%
summarise(SatMean = mean(Employee_Satisfaction_Score, na.rm = TRUE)) %>%
ggplot(aes(x = Years_At_Company, y = SatMean)) +
geom_line(color = "darkgreen", linewidth = 1.2) +
geom_point(size = 3, color = "red") +
geom_text(aes(label = round(SatMean, 2)), vjust = -0.6) +
labs(title = "Mức độ hài lòng trung bình theo thâm niên",
x = "Số năm làm việc", y = "Điểm hài lòng TB") +
theme_minimal()
### Biểu đồ 19 – Bar Chart nâng cao: Tỷ lệ nghỉ việc theo phòng
ban
Data %>%
group_by(Department) %>%
summarise(TyLeNghi = mean(Resigned) * 100) %>%
ggplot(aes(x = reorder(Department, -TyLeNghi), y = TyLeNghi, fill = Department)) +
geom_col() +
geom_text(aes(label = paste0(round(TyLeNghi, 1), "%")), vjust = -0.3) +
labs(title = "Tỷ lệ nghỉ việc theo phòng ban",
x = "Phòng ban", y = "Tỷ lệ nghỉ việc (%)") +
theme_minimal() +
theme(axis.text.x = element_text(angle = 30, hjust = 1))
### Biểu đồ 20 – Facet Grid: Lương theo Giới tính & Phòng
ban
ggplot(Data, aes(x = Gender, y = Monthly_Salary, fill = Gender)) +
geom_boxplot(alpha = 0.7) +
facet_wrap(~Department) +
labs(title = "So sánh lương giữa các giới tính theo từng phòng ban",
x = "Giới tính", y = "Mức lương") +
theme_light() +
theme(axis.text.x = element_text(angle = 20, hjust = 1))
### Biểu đồ 21 - Correlation Plot: Biểu đồ tương
quan
install.packages("GGally")
## Installing package into 'C:/Users/Admin/AppData/Local/R/win-library/4.5'
## (as 'lib' is unspecified)
## package 'GGally' successfully unpacked and MD5 sums checked
##
## The downloaded binary packages are in
## C:\Users\Admin\AppData\Local\Temp\RtmpKYkmzk\downloaded_packages
library(GGally)
## Warning: package 'GGally' was built under R version 4.5.1
Data %>%
select(Age, Monthly_Salary, Years_At_Company, Performance_Score, Employee_Satisfaction_Score) %>%
ggpairs(title = "Biểu đồ ma trận tương quan giữa các biến định lượng")
# CHƯƠNG 2: PHÂN TÍCH DỮ LIỆU MÃ CHỨNG KHOÁN DBC
Mục tiêu: Trong tiểu luận này, mục tiêu chính là phân tích cấu trúc và biến động nguồn vốn của Công ty CP Tập đoàn Dabaco Việt Nam thông qua dữ liệu từ bảng cân đối kế toán trong giai đoạn nghiên cứu từ năm 2015 - 2024. Cụ thể, bài tiểu luận tập trung vào hai nhóm chỉ tiêu chính của Nguồn Vốn, bao gồm: Nợ phải trả và Vốn chủ sở hữu.
# Đọc dữ liệu
install.packages("janitor")
## Installing package into 'C:/Users/Admin/AppData/Local/R/win-library/4.5'
## (as 'lib' is unspecified)
## package 'janitor' successfully unpacked and MD5 sums checked
##
## The downloaded binary packages are in
## C:\Users\Admin\AppData\Local\Temp\RtmpKYkmzk\downloaded_packages
library(janitor)
## Warning: package 'janitor' was built under R version 4.5.1
##
## Attaching package: 'janitor'
## The following objects are masked from 'package:stats':
##
## chisq.test, fisher.test
library(readxl)
dataDBC <- read_excel("D:/NNLT/DBC/dataDBC.xlsx", sheet = "Sheet1")
df <- read_excel("D:/NNLT/DBC/dataDBC.xlsx", sheet = "Sheet1")
head(df)
## # A tibble: 6 × 18
## Date `NỢ PHẢI TRẢ` `Nợ ngắn hạn` `Phải trả người bán ngắn hạn`
## <dbl> <dbl> <dbl> <dbl>
## 1 2024 7355476127696 6420694102809 762647490938
## 2 2023 8345469400426 7141605465752 795600820770
## 3 2022 8332876258119 7213028754790 2129218054781
## 4 2021 6176631172021 5171698802616 1392462971688
## 5 2020 5894311104553 4254585526684 1012195989287
## 6 2019 6565967444140 4819677610567 911471772009
## # ℹ 14 more variables: `Người mua trả tiền trước ngắn hạn` <dbl>,
## # `Thuế và các khoản phải nộp Nhà nước` <dbl>,
## # `Phải trả người lao động` <dbl>, `Chi phí phải trả ngắn hạn` <dbl>,
## # `Phải trả ngắn hạn khác` <dbl>, `Vay và nợ thuê tài chính ngắn hạn` <dbl>,
## # `Quỹ khen thưởng, phúc lợi` <dbl>, `Nợ dài hạn` <dbl>,
## # `VỐN CHỦ SỞ HỮU` <dbl>, `Vốn góp của chủ sở hữu` <dbl>,
## # `Thặng dư vốn cổ phần` <dbl>, `Quỹ đầu tư phát triển` <dbl>, …
Lệnh read_excel() đọc dữ liệu từ “Sheet1”. Sử dụng lệnh head() hiển thị 6 dòng đầu để xác định có đọc đúng và dữ liệu có bị lệch dòng, lệch cột hay không.
dim(dataDBC)
## [1] 10 18
Lệnh dim() dùng để xác định kích thước của bảng dữ liệu. Kết quả cho thấy: 10 18 nghĩa là bảng dataDBC có 10 hàng (quan sát) và 18 cột (biến). Đây là bước kiểm tra cơ bản, đảm bảo dữ liệu đã được đọc đúng và có đủ số lượng biến cần phân tích.
names(dataDBC)
## [1] "Date" "NỢ PHẢI TRẢ"
## [3] "Nợ ngắn hạn" "Phải trả người bán ngắn hạn"
## [5] "Người mua trả tiền trước ngắn hạn" "Thuế và các khoản phải nộp Nhà nước"
## [7] "Phải trả người lao động" "Chi phí phải trả ngắn hạn"
## [9] "Phải trả ngắn hạn khác" "Vay và nợ thuê tài chính ngắn hạn"
## [11] "Quỹ khen thưởng, phúc lợi" "Nợ dài hạn"
## [13] "VỐN CHỦ SỞ HỮU" "Vốn góp của chủ sở hữu"
## [15] "Thặng dư vốn cổ phần" "Quỹ đầu tư phát triển"
## [17] "Lợi nhuận sau thuế chưa phân phối" "TỔNG CỘNG NGUỒN VỐN"
dataDBC <- clean_names(dataDBC)
Hàm names() giúp người dùng kiểm tra nhanh toàn bộ cấu trúc tên biến trong bảng dữ liệu. Kết quả dữ liệu cho thấy gồm 18 biến mô tả cấu trúc nguồn vốn của doanh nghiệp. Vì trong R, tên biến (variable names) phải tuân thủ quy tắc cú pháp: Không có dấu tiếng Việt (ă, â, ê, ô, ơ, đ, …), Không có khoảng trắng, dấu chấm câu, ký tự đặc biệt (-, /, ,, (, ), v.v.), Không bắt đầu bằng số, nên sẽ xử lý bằng cách loại bỏ dấu và khoảng trắng có trong biến để trong quá trình gọi biến trong code không bị lỗi.
nam_bat_dau <- min(dataDBC$date, na.rm = TRUE)
nam_ket_thuc <- max(dataDBC$date, na.rm = TRUE)
cat("Phạm vi thời gian của bộ dữ liệu từ năm", nam_bat_dau, "đến năm", nam_ket_thuc, "\n")
## Phạm vi thời gian của bộ dữ liệu từ năm 2015 đến năm 2024
Bộ dữ liệu bao gồm 10 năm liên tiếp (2015–2024). Điều này cho phép quan sát xu hướng biến động dài hạn của các khoản nợ phải trả, vốn chủ sở hữu, và tổng nguồn vốn.
phan_loai_bien <- data.frame(
Nhom = c(
rep("NỢ PHẢI TRẢ - NỢ NGẮN HẠN", 8),
rep("NỢ PHẢI TRẢ - NỢ DÀI HẠN", 1),
rep("VỐN CHỦ SỞ HỮU", 5),
"TỔNG CỘNG NGUỒN VỐN"
),
Bien = c(
"no_phai_tra",
"no_ngan_han",
"phai_tra_nguoi_ban_ngan_han",
"nguoi_mua_tra_tien_truoc_ngan_han",
"thue_va_cac_khoan_phai_nop_nha_nuoc",
"phai_tra_nguoi_lao_dong",
"chi_phi_phai_tra_ngan_han",
"phai_tra_ngan_han_khac",
"no_dai_han",
"von_chu_so_huu",
"von_gop_cua_chu_so_huu",
"thang_du_von_co_phan",
"quy_dau_tu_phat_trien",
"loi_nhuan_sau_thue_chua_phan_phoi",
"tong_cong_nguon_von"
)
)
print(phan_loai_bien)
## Nhom Bien
## 1 NỢ PHẢI TRẢ - NỢ NGẮN HẠN no_phai_tra
## 2 NỢ PHẢI TRẢ - NỢ NGẮN HẠN no_ngan_han
## 3 NỢ PHẢI TRẢ - NỢ NGẮN HẠN phai_tra_nguoi_ban_ngan_han
## 4 NỢ PHẢI TRẢ - NỢ NGẮN HẠN nguoi_mua_tra_tien_truoc_ngan_han
## 5 NỢ PHẢI TRẢ - NỢ NGẮN HẠN thue_va_cac_khoan_phai_nop_nha_nuoc
## 6 NỢ PHẢI TRẢ - NỢ NGẮN HẠN phai_tra_nguoi_lao_dong
## 7 NỢ PHẢI TRẢ - NỢ NGẮN HẠN chi_phi_phai_tra_ngan_han
## 8 NỢ PHẢI TRẢ - NỢ NGẮN HẠN phai_tra_ngan_han_khac
## 9 NỢ PHẢI TRẢ - NỢ DÀI HẠN no_dai_han
## 10 VỐN CHỦ SỞ HỮU von_chu_so_huu
## 11 VỐN CHỦ SỞ HỮU von_gop_cua_chu_so_huu
## 12 VỐN CHỦ SỞ HỮU thang_du_von_co_phan
## 13 VỐN CHỦ SỞ HỮU quy_dau_tu_phat_trien
## 14 VỐN CHỦ SỞ HỮU loi_nhuan_sau_thue_chua_phan_phoi
## 15 TỔNG CỘNG NGUỒN VỐN tong_cong_nguon_von
Hàm data.frame() giúp tạo bảng phan_loai_bien sẽ có 2 cột: Nhom: nhóm phân loại chính (bài báo cáo này phân tích Nguồn vốn của doanh nghiệp gồm 2 chỉ tiêu chính: Nợ phải trả và Vốn chủ sở hữu) và Bien: tên biến tương ứng trong dữ liệu
debt_2024 <- dataDBC %>% filter(date == 2024) %>% pull(no_phai_tra)
equity_2024 <- dataDBC %>% filter(date == 2024) %>% pull(von_chu_so_huu)
cat("Giá trị mẫu - Tổng Nợ phải trả năm 2024:",
format(debt_2024, big.mark = ",", scientific = FALSE), "\n")
## Giá trị mẫu - Tổng Nợ phải trả năm 2024: 7,355,476,127,696
cat("Giá trị mẫu - Vốn chủ sở hữu năm 2024:",
format(equity_2024, big.mark = ",", scientific = FALSE), "\n\n")
## Giá trị mẫu - Vốn chủ sở hữu năm 2024: 6,766,079,699,901
cat("Nhận xét:\n")
## Nhận xét:
cat(" Các giá trị nằm trong khoảng 10^12 đến 10^13\n")
## Các giá trị nằm trong khoảng 10^12 đến 10^13
cat(" Điều này tương ứng với quy mô hàng nghìn tỷ đồng\n")
## Điều này tương ứng với quy mô hàng nghìn tỷ đồng
cat("Kết luận: Đơn vị dữ liệu gốc là Đồng Việt Nam (VND)\n")
## Kết luận: Đơn vị dữ liệu gốc là Đồng Việt Nam (VND)
cat("Để thuận tiện cho phân tích, nên quy đổi sang Tỷ VNĐ (chia 1e9).\n")
## Để thuận tiện cho phân tích, nên quy đổi sang Tỷ VNĐ (chia 1e9).
str(dataDBC)
## tibble [10 × 18] (S3: tbl_df/tbl/data.frame)
## $ date : num [1:10] 2024 2023 2022 2021 2020 ...
## $ no_phai_tra : num [1:10] 7.36e+12 8.35e+12 8.33e+12 6.18e+12 5.89e+12 ...
## $ no_ngan_han : num [1:10] 6.42e+12 7.14e+12 7.21e+12 5.17e+12 4.25e+12 ...
## $ phai_tra_nguoi_ban_ngan_han : num [1:10] 7.63e+11 7.96e+11 2.13e+12 1.39e+12 1.01e+12 ...
## $ nguoi_mua_tra_tien_truoc_ngan_han : num [1:10] 2.07e+11 2.21e+11 8.87e+11 5.88e+11 5.52e+11 ...
## $ thue_va_cac_khoan_phai_nop_nha_nuoc: num [1:10] 1.00e+11 3.25e+10 4.54e+10 7.96e+10 1.39e+11 ...
## $ phai_tra_nguoi_lao_dong : num [1:10] 8.63e+10 7.63e+10 6.49e+10 1.09e+11 1.07e+11 ...
## $ chi_phi_phai_tra_ngan_han : num [1:10] 5.31e+10 1.04e+11 6.45e+10 7.65e+10 6.35e+10 ...
## $ phai_tra_ngan_han_khac : num [1:10] 2.69e+11 1.04e+12 2.21e+11 2.38e+11 2.00e+11 ...
## $ vay_va_no_thue_tai_chinh_ngan_han : num [1:10] 4.93e+12 4.84e+12 3.70e+12 2.60e+12 2.16e+12 ...
## $ quy_khen_thuong_phuc_loi : num [1:10] 1.35e+10 3.34e+10 9.55e+10 8.97e+10 2.21e+10 ...
## $ no_dai_han : num [1:10] 9.35e+11 1.20e+12 1.12e+12 1.00e+12 1.64e+12 ...
## $ von_chu_so_huu : num [1:10] 6.77e+12 4.67e+12 4.64e+12 4.69e+12 4.21e+12 ...
## $ von_gop_cua_chu_so_huu : num [1:10] 3.35e+12 2.42e+12 2.42e+12 1.15e+12 1.05e+12 ...
## $ thang_du_von_co_phan : num [1:10] 8.22e+11 4.18e+11 4.18e+11 4.18e+11 4.18e+11 ...
## $ quy_dau_tu_phat_trien : num [1:10] 1.82e+12 1.80e+12 1.79e+12 2.52e+12 1.50e+12 ...
## $ loi_nhuan_sau_thue_chua_phan_phoi : num [1:10] 7.72e+11 2.79e+10 8.10e+09 5.95e+11 1.24e+12 ...
## $ tong_cong_nguon_von : num [1:10] 1.41e+13 1.30e+13 1.30e+13 1.09e+13 1.01e+13 ...
Hàm str() giúp mô tả cấu trúc dữ liệu tài chính: - Là tibble(bảng dữ liệu) có 10 dòng × 18 cột. - Từ kết quả cho thấy các biến đều là kiểu dữ liệu số (numeric). - Mỗi biến biểu diễn một chỉ tiêu trong phần “Nguồn vốn” của bảng cân đối kế toán.
Bộ dữ liệu được thu thập từ Báo cáo tài chính hợp nhất của Công ty Cổ phần Tập đoàn Dabaco Việt Nam (mã chứng khoán: DBC) giai đoạn 2015–2024, bao gồm 18 biến phản ánh cơ cấu Nguồn vốn. Các biến được chia thành 2 nhóm chính: Nợ phải trả và Vốn chủ sở hữu. Ý nghĩa chi tiết của từng biến được trình bày trong bảng dưới đây.
# --- Tạo bảng giải thích ý nghĩa các biến trong bộ dữ liệu ---
library(dplyr)
# Tạo data frame chứa tên biến và ý nghĩa chi tiết
giai_thich_bien <- data.frame(
Bien = c(
"date",
"no_phai_tra",
"no_ngan_han",
"phai_tra_nguoi_ban_ngan_han",
"nguoi_mua_tra_tien_truoc_ngan_han",
"thue_va_cac_khoan_phai_nop_nha_nuoc",
"phai_tra_nguoi_lao_dong",
"chi_phi_phai_tra_ngan_han",
"phai_tra_ngan_han_khac",
"vay_va_no_thue_tai_chinh_ngan_han",
"quy_khen_thuong_phuc_loi",
"no_dai_han",
"von_chu_so_huu",
"von_gop_cua_chu_so_huu",
"thang_du_von_co_phan",
"quy_dau_tu_phat_trien",
"loi_nhuan_sau_thue_chua_phan_phoi",
"tong_cong_nguon_von"
),
Y_nghia = c(
"Năm tài chính của dữ liệu – thể hiện chu kỳ thời gian để so sánh biến động nguồn vốn qua các năm.",
"Tổng nợ phải trả – bao gồm toàn bộ nghĩa vụ tài chính mà doanh nghiệp cần thanh toán trong tương lai.",
"Tổng nợ ngắn hạn – các khoản nợ có thời hạn thanh toán dưới 1 năm.",
"Khoản doanh nghiệp phải trả cho nhà cung cấp hàng hóa, dịch vụ trong ngắn hạn.",
"Các khoản tiền mà khách hàng trả trước cho doanh nghiệp để nhận hàng hóa/dịch vụ trong tương lai.",
"Các khoản thuế và nghĩa vụ tài chính doanh nghiệp phải nộp cho Nhà nước.",
"Tiền lương, thưởng và các khoản phải trả cho người lao động chưa chi trả.",
"Các chi phí đã phát sinh nhưng chưa thanh toán trong kỳ kế toán (như chi phí lãi vay, thuê ngoài, bảo trì…).",
"Các khoản phải trả khác không nằm trong các mục trên, ví dụ: ký quỹ, ký cược, hoặc tạm giữ hộ.",
"Các khoản vay và nợ thuê tài chính ngắn hạn, phải trả trong vòng 12 tháng tới.",
"Nguồn quỹ dùng để thưởng cho nhân viên hoặc phúc lợi tập thể (mang tính chất nội bộ).",
"Tổng nợ dài hạn – các khoản nợ có kỳ hạn thanh toán trên 1 năm, thường gồm vay ngân hàng dài hạn, trái phiếu…",
"Tổng vốn chủ sở hữu – phần tài sản ròng thuộc về các cổ đông sau khi trừ đi nghĩa vụ nợ.",
"Phần vốn góp ban đầu hoặc bổ sung của các chủ sở hữu (cổ đông).",
"Khoản chênh lệch giữa giá phát hành cổ phần và mệnh giá – thể hiện phần vốn thặng dư từ phát hành cổ phiếu.",
"Quỹ được trích lập từ lợi nhuận sau thuế nhằm tái đầu tư, mở rộng sản xuất kinh doanh.",
"Lợi nhuận tích lũy qua các năm mà doanh nghiệp chưa phân phối hoặc chia cổ tức.",
"Tổng cộng toàn bộ nguồn hình thành nên tài sản – bằng tổng nợ phải trả và vốn chủ sở hữu."
)
)
# In ra bảng
print(giai_thich_bien)
## Bien
## 1 date
## 2 no_phai_tra
## 3 no_ngan_han
## 4 phai_tra_nguoi_ban_ngan_han
## 5 nguoi_mua_tra_tien_truoc_ngan_han
## 6 thue_va_cac_khoan_phai_nop_nha_nuoc
## 7 phai_tra_nguoi_lao_dong
## 8 chi_phi_phai_tra_ngan_han
## 9 phai_tra_ngan_han_khac
## 10 vay_va_no_thue_tai_chinh_ngan_han
## 11 quy_khen_thuong_phuc_loi
## 12 no_dai_han
## 13 von_chu_so_huu
## 14 von_gop_cua_chu_so_huu
## 15 thang_du_von_co_phan
## 16 quy_dau_tu_phat_trien
## 17 loi_nhuan_sau_thue_chua_phan_phoi
## 18 tong_cong_nguon_von
## Y_nghia
## 1 Năm tài chính của dữ liệu – thể hiện chu kỳ thời gian để so sánh biến động nguồn vốn qua các năm.
## 2 Tổng nợ phải trả – bao gồm toàn bộ nghĩa vụ tài chính mà doanh nghiệp cần thanh toán trong tương lai.
## 3 Tổng nợ ngắn hạn – các khoản nợ có thời hạn thanh toán dưới 1 năm.
## 4 Khoản doanh nghiệp phải trả cho nhà cung cấp hàng hóa, dịch vụ trong ngắn hạn.
## 5 Các khoản tiền mà khách hàng trả trước cho doanh nghiệp để nhận hàng hóa/dịch vụ trong tương lai.
## 6 Các khoản thuế và nghĩa vụ tài chính doanh nghiệp phải nộp cho Nhà nước.
## 7 Tiền lương, thưởng và các khoản phải trả cho người lao động chưa chi trả.
## 8 Các chi phí đã phát sinh nhưng chưa thanh toán trong kỳ kế toán (như chi phí lãi vay, thuê ngoài, bảo trì…).
## 9 Các khoản phải trả khác không nằm trong các mục trên, ví dụ: ký quỹ, ký cược, hoặc tạm giữ hộ.
## 10 Các khoản vay và nợ thuê tài chính ngắn hạn, phải trả trong vòng 12 tháng tới.
## 11 Nguồn quỹ dùng để thưởng cho nhân viên hoặc phúc lợi tập thể (mang tính chất nội bộ).
## 12 Tổng nợ dài hạn – các khoản nợ có kỳ hạn thanh toán trên 1 năm, thường gồm vay ngân hàng dài hạn, trái phiếu…
## 13 Tổng vốn chủ sở hữu – phần tài sản ròng thuộc về các cổ đông sau khi trừ đi nghĩa vụ nợ.
## 14 Phần vốn góp ban đầu hoặc bổ sung của các chủ sở hữu (cổ đông).
## 15 Khoản chênh lệch giữa giá phát hành cổ phần và mệnh giá – thể hiện phần vốn thặng dư từ phát hành cổ phiếu.
## 16 Quỹ được trích lập từ lợi nhuận sau thuế nhằm tái đầu tư, mở rộng sản xuất kinh doanh.
## 17 Lợi nhuận tích lũy qua các năm mà doanh nghiệp chưa phân phối hoặc chia cổ tức.
## 18 Tổng cộng toàn bộ nguồn hình thành nên tài sản – bằng tổng nợ phải trả và vốn chủ sở hữu.
so_bien <- ncol(dataDBC)
so_quan_sat <- nrow(dataDBC)
so_trung_lap <- sum(duplicated(dataDBC))
so_thieu <- sum(is.na(dataDBC))
ty_le_thieu <- round(so_thieu / (so_bien * so_quan_sat) * 100, 2)
thong_tin_co_ban <- data.frame(
Chi_tieu = c(
"Số biến (cột)",
"Số quan sát (dòng)",
"Số quan sát trùng lặp",
"Số quan sát bị thiếu",
"Tỷ lệ quan sát bị thiếu (%)"
),
Gia_tri = c(so_bien, so_quan_sat, so_trung_lap, so_thieu, ty_le_thieu)
)
print(thong_tin_co_ban)
## Chi_tieu Gia_tri
## 1 Số biến (cột) 18
## 2 Số quan sát (dòng) 10
## 3 Số quan sát trùng lặp 0
## 4 Số quan sát bị thiếu 0
## 5 Tỷ lệ quan sát bị thiếu (%) 0
Hàm ncol() và nrow() thể hiện cột(số biến) và hàng(số quan sát). Hàm sum(duplicated()), sum(is.na()) hai chỉ tiêu này đều cho thấy số quan sát trùng lặp và số quan sát bị thiếu đều là 0, do đó tỉ lệ quan sát bị thiếu là không có
# --- ĐÁNH GIÁ SƠ BỘ XU HƯỚNG CÁC KHOẢN MỤC CHÍNH ---
# --- PHÂN TÍCH XU HƯỚNG 3 CHỈ TIÊU CHÍNH (2015–2024) ---
library(dplyr)
# 1. Tổng NỢ PHẢI TRẢ
cat("Xu hướng tổng NỢ PHẢI TRẢ (2015–2024):\n")
## Xu hướng tổng NỢ PHẢI TRẢ (2015–2024):
liabilities_trend <- dataDBC %>%
arrange(date) %>%
select(date, no_phai_tra)
for (i in 1:nrow(liabilities_trend)) {
year <- liabilities_trend$date[i]
value <- liabilities_trend$no_phai_tra[i]
cat(" ", year, ": ", format(value, big.mark = ",", scientific = FALSE), "\n", sep = "")
}
## 2015: 2,668,763,190,851
## 2016: 3,190,129,918,957
## 2017: 4,486,599,351,977
## 2018: 5,603,485,031,551
## 2019: 6,565,967,444,140
## 2020: 5,894,311,104,553
## 2021: 6,176,631,172,021
## 2022: 8,332,876,258,119
## 2023: 8,345,469,400,426
## 2024: 7,355,476,127,696
trend_direction_liab <- ifelse(tail(liabilities_trend$no_phai_tra, 1) > head(liabilities_trend$no_phai_tra, 1),
"Tăng", "Giảm")
cat("\nNhận xét tổng quan: Xu hướng tổng NỢ PHẢI TRẢ là", trend_direction_liab, "qua giai đoạn 2015–2024.\n\n")
##
## Nhận xét tổng quan: Xu hướng tổng NỢ PHẢI TRẢ là Tăng qua giai đoạn 2015–2024.
# 2. VỐN CHỦ SỞ HỮU
cat("Xu hướng VỐN CHỦ SỞ HỮU (2015–2024):\n")
## Xu hướng VỐN CHỦ SỞ HỮU (2015–2024):
equity_trend <- dataDBC %>%
arrange(date) %>%
select(date, von_chu_so_huu)
for (i in 1:nrow(equity_trend)) {
year <- equity_trend$date[i]
value <- equity_trend$von_chu_so_huu[i]
cat(" ", year, ": ", format(value, big.mark = ",", scientific = FALSE), "\n", sep = "")
}
## 2015: 1,946,447,536,231
## 2016: 2,339,141,904,502
## 2017: 2,502,616,605,237
## 2018: 2,746,528,417,636
## 2019: 3,025,957,478,860
## 2020: 4,206,960,190,688
## 2021: 4,685,923,120,134
## 2022: 4,641,227,653,231
## 2023: 4,666,234,857,446
## 2024: 6,766,079,699,901
trend_direction_equity <- ifelse(tail(equity_trend$von_chu_so_huu, 1) > head(equity_trend$von_chu_so_huu, 1),
"Tăng", "Giảm")
cat("\nNhận xét tổng quan: Xu hướng VỐN CHỦ SỞ HỮU là", trend_direction_equity, "qua giai đoạn 2015–2024.\n\n")
##
## Nhận xét tổng quan: Xu hướng VỐN CHỦ SỞ HỮU là Tăng qua giai đoạn 2015–2024.
# 3. TỔNG CỘNG NGUỒN VỐN
cat("Xu hướng TỔNG CỘNG NGUỒN VỐN (2015–2024):\n")
## Xu hướng TỔNG CỘNG NGUỒN VỐN (2015–2024):
total_capital_trend <- dataDBC %>%
arrange(date) %>%
select(date, tong_cong_nguon_von)
for (i in 1:nrow(total_capital_trend)) {
year <- total_capital_trend$date[i]
value <- total_capital_trend$tong_cong_nguon_von[i]
cat(" ", year, ": ", format(value, big.mark = ",", scientific = FALSE), "\n", sep = "")
}
## 2015: 4,615,210,727,082
## 2016: 5,529,271,823,459
## 2017: 6,989,215,957,214
## 2018: 8,350,013,449,187
## 2019: 9,591,924,923,000
## 2020: 10,101,271,295,241
## 2021: 10,862,564,292,155
## 2022: 12,974,103,921,350
## 2023: 13,011,704,257,872
## 2024: 14,121,555,827,597
trend_direction_total <- ifelse(tail(total_capital_trend$tong_cong_nguon_von, 1) > head(total_capital_trend$tong_cong_nguon_von, 1),
"Tăng", "Giảm")
cat("\nNhận xét tổng quan: Xu hướng TỔNG CỘNG NGUỒN VỐN là", trend_direction_total, "qua giai đoạn 2015–2024.\n")
##
## Nhận xét tổng quan: Xu hướng TỔNG CỘNG NGUỒN VỐN là Tăng qua giai đoạn 2015–2024.
library(ggplot2)
install.packages("tidyr")
## Installing package into 'C:/Users/Admin/AppData/Local/R/win-library/4.5'
## (as 'lib' is unspecified)
## package 'tidyr' successfully unpacked and MD5 sums checked
## Warning: cannot remove prior installation of package 'tidyr'
## Warning in file.copy(savedcopy, lib, recursive = TRUE): problem copying
## C:\Users\Admin\AppData\Local\R\win-library\4.5\00LOCK\tidyr\libs\x64\tidyr.dll
## to C:\Users\Admin\AppData\Local\R\win-library\4.5\tidyr\libs\x64\tidyr.dll:
## Permission denied
## Warning: restored 'tidyr'
##
## The downloaded binary packages are in
## C:\Users\Admin\AppData\Local\Temp\RtmpKYkmzk\downloaded_packages
library(tidyr)
## Warning: package 'tidyr' was built under R version 4.5.1
dataDBC %>%
select(date, no_phai_tra, von_chu_so_huu, tong_cong_nguon_von) %>%
pivot_longer(-date, names_to = "Chi_tieu", values_to = "Gia_tri") %>%
ggplot(aes(x = date, y = Gia_tri, color = Chi_tieu, group = Chi_tieu)) +
geom_line(size = 1.2) +
geom_point(size = 2) +
theme_minimal() +
labs(title = "Xu hướng Nợ phải trả, Vốn chủ sở hữu và Tổng nguồn vốn (2015–2024)",
x = "Năm", y = "Giá trị (tỷ VND)")
## Warning: Using `size` aesthetic for lines was deprecated in ggplot2 3.4.0.
## ℹ Please use `linewidth` instead.
## This warning is displayed once every 8 hours.
## Call `lifecycle::last_lifecycle_warnings()` to see where this warning was
## generated.
for (b in c("no_phai_tra", "von_chu_so_huu", "tong_cong_nguon_von")) {
boxplot(dataDBC[[b]], main = paste("Kiểm tra ngoại lai -", b))
print(summary(dataDBC[[b]]))
}
## Min. 1st Qu. Median Mean 3rd Qu. Max.
## 2.669e+12 4.766e+12 6.035e+12 5.862e+12 7.158e+12 8.345e+12
## Min. 1st Qu. Median Mean 3rd Qu. Max.
## 1.946e+12 2.564e+12 3.616e+12 3.753e+12 4.660e+12 6.766e+12
## Min. 1st Qu. Median Mean 3rd Qu. Max.
## 4.615e+12 7.329e+12 9.847e+12 9.615e+12 1.245e+13 1.412e+13
Nhận xét kiểm tra ngoại lai – Nợ phải trả - Không có điểm ngoại lai (outlier): Biểu đồ không xuất hiện các chấm rời nằm ngoài hai “râu” (whiskers), tức là không có giá trị ngoại lai đáng kể. Điều này cho thấy dữ liệu khá ổn định, không có năm nào có giá trị nợ phải trả quá khác biệt so với các năm khác. - Phân bố dữ liệu: Chiều dài hộp và râu cho thấy dữ liệu phân bố khá đều, không bị lệch nhiều. Trung vị nằm gần giữa hộp → nợ phải trả phân bố đối xứng, không nghiêng về phía tăng hay giảm mạnh trong giai đoạn phân tích. - Khoảng biến động: Phạm vi từ đáy hộp đến đỉnh hộp thể hiện sự biến động trung bình của nợ phải trả giữa các năm. Nhìn chung, biến động không quá lớn, chứng tỏ doanh nghiệp duy trì mức nợ phải trả ổn định qua thời gian.
Nhận xét kiểm tra ngoại lai – Vốn chủ sở hữu - Phạm vi giá trị của “vốn chủ sở hữu” nằm trong khoảng từ 2.000 đến 6700 (tỷ đồng). - Đường giữa hộp (Median) nằm gần khoảng 3.600–3.800, cho thấy phân bố giá trị khá cân đối, không bị lệch mạnh. - Không có điểm dữ liệu nào nằm ngoài râu trên hoặc râu dưới ⟹ không xuất hiện ngoại lai (outlier). - Độ cao của hộp (IQR) cho thấy biến động vừa phải, phản ánh sự tăng trưởng tương đối ổn định của vốn chủ sở hữu qua các năm.
Nhận xét kiểm tra ngoại lai – Tổng cộng nguồn vốn - Dữ liệu phân bố khá cân đối, đường trung vị (đường đậm trong hộp) nằm gần giữa hộp, cho thấy phân bố không bị lệch mạnh. - Khoảng giá trị dao động từ khoảng 6.000 tỷ đồng đến 13.000 tỷ đồng. - Không có điểm ngoại lai (outlier) nào được thể hiện trên đồ thị, vì không có điểm riêng lẻ nằm ngoài hai “râu” của hộp. Điều này cho thấy tổng cộng nguồn vốn biến động ổn định, không có năm nào bất thường về quy mô vốn.
dataDBC <- dataDBC %>%
mutate(across(
.cols = -date,
.fns = ~ round(.x / 1e9, 3)
))
head(dataDBC)
## # A tibble: 6 × 18
## date no_phai_tra no_ngan_han phai_tra_nguoi_ban_ngan…¹ nguoi_mua_tra_tien_t…²
## <dbl> <dbl> <dbl> <dbl> <dbl>
## 1 2024 7355. 6421. 763. 207.
## 2 2023 8345. 7142. 796. 221.
## 3 2022 8333. 7213. 2129. 887.
## 4 2021 6177. 5172. 1392. 588.
## 5 2020 5894. 4255. 1012. 552.
## 6 2019 6566. 4820. 911. 410.
## # ℹ abbreviated names: ¹phai_tra_nguoi_ban_ngan_han,
## # ²nguoi_mua_tra_tien_truoc_ngan_han
## # ℹ 13 more variables: thue_va_cac_khoan_phai_nop_nha_nuoc <dbl>,
## # phai_tra_nguoi_lao_dong <dbl>, chi_phi_phai_tra_ngan_han <dbl>,
## # phai_tra_ngan_han_khac <dbl>, vay_va_no_thue_tai_chinh_ngan_han <dbl>,
## # quy_khen_thuong_phuc_loi <dbl>, no_dai_han <dbl>, von_chu_so_huu <dbl>,
## # von_gop_cua_chu_so_huu <dbl>, thang_du_von_co_phan <dbl>, …
dataDBC$date <- as.numeric(dataDBC$date)
dataDBC <- dataDBC[order(dataDBC$date), ]
head(dataDBC)
## # A tibble: 6 × 18
## date no_phai_tra no_ngan_han phai_tra_nguoi_ban_ngan…¹ nguoi_mua_tra_tien_t…²
## <dbl> <dbl> <dbl> <dbl> <dbl>
## 1 2015 2669. 2411. 534. 94.5
## 2 2016 3190. 2630. 318. 147.
## 3 2017 4487. 3462. 564. 132.
## 4 2018 5603. 4075. 923. 207.
## 5 2019 6566. 4820. 911. 410.
## 6 2020 5894. 4255. 1012. 552.
## # ℹ abbreviated names: ¹phai_tra_nguoi_ban_ngan_han,
## # ²nguoi_mua_tra_tien_truoc_ngan_han
## # ℹ 13 more variables: thue_va_cac_khoan_phai_nop_nha_nuoc <dbl>,
## # phai_tra_nguoi_lao_dong <dbl>, chi_phi_phai_tra_ngan_han <dbl>,
## # phai_tra_ngan_han_khac <dbl>, vay_va_no_thue_tai_chinh_ngan_han <dbl>,
## # quy_khen_thuong_phuc_loi <dbl>, no_dai_han <dbl>, von_chu_so_huu <dbl>,
## # von_gop_cua_chu_so_huu <dbl>, thang_du_von_co_phan <dbl>, …
Dữ liệu được sắp xếp từ năm 2015 đến năm 2024.
library(dplyr)
# Tạo vector nhãn ngắn gọn (để dùng khi vẽ biểu đồ)
labels <- c(
no_phai_tra = "Nợ phải trả",
no_ngan_han = "Nợ ngắn hạn",
phai_tra_nguoi_ban_ngan_han = "Phải trả người bán NH",
nguoi_mua_tra_tien_truoc_ngan_han = "Người mua trả tiền trước NH",
thue_va_cac_khoan_phai_nop_nha_nuoc = "Thuế và khoản nộp NN",
phai_tra_nguoi_lao_dong = "Phải trả NLĐ",
chi_phi_phai_tra_ngan_han = "Chi phí phải trả NH",
phai_tra_ngan_han_khac = "Phải trả NH khác",
vay_va_no_thue_tai_chinh_ngan_han = "Vay và nợ thuê TC NH",
quy_khen_thuong_phuc_loi = "Quỹ KTPL",
no_dai_han = "Nợ dài hạn",
von_chu_so_huu = "Vốn chủ sở hữu",
von_gop_cua_chu_so_huu = "Vốn góp CSH",
thang_du_von_co_phan = "Thặng dư VCP",
quy_dau_tu_phat_trien = "Quỹ ĐTPT",
loi_nhuan_sau_thue_chua_phan_phoi = "LNST chưa PP",
tong_cong_nguon_von = "Tổng nguồn vốn"
)
# Gán nhãn làm thuộc tính
attr(dataDBC, "variable_labels") <- labels
library(psych)
describe(dataDBC[ , !names(dataDBC) %in% c("date")])
## vars n mean sd median trimmed
## no_phai_tra 1 10 5861.97 1954.86 6035.47 5950.68
## no_ngan_han 2 10 4759.97 1734.75 4537.13 4746.96
## phai_tra_nguoi_ban_ngan_han 3 10 934.31 513.14 853.54 861.93
## nguoi_mua_tra_tien_truoc_ngan_han 4 10 344.59 258.36 214.39 307.99
## thue_va_cac_khoan_phai_nop_nha_nuoc 5 10 58.11 38.42 44.27 53.08
## phai_tra_nguoi_lao_dong 6 10 72.03 23.14 66.43 71.93
## chi_phi_phai_tra_ngan_han 7 10 68.00 25.29 64.01 68.37
## phai_tra_ngan_han_khac 8 10 269.26 281.48 227.98 202.91
## vay_va_no_thue_tai_chinh_ngan_han 9 10 2974.18 1195.71 2655.01 2912.98
## quy_khen_thuong_phuc_loi 10 10 39.49 30.29 27.75 35.73
## no_dai_han 11 10 1102.00 465.00 1072.02 1126.99
## von_chu_so_huu 12 10 3752.71 1496.13 3616.46 3601.82
## von_gop_cua_chu_so_huu 13 10 1433.44 940.06 979.32 1295.04
## thang_du_von_co_phan 14 10 458.74 127.47 418.43 418.43
## quy_dau_tu_phat_trien 15 10 1441.47 564.50 1423.05 1401.99
## loi_nhuan_sau_thue_chua_phan_phoi 16 10 418.96 373.11 354.20 367.29
## tong_cong_nguon_von 17 10 9614.68 3250.81 9846.60 9676.26
## mad min max range skew
## no_phai_tra 2126.70 2668.76 8345.47 5676.71 -0.27
## no_ngan_han 2192.97 2410.96 7213.03 4802.07 0.15
## phai_tra_nguoi_ban_ngan_han 332.15 318.47 2129.22 1810.75 1.07
## nguoi_mua_tra_tien_truoc_ngan_han 149.77 94.49 887.48 792.99 0.83
## thue_va_cac_khoan_phai_nop_nha_nuoc 26.92 16.95 139.47 122.52 0.85
## phai_tra_nguoi_lao_dong 18.42 36.33 108.53 72.20 0.30
## chi_phi_phai_tra_ngan_han 24.39 28.73 104.36 75.63 0.11
## phai_tra_ngan_han_khac 50.85 31.90 1037.39 1005.49 1.92
## vay_va_no_thue_tai_chinh_ngan_han 1096.32 1509.51 4928.46 3418.96 0.50
## quy_khen_thuong_phuc_loi 20.45 13.52 95.53 82.02 0.88
## no_dai_han 439.89 257.80 1746.29 1488.49 -0.26
## von_chu_so_huu 1570.99 1946.45 6766.08 4819.63 0.53
## von_gop_cua_chu_so_huu 296.14 627.42 3346.69 2719.27 0.89
## thang_du_von_co_phan 0.00 418.43 821.52 403.09 2.28
## quy_dau_tu_phat_trien 554.83 679.13 2519.66 1840.53 0.30
## loi_nhuan_sau_thue_chua_phan_phoi 294.31 8.10 1243.15 1235.05 0.89
## tong_cong_nguon_von 4436.60 4615.21 14121.56 9506.35 -0.12
## kurtosis se
## no_phai_tra -1.36 618.18
## no_ngan_han -1.56 548.58
## phai_tra_nguoi_ban_ngan_han 0.28 162.27
## nguoi_mua_tra_tien_truoc_ngan_han -0.74 81.70
## thue_va_cac_khoan_phai_nop_nha_nuoc -0.62 12.15
## phai_tra_nguoi_lao_dong -1.19 7.32
## chi_phi_phai_tra_ngan_han -1.50 8.00
## phai_tra_ngan_han_khac 2.63 89.01
## vay_va_no_thue_tai_chinh_ngan_han -1.31 378.12
## quy_khen_thuong_phuc_loi -0.91 9.58
## no_dai_han -1.11 147.05
## von_chu_so_huu -0.95 473.12
## von_gop_cua_chu_so_huu -0.91 297.27
## thang_du_von_co_phan 3.57 40.31
## quy_dau_tu_phat_trien -1.03 178.51
## loi_nhuan_sau_thue_chua_phan_phoi -0.25 117.99
## tong_cong_nguon_von -1.54 1027.99
library(ggplot2)
library(dplyr)
# Đảm bảo sắp xếp theo thời gian
dataDBC <- dataDBC %>% arrange(date)
# --- Vẽ xu hướng tổng nợ phải trả ---
ggplot(dataDBC, aes(x = date, y = no_phai_tra)) +
geom_line(color = "#0072B2", size = 1.2) + # Đường xu hướng
geom_point(color = "#D55E00", size = 3) + # Các điểm dữ liệu
geom_smooth(method = "lm", se = FALSE, color = "gray40", linetype = "dashed") + # Đường hồi quy tuyến tính
theme_minimal(base_size = 13) +
labs(title = "Xu hướng Tổng nợ phải trả qua các năm",
x = "Năm",
y = "Tổng nợ phải trả (Tỷ đồng)") +
theme(
plot.title = element_text(face = "bold", hjust = 0.5, size = 15),
axis.title = element_text(face = "bold")
)
## `geom_smooth()` using formula = 'y ~ x'
Nhận xét chi tiết xu hướng tổng nợ phải trả Giai đoạn 2015 – 2018: Đây
là giai đoạn doanh nghiệp mở rộng quy mô hoạt động. Tổng nợ phải trả
tăng mạnh, từ khoảng 2.800 tỷ đồng lên gần 5.500 tỷ đồng
Giai đoạn 2018 – 2020: Nợ tiếp tục tăng lên mức khoảng 6.800 tỷ đồng vào năm 2019, sau đó giảm nhẹ còn khoảng 5.900 tỷ đồng vào năm 2020. Sự giảm nhẹ này có thể liên quan đến giai đoạn dịch COVID-19, khi doanh nghiệp giảm vay mới hoặc trả bớt nợ.
Giai đoạn 2020 – 2023: Sau năm 2020, tổng nợ tăng mạnh trở lại, đạt đỉnh hơn 8.500 tỷ đồng vào năm 2022 và duy trì mức cao đến năm 2023. Cho thấy doanh nghiệp phục hồi và mở rộng trở lại sau dịch.
library(dplyr)
library(ggplot2)
library(tidyr)
co_cau_no <- dataDBC %>%
mutate(
ty_trong_no_ngan_han = no_ngan_han / no_phai_tra * 100,
ty_trong_no_dai_han = no_dai_han / no_phai_tra * 100,
ty_le_no_tren_von = no_phai_tra / tong_cong_nguon_von * 100
)
# Biểu đồ cơ cấu nợ
co_cau_long <- co_cau_no %>%
select(date, ty_trong_no_ngan_han, ty_trong_no_dai_han) %>%
pivot_longer(-date, names_to = "Loai_no", values_to = "Ty_trong")
ggplot(co_cau_long, aes(x = factor(date), y = Ty_trong, fill = Loai_no)) +
geom_bar(stat = "identity", position = "stack") +
labs(title = "Cơ cấu nợ qua các năm",
x = "Năm", y = "Tỷ trọng (%)") +
scale_fill_manual(values = c("#0073C2", "#E69F00"),
name = "Loại nợ",
labels = c("Nợ dài hạn", "Nợ ngắn hạn")) +
theme_minimal(base_size = 13)
Nhận xét cơ cấu nợ qua các năm (2015–2024) Dựa vào biểu đồ cột chồng thể
hiện tỷ trọng nợ ngắn hạn và nợ dài hạn, ta có thể thấy: 1. Nợ ngắn hạn
chiếm tỷ trọng chủ yếu Trong toàn giai đoạn 2015–2024, nợ ngắn hạn luôn
chiếm phần lớn trong tổng nợ phải trả, dao động từ khoảng 70% đến 90%.
Điều này cho thấy doanh nghiệp phụ thuộc nhiều vào các khoản vay ngắn
hạn, chủ yếu để phục vụ nhu cầu vốn lưu động, hàng tồn kho hoặc hoạt
động sản xuất – kinh doanh ngắn kỳ. 2. Nợ dài hạn có xu hướng biến động
ngược chiều Tỷ trọng nợ dài hạn nhìn chung ở mức thấp (10–30%), tuy
nhiên có sự dao động nhẹ giữa các năm. 3. Cơ cấu nợ ít biến động mạnh
nhưng thể hiện chiến lược rõ ràng: Cơ cấu nợ qua các năm khá ổn định, tỷ
trọng nợ ngắn hạn luôn duy trì mức cao, cho thấy doanh nghiệp giữ chiến
lược tài chính linh hoạt — tận dụng nguồn vốn ngắn hạn chi phí thấp
nhưng có rủi ro thanh khoản cao hơn. Việc tỷ lệ nợ dài hạn thấp cũng
đồng nghĩa với áp lực trả nợ ngắn hạn lớn hơn, nhất là khi điều kiện tín
dụng hoặc thị trường thay đổi. 4. Cơ cấu nợ mất cân đối (nợ ngắn hạn
chiếm tỷ trọng lớn) → rủi ro thanh toán cao hơn, đặc biệt nếu dòng tiền
ngắn hạn bị gián đoạn. Tuy nhiên, chiến lược sử dụng nợ ngắn hạn cũng
giúp doanh nghiệp tận dụng lãi suất thấp, tăng hiệu quả sử dụng vốn
trong ngắn hạn.
library(dplyr)
library(tidyr)
library(ggplot2)
# Lấy nhãn từ thuộc tính đã gán
labels <- attr(dataDBC, "variable_labels")
# Tạo bảng cơ cấu nợ ngắn hạn (trừ no_phai_tra)
co_cau_no_ngan_han <- dataDBC %>%
mutate(
tong_no_ngan_han = phai_tra_nguoi_ban_ngan_han +
nguoi_mua_tra_tien_truoc_ngan_han +
thue_va_cac_khoan_phai_nop_nha_nuoc +
phai_tra_nguoi_lao_dong +
chi_phi_phai_tra_ngan_han +
phai_tra_ngan_han_khac
) %>%
select(date, phai_tra_nguoi_ban_ngan_han, nguoi_mua_tra_tien_truoc_ngan_han,
thue_va_cac_khoan_phai_nop_nha_nuoc, phai_tra_nguoi_lao_dong,
chi_phi_phai_tra_ngan_han, phai_tra_ngan_han_khac, tong_no_ngan_han) %>%
pivot_longer(
cols = -c(date, tong_no_ngan_han),
names_to = "khoan_muc",
values_to = "gia_tri"
) %>%
mutate(
ty_trong = gia_tri / tong_no_ngan_han * 100,
# Thay tên khoản mục bằng nhãn thân thiện
khoan_muc = labels[khoan_muc]
)
# Vẽ biểu đồ cơ cấu nợ ngắn hạn qua các năm
ggplot(co_cau_no_ngan_han, aes(x = date, y = ty_trong, fill = khoan_muc)) +
geom_bar(stat = "identity") +
scale_fill_brewer(palette = "Set2") +
labs(
title = "Cơ cấu các khoản mục trong Nợ ngắn hạn qua các năm",
x = "Năm", y = "Tỷ trọng (%)",
fill = "Khoản mục"
) +
theme_minimal(base_size = 14) +
theme(
plot.title = element_text(face = "bold", hjust = 0.5),
legend.position = "right"
)
library(dplyr)
library(tidyr)
library(ggplot2)
# Lấy nhãn từ thuộc tính đã gán trước đó
labels <- attr(dataDBC, "variable_labels")
# Tính cơ cấu vốn chủ sở hữu
co_cau_von_chu_so_huu <- dataDBC %>%
mutate(
tong_von_csh = von_gop_cua_chu_so_huu +
thang_du_von_co_phan +
quy_dau_tu_phat_trien +
loi_nhuan_sau_thue_chua_phan_phoi
) %>%
select(date, von_gop_cua_chu_so_huu, thang_du_von_co_phan,
quy_dau_tu_phat_trien, loi_nhuan_sau_thue_chua_phan_phoi, tong_von_csh) %>%
pivot_longer(
cols = -c(date, tong_von_csh),
names_to = "khoan_muc",
values_to = "gia_tri"
) %>%
mutate(
ty_trong = gia_tri / tong_von_csh * 100,
khoan_muc = labels[khoan_muc]
)
# Vẽ biểu đồ cơ cấu vốn chủ sở hữu
ggplot(co_cau_von_chu_so_huu, aes(x = date, y = ty_trong, fill = khoan_muc)) +
geom_bar(stat = "identity") +
scale_fill_brewer(palette = "Pastel1") +
labs(
title = "Cơ cấu vốn chủ sở hữu qua các năm",
x = "Năm", y = "Tỷ trọng (%)",
fill = "Khoản mục"
) +
theme_minimal(base_size = 14) +
theme(
plot.title = element_text(face = "bold", hjust = 0.5),
legend.position = "right"
)
\[ D/E = \frac{\text{Tổng nợ phải trả}}{\text{Vốn chủ sở hữu}} \]
dataDBC <- dataDBC %>%
mutate(he_so_no_tren_von_csh = no_phai_tra / von_chu_so_huu)
ggplot(dataDBC, aes(x = date, y = he_so_no_tren_von_csh)) +
geom_line(color = "steelblue", linewidth = 1.2) +
geom_point(color = "darkred", size = 3) +
geom_text(aes(label = round(he_so_no_tren_von_csh, 2)),
vjust = -1, size = 3.5, color = "black") +
labs(
title = "Hệ số nợ trên vốn chủ sở hữu (D/E) qua các năm",
x = "Năm",
y = "Hệ số D/E"
) +
ylim(0.5, 2.25) +
theme_minimal(base_size = 13) +
theme(
plot.title = element_text(face = "bold", hjust = 0.5),
axis.title = element_text(face = "bold")
)
Đánh giá: 2017–2019: Doanh nghiệp sử dụng đòn bẩy tài chính cao, tiềm ẩn
rủi ro. 2020–2021: Cải thiện rõ rệt, D/E giảm xuống mức an toàn (~1.3).
2024: Mức D/E chỉ còn 1.09, thể hiện cơ cấu vốn ổn định và lành mạnh
hơn. → Sau giai đoạn biến động, doanh nghiệp đang giảm dần phụ thuộc vào
nợ, tăng khả năng tự chủ tài chính.
\[ Tốc~độ~tăng~trưởng~(\%) = \frac{X_t - X_{t-1}}{X_{t-1}} \times 100 \]
library(dplyr)
library(reshape2)
##
## Attaching package: 'reshape2'
## The following object is masked from 'package:tidyr':
##
## smiths
library(ggplot2)
# --- 1. Tính tốc độ tăng trưởng ---
tang_truong_vcsh <- dataDBC %>%
arrange(date) %>%
mutate(
tang_truong_von_csh = ((von_chu_so_huu - lag(von_chu_so_huu)) / lag(von_chu_so_huu)) * 100,
tang_truong_ln_chua_pp = ((loi_nhuan_sau_thue_chua_phan_phoi - lag(loi_nhuan_sau_thue_chua_phan_phoi)) / lag(loi_nhuan_sau_thue_chua_phan_phoi)) * 100
) %>%
select(date, starts_with("tang_truong"))
print(tang_truong_vcsh)
## # A tibble: 10 × 3
## date tang_truong_von_csh tang_truong_ln_chua_pp
## <dbl> <dbl> <dbl>
## 1 2015 NA NA
## 2 2016 20.2 87.3
## 3 2017 6.99 -52.2
## 4 2018 9.75 81.5
## 5 2019 10.2 -3.35
## 6 2020 39.0 257.
## 7 2021 11.4 -52.1
## 8 2022 -0.954 -98.6
## 9 2023 0.539 245.
## 10 2024 45.0 2666.
# --- 2. Chuyển đổi định dạng năm ---
tang_truong_vcsh$date <- as.integer(tang_truong_vcsh$date) # Đảm bảo là số nguyên
# --- 2. Lấy nhãn tiếng Việt ngắn gọn cho các biến ---
labels_vcsh <- c(
tang_truong_von_csh = "Vốn chủ sở hữu",
tang_truong_ln_chua_pp = "LNST chưa phân phối"
)
# --- 3. Chuyển dữ liệu sang dạng dài ---
tang_truong_long <- melt(tang_truong_vcsh, id.vars = "date",
variable.name = "Khoan_muc", value.name = "Tang_truong")
# --- 4. Vẽ biểu đồ ---
ggplot(tang_truong_long, aes(x = date, y = Tang_truong, color = Khoan_muc, group = Khoan_muc)) +
geom_line(size = 1.2) +
geom_point(size = 2.5) +
scale_color_manual(
values = c("steelblue", "orange"),
labels = labels_vcsh
) +
labs(
title = "Tốc độ tăng trưởng (%) các khoản mục trong Vốn chủ sở hữu",
x = "Năm",
y = "Tốc độ tăng trưởng (%)",
color = "Khoản mục"
) +
theme_minimal(base_size = 13) +
theme(plot.title = element_text(face = "bold", hjust = 0.5))+
scale_x_continuous(breaks = unique(tang_truong_long$date))
## Warning: Removed 2 rows containing missing values or values outside the scale range
## (`geom_line()`).
## Warning: Removed 2 rows containing missing values or values outside the scale range
## (`geom_point()`).