1. Sales <- read_csv("C:/Users/My Asus/Downloads/100000 Sales Records.csv")
2. colnames(Sales) <- c("Region","Country", "Item.Type", "Sales.Channel","Order.Priority" ,"Order.Date","Order.ID" ,"Ship.Date","Units.Sold","Unit.Price", "Unit.Cost", "Total.Revenue", "Total.Cost", "Total.Profit")
3. options(scipen = 999)
1. meaning_variable <- data.frame(
2. Ten_bien = c("Region", "Country", "Item.Type", "Sales.Channel", "Order.Priority", "Order.Date", "Order.ID", "Ship.Date", "Units.Sold", "Unit.Price", "Unit.Cost", "Total.Revenue", "Total.Cost", "Total.Profit"),
3. Y_Nghia = c("Châu lục", "Đất nước", "Loại hàng hóa", "Kênh bán hàng", "Mức độ ưu tiên cho đơn hàng", "Ngày đặt hàng", "Mã vận đơn", "Ngày giao hàng", "Số lượng hàng hóa bán ra", "Giá của một đơn vị hàng hóa", "Giá để sản xuất một đơn vị hàng hóa", "Tổng doanh thu", "Tổng chi phí", "Tổng lợi nhuận")
4. )
5. knitr::kable(meaning_variable)
| Ten_bien | Y_Nghia |
|---|---|
| Region | Châu lục |
| Country | Đất nước |
| Item.Type | Loại hàng hóa |
| Sales.Channel | Kênh bán hàng |
| Order.Priority | Mức độ ưu tiên cho đơn hàng |
| Order.Date | Ngày đặt hàng |
| Order.ID | Mã vận đơn |
| Ship.Date | Ngày giao hàng |
| Units.Sold | Số lượng hàng hóa bán ra |
| Unit.Price | Giá của một đơn vị hàng hóa |
| Unit.Cost | Giá để sản xuất một đơn vị hàng hóa |
| Total.Revenue | Tổng doanh thu |
| Total.Cost | Tổng chi phí |
| Total.Profit | Tổng lợi nhuận |
1. str(Sales)
## spc_tbl_ [100,000 × 14] (S3: spec_tbl_df/tbl_df/tbl/data.frame)
## $ Region : chr [1:100000] "Middle East and North Africa" "Central America and the Caribbean" "Sub-Saharan Africa" "Sub-Saharan Africa" ...
## $ Country : chr [1:100000] "Azerbaijan" "Panama" "Sao Tome and Principe" "Sao Tome and Principe" ...
## $ Item.Type : chr [1:100000] "Snacks" "Cosmetics" "Fruits" "Personal Care" ...
## $ Sales.Channel : chr [1:100000] "Online" "Offline" "Offline" "Online" ...
## $ Order.Priority: chr [1:100000] "C" "L" "M" "M" ...
## $ Order.Date : chr [1:100000] "10/8/2014" "2/22/2015" "12/9/2015" "9/17/2014" ...
## $ Order.ID : num [1:100000] 535113847 874708545 854349935 892836844 129280602 ...
## $ Ship.Date : chr [1:100000] "10/23/2014" "2/27/2015" "1/18/2016" "10/12/2014" ...
## $ Units.Sold : num [1:100000] 934 4551 9986 9118 5858 ...
## $ Unit.Price : num [1:100000] 152.58 437.2 9.33 81.73 668.27 ...
## $ Unit.Cost : num [1:100000] 97.44 263.33 6.92 56.67 502.54 ...
## $ Total.Revenue : num [1:100000] 142510 1989697 93169 745214 3914726 ...
## $ Total.Cost : num [1:100000] 91009 1198415 69103 516717 2943879 ...
## $ Total.Profit : num [1:100000] 51501 791282 24066 228497 970846 ...
## - attr(*, "spec")=
## .. cols(
## .. Region = col_character(),
## .. Country = col_character(),
## .. Item.Type = col_character(),
## .. Sales.Channel = col_character(),
## .. Order.Priority = col_character(),
## .. Order.Date = col_character(),
## .. Order.ID = col_double(),
## .. Ship.Date = col_character(),
## .. Units.Sold = col_double(),
## .. Unit.Price = col_double(),
## .. Unit.Cost = col_double(),
## .. Total.Revenue = col_double(),
## .. Total.Cost = col_double(),
## .. Total.Profit = col_double()
## .. )
## - attr(*, "problems")=<externalptr>
Nhận xét: Kết quả cho thấy bộ dữ liệu gồm 100.000 dòng và 14 cột, trong đó có 7 biến ký tự là Region, Country, Item.Type, Sales.Channel, Order.Priority, Order.Date, Ship.Date và 7 biến số là Units.Sold, Unit.Price, Unit.Cost, Total.Revenue, Total.Cost, Total.Profit
1. dim(Sales)
## [1] 100000 14
Nhận xét: Kết quả cho thấy bộ dữ liệu gồm 100.000 dòng và 14 biến. Giải thích: -
dim(Sales): hiển thị dạng (số dòng, số cột). Ví dụ (100.000, 14).
1. tab <- table(Sales$Region)
2. tab_formatted <- format(tab, big.mark = "." , decimal.mark = ",")
3. knitr::kable(tab_formatted)
| x | |
|---|---|
| Asia | 14.547 |
| Australia and Oceania | 8.113 |
| Central America and the Caribbean | 10.731 |
| Europe | 25.877 |
| Middle East and North Africa | 12.580 |
| North America | 2.133 |
| Sub-Saharan Africa | 26.019 |
Nhận xét: Khu vực Sub-Saharan Africa chiếm số lượng đơn hàng lớn nhất với 26.019 đơn. Ngược lại, North America chỉ có 2.133 đơn, thấp nhất trong bảng, phản ánh mức độ hoạt động bán hàng còn hạn chế tại đây. Những số liệu này giúp chỉ ra khu vực trọng điểm cần tập trung nguồn lực kinh doanh và nhận diện được các vùng tiềm năng hoặc vùng cần điều chỉnh chính sách bán hàng để tối ưu doanh thu và lợi nhuận.
Giải thích: -
table(Sales$Region): đếm số lần xuất hiện của từng khu vực trong cột Region.
Giải thích: - Hàm
summary()cho 5 giá trị thống kê cơ bản: min, Q1, median, mean, Q3, max là nền tảng để nhận diện phân bố dữ liệu. - Hàmformat_summarydùng để chuyển số sang dạng đẹp và dễ đọc: big.mark = “.”: ngăn cách hàng nghìn bằng dấu chấm. decimal.mark = “,”: dùng dấu phẩy cho phần thập phân. scientific = FALSE: không để số ở dạng khoa học (không hiện e+). -sapplyduyệt qua từng phần tử trong summary, áp chức năngformat_summarylên đó.
1. s <- summary(Sales$Units.Sold)
2. format_summary <- function(x) prettyNum(x, big.mark = ".", decimal.mark = ",", scientific = FALSE)
3. print(sapply(s, format_summary))
## Min. 1st Qu. Median Mean 3rd Qu. Max.
## "1" "2.505" "5.007" "5.001,446" "7.495,25" "10.000"
Nhận xét: Số lượng sản phẩm bán ra từ 1 đến 10.000, cho thấy doanh nghiệp bán cả lẻ lẫn sỉ hoặc phục vụ nhiều phân khúc khách hàng. Phần lớn đơn hàng nằm trong khoảng từ 2.505 đến 7.495,25 , trong đó giá trị phổ biến là trung vị 5.007. Việc này giúp doanh nghiệp dễ dự báo nguồn hàng, tối ưu sản xuất và đáp ứng đúng nhu cầu thị trường.
1. s <- summary(Sales$Unit.Price)
2. format_summary <- function(x) prettyNum(x, big.mark = ".", decimal.mark = ",", scientific = FALSE)
3. print(sapply(s, format_summary))
## Min. 1st Qu. Median Mean 3rd Qu. Max.
## "9,33" "109,28" "205,7" "266,704" "437,2" "668,27"
Nhận xét: Giá bán sản phẩm trải dài từ 9,33 đến 668,27, thể hiện sự đa dạng và phù hợp với nhiều phân khúc khách hàng. Đa số sản phẩm có giá nằm giữa Q1 là 109,28 và Q3 là 437,2, còn giá phổ biến là trung vị 205,7.Mức giá bán trải rộng giúp doanh nghiệp tiếp cận nhiều nhóm khách hàng, tăng khả năng cạnh tranh và tối đa hóa doanh thu.
1. s <- summary(Sales$Unit.Cost)
2. format_summary <- function(x) prettyNum(x, big.mark = ".", decimal.mark = ",", scientific = FALSE)
3. print(sapply(s, format_summary))
## Min. 1st Qu. Median Mean 3rd Qu. Max.
## "6,92" "56,67" "117,11" "188,0197" "364,69" "524,96"
Nhận xét: Chi phí đơn vị sản phẩm dao động từ 6,92 đến 524,96, thể hiện sự khác biệt lớn giữa các loại sản phẩm hoặc nhóm hàng. Đa số chi phí nằm trong khoảng từ 56,67 đến 364,69, và giá trị phổ biến là trung vị 117,11. Mức chi phí trải rộng giúp doanh nghiệp vừa quản lý được hàng hóa giá rẻ tối ưu chi phí, vừa kiểm soát nhóm sản phẩm giá cao để tăng lợi nhuận.
1. s <- summary(Sales$Total.Revenue)
2. format_summary <- function(x) prettyNum(x, big.mark = ".", decimal.mark = ",", scientific = FALSE)
3. print(sapply(s, format_summary))
## Min. 1st Qu. Median Mean 3rd Qu. Max.
## "18,66" "279.753,3" "789.891,6" "1.336.067" "1.836.490" "6.682.700"
Nhận xét: Doanh thu bán hàng của doanh nghiệp trải từ 18,66 đến 6.682.700, cho thấy sự chênh lệch lớn giữa các giao dịch. Phần lớn doanh thu của các đơn hàng nằm trong khoảng giữa Q1 là 279.753,3 và Q3 là 1.836.490, với mức phổ biến nhất là trung vị 789.891,6. Điều này chứng tỏ doanh nghiệp có thể bán từ những đơn nhỏ đến rất lớn, tăng khả năng tiếp cận khách hàng đa dạng và tối đa hóa doanh thu.
1. s <- summary(Sales$Total.Cost)
2. format_summary <- function(x) prettyNum(x, big.mark = ".", decimal.mark = ",", scientific = FALSE)
3. print(sapply(s, format_summary))
## Min. 1st Qu. Median Mean 3rd Qu. Max.
## "13,84" "162.928,3" "467.937,4" "941.975,5" "1.209.475" "5.249.075"
Nhận xét:Tổng chi phí mỗi đơn hàng dao động từ 13,84 đến 5.249.075, cho thấy doanh nghiệp có cả các đơn hàng nhỏ lẻ và các đơn hàng lớn. Hầu hết chi phí tập trung trong khoảng từ 162.928,3 đến 1.209.475, với mức phổ biến nhất là 467.937,4. Thông tin này giúp doanh nghiệp dễ dàng dự đoán chi phí vận hành, kiểm soát ngân sách, đồng thời phân bổ nguồn lực hợp lý để phục vụ các đơn hàng đa dạng, góp phần nâng cao hiệu quả và lợi nhuận kinh doanh.
1. s<- summary(Sales$Total.Profit)
2. format_summary <- function(x) prettyNum(x, big.mark = ".", decimal.mark = ",", scientific = FALSE)
3. print(sapply(s, format_summary))
## Min. 1st Qu. Median Mean 3rd Qu. Max.
## "4,82" "95.900" "283.657,5" "394.091,2" "568.384,1" "1.738.700"
Nhận xét:Tổng lợi nhuận của mỗi đơn hàng dao động từ 4,82 đến 1.738.700, nghĩa là doanh nghiệp có đơn hàng lợi nhuận thấp và cũng có đơn hàng rất cao. Đa số lợi nhuận thu được nằm khoảng từ Q1 là 95.900 đến Q3 là 568.384,1, còn mức phổ biến nhất là trung vị 283.657,5. Điều này cho thấy phần lớn các giao dịch mang lại lợi nhuận vừa phải. Nắm rõ các mốc lợi nhuận này giúp doanh nghiệp biết rõ tình hình kinh doanh, xây dựng kế hoạch phù hợp và dễ dàng kiểm soát hiệu quả hoạt động.
1. sapply(Sales,function(Sales) sum(is.na(Sales)))
## Region Country Item.Type Sales.Channel Order.Priority
## 0 0 0 0 0
## Order.Date Order.ID Ship.Date Units.Sold Unit.Price
## 0 0 0 0 0
## Unit.Cost Total.Revenue Total.Cost Total.Profit
## 0 0 0 0
Nhận xét:Kết quả kiểm tra trả về toàn bộ giá trị bằng 0, nghĩa là không có bất kỳ giá trị thiếu nào trong 14 cột dữ liệu
Giải thích: -
sapply(...): áp dụng kiểm tra cho từng cột trong bảng Sales, trả về một số cho mỗi cột. -sum(is.na(Sales)): đếm tổng số giá trị bị thiếu trong mỗi cột, các giá trị thiếu được hàm is.na trả về TRUE. —
1. Sales[duplicated(Sales),]
Nhận xét:Kết quả hiển thị là một bảng rỗng (# A tibble: 0 x 14), nghĩa là không có dòng dữ liệu nào bị trùng lặp.
Giải thích:
Sales[duplicated(Sales),]: lọc ra các dòng trùng, nếu bảng kết quả rỗng thì dữ liệu không bị lặp lại.
1. scale <- function(x) {
2. if (!is.numeric(x)) {
3. message("Cột không phải dạng số. Không thể chuẩn hóa.")
4. return(NULL)}
5. if (max(x) == min(x)) {
6. message("Tất cả giá trị giống nhau. Trả về toàn 0.")
7. return(rep(0, length(x))) }
8. scaled <- (x - min(x)) / (max(x) - min(x))
9. return(scaled)}
Nhận xét:Việc chuẩn hóa giúp đưa các biến về cùng thang đo, thuận tiện khi so sánh hoặc vẽ biểu đồ. Đây là bước cần thiết trong các phân tích thống kê hoặc mô hình hóa vì nó giúp loại bỏ sự khác biệt về đơn vị đo lường giữa các biến.
Giải thích:
- Dòng số 1:scale <- function(x){ ... }: Định nghĩa một hàm tên là scale, nhận đối số là biến x (có thể là một vector). - Dòng số 2:if (!is.numeric(x)) { ... }: Kiểm tra nếu x không phải là kiểu số (numeric), thì: message(“Cot khong phai dang so. Khong the chuan hoa.”): Thông báo trên màn hình rằng cột không phải dạng số.return(NULL): Trả về giá trị rỗng, kết thúc hàm (không báo lỗi). - Dòng số 5:if (max(x) == min(x)) { ... }: Kiểm tra nếu tất cả giá trị trong x đều giống nhau (giá trị lớn nhất bằng giá trị nhỏ nhất):message("Tat ca gia tri giong nhau. Tra ve toan 0."): Thông báo trên màn hình.return(rep(0, length(x))): Trả về một vector toàn giá trị 0, độ dài bằng độ dài của x. - Dòng số 8:scaled <- (x - min(x)) / (max(x) - min(x)): Đây là công thức chuẩn hóa min-max, đưa mọi giá trị về khoảng từ 0 đến 1. Từng phần tử sẽ lấy giá trị trừ giá trị nhỏ nhất rồi chia cho hiệu số lớn nhất - nhỏ nhất - Dòng số 9:return(scaled): Trả về vector đã chuẩn hóa.
1. Sales$Order.Date <- as.Date(Sales$Order.Date, format = "%m/%d/%Y")
2. Sales$Ship.Date <- as.Date(Sales$Ship.Date, format = "%m/%d/%Y")
Giải thích: Hai dòng lệnh chuyển đổi cột Order.Date và Ship.Date từ kiểu ký tự (character) sang kiểu ngày tháng (Date) bằng hàm
as.Date().
1. boxplot(Sales$Units.Sold)
Nhận xét:Min= 1, Q1 = 2.505, Q2 (Median) = 5.007, Q3 = 7495, Max = 10.000 Số lượng sản phẩm bán ra từ 1 đến 10.000 sản phẩm. Một nửa số đơn hàng có lượng bán trong khoảng 2.505 – 7.495 sản phẩm, được giới hạn bởi hai tứ phân vị Q1 và Q3. Giá trị trung vị Q2 = 5.007 nằm gần giữa hộp, cho thấy dữ liệu phân bố khá cân đối quanh mức trung bình.
1. boxplot(Sales$Unit.Price)
Nhận xét:Min = 9,33, Q1 = 109,28, Q2 = 205,70, Q3 = 437,20, Max = 668,27 Giá bán mỗi sản phẩm có sự chênh lệch rõ rệt giữa các loại hàng. Một nửa số sản phẩm có giá nằm trong khoảng 109,28 – 437,20. Giá trị trung vị Q2 = 205,70 thể hiện mức giá phổ biến nhất rơi vào nhóm trung bình thấp, quanh 200 đồng. Giá thấp nhất là 9,33 đồng, trong khi cao nhất là 668,27 đồng, cho thấy doanh nghiệp kinh doanh đa dạng nhiều loại hàng hóa từ giá rẻ đến cao cấp.
1. boxplot(Sales$Unit.Cost)
Nhận xét:Min = 6,92, Q1 = 56,67, Q2 = 117,11, Q3 = 364,69, Max = 524,96 Chi phí sản xuất dao động từ 6,92 đến 524,96 đồng, cho thấy mức độ khác biệt đáng kể giữa các mặt hàng. Một nửa số sản phẩm có chi phí nằm trong khoảng 56,67 – 364,69. Giá trị trung vị Q2 = 117,11 thấp hơn trung bình = 188,02. Dữ liệu có dạng lệch phải, do một vài sản phẩm có chi phí cao vượt trội so với phần còn lại. ___
1. Sales %>%
2. group_by(Region) %>%
3. summarise(Total_Revenue = sum(Total.Revenue, na.rm = TRUE)) %>%
4. mutate(Total_Revenue = format(Total_Revenue, big.mark = ".", decimal.mark = ",", scientific = FALSE)) %>% kable(caption = "Tổng doanh thu theo vùng", align = 'c')
| Region | Total_Revenue |
|---|---|
| Asia | 19.293.401.220 |
| Australia and Oceania | 10.701.522.224 |
| Central America and the Caribbean | 14.553.730.165 |
| Europe | 34.241.150.923 |
| Middle East and North Africa | 16.921.412.795 |
| North America | 2.937.002.333 |
| Sub-Saharan Africa | 34.958.453.406 |
Nhận xét: Doanh thu phân bố không đồng đều, tập trung cao ở Sub-Saharan Afica và Châu Âu, trong khi Bắc Mỹ và Châu Đại Dương có doanh thu thấp hơn. Điều này gợi ý doanh nghiệp nên: xem xét chiến lược mở rộng hoặc tái cấu trúc thị trường Bắc Mỹ. Đầu tư thêm vào Châu Á để tận dụng tiềm năng tăng trưởng. Giữ vững thị phần tại Châu Âu và Châu Phi bằng chiến lược duy trì quan hệ khách hàng và năng lực phân phối. Giải thích: - Dòng số 3: Tính tổng doanh thu từng khu vực. Doanh thu của một khu vực bằng tổng doanh thu của tất cả đơn hàng thuộc khu vực đó. - Dòng số 4: Định dạng cột Total_Revenue thành dạng chuỗi, dùng dấu chấm làm dấu ngăn cách hàng nghìn và dấu phẩy cho thập phân, đảm bảo số không bị viết dạng lũy thừa.
1. Sales %>%
2. group_by(Item.Type) %>%
3. summarise(Mean_Profit = mean(Total.Profit, na.rm = TRUE)) %>%
4. mutate(Mean_Profit = format(Mean_Profit, big.mark = ".", decimal.mark = ",", scientific = FALSE)) %>% kable(caption = "Lợi nhuận trung bình theo loại sản phẩm", align = 'c')
| Item.Type | Mean_Profit |
|---|---|
| Baby Food | 477.893,17 |
| Beverages | 78.725,18 |
| Cereal | 444.521,90 |
| Clothes | 369.441,41 |
| Cosmetics | 870.896,84 |
| Fruits | 11.900,44 |
| Household | 830.027,31 |
| Meat | 286.999,40 |
| Office Supplies | 633.697,24 |
| Personal Care | 124.394,45 |
| Snacks | 276.755,89 |
| Vegetables | 314.467,25 |
Nhận xét: Kết quả cho thấy lợi nhuận trung bình giữa các nhóm sản phẩm có sự chênh lệch đáng kể, phản ánh sự khác biệt trong cơ cấu chi phí, nhu cầu thị trường và chiến lược định giá của doanh nghiệp. Nhóm Cosmetics và Household đạt mức lợi nhuận trung bình cao nhất, các nhóm như Fruits và Beverages có lợi nhuận trung bình thấp nhất. Doanh nghiệp có thể tập trung đẩy mạnh sản xuất và tiếp thị cho các nhóm có lợi nhuận cao đồng thời xem xét tối ưu chi phí hoặc định vị lại giá bán cho các nhóm có lợi nhuận thấp nhằm cải thiện hiệu quả kinh doanh chung. Giải thích: - Dòng số 3: Tính lợi nhuận trung bình từng loại sản phẩm. - Dòng số 4: Định dạng cột thành dạng chuỗi, dùng dấu chấm làm dấu ngăn cách hàng nghìn và dấu phẩy cho thập phân, đảm bảo số không bị viết dạng lũy thừa.
1. library(dplyr)
2. Sales %>%
3. group_by(Country) %>%
4. summarise(Total_Profit = sum(Total.Profit, na.rm = TRUE)) %>%
5. arrange(desc(Total_Profit)) %>%
6. slice(1:10) %>% mutate(Total_Profit = format(Total_Profit, big.mark = ".", decimal.mark = ",", scientific = FALSE)) %>% kable(caption = "Tổng lợi nhuận theo quốc gia", align = 'c')
| Country | Total_Profit |
|---|---|
| Sudan | 249.523.549 |
| Hungary | 241.860.844 |
| Federated States of Micronesia | 241.045.260 |
| Liberia | 239.114.337 |
| Australia | 238.598.456 |
| Benin | 238.294.600 |
| New Zealand | 237.880.636 |
| Bahrain | 237.638.193 |
| Marshall Islands | 236.922.446 |
| Malta | 234.376.856 |
Nhận xét:Kết quả cho thấy Sudan dẫn đầu, Hungary và Federated States of Micronesia lần lượt đứng thứ hai và ba, cho thấy đây cũng là những thị trường tiềm năng, có sức mua tốt hoặc lợi nhuận cao. Doanh nghiệp nên duy trì và mở rộng thị phần tại các quốc gia đang có lợi nhuận cao, đồng thời phân tích sâu nguyên nhân tạo nên hiệu quả ở các thị trường nhỏ để nhân rộng mô hình. Ngoài ra, cần tiếp tục so sánh chi phí, thuế và mức độ cạnh tranh giữa các quốc gia nhằm tối ưu chiến lược phân bổ nguồn lực toàn cầu.
Giải thích: - Dòng số 4: tính tổng lợi nhuận của từng quốc gua. Hàm
sumcộng dồn lợi nhuận vàna.rm = TRUEbỏ qua các giá trị thiếu. - Dòng số 5: Sắp xếp lại các nhóm quốc gia theo giá trị tổng lợi nhuận vừa tính, từ quốc gia có lợi nhuận cao nhất tới thấp nhất. - Dòng số 6:slice(1:10)Lấy ra 10 quốc gia đầu tiên để tập trung phân tích. - Dòng số 7: dùng dấu chấm ngăn cách hàng nghìn, dấu phẩy cho thập phân, và không hiện dạng khoa học.
1. Sales %>%
2. group_by(Sales.Channel) %>%
3. summarise(Total_Units = sum(Units.Sold, na.rm = TRUE)) %>%
4. mutate(Total_Units = format(Total_Units, big.mark = ".", decimal.mark = ",", scientific = FALSE)) %>% kable(caption = "Số lượng bán ra theo kênh phân phốiphối", align = 'c')
| Sales.Channel | Total_Units |
|---|---|
| Offline | 249.871.172 |
| Online | 250.273.445 |
Nhận xét:Kết quả phân tích cho thấy doanh nghiệp đang vận hành hai kênh bán hàng chính là Online và Offline, với quy mô tiêu thụ gần như tương đương nhau.Kết quả này cho thấy thương mại điện tử đã trở thành kênh bán hàng chủ lực có số lượng lớn. Việc doanh số online đạt mức gần ngang bằng với offline chứng tỏ doanh nghiệp đã thích ứng tốt với xu hướng tiêu dùng hiện đại và tận dụng hiệu quả các nền tảng số trong hoạt động kinh doanh . Giải thích: - Dòng số 2: nhóm dữ liệu theo từng Sales.Channel. - Dòng số 3: tính tổng số lượng đã bán trong mỗi kênh bán hàng, đặt tên cột mới là
Total_Units.Tham sốna.rm = TRUE` nghĩa là bỏ qua các giá trị bị thiếu khi tính tổng. - Dòng số 4: dùng dấu chấm ngăn cách hàng nghìn, dấu phẩy cho thập phân, và không hiện dạng khoa học
1. Sales %>%
2. group_by(Region) %>%
3. summarise(Total_Cost = sum(Total.Cost, na.rm = TRUE)) %>%
4. mutate(Total_Cost = format(Total_Cost, big.mark = ".", decimal.mark = ",", scientific = FALSE))%>%
5. kable(caption = "Tổng chi phí theo vùng", align = 'c')
| Region | Total_Cost |
|---|---|
| Asia | 13.585.889.703 |
| Australia and Oceania | 7.526.098.662 |
| Central America and the Caribbean | 10.266.519.643 |
| Europe | 24.160.571.432 |
| Middle East and North Africa | 11.941.878.416 |
| North America | 2.064.450.717 |
| Sub-Saharan Africa | 24.652.140.764 |
Nhận xét:Kết quả cho thấy Sub-Saharan Africa và Europe là hai khu vực có tổng chi phí cao nhất, North America có tổng chi phí thấp nhất. Doanh nghiệp đang chi nhiều cho những khu vực có quy mô thị trường lớn. Tuy nhiên, để hiệu quả hơn, cần xem xét xem chi phí bỏ ra có tương xứng với lợi nhuận thu được không – nếu chi phí cao mà lợi nhuận thấp, doanh nghiệp nên tìm cách tối ưu chi phí vận hành và phân phối ở những vùng đó. Giải thích: - Dòng số 2: nhóm dữ liệu theo vùng để mỗi vùng là một nhóm riêng biệt. - Dòng số 3: tính tổng chi phí cho từng vùng bằng cách cộng toàn bộ các giá trị, đặt tên cột mới là
Total_Cost. Tham sốna.rm = TRUEgiúp bỏ qua các giá trị thiếu khi tính tổng. - Dòng số 4: dùng dấu chấm ngăn cách hàng nghìn, dấu phẩy cho thập phân, và không sử dụng ký hiệu khoa học.
1. Sales %>% filter(Order.Priority == "High") %>% group_by(Region) %>%
2. summarise(Orders_High_Priority = n()) %>%
3. mutate(Orders_High_Priority = format(Orders_High_Priority, big.mark = ".", decimal.mark = ",", scientific = FALSE)) %>%
4. knitr::kable(caption = "Số lượng đơn hàng ưu tiên cao theo vùn", align = 'c')
| Region | Orders_High_Priority |
|---|
Nhận xét:Dữ liệu cho Europe dẫn đầu, tiếp theo là Sub-Saharan Africa. Trong khi đó,Australia and Oceania và Central America and the Caribbean có số đơn ưu tiên thấp hơn và North America có số đơn ưu tiên thấp nhất.Doanh nghiệp nên duy trì năng lực xử lý đơn hàng nhanh tại Europe và Sub-Saharan Africa vì đây là hai khu vực có nhu cầu cao nhất. Đồng thời, cần phân tích nguyên nhân khiến các khu vực khác có số đơn ưu tiên thấp, để xem xét có nên mở rộng chính sách giao hàng nhanh hoặc tăng năng lực phục vụ nhằm nâng cao trải nghiệm khách hàng.
Giải thích: - Dòng số 1: lọc dữ liệu để chỉ giữ lại các đơn hàng có độ ưu tiên là “High” (Order.Priority == “High”). Nhóm những dòng vừa lọc theo từng vùng. - Dòng số 3: đếm số lượng đơn hàng ưu tiên cao ở mỗi khu vực, lưu kết quả vào cột
Orders_High_Priority. - Dòng số 4: dùng dấu chấm để ngăn cách hàng nghìn, dấu phẩy cho thập phân và loại bỏ ký hiệu khoa học.
1. Sales %>% group_by(Region, Sales.Channel) %>%
2. summarise(Avg_Units = mean(Units.Sold, na.rm = TRUE)) %>%
3. mutate(Avg_Units = format(Avg_Units, big.mark = ".", decimal.mark = ",", scientific = FALSE)) %>%
4. kable(caption = "Đơn hàng trung bình theo kênh phân phối mỗi vùng", align = 'c')
| Region | Sales.Channel | Avg_Units |
|---|---|---|
| Asia | Offline | 4.983,775 |
| Asia | Online | 5.027,886 |
| Australia and Oceania | Offline | 4.990,001 |
| Australia and Oceania | Online | 5.066,263 |
| Central America and the Caribbean | Offline | 5.007,625 |
| Central America and the Caribbean | Online | 5.033,281 |
| Europe | Offline | 5.007,999 |
| Europe | Online | 4.936,606 |
| Middle East and North Africa | Offline | 5.003,483 |
| Middle East and North Africa | Online | 5.052,756 |
| North America | Offline | 5.142,161 |
| North America | Online | 5.025,662 |
| Sub-Saharan Africa | Offline | 4.998,259 |
| Sub-Saharan Africa | Online | 4.986,087 |
Nhận xét: Có thể thấy, số lượng bán ra giữa hai kênh bán hàng không chênh lệch nhiều, nhưng đa phần thì kệnh online sẽ bán nhiều sản phẩm hơn.Điều này cho thấy tại một số thị trường, kênh bán hàng trực tuyến đang phát huy hiệu quả tốt hơn truyền thống, đặc biệt khi người tiêu dùng dễ tiếp cận công nghệ và thích nghi với mua sắm online. Tuy nhiên, sự khác biệt từng vùng cũng phản ánh thói quen tiêu dùng, cơ sở hạ tầng, và chiến lược bán hàng của doanh nghiệp cần linh hoạt, phù hợp từng khu vực để tối ưu hóa hiệu quả kinh doanh.
Giải thích: - Dòng số 1: nhóm dữ liệu theo hai biến vùng và kênh bán hàng để chia thành các nhóm nhỏ, mỗi nhóm là một vùng với kênh bán hàng khác nhau. - Dòng số 2: tính trung bình số lượng bán ra
Avg_Unitsvới mỗi nhóm nhỏ, sử dụngna.rm = TRUEđể bỏ qua các giá trị NA khi tính trung bình. - Dòng số 3: dùng dấu chấm ngăn cách hàng nghìn, dấu phẩy cho thập phân và không dùng dạng khoa học.
1. Profit_summary <- aggregate(x = Sales$Total.Profit,
2. by = list(Region = Sales$Region, Order.Priority = Sales$Order.Priority),
3. FUN = mean)
4. colnames(Profit_summary) [3] <- "MeanProfit"
5. Profit_summary_formatted <- Profit_summary %>%
6. mutate(MeanProfit = format(MeanProfit, big.mark = ".", decimal.mark = ",", scientific = FALSE))
7. knitr::kable(Profit_summary_formatted)
| Region | Order.Priority | MeanProfit |
|---|---|---|
| Asia | C | 396.745,3 |
| Australia and Oceania | C | 385.122,6 |
| Central America and the Caribbean | C | 392.267,8 |
| Europe | C | 388.972,2 |
| Middle East and North Africa | C | 398.332,8 |
| North America | C | 412.857,6 |
| Sub-Saharan Africa | C | 397.989,1 |
| Asia | H | 392.182,2 |
| Australia and Oceania | H | 398.107,5 |
| Central America and the Caribbean | H | 397.040,2 |
| Europe | H | 392.669,5 |
| Middle East and North Africa | H | 379.711,8 |
| North America | H | 407.302,2 |
| Sub-Saharan Africa | H | 402.767,4 |
| Asia | L | 397.738,2 |
| Australia and Oceania | L | 387.020,4 |
| Central America and the Caribbean | L | 398.463,8 |
| Europe | L | 386.221,7 |
| Middle East and North Africa | L | 406.880,3 |
| North America | L | 409.641,0 |
| Sub-Saharan Africa | L | 390.830,8 |
| Asia | M | 382.613,7 |
| Australia and Oceania | M | 395.259,8 |
| Central America and the Caribbean | M | 410.189,6 |
| Europe | M | 390.358,6 |
| Middle East and North Africa | M | 398.695,5 |
| North America | M | 406.660,5 |
| Sub-Saharan Africa | M | 393.071,0 |
Nhận xét: Dữ liệu cho thấy North America có mức lợi nhuận trung bình cao nhất với các đơn hàng ưu tiên Critical và High, phản ánh sức mua mạnh mẽ cũng như hiệu quả kinh doanh của doanh nghiệp tại thị trường này. Europe và Central America and the Caribbean cũng duy trì mức lợi nhuận ổn định ở cả các mức độ ưu tiên đơn hàng khác nhau. Trong khi đó, các khu vực như Asia và Middle East and North Africa có mức lợi nhuận thấp hơn một chút, cho thấy tiềm năng phát triển nhưng đồng thời cần cải thiện hiệu quả vận hành, đặc biệt ở các đơn hàng ưu tiên thấp và trung bình. Việc phân tích giúp doanh nghiệp lựa chọn chiến lược phân phối phù hợp từng khu vực để tối ưu hóa lợi nhuận tổng thể.
Giải thích: - Dòng số 1: dùng
aggregate()để tính trung bình lợi nhuận cho từng nhóm tổ hợp vùng miền và mức ưu tiên đơn hàng. Kết quả trả về một bảng tóm tắt có ba cột: Region, Order.Priority, và giá trị trung bình lợi nhuận. - Dòng số 2: đổi tên cột thứ ba thànhMeanProfit. - Dòng số 3: sử dụngmutate()thêm dấu chấm ngăn cách hàng nghìn, dấu phẩy cho thập phân, loại bỏ dạng số khoa học, giúp số dễ nhìn hơn khi trình bày hoặc báo cáo.
1. Sales$delivery_date <- Sales$Ship.Date - Sales$Order.Date
2. Sales$Sort_Date <- ifelse( Sales$delivery_date < 12, "Tốc độ nhanh",ifelse( Sales$delivery_date < 38, "Tốc độ trung bình", "Tốc độ chậm"))
3. result <- table(Sales$Sort_Date)
4. print(format(result, big.mark = "." , decimal.mark = ",", scientific = FALSE))
##
## Tốc độ chậm Tốc độ nhanh Tốc độ trung bình
## "25.709" "23.553" "50.738"
Nhận xét:Kết quả phân tích cho thấy thời gian giao hàng trung bình là 25,04 ngày, dao động từ 0–50 ngày. Khoảng 50% đơn hàng (50.738 đơn) thuộc nhóm tốc độ trung bình (12–38 ngày) — mức phổ biến và ổn định nhất. Nhóm nhanh (<12 ngày) chiếm 23.553 đơn (≈25%), phản ánh khả năng xử lý linh hoạt.Trong khi đó, nhóm chậm (>38 ngày) có 25.709 đơn (≈25%), cho thấy vẫn tồn tại các hạn chế về vận chuyển hoặc khoảng cách.
Giải thích: - Dòng số 1: tính số ngày giao hàng cho từng đơn bằng cách lấy
Ship.DatetrừOrder.Date, kết quả lưu vào cộtdelivery_date. - Dòng số 2: phân loại mỗi đơn hàng thành 3 nhóm tốc độ dựa vào số ngày giao hàng vừa tính: dưới 12 ngày là “Tốc độ nhanh”, từ 12 đến dưới 38 ngày là “Tốc độ trung bình”, còn lại là “Tốc độ chậm”. - Dòng số 3: đếm số lượng đơn hàng thuộc mỗi nhóm tốc độ giao hàng, kết quả lưu vào biếnresult. - Dòng số 4: định dạng lại số lượng đơn hàng ở mỗi nhóm theo kiểu Việt Nam – dùng dấu chấm ngăn cách hàng nghìn, dấu phẩy cho thập phân, không hiện dạng khoa học – rồi in ra kết quả để dễ đọc khi báo cáo.
1. Reve_Item_Priority <- aggregate(Sales$Total.Revenue, by = list(Item = Sales$Item.Type, Priority = Sales$Order.Priority), FUN = sum)
2. colnames(Reve_Item_Priority)[3] <- "Revenue"
3. Reve_Item_Priority_sorted <- Reve_Item_Priority[order(Reve_Item_Priority$Revenue, decreasing = TRUE),]
4. top5 <- head(Reve_Item_Priority_sorted, 5) %>%
5. mutate(Revenue = format(Revenue, big.mark = ".", decimal.mark = ",", scientific = FALSE))
6. knitr::kable(top5)
| Item | Priority | Revenue | |
|---|---|---|---|
| 45 | Office Supplies | M | 7.092.747.489 |
| 31 | Household | L | 7.075.645.433 |
| 43 | Household | M | 6.963.174.924 |
| 21 | Office Supplies | H | 6.934.264.465 |
| 7 | Household | C | 6.892.145.842 |
1. bottom5 <- tail(Reve_Item_Priority_sorted, 5) %>%
2. mutate(Revenue = format(Revenue, big.mark = ".", decimal.mark = ",", scientific = FALSE))
3. knitr::kable(bottom5)
| Item | Priority | Revenue | |
|---|---|---|---|
| 2 | Beverages | C | 489.781.794 |
| 18 | Fruits | H | 97.379.757 |
| 6 | Fruits | C | 96.050.857 |
| 30 | Fruits | L | 93.937.323 |
| 42 | Fruits | M | 93.270.648 |
Nhận xét:Nhìn vào hai bảng dữ liệu, có thể thấy nhóm hàng Office Supplies và Household đạt doanh thu cao nhất ở các mức ưu tiên khác nhau. Điều này cho thấy nhu cầu của khách hàng với các mặt hàng này rất ổn định, bất kể ở mức độ ưu tiên đơn hàng nào. Đây là các nhóm sản phẩm chiến lược mang lại nguồn thu lớn cho doanh nghiệp.Trong khi đó, các nhóm như Fruits và Beverages có doanh thu thấp hơn đáng kể. Điều này phản ánh đây là các mặt hàng không phải chủ lực, có lượng tiêu thụ hoặc giá trị đơn hàng thấp, và ít được chú trọng trên tổng thể hoạt động kinh doanh. Nhận định này giúp doanh nghiệp xác định đúng nhóm sản phẩm cần ưu tiên phát triển và tối ưu hóa danh mục sản phẩm để tăng trưởng doanh thu bền vững.
Giải thích: - Dòng số 1: dùng hàm
aggregate()để tính tổng doanh thu nhóm theo từng loại sản phẩm và mức độ ưu tiên đơn hàng. Kết quả trả về một bảng với các cột: Loại sản phẩm, Ưu tiên đơn hàng, và tổng doanh thu từng nhóm. - Dòng số 2: đổi tên cột thứ ba thànhRevenue. - Dòng số 3: sắp xếp lại bảng vừa tổng hợp theo cộtRevenuegiảm dần. - Dòng số 4: lấy 5 dòng đầu bảng có doanh thu cao nhất và định dạng lại cột Revenue để có dấu chấm ngăn cách hàng nghìn, dấu phẩy cho thập phân, không hiển thị dạng số khoa học - Dòng số 5: lấy 5 dòng cuối bảng có doanh thu thấp nhất và định dạng lại cột Revenue để có dấu chấm ngăn cách hàng nghìn, dấu phẩy cho thập phân, không hiển thị dạng số khoa học.
1. library(flextable)
## systemfonts and textshaping have been compiled with different versions of Freetype. Because of this, textshaping will not use the font cache provided by systemfonts
1. Asia <- Sales %>% filter(Region == "Asia")
2. q_unit <- quantile(Asia$Units.Sold, probs = c(0.25, 0.75), na.rm = TRUE)
3. q_profit <- quantile(Asia$Total.Profit, probs = c(0.25, 0.75), na.rm = TRUE)
4. Asia$PhatTrien <- ifelse( Asia$Units.Sold < q_unit[1] & Asia$Total.Profit < q_profit[1], "Phát triển chậm", ifelse( Asia$Units.Sold <= q_unit[2] & Asia$Total.Profit <= q_profit[2], "Phát triển trung bình", "Phát triển tốt"))
5. freq_table <- Asia %>% count(Nhom = PhatTrien) %>% mutate(Ty_le = round(100 * n / sum(n), 2)) %>% mutate(n = format(n, big.mark = ".",decimal.mark = ",", scientific = FALSE), Ty_le = format(Ty_le, big.mark = ".", decimal.mark = ",", scientific = FALSE))
6. freq_table %>% flextable() %>% set_header_labels( Nhom = "Nhóm phát triển", n = "Tần suất", Ty_le = "Tỷ lệ (%)") %>% align(align = "center", part = "all") %>% autofit()
Nhóm phát triển | Tần suất | Tỷ lệ (%) |
|---|---|---|
Phát triển chậm | 2.110 | 14,50 |
Phát triển trung bình | 7.102 | 48,82 |
Phát triển tốt | 5.335 | 36,67 |
Nhận xét: Kết quả phân nhóm cho thấy phần lớn các đơn hàng tại thị trường châu Á thuộc nhóm phát triển trung bình với tỷ lệ 48,82%, phản ánh sự ổn định và chiếm thị phần chính của các sản phẩm này. Trong khi đó, nhóm phát triển tốt chiếm 36,67%, thể hiện có hơn một phần ba đơn hàng đạt hiệu quả kinh doanh cao, đây là nhóm cần được ưu tiên đầu tư mở rộng để tối đa hóa lợi nhuận. Ngược lại, chỉ 14,5% số đơn thuộc nhóm phát triển chậm, đa phần là các sản phẩm có lượng bán và lợi nhuận thấp; doanh nghiệp nên rà soát, điều chỉnh chính sách hoặc đổi mới sản phẩm đối với nhóm này để cải thiện hiệu quả hoạt động kinh doanh
Giải thích: - Dòng số 1: lọc bảng Sales để chỉ lấy các dòng thuộc khu vực châu Á, giúp bạn phân tích riêng dữ liệu châu Á. - Dòng số 2 và 3: tính các giá trị phân vị của số lượng bán và tổng lợi nhuận ở khu vực này, dùng làm mốc phân nhóm phát triển. - Dòng số 4: phân loại từng đơn hàng trong dữ liệu thành 3 nhóm phát triển dựa vào mức thấp, trung bình, hoặc cao của cả số lượng bán và lợi nhuận so với các phân vị. - Dòng số 5: thống kê số lượng từng nhóm phát triển và tính tỷ lệ phần trăm, sau đó định dạng dùng dấu chấm ngăn cách hàng nghìn, dấu phẩy cho thập phân, không ở dạng khoa học. - Dòng số 6: chuyển bảng kết quả sang flextable, chỉnh lại nhãn cột tiếng Việt, căn giữa toàn bộ bảng và tự động điều chỉnh độ rộng để trình bày báo cáo đẹp mắt.
1. Sales %>%
2. group_by(Region) %>%
3. summarise(Min_Revenue = min(Total.Revenue, na.rm = TRUE), Max_Revenue = max(Total.Revenue, na.rm = TRUE)) %>%
4. mutate(Min_Revenue = format(Min_Revenue, big.mark = ".", decimal.mark = ",", scientific = FALSE),
5. Max_Revenue = format(Max_Revenue, big.mark = ".", decimal.mark = ",", scientific = FALSE)) %>%
6. knitr::kable(caption = "Doanh thu nhỏ nhất và lớn nhất theo vùng", align = 'c')
| Region | Min_Revenue | Max_Revenue |
|---|---|---|
| Asia | 27,99 | 6.678.690 |
| Australia and Oceania | 93,30 | 6.674.681 |
| Central America and the Caribbean | 130,62 | 6.678.690 |
| Europe | 18,66 | 6.680.695 |
| Middle East and North Africa | 81,73 | 6.679.359 |
| North America | 74,64 | 6.664.657 |
| Sub-Saharan Africa | 27,99 | 6.682.700 |
Nhận xét: Tỷ suất lợi nhuận (Profit Rate) giữa các khu vực trên thế giới khá đồng đều, dao động quanh mức 0.294 đến 0.297. Australia and Oceania và North America đạt tỷ suất lợi nhuận cao nhất, cho thấy hoạt động kinh doanh tại hai khu vực này hiệu quả hơn, có chi phí tối ưu và khả năng sinh lời tốt. Ngược lại, các khu vực còn lại như Asia, Europe, Middle East and North Africa duy trì lợi nhuận ở mức ổn định, phản ánh sự cân bằng giữa chi phí và doanh thu. Nhìn chung, sự chênh lệch lợi nhuận giữa các thị trường chưa quá lớn, chứng tỏ doanh nghiệp đã xây dựng chiến lược kinh doanh khá đồng bộ trên phạm vi toàn cầu.
Giải thích: - Dòng số 1: nhóm dữ liệu theo từng vùng miền để chia thành các nhóm nhỏ, mỗi nhóm ứng với một vùng nhất định. - Dòng số 2: tính tỷ suất lợi nhuận ở từng vùng bằng cách lấy tổng lợi nhuận chia cho tổng doanh thu của vùng đó, sử dụng
na.rm = TRUEđể bỏ qua giá trị thiếu khi tính toán. - Dòng số 3: định dạng lại số liệu tỷ suất lợi nhuận bằng cách dùng dấu chấm ngăn cách hàng nghìn, dấu phẩy cho thập phân và không dùng dạng số khoa học.
1. Sales %>%
2. group_by(Region) %>%
3. summarise(Min_Revenue = min(Total.Revenue, na.rm = TRUE), Max_Revenue = max(Total.Revenue, na.rm = TRUE)) %>%
4. mutate(Min_Revenue = format(Min_Revenue, big.mark = ".", decimal.mark = ",", scientific = FALSE),
5. Max_Revenue = format(Max_Revenue, big.mark = ".", decimal.mark = ",", scientific = FALSE)) %>%
6. knitr::kable(caption = "Doanh thu tối thiểu, tối đa theo từng vùng", align = 'c')
| Region | Min_Revenue | Max_Revenue |
|---|---|---|
| Asia | 27,99 | 6.678.690 |
| Australia and Oceania | 93,30 | 6.674.681 |
| Central America and the Caribbean | 130,62 | 6.678.690 |
| Europe | 18,66 | 6.680.695 |
| Middle East and North Africa | 81,73 | 6.679.359 |
| North America | 74,64 | 6.664.657 |
| Sub-Saharan Africa | 27,99 | 6.682.700 |
Nhận xét:Bảng số liệu cho thấy doanh thu tối đa ở tất cả các khu vực đều rất cao, phản ánh tiềm năng thị trường và khả năng đạt các đơn hàng lớn ở mỗi khu vực. Tuy nhiên, doanh thu tối thiểu lại có sự khác biệt đáng kể giữa các vùng, thấp nhất là Europe, cao nhất là Central America and the Caribbea. Điều này cho thấy, dù các khu vực đều có khả năng phát sinh những đơn hàng giá trị rất lớn, nhưng mức doanh thu nhỏ nhất lại khác biệt rõ rệt, phản ánh sự đa dạng trong quy mô giao dịch và cấu trúc thị trường ở từng region. Các doanh nghiệp cần cân nhắc những đặc điểm này khi xây dựng chính sách bán hàng và phân bổ nguồn lực vào các khu vực chiến lược để vừa tận dụng nhóm khách hàng lớn, vừa mở rộng sang các phân khúc nhỏ nhưng tiềm năng.
Giải thích: - Dòng số 1: nhóm dữ liệu theo từng vùng miền để chia thành các nhóm nhỏ, mỗi nhóm ứng với một vùng nhất định. - Dòng số 2: với mỗi nhóm, tính giá trị doanh thu nhỏ nhất và lớn nhất bằng cách lấy min và max của cột Total.Revenue, đồng thời bỏ qua các giá trị thiếu (NA) khi tính toán. - Dòng số 3: dùng dấu chấm ngăn cách hàng nghìn, dấu phẩy cho thập phân và không dùng dạng số khoa học.
1. Sales %>% group_by(Item.Type) %>%
2. summarise( Min_Units_Sold = min(Units.Sold, na.rm = TRUE), Max_Units_Sold = max(Units.Sold, na.rm = TRUE)) %>%
3. mutate( Min_Units_Sold = format(Min_Units_Sold, big.mark = ".", decimal.mark = ",", scientific = FALSE), Max_Units_Sold = format(Max_Units_Sold, big.mark = ".", decimal.mark = ",", scientific = FALSE) ) %>%
4. kable(caption = "Số lượng sản phẩm bán được cao nhất và thấp nhấ", align = 'c')
| Item.Type | Min_Units_Sold | Max_Units_Sold |
|---|---|---|
| Baby Food | 1 | 9.995 |
| Beverages | 1 | 9.999 |
| Cereal | 1 | 10.000 |
| Clothes | 2 | 9.999 |
| Cosmetics | 1 | 10.000 |
| Fruits | 2 | 9.997 |
| Household | 1 | 10.000 |
| Meat | 5 | 10.000 |
| Office Supplies | 3 | 9.999 |
| Personal Care | 1 | 10.000 |
| Snacks | 1 | 10.000 |
| Vegetables | 1 | 10.000 |
Nhận xét:Bảng số liệu cho thấy các loại mặt hàng như Baby Food, Beverages, Cereal, Household, Cosmetics, và Personal Care đều đạt mức bán tối đa cao, đồng thời mức bán tối thiểu của các mặt hàng này lại rất thấp, chỉ từ 1 đến vài đơn vị. Điều này cho thấy nhu cầu thị trường đối với các sản phẩm thiết yếu luôn ổn định, có thể đạt sản lượng lớn trong nhiều kỳ bán hàng khác nhau. Doanh nghiệp cần triển khai chiến lược phân phối và quản lý hàng tồn kho linh hoạt để tận dụng tối đa cơ hội bán hàng và hạn chế rủi ro khi sản lượng biến động mạnh.
Giải thích: - Dòng số 1: nhóm dữ liệu theo từng loại sản phẩm. - Dòng số 2: với mỗi nhóm, tính số lượng bán nhỏ nhất và lớn nhất bằng cách lấy min và max trên cột Units.Sold, đồng thời bỏ qua các giá trị thiếu (NA) khi tính toán. - Dòng số 3: dùng dấu chấm ngăn cách hàng nghìn, dấu phẩy cho thập phân và không dùng dạng số khoa học.
1. Sales %>% group_by(Region, Item.Type) %>%
2. summarise(Order_Count = n()) %>%
3. mutate(Order_Count = format(Order_Count, big.mark = ".", decimal.mark = ",", scientific = FALSE)) %>%
4. kable(caption = "Số lượng đơn hàng theo từng loại sản phẩm và khu vực", align = 'c')
| Region | Item.Type | Order_Count |
|---|---|---|
| Asia | Baby Food | 1.246 |
| Asia | Beverages | 1.178 |
| Asia | Cereal | 1.262 |
| Asia | Clothes | 1.207 |
| Asia | Cosmetics | 1.194 |
| Asia | Fruits | 1.214 |
| Asia | Household | 1.136 |
| Asia | Meat | 1.209 |
| Asia | Office Supplies | 1.271 |
| Asia | Personal Care | 1.198 |
| Asia | Snacks | 1.233 |
| Asia | Vegetables | 1.199 |
| Australia and Oceania | Baby Food | 668 |
| Australia and Oceania | Beverages | 680 |
| Australia and Oceania | Cereal | 715 |
| Australia and Oceania | Clothes | 655 |
| Australia and Oceania | Cosmetics | 673 |
| Australia and Oceania | Fruits | 679 |
| Australia and Oceania | Household | 657 |
| Australia and Oceania | Meat | 668 |
| Australia and Oceania | Office Supplies | 648 |
| Australia and Oceania | Personal Care | 704 |
| Australia and Oceania | Snacks | 658 |
| Australia and Oceania | Vegetables | 708 |
| Central America and the Caribbean | Baby Food | 892 |
| Central America and the Caribbean | Beverages | 874 |
| Central America and the Caribbean | Cereal | 875 |
| Central America and the Caribbean | Clothes | 937 |
| Central America and the Caribbean | Cosmetics | 928 |
| Central America and the Caribbean | Fruits | 889 |
| Central America and the Caribbean | Household | 898 |
| Central America and the Caribbean | Meat | 906 |
| Central America and the Caribbean | Office Supplies | 903 |
| Central America and the Caribbean | Personal Care | 860 |
| Central America and the Caribbean | Snacks | 903 |
| Central America and the Caribbean | Vegetables | 866 |
| Europe | Baby Food | 2.152 |
| Europe | Beverages | 2.104 |
| Europe | Cereal | 2.195 |
| Europe | Clothes | 2.162 |
| Europe | Cosmetics | 2.091 |
| Europe | Fruits | 2.177 |
| Europe | Household | 2.182 |
| Europe | Meat | 2.153 |
| Europe | Office Supplies | 2.196 |
| Europe | Personal Care | 2.153 |
| Europe | Snacks | 2.117 |
| Europe | Vegetables | 2.195 |
| Middle East and North Africa | Baby Food | 1.060 |
| Middle East and North Africa | Beverages | 1.049 |
| Middle East and North Africa | Cereal | 1.044 |
| Middle East and North Africa | Clothes | 1.042 |
| Middle East and North Africa | Cosmetics | 1.041 |
| Middle East and North Africa | Fruits | 1.017 |
| Middle East and North Africa | Household | 1.040 |
| Middle East and North Africa | Meat | 1.025 |
| Middle East and North Africa | Office Supplies | 1.064 |
| Middle East and North Africa | Personal Care | 1.064 |
| Middle East and North Africa | Snacks | 1.079 |
| Middle East and North Africa | Vegetables | 1.055 |
| North America | Baby Food | 182 |
| North America | Beverages | 176 |
| North America | Cereal | 192 |
| North America | Clothes | 164 |
| North America | Cosmetics | 188 |
| North America | Fruits | 159 |
| North America | Household | 187 |
| North America | Meat | 177 |
| North America | Office Supplies | 173 |
| North America | Personal Care | 180 |
| North America | Snacks | 172 |
| North America | Vegetables | 183 |
| Sub-Saharan Africa | Baby Food | 2.207 |
| Sub-Saharan Africa | Beverages | 2.197 |
| Sub-Saharan Africa | Cereal | 2.138 |
| Sub-Saharan Africa | Clothes | 2.137 |
| Sub-Saharan Africa | Cosmetics | 2.255 |
| Sub-Saharan Africa | Fruits | 2.127 |
| Sub-Saharan Africa | Household | 2.178 |
| Sub-Saharan Africa | Meat | 2.182 |
| Sub-Saharan Africa | Office Supplies | 2.171 |
| Sub-Saharan Africa | Personal Care | 2.205 |
| Sub-Saharan Africa | Snacks | 2.146 |
| Sub-Saharan Africa | Vegetables | 2.076 |
Nhận xét:Dữ liệu thống kê về số lượng đơn đặt hàng theo từng mặt hàng ở các khu vực cho thấy chênh lệch rõ rệt giữa các vùng kinh tế. Khu vực Europe và Africa có số lượng đơn đặt hàng trung bình cao nhất, phản ánh nhu cầu tiêu dùng lớn hoặc thị trường phát triển tốt hơn so với các khu vực như North America và Oceania, nơi giá trị Order_Count thấp hơn nhiều. Điều này có thể gợi ý sự khác biệt trong quy mô thị trường, mức độ phát triển kinh tế hoặc xu hướng tiêu dùng giữa các khu vực địa lý khác nhau
Giải thích: - Dòng số 1: nhóm dữ liệu theo hai biến vùng và loại sản phẩm, chia thành các nhóm nhỏ ứng với từng vùng miền và từng loại sản phẩm. - Dòng số 2: đếm số lượng đơn hàng trong mỗi nhóm, sử dụng hàm
n()để lấy tổng số dòng tương ứng với mỗi cặp nhóm. - Dòng số 3: định dạng lại số liệu trong cộtOrder_Countđể dùng dấu chấm ngăn cách hàng nghìn, dấu phẩy cho thập phân, và không sử dụng dạng số khoa học, giúp kết quả dễ đọc và trình bày trong báo cáo.
1. Sales %>%
2. group_by(Order.Priority) %>%
3. summarise(Avg_Revenue = mean(Total.Revenue, na.rm = TRUE)) %>%
4. mutate(Avg_Revenue = format(Avg_Revenue, big.mark = ".", decimal.mark = ",", scientific = FALSE)) %>%
5. knitr::kable(caption = "Doanh thu bình quân theo mức ưu tiên đơn hàng", align = 'c')
| Order.Priority | Avg_Revenue |
|---|---|
| C | 1.332.787 |
| H | 1.336.865 |
| L | 1.333.236 |
| M | 1.341.358 |
Nhận xét:Dựa trên bảng số liệu, doanh thu trung bình giữa các mức độ ưu tiên đơn hàng có sự dao động nhưng không chênh lệch đáng kể. Giá trị doanh thu trung bình cao nhất ở nhóm Medium , tiếp theo là High, Low, và thấp nhất là Critical. Sự khác biệt doanh thu giữa các nhóm không lớn, cho thấy mức độ ưu tiên đơn hàng không ảnh hưởng rõ rệt tới doanh thu trung bình. Điều này có thể phản ánh rằng các chiến lược ưu tiên đơn hàng hiện tại chưa tạo ra khác biệt đáng kể về mặt kinh tế hoặc các yếu tố khác mới là động lực chính ảnh hưởng đến doanh thu trung bình.
Giải thích: - Dòng số 1: nhóm dữ liệu theo từng mức độ ưu tiên của đơn hàng, tạo các nhóm nhỏ tương ứng để phân tích riêng biệt. - Dòng số 2: với mỗi nhóm, tính giá trị trung bình doanh thu bằng cách lấy trung bình trên cột Total.Revenue, loại bỏ các giá trị thiếu khi tính toán. - Dòng số 3: định dạng dấu chấm ngăn cách hàng nghìn, dấu phẩy cho thập phân và không dùng dạng số khoa học.
1. Sales %>% group_by(Item.Type, Sales.Channel) %>%
2. summarise(Avg_Units = mean(Units.Sold, na.rm = TRUE)) %>%
3. mutate(Avg_Units = format(Avg_Units, big.mark = ".", decimal.mark = ",", scientific = FALSE)) %>% knitr::kable(caption = "Số lượng sản phẩm trung bình", align = 'c')
| Item.Type | Sales.Channel | Avg_Units |
|---|---|---|
| Baby Food | Offline | 4.988,928 |
| Baby Food | Online | 4.981,679 |
| Beverages | Offline | 5.016,622 |
| Beverages | Online | 5.037,624 |
| Cereal | Offline | 5.036,853 |
| Cereal | Online | 4.999,033 |
| Clothes | Offline | 5.056,172 |
| Clothes | Online | 5.004,507 |
| Cosmetics | Offline | 5.015,648 |
| Cosmetics | Online | 5.002,090 |
| Fruits | Offline | 4.956,665 |
| Fruits | Online | 4.919,408 |
| Household | Offline | 4.989,071 |
| Household | Online | 5.027,227 |
| Meat | Offline | 4.984,775 |
| Meat | Online | 5.051,061 |
| Office Supplies | Offline | 5.038,100 |
| Office Supplies | Online | 5.000,721 |
| Personal Care | Offline | 5.007,735 |
| Personal Care | Online | 4.921,052 |
| Snacks | Offline | 5.031,746 |
| Snacks | Online | 5.006,479 |
| Vegetables | Offline | 4.909,673 |
| Vegetables | Online | 5.052,066 |
Nhận xét: Doanh số trung bình của các loại mặt hàng giữa kênh bán hàng online và offline có sự khác biệt nhẹ nhưng không quá lớn. Một số nhóm hàng như Clothes, Beverages và Cosmetics có doanh số trung bình cao hơn ở kênh offline, trong khi đó Household và Vegetables lại nhỉnh hơn ở kênh online. Điều này cho thấy hành vi mua sắm của khách hàng theo từng nhóm hàng và kênh bán có đặc trưng riêng, nhưng nhìn chung kênh bán chưa ảnh hưởng rõ rệt tới sản lượng trung bình. Doanh nghiệp nên khai thác sâu hơn các mặt hàng nổi trội ở từng kênh để tối ưu hóa chính sách bán hàng, tăng hiệu quả kinh doanh.
Giải thích: - Dòng số 1: nhóm dữ liệu theo từng loại sản phẩm và từng kênh bán hàng, tạo nên các nhóm nhỏ để phân tích riêng biệt cho từng tổ hợp sản phẩm và kênh. - Dòng số 2: với mỗi nhóm, tính giá trị trung bình số lượng bán ra trong nhóm bằng hàm mean, loại bỏ các giá trị NA. - Dòng số 3: dùng dấu chấm ngăn cách hàng nghìn, dấu phẩy cho thập phân, không dùng dạng số khoa học.
1. library(flextable)
2. Sales %>%
3. group_by(Region) %>%
4. summarise(Min_Profit = min(Total.Profit, na.rm = TRUE), Max_Profit = max(Total.Profit, na.rm = TRUE)) %>%
5. mutate(across(c(Min_Profit, Max_Profit), ~format(.x, big.mark = ".", decimal.mark = ",", scientific = FALSE))) %>%
6. flextable() %>%
7. autofit()
Region | Min_Profit | Max_Profit |
|---|---|---|
Asia | 7,23 | 1.738.005 |
Australia and Oceania | 24,10 | 1.737.657 |
Central America and the Caribbean | 33,74 | 1.737.657 |
Europe | 4,82 | 1.736.092 |
Middle East and North Africa | 25,06 | 1.738.178 |
North America | 19,28 | 1.734.527 |
Sub-Saharan Africa | 7,23 | 1.738.700 |
Nhận xét: Khoảng lợi nhuận tối thiểu và tối đa giữa các khu vực trên thế giới có sự khác biệt rõ nét, nhưng mức lợi nhuận tối đa luôn ở mức rất cao ở mọi khu vực. Khu vực Central America and the Caribbean có lợi nhuận tối thiểu cao nhất, trong khi khu vực Europe có mức thấp nhất. Mức lợi nhuận tối đa ở tất cả các vùng đều gần nhau, phản ánh tiềm năng sinh lời lớn tại mọi khu vực bất kể biến động giá trị nhỏ ở lợi nhuận tối thiểu. Như vậy, doanh nghiệp có thể cân nhắc đa dạng hóa đầu tư các khu vực để khai thác cơ hội sinh lời, đồng thời chú trọng đến yếu tố kiểm soát rủi ro nhằm giảm khả năng xuất hiện lợi nhuận tối thiểu thấp.
Giải thích: - Dòng số 3: nhóm dữ liệu theo từng tổ hợp loại sản phẩm và từng kênh bán hàng, tạo ra các nhóm nhỏ phục vụ phân tích chéo giữa hai tiêu chí này. - Dòng số 4: với mỗi nhóm vừa tạo, tính giá trị trung bình số lượng bán ra sử dụng hàm mean và bỏ qua các giá trị thiếu. - Dòng số 5: dùng dấu chấm ngăn cách hàng nghìn, dấu phẩy cho thập phân, không dùng dạng số khoa học
1. Sales %>% group_by(Region, Sales.Channel) %>%
2. summarise(Avg_Profit = mean(Total.Profit, na.rm = TRUE)) %>%
3. mutate(Avg_Profit = format(Avg_Profit, big.mark = ".", decimal.mark = ",", scientific = FALSE)) %>% kable(caption = "LỢi nhuận trung bình các các kênh bán hàng", align = 'c')
| Region | Sales.Channel | Avg_Profit |
|---|---|---|
| Asia | Offline | 388.019,3 |
| Asia | Online | 396.614,6 |
| Australia and Oceania | Offline | 391.310,6 |
| Australia and Oceania | Online | 391.485,7 |
| Central America and the Caribbean | Offline | 402.124,4 |
| Central America and the Caribbean | Online | 396.804,8 |
| Europe | Offline | 391.640,8 |
| Europe | Online | 387.490,1 |
| Middle East and North Africa | Offline | 392.599,7 |
| Middle East and North Africa | Online | 399.103,7 |
| North America | Offline | 420.032,2 |
| North America | Online | 397.768,3 |
| Sub-Saharan Africa | Offline | 396.612,5 |
| Sub-Saharan Africa | Online | 395.606,2 |
Nhận xét:Lợi nhuận trung bình ở các khu vực có sự khác biệt nhẹ giữa hai kênh bán hàng online và offline, nhưng nhìn chung mức lợi nhuận không thay đổi quá lớn theo kênh bán. North America có mức lợi nhuận trung bình cao nhất, đặc biệt ở kênh offline, trong khi các khu vực khác như Asia, Sub-Saharan Africa và Central America and the Caribbean có mức lợi nhuận đồng đều giữa hai kênh. Điều này chỉ ra rằng việc phân phối kênh bán hàng chưa tạo ra sự khác biệt mạnh về hiệu quả sinh lời trong từng khu vực, tuy nhiên doanh nghiệp nên ưu tiên phát triển kênh offline ở những thị trường có lợi nhuận nổi trội để tối đa hóa giá trị kinh tế.
Giải thích: -Dòng số 1: nhóm dữ liệu theo từng vùng miền và từng kênh bán hàng, tạo các nhóm nhỏ cho từng tổ hợp của hai biến này. - Dòng số 2: với mỗi nhóm vừa tạo, tính giá trị trung bình lợi nhuận bằng hàm mean, loại bỏ các giá trị thiếu. - Dòng số 3: sử dụng dấu chấm ngăn cách hàng nghìn, dấu phẩy cho thập phân và không dùng dạng số khoa học.
1. Sales %>% group_by(Order.Priority) %>%
2. summarise( Order_Count = n(), Avg_Revenue = mean(Total.Revenue, na.rm = TRUE) ) %>%
3. mutate( Order_Count = format(Order_Count, big.mark = ".", decimal.mark = ",", scientific = FALSE), Avg_Revenue = format(Avg_Revenue, big.mark = ".", decimal.mark = ",", scientific = FALSE) ) %>% kable(caption = "Tổng doanh thu theo vùng", align = 'c')
| Order.Priority | Order_Count | Avg_Revenue |
|---|---|---|
| C | 24.951 | 1.332.787 |
| H | 24.945 | 1.336.865 |
| L | 25.016 | 1.333.236 |
| M | 25.088 | 1.341.358 |
Nhận xét: Số lượng đơn hàng trung bình của các mức độ ưu tiên không chênh lệch nhiều, giao động từ khoảng 24.945 đến 25.088. Doanh thu trung bình cao nhất ở nhóm Medium và thấp nhất ở Critical. Điều này cho thấy việc ưu tiên đơn hàng chưa tạo ra sự khác biệt lớn về số lượng giao dịch, nhưng nhóm Medium lại mang về doanh thu tốt nhất. Ý nghĩa kinh tế là doanh nghiệp có thể cân nhắc nâng tỷ trọng nhóm Medium để tối ưu hóa tổng doanh thu trong khi vẫn duy trì số lượng đơn hàng ổn định.
Giải thích: - Dòng số 1: nhóm dữ liệu theo từng mức độ ưu tiên của đơn hàng (Order.Priority), tạo nhóm để phân tích từng loại ưu tiên. - Dòng số 2: với mỗi nhóm, tính số lượng đơn hàng bằng hàm n(), và tính trung bình doanh thu sử dụng hàm mean trên cột Total.Revenue, loại bỏ các giá trị thiếu (NA). - Dòng số 3: dùng dấu chấm ngăn cách hàng nghìn, dấu phẩy cho thập phân, không hiện dạng số khoa học.
1. Asia = Sales[Sales$Region=="Asia",]
2. q_unit <- quantile(Asia$Units.Sold, probs = c(0.25, 0.75))
3. q_profit <- quantile(Asia$Total.Profit, probs = c(0.25, 0.75))
Giả thích: - Dòng số 1: lọc bảng Sales để chỉ lấy các dòng có Region là “Asia”, lưu kết quả vào biến Asia. - Dòng số 2: tính các giá trị phân vị 25% và 75% của biến số lượng bán trong bảng Asia bằng hàm quantile, giúp xác định khoảng thấp, trung bình, cao cho biến này. - Dòng số 3: tính các giá trị phân vị 25% và 75% của biến tổng lợi nhuận trong bảng Asia, dùng để phân nhóm lợi nhuận thành thấp, trung bình, cao.
1. library(ggplot2)
2. library(dplyr)
3. pie_colors <- c("Phát triển chậm" = "#ff9999","Phát triển trung bình" = "#ffd966","Phát triển tốt" = "#90ee90")
4. ggplot(freq_table, aes(x = "", y = Ty_le, fill = Nhom)) +
5. geom_col(width = 1, color = "gray93") +
6. geom_text(aes(label = paste0(Ty_le, "%")), position = position_stack(vjust = 0.55), size = 5, color = "black", fontface = "bold") +
7. scale_fill_manual(values = pie_colors) +
8. labs(title = "Tỷ lệ các mức phát triển của thị trường",fill = "Mức phát triển") + theme_void() +
9. theme(plot.title = element_text(face = "bold", size = 17, hjust = 0.5), legend.title = element_text(size = 14, face = "bold"), legend.text = element_text(size = 13),legend.position = "right" ) +
10. coord_polar(theta = "y")
Nhận xét: Kết quả phân nhóm cho thấy phần lớn các đơn hàng tại thị trường châu Á thuộc nhóm phát triển trung bình với tỷ lệ 48,82%, phản ánh sự ổn định và chiếm thị phần chính của các sản phẩm này. Trong khi đó, nhóm phát triển tốt chiếm 36,67%, thể hiện có hơn một phần ba đơn hàng đạt hiệu quả kinh doanh cao, đây là nhóm cần được ưu tiên đầu tư mở rộng để tối đa hóa lợi nhuận. Ngược lại, chỉ 14,5% số đơn thuộc nhóm phát triển chậm, đa phần là các sản phẩm có lượng bán và lợi nhuận thấp; doanh nghiệp nên rà soát, điều chỉnh chính sách hoặc đổi mới sản phẩm đối với nhóm này để cải thiện hiệu quả hoạt động kinh doanh
Giải thích: Dòng 3: khai báo màu cho từng nhóm phát triển. Dòng 4: khởi tạo biểu đồ ggplot với dữ liệu đầu vào là freq_table, thiết lập ánh xạ trục y là tỷ lệ phần trăm , fill màu theo nhóm phát triển. Trục x để rỗng (“”) để phục vụ vẽ biểu đồ tròn. Dòng 5: vẽ các lát của biểu đồ tròn bằng geom_col với độ rộng tối đa (width = 1), viền lát màu xám nhạt để tạo hiệu ứng tách bạch các vùng dữ liệu. Dòng 6: thêm nhãn phần trăm trên từng lát bằng geom_text, định dạng chữ lớn, đậm và căn giữa. Dòng 7: gán đúng màu từng nhóm phát triển bằng scale_fill_manual dựa trên bảng pie_colors đã khai báo. Dòng 8: đặt tiêu đề cho biểu đồ, đặt tên cho legend và loại bỏ toàn bộ trục/nền/khung bằng theme_void để biểu đồ dễ nhìn. Dòng 9: chỉnh định dạng font, cỡ chữ, căn giữa tiêu đề, đặt legend bên phả. Dòng 10: chuyển đồ thị cột sang biểu đồ tròn bằng coord_polar(theta = “y”).
1. df_sum <- Sales %>% mutate(Year = format(as.Date(Order.Date, "%m/%d/%Y"), "%Y")) %>%
2. group_by(Region, Year) %>%
3. summarise( Revenue = sum(Total.Revenue, na.rm = TRUE), Cost = sum(Total.Cost, na.rm = TRUE), Profit = sum(Total.Profit, na.rm = TRUE),
4. .groups = "drop" ) %>%
5. pivot_longer(c("Revenue", "Cost", "Profit"), names_to = "Indicator", values_to = "Value")
Dòng 1: tạo biến năm từ cột Order.Date và thêm vào bảng dữ liệu với hàm mutate. Dòng 2: nhóm dữ liệu theo từng vùng miền và từng năm. Dòng 3: tính tổng doanh thu, tổng chi phí, và tổng lợi nhuận cho mỗi nhóm vùng miền và năm; sử dụng na.rm = TRUE để bỏ qua các giá trị thiếu. Dòng 4: bỏ grouping sau khi tổng hợp với “.groups = ‘drop’” để kết quả đưa về dạng bảng không còn bị ràng buộc nhóm. Dòng 5: chuyển ba cột chỉ số sang dạn dài với pivot_longer, gom toàn bộ các giá trị chỉ số vào một cột Indicator và giá trị tương ứng vào một cột Value.
1. comma_vn <- function(x) format(x, big.mark = ".", decimal.mark = ",", scientific = FALSE)
2. df_my <- df_sum %>% filter(Region == "North America")
3. ggplot(df_my, aes(x = Year, y = Value, color = Indicator, group = Indicator)) +
4. geom_line(size = 1.4) + geom_point(size = 2.5) +
5. geom_text( aes(label = comma_vn(round(Value,0))), vjust = -0.5, size = 3, fontface = "bold", color= "black") +
6. scale_color_manual( values = c("Revenue" = "#1C7ED6", "Cost" = "#FFC854", "Profit" = "#21A"), labels = c("Doanh thu", "Chi phí", "Lợi nhuận"), name = "Chỉ số tài chính") +
7. scale_y_continuous(labels = comma_vn, expand = expansion(mult = c(0, 0.12))) +
8. geom_hline(yintercept = 0, color = "gray40") +
9. labs(title = "Chi phí, Lợi nhuận và Doanh thu North America", x = "Năm", y = "Giá trị", color = "Chỉ số tài chính" ) +
10. theme_minimal() +
11. theme( plot.title = element_text(face = "bold", size = 14),legend.position = "bottom")
Nhận xét: Biểu đồ cho thấy North America trải qua một chu kỳ kinh doanh điển hình với giai đoạn tăng trưởng mạnh, sau đó là suy thoái. Từ năm 2010 đến 2013, doanh thu, chi phí và lợi nhuận đều tăng đồng bộ, phản ánh sự mở rộng kinh tế, nhu cầu tiêu dùng cao và môi trường đầu tư thuận lợi. Tuy nhiên, từ sau năm 2013, doanh thu và lợi nhuận giảm mạnh, trong khi chi phí vẫn duy trì ở mức cao, cho thấy hiệu quả sản xuất – kinh doanh giảm sút. Diễn biến này có thể xuất phát từ suy giảm tăng trưởng kinh tế toàn cầu, biến động tỷ giá hoặc cạnh tranh gia tăng khiến biên lợi nhuận bị thu hẹp. Đến năm 2017, cả ba chỉ tiêu đều ở mức thấp nhất trong giai đoạn, cho thấy nền kinh tế khu vực bước vào pha điều chỉnh hoặc suy thoái nhẹ, đòi hỏi các doanh nghiệp phải tái cấu trúc hoạt động và tối ưu chi phí để duy trì khả năng sinh lợi.
Giải thích: Dòng 2: lọc dữ liệu chỉ lấy khu vực North America. Dòng 3: khởi tạo biểu đồ line và scatter, ánh xạ trục x là năm , trục y là giá trị, màu và nhóm theo chỉ số tài chính. Dòng 4: vẽ đường biểu diễn từng chỉ số , vẽ thêm các điểm dữ liệu trên từng năm. Dòng 5: thêm nhãn số liệu lên mỗi điểm bằng geom_text, dùng hàm comma_vn để số dễ đọc, chữ đậm,định dạn có dấu chấm ngăn cách hàng nghìn. Dòng 6: chỉnh màu thủ công cho từng đường và gán nhãn giải thích tiếng Việt cho legend, đồng thời đặt tiêu đề legend thành “Chỉ số tài chính”. Dòng 7: định dạng số trục y bằng hàm comma_vn. Dòng 8: thêm đường kẻ ngang màu xám ở giá trị y = 0 làm cột mốc nền giúp dễ so sánh các chỉ số với nhau, nhất là lợi nhuận âm/dương. Dòng 9: đặt tiêu đề, nhãn trục, nhãn legend tiếng Việt. Dòng 11: căn tiêu đề đậm, chỉnh font và vị trí legend xuống dưới cho cân đối.
1. Sales <- Sales %>% mutate(Year = format(as.Date(Order.Date, "%m/%d/%Y"), "%Y"))
2. latest_year <- Sales %>% filter(Region == "North America") %>%
3. summarise(MaxYear = max(Year, na.rm = TRUE)) %>% pull(MaxYear)
4. country_rev_na_latest <- Sales %>% filter(Region == "North America", Year == latest_year) %>%
5. group_by(Country) %>% summarise(TotalRevenue = sum(Total.Revenue, na.rm = TRUE), .groups = "drop")
Dòng 1: tạo thêm cột Year trong bảng Sales bằng cách chuyển Order.Date sang kiểu Date rồi lấy năm, giúp phân tích theo từng năm. Dòng 2: lọc dữ liệu chỉ giữ lại các dòng có vùng là “North America” . Dòng 3: lấy ra năm mới nhất trong vùng “North America”, tạo biến latest_year để dùng cho các bước tiếp theo. Dòng 4: lọc tiếp bảng Sales để chỉ giữ các đơn hàng của khu vực “North America” và đúng năm mới nhất. Dòng 5: nhóm dữ liệu theo từng nước, tính tổng doanh thu của mỗi nước trong năm mới nhất, và bỏ grouping với .groups = ‘drop’.
1. comma_vn <- function(x) format(x, big.mark = ".", decimal.mark = ",", scientific = FALSE)
2. ggplot(country_rev_na_latest, aes(x = "", y = TotalRevenue, fill = Country)) +
3. geom_col(width = 1, color = "gray90") +
4. coord_polar(theta = "y") +
5. geom_text(aes(label = comma_vn(round(TotalRevenue, 0))), position = position_stack(vjust = 0.5), size = 3, color = "black", fontface = "bold" ) +
6. scale_fill_brewer(palette = "Set3") +
7. labs( title = paste("Doanh thu North America"), fill = "Quốc gia") +
8. theme_void(base_family = "Arial") +
9. theme( plot.title = element_text(face = "bold", size = 16, hjust = 0.5), legend.title = element_text(size = 13, face = "bold"), legend.text = element_text(size = 13),legend.position = "right" )
Nhận xét: Biểu đồ trên thể hiện doanh thu của các quốc gia thuộc khu vực Bắc Mỹ năm 2017, bao gồm Hoa Kỳ, Mexico, Canada và Greenland. Có thể thấy Mexico dẫn đầu về doanh thu. Hoa Kỳ đứng thứ hai. Canada và Greenland lần lượt đạt 50,1 triệu và 47,5 triệu, phản ánh quy mô dân số nhỏ hơn và cơ cấu kinh tế thiên về tài nguyên – dịch vụ thay vì sản xuất hàng hóa tiêu dùng. Tổng thể, cơ cấu doanh thu cho thấy sự phân hóa rõ rệt giữa các nền kinh tế trong khu vực Bắc Mỹ: Mexico nổi bật nhờ năng lực sản xuất và chi phí thấp, trong khi Hoa Kỳ và Canada giữ vai trò trung tâm tài chính – công nghệ và thương mại, góp phần duy trì sự ổn định tăng trưởng chung của khu vực.
Giải thích: Dòng 3: vẽ từng lát của biểu đồ tròn bằng geom_col, mở rộng toàn bộ lát (width = 1), viền lát màu xám nhẹ để các lát tách biệt rõ ràng. Dòng 4: chuyển biểu đồ sang dạng pie chart bằng cách dùng tọa độ cực với coord_polar(theta = “y”), giúp biểu diễn phần trăm doanh thu của từng nước trong tổng khu vực. Dòng 5: thêm nhãn doanh thu lên mỗi lát bằng geom_text, định dạng số với hàm comma_vn, chữ lớn và đậm, căn giữa lát. Dòng 6: gán bảng màu tự động cho từng lát bằng scale_fill_brewer với palette Set3, giúp biểu đồ nhiều màu rõ ràng. Dòng 7: đặt tiêu đề cho biểu đồ và nhãn cho bảng chú thích màu theo Quốc gia để giải thích các lát tương ứng. Dòng 8: dùng theme_void để loại bỏ trục, khung, giúp biểu đồ tập trung hoàn toàn vào các lát màu và số liệu doanh thu từng quốc gia. Dòng 9: chỉnh font chữ, căn giữa tiêu đề, tăng kích thước và độ đậm cho tiêu đề, đặt legend bên phải.
1. europe_data <- Sales %>% filter(Region == "Europe") %>%
2. group_by(Country) %>%
3. summarise( TotalProfit = sum(Total.Profit, na.rm = TRUE),TotalCost = sum(Total.Cost, na.rm = TRUE) )
4. top10_countries <- europe_data %>% arrange(desc(TotalProfit)) %>% slice_head(n = 10) %>%
5. pull(Country)
6. europe_long_top10 <- europe_data %>% filter(Country %in% top10_countries) %>%
7. pivot_longer( cols = c(TotalProfit, TotalCost), names_to = "Indicator", values_to = "Value" )
Dòng 1: lọc dữ liệu để chỉ lấy các dòng thuộc khu vực ‘Europe’, xuất ra bảng europe_data chứa các quốc gia cùng với tổng lợi nhuận và tổng chi phí. Dòng 2: nhóm dữ liệu vừa lọc theo từng quốc gia để chuẩn bị cho việc tính tổng theo từng nước. Dòng 3: tính tổng lợi nhuận và tổng chi phí cho mỗi quốc gia. Dòng 4: sắp xếp bảng vừa tính theo TotalProfit giảm dần và lấy ra 10 quốc gia có lợi nhuận cao nhất, dùng hàm slice_head(n = 10) để chọn nhanh. Dòng 5: trích xuất tên các quốc gia top 10 ra một vector bằng hàm pull(Country) để dùng cho bước tiếp theo. Dòng 6: lọc lại europe_data chỉ giữ những quốc gia thuộc top 10 vừa tạo và chuẩn bị để chuyển đổi định dạng bảng. Dòng 7: chuyển dữ liệu từ dạng rộng sang dạng dài bằng pivot_longer, ghép hai cột số liệu (TotalProfit và TotalCost) vào một cột giá trị, một cột tên chỉ số
1. ggplot(europe_long_top10, aes(x = reorder(Country, Value), y = Value, fill = Indicator)) +
2. geom_col(position = position_dodge(width = 0.7), width = 0.7, alpha = 0.93) +
3. geom_text(aes(label = format(Value, big.mark = ".",decimal.mark = ",", scientific = FALSE)), position = position_dodge(width = 0.7), hjust = 1, vjust = 0.5, size = 3.2, family = "Arial", color = "black") +
4. scale_fill_manual(values = c("TotalProfit" = "#21A179", "TotalCost" = "#FFC300"),labels = c("Lợi nhuận", "Chi phí")) +
5. coord_flip() +
6. scale_y_continuous(labels = function(x) format(x, big.mark = ".", decimal.mark = ",", scientific = FALSE),
7. expand = expansion(mult = c(0, 0.12))) +
8. labs( title = "Top 10 quốc gia Châu Âu theo tổng lợi nhuận và chi phí", subtitle = "Quốc gia xếp theo tổng lợi nhuận cao nhất", x = "Quốc gia", y = "Tổng giá trị", fill = "Chỉ số") +
9. theme_minimal(base_size = 10) +
10. theme(legend.position = "bottom",axis.text.y = element_text(family = "Arial", size = 13) )
Nhận xét: Biểu đồ cho thấy top 10 quốc gia Châu Âu có tổng lợi nhuận và chi phí cao nhất, trong đó Hungary, Malta và Romania là ba quốc gia dẫn đầu với tổng lợi nhuận. Tuy nhiên, chi phí tại các quốc gia này cũng ở mức rất cao, dao động , phản ánh quy mô hoạt động kinh tế lớn và mức đầu tư cao. Điều đáng chú ý là chênh lệch giữa lợi nhuận và chi phí ở tất cả các quốc gia đều khá lớn, cho thấy hiệu quả kinh tế chưa thật sự tối ưu. Tức là doanh thu cao nhưng chi phí vận hành cũng lớn, dẫn đến biên lợi nhuận không quá vượt trội. Nhìn chung, nhóm quốc gia Đông Âu như Hungary, Romania, Bulgaria đang có xu hướng mở rộng quy mô sản xuất và thương mại, thể hiện qua mức chi tiêu và lợi nhuận cao, trong khi các quốc gia nhỏ hơn như Estonia, Macedonia hay Serbia vẫn duy trì hiệu quả ổn định nhưng ở quy mô nhỏ hơn. Xu hướng này phản ánh sự phân hóa về năng lực sản xuất và hiệu quả kinh tế giữa các nền kinh tế Châu Âu, trong đó các nước có thị trường đang phát triển vẫn còn dư địa để cải thiện hiệu suất chi phí nhằm tối đa hóa lợi nhuận.
Giải thích: Dòng 1: khởi tạo đối tượng ggplot, dùng dữ liệu đã được chuyển về dạng dài cho top 10 quốc gia, ánh xạ trục x là tên quốc gia, trục y là giá trị chỉ số, fill màu theo loại chỉ số. Dòng 2: vẽ các cột dạng bar plot đứng cạnh nhau với từng quốc gia có hai cột đại diện cho lợi nhuận và chi phí, điều chỉnh chiều rộng và độ trong suốt để các cột phân biệt rõ ràng. Dòng 3: thêm nhãn giá trị lên từng cột bằng geom_text, định dạng số với dấu chấm ngăn cách hàng nghìn, dấu phẩy cho thập phân và không ở dạng số khoa học, căn chỉnh vị trí và cỡ chữ phù hợp. Dòng 4: gán màu tự chọn cho hai loại chỉ số bằng scale_fill_manual: màu xanh cho ‘Lợi nhuận’, vàng cho ‘Chi phí’. Dòng 5: lật ngang biểu đồ bằng coord_flip. Dòng 6: định dạng lại trục y bằng scale_y_continuous, dùng hàm format để số liệu dễ hiểu, đồng thời mở rộng phía trên để tránh nhãn bị cắt cụt. Dòng 7: thêm tiêu đề, phụ đề, nhãn trục và nhãn chú thích. Dòng 9: chỉnh vị trí legend xuống dưới, tăng cỡ chữ trục y và dùng font Arial cho bảng chú thích và trục.
1. bubble_df <- Sales %>% group_by(Item.Type, Year) %>%
2. summarise( TotalProfit = sum(Total.Profit, na.rm=TRUE), UnitsSold = sum(Units.Sold, na.rm=TRUE) ) %>%
3. ungroup()
Dòng 1: nhóm dữ liệu theo từng loại sản phẩm và từng năm, phục vụ phân tích tổng hợp theo từng nhóm nhỏ của hai tiêu chí này. Dòng 2: với mỗi nhóm vừa tạo, tính tổng lợi nhuận và tổng số lượng bán ra bằng cách cộng tất cả các giá trị, đồng thời bỏ qua các giá trị thiếu (NA) với na.rm = TRUE
1. top_items <- bubble_df %>% group_by(Item.Type) %>%
2. summarise(SumProfit = sum(TotalProfit)) %>% arrange(desc(SumProfit)) %>% slice(1:8) %>%
3. pull(Item.Type)
4. bubble_df <- bubble_df %>% filter(Item.Type %in% top_items)
Dòng 1: nhóm dữ liệu từ bảng bubble_df theo từng loại sản phẩm. Dòng 2: tính tổng lợi nhuận toàn bộ cho từng sản phẩm rồi sắp xếp bảng theo giá trị giảm dần, sau đó lấy ra tám sản phẩm có tổng lợi nhuận cao nhất bằng slice(1:8). Dòng 3: trích riêng tên tám sản phẩm top lợi nhuận thành một vector để dùng cho các bước tiếp theo, thông qua hàm pull(Item.Type). Dòng 4: lọc bảng bubble_df chỉ giữ các sản phẩm thuộc top 8 của lợi nhuận
1. ggplot(bubble_df, aes(x=Year, y=Item.Type, size=UnitsSold, fill=TotalProfit)) +
2. geom_point(alpha=0.87, shape=21, color="#333333") +
3. scale_size_continuous(range=c(3.5, 17), name="Số lượng bán") +
4. scale_fill_viridis_c(option="plasma", name="Tổng lợi nhuận") +
5. geom_text(aes(label=comma_vn(round(TotalProfit,0))), size=2.2, color="black", vjust=0.8, fontface="bold") + labs(title="Lợi nhuận theo quy mô sản phẩm ", subtitle="Bong bóng càng to: càng nhiều bán; màu nóng = lãi lớn, số trong bóng = lãi", x="Năm", y="Sản phẩm")+
6. theme_light(base_size=11) +
7. theme(plot.title = element_text(face="bold",size=13), axis.text.y = element_text(size=10, face="bold") ) +
8. scale_x_discrete(expand=expansion(mult=c(0.04,0.08)))
Nhận xét:Các sản phẩm Household, Cosmetics và Baby Food là những mặt hàng nổi bật nhất với lợi nhuận mỗi năm từ 800 triệu đến trên 1,3 tỷ, đồng thời có quy mô bán hàng rất lớn (trên 4 triệu đơn vị mỗi năm). Ngược lại, nhóm Vegetables và Meat có lợi nhuận thấp hơn rõ rệt, nhiều năm chỉ đạt khoảng 200–400 triệu. Đặc biệt, xu hướng chung là lợi nhuận và số lượng bán đều giảm nhẹ qua các năm: Household giảm từ 1,2 tỷ năm 2010 xuống dưới 500 triệu năm 2017, còn Vegetables chỉ còn khoảng 200 triệu năm cuối. Điều này cho thấy doanh nghiệp cần tập trung vào các nhóm hàng chủ lực, đồng thời cân nhắc các giải pháp để cải thiện sức bán và lợi nhuận cho các sản phẩm yếu hơn trong tương lai.
Giải thích:Dòng 2: Hiển thị các bong bóng có độ trong suốt vừa phải, viền màu tối, giúp các nhóm dữ liệu dễ nhìn rõ và không bị che lấp nhau. Dòng 3: Điều chỉnh kích thước bong bóng nằm trong một khoảng phù hợp để phân biệt rõ sản phẩm bán nhiều hay ít. Dòng 4: Chọn bảng màu nóng lạnh cho bong bóng, làm nổi bật sản phẩm có lợi nhuận cao và thấp. Dòng 5: Thêm số liệu lợi nhuận trực tiếp trên mỗi bong bóng. Dòng 5: Chỉnh giao diện sáng và phông chữ thân thiện cho biểu đồ dễ đọc. Dòng 6: Làm nổi bật tiêu đề, nhãn trục, đồng thời bố trí các năm trải đều trên biểu đồ để dễ quan sát biến động qua từng năm.
1. library(dplyr)
2. country_total <- Sales %>% group_by(Country) %>%
3. summarise(TotalRevenue = sum(Total.Revenue, na.rm = TRUE), .groups = "drop")
4. top3_countries <- country_total %>% arrange(TotalRevenue) %>% slice_head(n = 3) %>%
5. pull(Country)
6. sales_heatmap <- Sales %>% filter(Country %in% top3_countries) %>%
7. group_by(Item.Type, Country) %>%
8. summarise(TotalRevenue = sum(Total.Revenue, na.rm = TRUE), .groups = "drop")
Dòng 1: Nhóm dữ liệu theo từng quốc gia để tổng hợp doanh thu chung cho mỗi nước. Dòng 2: Tính tổng doanh thu của từng quốc gia, sắp xếp lại bảng theo doanh thu tăng dần, sau đó lấy ra ba quốc gia có tổng doanh thu thấp nhất cho phân tích tiếp theo. Dòng 3: Trích riêng tên ba quốc gia này thành một vector để thuận tiện lọc dữ liệu ở bước tiếp theo. Dòng 4: Lọc bảng Sales chỉ giữ lại các dòng thuộc ba quốc gia vừa xác định để phục vụ phân tích chuyên sâu. Dòng 5: Tiếp tục nhóm dữ liệu đã lọc theo loại sản phẩm và quốc gia, nhằm chuẩn bị cho việc tổng hợp doanh thu từng nhóm sản phẩm ở từng quốc gia. Dòng 6: Tính tổng doanh thu cho từng nhóm sản phẩm tại từng quốc gia, tạo bảng tổng hợp để phân tích mức chênh lệch doanh thu giữa các nhóm sản phẩm ở top quốc gia đã chọn.
1. ggplot(sales_heatmap, aes(x = Country, y = Item.Type, fill = TotalRevenue)) +
2. geom_tile(color = "white", linewidth = 0.6) +
3. geom_text(aes(label = format(TotalRevenue, big.mark = ".", decimal.mark = ",",scientific = FALSE )), color = "black", size = 3) +
4. scale_fill_gradient(low = "#FDEBD0", high = "#922B21", name = "Tổng doanh thu") +
5. labs(title = "Top 3 quốc gia có doanh thu thấp nhất", x = "Quốc gia (doanh thu thấp nhất)",y = "Loại sản phẩm") + theme_minimal(base_size = 11) +
6. theme(axis.text.x = element_text(angle = 20, hjust = 1, size = 9), axis.text.y = element_text(size = 9))
Nhận xét:Các quốc gia có doanh thu thấp nhất đều ghi nhận doanh thu của từng loại sản phẩm ở mức rất thấp so với mặt bằng chung, đặc biệt nhóm Office Supplies và Household nổi bật với giá trị lớn nhưng vẫn là thấp nhất so với các nước khác. Điều này phản ánh tiềm năng phát triển của các thị trường này còn hạn chế do sức mua kém hoặc đặc thù kinh tế tại địa phương. Doanh nghiệp cần đánh giá lý do cụ thể để có thể điều chỉnh chiến lược tiếp cận phù hợp, ưu tiên phát triển kênh tiêu thụ và chủng loại sản phẩm tiềm năng nếu muốn cải thiện doanh thu các quốc gia này.
Giải thích:Dòng 1: Lấy dữ liệu đã tổng hợp để biểu diễn mối quan hệ giữa quốc gia và loại sản phẩm, dùng màu sắc để thể hiện tổng doanh thu. Dòng 2: Vẽ từng ô dữ liệu dạng lưới, mỗi ô đại diện cặp Quốc gia – Loại sản phẩm, có đường viền trắng để các ô tách biệt rõ ràng. Dòng 3: In trực tiếp số doanh thu lên từng ô, các giá trị được định dạng bằng dấu chấm ngăn cách hàng nghìn và dấu phẩy cho phần thập phân, giúp người xem dễ đọc số liệu. Dòng 4: Tạo bảng màu chuyển từ màu nhạt sang màu đậm, thể hiện doanh thu thấp đến cao; màu đậm giúp nhận diện nhóm sản phẩm hoặc quốc gia có doanh thu nổi bật. Dòng 5: Đặt tiêu đề, nhãn trục x (quốc gia có doanh thu thấp), trục y (loại sản phẩm), và sử dụng giao diện tối giản để tăng tính thẩm mỹ và tập trung vào dữ liệu chính. Dòng 6: Chỉnh sửa nhãn trục x nghiêng, co giãn và tăng cỡ cho nhãn giúp dễ đọc tên quốc gia và sản phẩm ngay cả khi số lượng ô nhiều.
1. library(ggplot2)
2. library(dplyr)
3. library(scales)
4. sales_asia <- Sales %>% filter(Region == "Asia")
5. sum_by_product <- sales_asia %>% group_by(Country, Item.Type) %>%
6. summarise(TotalCost = sum(Total.Cost), .groups = 'drop')
7. top5_tbl <- sum_by_product %>% group_by(Item.Type) %>%
8. summarise(TotalCost = sum(TotalCost), .groups = 'drop') %>% arrange(desc(TotalCost)) %>% slice_head(n = 5)
9. top5_items <- top5_tbl$Item.Type
10. plot_data <- sum_by_product %>%
11. mutate(Item.Type = ifelse(Item.Type %in% top5_items, Item.Type, "Các sản phẩm khác")) %>%
12. group_by(Item.Type) %>%
13. summarise(TotalCost = sum(TotalCost), .groups = 'drop') %>%
14. mutate(Percentage = round(100 * TotalCost / sum(TotalCost), 1)) %>%
15. arrange(desc(TotalCost))
16. total_cost_sum <- sum(plot_data$TotalCost)
Dòng 1: Lọc dữ liệu để chỉ giữ lại các giao dịch thuộc khu vực châu Á, tập trung chuyên sâu vào khu vực này. Dòng 2: Tổng hợp chi phí cho từng loại sản phẩm tại từng quốc gia ở châu Á, giúp xác định mức độ chi phí theo từng phân khúc thị trường. Dòng 3: Tiếp tục nhóm dữ liệu theo tên sản phẩm, cộng dồn tổng chi phí của mỗi loại sản phẩm trên toàn khu vực để nhận diện các sản phẩm có chi phí lớn nhất. Dòng 4: Sắp xếp dữ liệu, lấy ra top 5 sản phẩm có tổng chi phí cao nhất, tạo bộ lọc các mặt hàng quan trọng về chi phí. Dòng 5: Trích riêng tên top 5 sản phẩm này thành một vector nhằm phục vụ các thao tác lọc tiếp theo. Dòng 6: Tiến hành gộp lại dữ liệu, thay thế các sản phẩm không thuộc top 5 bằng nhãn “Các sản phẩm khác”, sau đó cộng dồn và tính phần trăm chi phí từng nhóm, cuối cùng sắp xếp lại để dễ dàng nhận diện vị trí đóng góp chi phí từng nhóm sản phẩm trong tổng thể, đồng thời xác định tổng chi phí của toàn bộ các sản phẩm.
1. pastel_colors <- c("#FFB3BA", "#BAE1FF", "#BFFCC6", "#FFFACD", "#D5BAFF", "#FFDAC1")
2. ggplot(plot_data, aes(x = 2, y = TotalCost, fill = Item.Type)) +
3. geom_bar(stat = "identity", width = 1.5, color = "black") +
4. scale_fill_manual(values = pastel_colors) +
5. coord_polar(theta = "y") +
6. xlim(0.5, 3) +
7. geom_text(aes(label = paste0(Percentage, "%")), position = position_stack(vjust = 0.5), size = 3, color = "black", fontface = "bold") +
8. annotate("text", x = 0.5, y = 0, label = paste0("Tổng: ", scales::comma(total_cost_sum, big.mark = ".", decimal.mark = ",")), size = 4, fontface = "bold",color = "black") +
9. labs(title = "Top 5 sản phẩm có chi phí cao tại Asia") +
10. theme_void() +
11. theme(plot.title = element_text(size = 16, face = "bold", hjust = 0.5))
Nhận xét: Biểu đồ cho thấy nhóm Office Supplies chiếm tỷ trọng chi phí lớn nhất tại thị trường châu Á, theo sau là Household, Meat, Cosmetics và Baby Food. Điều này chứng tỏ rằng các doanh nghiệp có thể ưu tiên kiểm soát chi phí ở các mặt hàng này nhằm tối ưu hóa hiệu quả tài chính khu vực. Việc tập trung vào quản trị và thương lượng đầu vào, đặc biệt với nhóm Office Supplies cùng Household, sẽ giúp giảm áp lực chi phí tổng thể, nâng cao lợi nhuận.
Giải thích:Dòng 1: Đặt màu pastel cho các nhóm sản phẩm để biểu đồ dễ nhìn và phân biệt rõ từng nhóm. Dòng 2: Vẽ biểu đồ dạng tròn với dữ liệu đã tổng hợp, mỗi nhóm sản phẩm là một phần trong biểu đồ. Dòng 3: Tạo các thanh biểu diễn tổng chi phí cho từng nhóm, viền đen giúp các nhóm nổi bật rõ ràng. Dòng 4: Gán từng màu pastel đã chọn cho sản phẩm, giúp nhận diện từng nhóm trực quan hơn. Dòng 5: Đổi sang biểu đồ tròn bằng cách chuyển hệ toạ độ sang dạng tròn, tạo cảm giác như pie chart, phù hợp để thể hiện tỷ trọng từng nhóm trong tổng chi phí. Dòng 6: Mở rộng vùng vẽ để các phần trong biểu đồ tròn không bị thu hẹp, giúp dễ nhìn rõ giá trị từng phần. Dòng 7: Chèn tỷ lệ phần trăm chi phí lên mỗi nhóm sản phẩm, làm cho người xem nhận biết được tỷ trọng từng phần một cách trực quan ngay trên biểu đồ. Dòng 8: Viết tổng chi phí chính giữa biểu đồ, giúp người xem dễ dàng biết được quy mô tổng cộng của dữ liệu ngay tại vị trí nổi bật nhất. Dòng 9: Đặt tiêu đề cho biểu đồ thể hiện rõ mục tiêu phân tích: các sản phẩm có chi phí cao nhất ở khu vực châu Á. Dòng 10: Loại bỏ các chi tiết dư thừa, chỉ giữ lại nội dung chính giúp biểu đồ đơn giản, tập trung vào số liệu.
1. profit_year_region <- Sales %>% filter(Region %in% c("Asia", "Europe")) %>%
2. group_by(Year, Region) %>%
3. summarise(TotalProfit = sum(Total.Profit), .groups = 'drop') %>% arrange(Year, Region)
4. ggplot(profit_year_region, aes(x = as.factor(Year), y = TotalProfit, fill = Region)) +
5. geom_col(position = "dodge", color = "black", width = 0.7) +
6. geom_text( aes(label = scales::comma(TotalProfit, big.mark = ".", decimal.mark = ",")), position = position_dodge(width = 0.7), vjust = 0.5, hjust = 1, size = 4, color = "black", angle = 90) +
7. scale_y_continuous(labels = scales::comma_format(big.mark = ".", decimal.mark = ",")) +
8. scale_fill_manual(values = c("Asia" = "#8fd3f4", "Europe" = "#dab6fc")) +
9. labs(title = "Tổng Lợi nhuận theo năm (Châu Á vs Châu Âu)", x = "Năm", y = "Tổng lợi nhuận", fill = "Khu vực") +
10. theme_minimal(base_size = 14) +
11. theme(plot.title = element_text(face = "bold", hjust = 0.5))
>Nhận xét” Biểu đồ cho thấy tổng lợi nhuận của châu
Âu luôn vượt trội hơn so với châu Á trong toàn bộ các năm khảo sát. Tuy
nhiên, lợi nhuận của châu Á ổn định và có xu hướng tăng đều qua các năm,
phản ánh sức tăng trưởng bền vững tại thị trường này. Chênh lệch lợi
nhuận giữa hai khu vực có thể xuất phát từ quy mô thị trường hoặc vị thế
cạnh tranh, gợi ý doanh nghiệp nên tiếp tục đầu tư để khai thác tiềm
năng tăng trưởng tại châu Á đồng thời duy trì lợi thế ở châu Âu.
Giải thích:Dòng 1: Lọc dữ liệu chỉ gồm Châu Á và Châu Âu, tổng hợp theo năm và khu vực để tính tổng lợi nhuận cho từng nhóm. Dòng 2: Sắp xếp kết quả theo năm và khu vực, giúp so sánh hiệu quả kinh doanh qua từng giai đoạn và từng khu vực. Dòng 3: Vẽ biểu đồ cột, trục ngang là năm, trục dọc là tổng lợi nhuận, mỗi khu vực sẽ là một màu khác nhau giúp phân biệt rõ từng nhóm. Dòng 4: Hiển thị các cột nằm cạnh nhau bằng kỹ thuật “dodge”, giúp trực quan so sánh lợi nhuận giữa hai khu vực trong cùng một năm. Dòng 7: Chọn màu riêng cho từng khu vực giúp biểu đồ có tính nhận diện rõ ràng, tránh gây nhầm lẫn khi so sánh các cột. Dòng 8: Đặt tiêu đề, nhãn trục và giải thích ý nghĩa từng phần ngay trên đồ thị.
1. sales_asia <- Sales %>% filter(Region == "Asia")
2. sum_by_product <- sales_asia %>% group_by(Country, Item.Type) %>%
3. summarise(TotalRevenue = sum(Total.Revenue), .groups = 'drop')
4. top5_tbl <- sum_by_product %>% group_by(Item.Type) %>%
5. summarise(TotalRevenue = sum(TotalRevenue), .groups = 'drop') %>%
6. arrange(desc(TotalRevenue)) %>% slice_head(n = 5)
7. top5_items <- top5_tbl$Item.Type
8. plot_data <- sum_by_product %>%
9. mutate(Item.Type = ifelse(Item.Type %in% top5_items, Item.Type, "Các sản phẩm khác")) %>%
10. group_by(Item.Type) %>%
11. summarise(TotalRevenue = sum(TotalRevenue), .groups = 'drop')
12. total_revenue_sum <- sum(plot_data$TotalRevenue)
13. plot_data <- plot_data %>% arrange(desc(TotalRevenue))
14. bar_colors <- c("#FFB3BA", "#BAE1FF", "#BFFCC6", "#FFFACD", "#D5BAFF", "#FFDAC1")
15. ggplot(plot_data, aes(x = reorder(Item.Type, -TotalRevenue), y = TotalRevenue, fill = Item.Type)) +
16. geom_col(color = "black", width = 0.7) +
17. scale_fill_manual(values = bar_colors) +
18. geom_text( aes(label = scales::comma(TotalRevenue, big.mark = ".", decimal.mark = ",")), angle = 90, vjust = 0.5, hjust = 1, size = 3, color = "black", fontface = "bold") +
19. labs(title = "Top 5 sản phẩm cao nhất", subtitle = "Gồm nhóm 'Các sản phẩm khác'", x = NULL,y = "Tổng doanh thu") +
20. scale_y_continuous(labels = scales::comma_format(big.mark = ".", decimal.mark = ",")) +
21. theme_minimal(base_size = 16) +
22. theme( axis.text.x = element_blank(), axis.ticks.x = element_blank(), plot.title = element_text(face = "bold", hjust = 0.5))
Nhận xét: Biểu đồ thể hiện Baby Food, Cosmetics, Household, Meat và nhóm ‘Các sản phẩm khác’ là năm mặt hàng có tổng doanh thu cao nhất tại thị trường châu Á. Nhóm ‘Các sản phẩm khác’ dẫn đầu với doanh thu vượt trội, tiếp theo là Household, Cosmetics, Meat và Baby Food. Điều này cho thấy sự đa dạng về nhu cầu tiêu dùng tại khu vực châu Á, trong đó các mặt hàng thiết yếu và chăm sóc cá nhân đóng vai trò quan trọng trong cơ cấu doanh thu, giúp doanh nghiệp xác định ưu tiên nguồn lực và chiến lược tiếp thị phù hợp.
Giải thích:Dòng 1–2: Lọc dữ liệu của khu vực Châu Á, sau đó nhóm theo quốc gia và sản phẩm để tổng hợp doanh thu từng nhóm. Dòng 3–6: Tiếp tục nhóm theo loại sản phẩm rồi tính tổng doanh thu trên toàn khu vực, sắp xếp theo thứ tự doanh thu giảm dần và chọn ra top 5 sản phẩm đạt giá trị doanh thu cao nhất. Dòng 7: Trích tên top 5 sản phẩm thành danh sách riêng, hỗ trợ cho việc phân loại nhóm sản phẩm trong các bước tiếp theo. Dòng 8–11: Gộp các sản phẩm không nằm trong top 5 thành nhóm “Các sản phẩm khác”, sau đó cộng dồn tổng doanh thu cho từng nhóm. Dòng 12–13: Tính tổng doanh thu toàn bộ nhóm để sử dụng cho hiển thị báo cáo và sắp xếp lại bảng dữ liệu theo doanh thu giảm dần. Dòng 14–22: Chọn màu pastel giúp biểu đồ dễ phân biệt các nhóm; vẽ biểu đồ cột doanh thu, mỗi nhóm sản phẩm là một cột, nhãn số doanh thu được định dạng rõ ràng và chèn trực tiếp trên cột. Tiêu đề, chú thích, bố cục, và nhãn đều được tuỳ chỉnh phù hợp.
1. Sales$Year <- format(Sales$Order.Date, "%Y")
2. avg_profit <- Sales %>%
3. group_by(Year) %>%
4. summarise(
5. Average_P = mean(Total.Profit, na.rm = TRUE),
6. Min_Profit = min(Total.Profit, na.rm = TRUE),
7. Max_Profit = max(Total.Profit, na.rm = TRUE),
8. Var_Profit = var(Total.Profit, na.rm = TRUE),
9. .groups = "drop")
10. avg_profit_formatted <- avg_profit %>%
11. mutate(across(-Year, ~format(., big.mark = ".", decimal.mark = ",",
12. scientific = FALSE)))
Dòng 1: Tạo một cột mới “Year” trong bảng dữ liệu Sales, trích xuất năm từ cột ngày đặt hàng để tiện phân nhóm theo năm. Dòng 2-9: Nhóm dữ liệu theo năm và tính các chỉ số thống kê về lợi nhuận bao gồm: lợi nhuận trung bình, lợi nhuận nhỏ nhất, lớn nhất và phương sai lợi nhuận. Việc sử dụng tham số .groups = “drop” đảm bảo kết quả không còn giữ trạng thái nhóm. Dòng 10-12: Định dạng các giá trị số trong bảng kết quả với dấu chấm ngăn cách hàng nghìn và dấu phẩy cho phần thập phân
1. avg_profit$Year <- as.numeric(avg_profit$Year)
2. ggplot(avg_profit, aes(x = Year, y = Average_P)) +
3. geom_col(fill = "skyblue", color = "black", width = 0.7) +
4. geom_point(color = "red", size = 3) +
5. geom_text(aes(label = format(Average_P, big.mark = ".", decimal.mark = ",", scientific = FALSE)),
6. vjust = -0.5, color = "black", size = 3, fontface = "bold") +
7. geom_hline(yintercept = mean(avg_profit$Average_P),
8. color = "darkgreen", linetype = "dashed", linewidth = 0.8) +
9. scale_y_continuous(labels = function(x) format(x, big.mark = ".", decimal.mark = ",", scientific = FALSE)) +
10. scale_x_continuous(breaks = as.numeric(avg_profit$Year)) +
11. labs( title = "Lợi nhuận trung bình các năm", x = "Năm", y = "Lợi nhuận trung bình" ) +
12. theme_minimal() +
13. theme( text = element_text(size = 14), plot.title = element_text(hjust = 0.5, face = "bold"))
Nhận xét: Biểu đồ cho thấy lợi nhuận trung bình hàng năm duy trì mức ổn định qua các năm từ 2010 đến 2017, dao động quanh mốc 391.000 đến gần 397.500. Không có biến động lớn hay xu hướng giảm rõ rệt, phản ánh sự kiểm soát tốt chi phí và doanh thu qua giai đoạn này. Điều này cho phép doanh nghiệp có nền tảng vững chắc để hoạch định tăng trưởng hoặc đầu tư mở rộng trong dài hạn.
Giải thích:Đoạn 2-3: Khởi tạo biểu đồ với ggplot2. Cột x là năm, cột y là lợi nhuận trung bình. Dùng geom_col (cột dọc) để thể hiện quy mô lợi nhuận từng năm, màu xanh nhạt dễ đọc, viền rõ nét. Đoạn 4-6: Thêm các điểm đỏ (geom_point) lên đầu cột giúp nổi bật giá trị từng năm. Đoạn 7-8: Vẽ thêm đường kẻ ngang tại mức lợi nhuận trung bình toàn kỳ (geom_hline), dùng nét đứt màu xanh lá đậm. Đường này là mốc để so sánh các năm vượt/không vượt trung bình chung.
1. Cost_summary <- aggregate( x = Sales$Total.Cost, by = list(Region = Sales$Region, Order.Priority = Sales$Order.Priority),FUN = mean)
2. colnames(Cost_summary)[3] <- "MeanCost"
3. Cost_summary_formatted <- Cost_summary %>%
4. mutate( MeanCost = format(MeanCost, big.mark = ".", decimal.mark = ",", scientific = FALSE))
5. ggplot(Cost_summary, aes(x = Region, y = MeanCost, fill = Order.Priority)) +
6. geom_col(position = "dodge", alpha = 0.8) +
7. geom_text(aes(label = format(MeanCost, big.mark = ".", decimal.mark = ",", scientific = FALSE)),
8. position = position_dodge(0.9), angle = 90, hjust = 1.2, vjust = 0.5, size = 3, color = "black") +
9. geom_point(size = 3, color = "black", position = position_dodge(0.9)) +
10. geom_hline(yintercept = mean(Cost_summary$MeanCost), linetype = "dashed", color = "red") +
11. facet_wrap(~Order.Priority) +
12. scale_y_continuous( labels = function(x) format(x, big.mark = ".", decimal.mark = ",", scientific = FALSE) ) +
13. theme_minimal() +
14. labs( title = "Chi phí trung bình theo khu vực và mức độ ưu tiên đơn hàng", x = "Khu vực", y = "Chi phí trung bình" ) +
15. theme( axis.text.x = element_text(angle = 20, hjust = 1, vjust = 1, size = 7), axis.text.y = element_text(size = 10), plot.title = element_text(hjust = 0.5, size = 14, face = "bold"), legend.position = "bottom" )
Nhận xét: Biểu đồ cho thấy chi phí trung bình của các đơn hàng có sự khác biệt theo mức độ ưu tiên và khu vực. Nhìn chung, các đơn hàng Critical có chi phí cao nhất, phản ánh nhu cầu xử lý gấp khiến chi phí vận hành tăng. Ngược lại, đơn hàng Low có chi phí thấp nhất, cho thấy khả năng tối ưu chi phí tốt hơn khi thời gian giao hàng linh hoạt. Sự chênh lệch giữa các khu vực không lớn, cho thấy chính sách chi phí của doanh nghiệp được quản lý khá đồng đều trên toàn cầu.
Giải thích:Dòng 1: Tổng hợp chi phí trung bình của từng khu vực và theo mức độ ưu tiên đơn hàng bằng hàm aggregate, kết quả lưu trong bảng mới với các cột: khu vực, mức ưu tiên và chi phí trung bình. Dòng 2: Đổi tên cột chi phí trung bình thành MeanCost để dễ thao tác và trình bày. Dòng 3-4: Định dạng lại giá trị chi phí trung bình cho dễ đọc, sử dụng dấu chấm ngăn cách hàng nghìn và dấu phẩy ngăn cách phần thập phân. Dòng 5: Thiết lập biểu đồ cột, với trục hoành là khu vực, trục tung là chi phí trung bình, màu sắc thể hiện các mức độ ưu tiên đơn hàng. Dòng 6: Hiển thị các cột bên cạnh nhau (dodge) để dễ so sánh giữa các mức ưu tiên cho từng khu vực, đồng thời làm các cột có độ trong suốt giúp nhìn rõ sự chồng lấp. Dòng 7: Chèn nhãn số chi phí trung bình cho từng cột để người xem đọc giá trị chính xác ngay trên biểu đồ, chữ quay dọc gọn và phù hợp với nhãn hẹp. Dòng 8-9: Chèn các điểm nổi bật ngay trên phần đầu cột để nhấn mạnh giá trị từng nhóm; đồng thời thêm đường ngang thể hiện mức chi phí trung bình chung để so sánh với từng nhóm. Dòng 10: Phân tách biểu đồ thành nhiều khung nhỏ theo từng mức độ ưu tiên đơn hàng bằng facet_wrap (faceting), giúp so sánh từng nhóm ưu tiên riêng biệt và trực quan hơn. Dòng 11-12: Định dạng lại trục tung dùng dấu chấm và phẩy và sử dụng phong cách tối giản giúp biểu đồ thoáng và tập trung vào dữ liệu chính. Dòng 15–17: Đặt tiêu đề biểu đồ, nhãn trục, chỉnh phông chữ, định dạng nhãn trục X dễ đọc, đồng thời đưa chú thích xuống dướ.
1. Sales$delivery_date <- as.numeric(difftime(as.Date(Sales$Ship.Date, "%m/%d/%Y"), as.Date(Sales$Order.Date, "%m/%d/%Y"), units = "days"))
2. Sales$Sort_Date <- ifelse( Sales$delivery_date < 12, "Tốc độ nhanh", ifelse( Sales$delivery_date < 38, "Tốc độ trung bình","Tốc độ chậm"))
3. sort_summary <- Sales %>% group_by(Sort_Date) %>%
4. summarise(n = n(), .groups = "drop") %>%
5. mutate(Percentage = round(100 * n / sum(n), 1))
6. ggplot(sort_summary, aes(x = 2, y = n, fill = Sort_Date)) +
7. geom_bar(stat = "identity", width = 1.5, color = "black") +
8. coord_polar(theta = "y") +
9. xlim(0.5, 3) +
10. geom_text(aes(label = paste0(Percentage, "%")), position = position_stack(vjust = 0.5), size = 4, color = "black", fontface = "bold") +
11. scale_fill_brewer(palette = "Set2", name = "Tốc độ giao hàng") +
12. labs( title = "Phân loại tốc độ giao hàng của đơn hàng", caption = "Tính theo phần trăm" ) +
13. theme_void() +
14. theme( plot.title = element_text(face = "bold", size = 14, hjust = 0.5), legend.position = "bottom")
Nhận xét:Phân tích biểu đồ cho thấy phần lớn đơn hàng được giao với tốc độ trung bình, chiếm 50,7% tổng số đơn. Tỷ lệ giao hàng nhanh và chậm lần lượt là 23,6% và 25,7%, phản ánh sự cân bằng giữa các mức độ tốc độ nhưng chưa quá thiên về dịch vụ nhanh. Điều này cho thấy doanh nghiệp đã tối ưu hóa khâu hậu cần ổn định, tuy nhiên nếu tăng tỷ lệ giao hàng nhanh có thể nâng cao trải nghiệm khách hàng cạnh tranh hơn trên thị trường.
Giải thích:Dòng 1: Tính số ngày giao hàng của từng đơn bằng cách lấy hiệu giữa ngày giao và ngày đặt hàng, tạo cột “delivery_date” cho bảng Sales. Dòng 2: Phân loại tốc độ giao hàng thành ba nhóm: Tốc độ nhanh (dưới 12 ngày), Tốc độ trung bình (12 đến dưới 38 ngày), Tốc độ chậm (từ 38 ngày trở lên) và ghi vào cột “Sort_Date”. Dòng 3-5: Tổng hợp số lượng đơn hàng cho từng nhóm tốc độ, đồng thời tính phần trăm số lượng từng nhóm so với toàn bộ đơn hàng. Dòng 6-14: Vẽ biểu đồ tròn (pie chart) bằng ggplot2 biểu diễn tỷ lệ các nhóm tốc độ giao hàng. Mỗi phần của biểu đồ ứng với một nhóm tốc độ, màu sắc phân biệt rõ ràng, phần trăm được chèn trực tiếp vào từng lát.
1. Reve_Item_Priority <- aggregate(Sales$Total.Revenue,
2. by = list(Item = Sales$Item.Type, Priority = Sales$Order.Priority),
3. FUN = sum)
4. comma_vn <- function(x) {format(x, big.mark = ".", decimal.mark = ",", scientific = FALSE)}
5. mean_x <- mean(Reve_Item_Priority$x, na.rm = TRUE)
6. ggplot(Reve_Item_Priority, aes(x = Item, y = x, fill = Priority)) +
7. geom_col(position = position_dodge(width = 0.9), width = 0.7, alpha = 0.9) +
8. geom_hline( yintercept = mean_x,color = "#FF6680", linetype = "longdash", size = 1.15 ) +
9. annotate("text", x = length(unique(Reve_Item_Priority$Item)), y = mean_x, label = paste("Trung bình:", comma_vn(round(mean_x, 0))), vjust = 0.5, hjust = 0, color = "#FF6680", size = 4, fontface = "bold" ) +
10. scale_y_continuous(labels = comma_vn) +
11. scale_fill_brewer(palette = "Set2") +
12. labs( title = "Tổng doanh thu theo loại hàng và độ ưu tiên", x = "Loại hàng",y = "Tổng doanh thu", fill = "Độ ưu tiên") +
13. theme_light(base_size = 13) +
14. theme(plot.title = element_text(face = "bold", hjust = 0.5), legend.position = "bottom" ) +
15. coord_flip(clip = "off")
Nhận xét: Những nhóm hàng như Office Supplies, Meat, Cosmetics và Baby Food đạt mức doanh thu cao vượt trội so với các nhóm khác, chứng tỏ đây là các mặt hàng thiết yếu hoặc có nhu cầu ổn định và khả năng sinh lời cao. Trong khi đó, các mặt hàng như Fruits, Personal Care và Vegetables có doanh thu thấp hơn đáng kể, cho thấy nhu cầu tiêu dùng thấp hoặc quy mô thị trường nhỏ hơn trong giai đoạn phân tích. Mức doanh thu trung bình (2.783.472.356) được biểu diễn bằng đường đứt màu hồng đóng vai trò như một ngưỡng đánh giá hiệu quả hoạt động của từng loại hàng. Các nhóm hàng có tổng doanh thu vượt ngưỡng này thể hiện khả năng đóng góp tích cực vào tăng trưởng doanh thu toàn doanh nghiệp, trong khi các nhóm thấp hơn trung bình có thể cần điều chỉnh chiến lược marketing, giá bán hoặc danh mục sản phẩm để nâng cao hiệu quả kinh doanh.
Giải thích:Dòng 1–3: Đầu tiên, dữ liệu được tổng hợp để tính tổng doanh thu theo từng loại hàng và từng mức độ ưu tiên đơn hàng. Cụ thể, hàm aggregate nhóm dữ liệu theo cột loại hàng và cột độ ưu tiên, sau đó tính tổng doanh thu cho từng nhóm. Dòng 7: Tính giá trị trung bình của tổng doanh thu trên toàn bộ các nhóm, từ đó làm cơ sở để so sánh với từng loại hàng và mức ưu tiên cụ thể. Dòng 9: Hiển thị các cột cạnh nhau (dodge) cho phép so sánh trực quan tổng doanh thu giữa các nhóm độ ưu tiên cho cùng một loại hàng, đồng thời điều chỉnh độ rộng và độ trong để biểu đồ rõ ràng, dễ phân biệt. Dòng 10: Thêm đường kẻ ngang biểu diễn giá trị trung bình; đường này giúp người đọc so sánh từng loại hàng/ngưỡng ưu tiên với mức trung bình chung toàn dữ liệu. Dòng 14: Đặt tiêu đề,tên trục và chú thích rõ ràng. Dòng 17: Lật ngược trục nhằm chuyển các cột thành ngang, giúp tên loại sản phẩm dài dễ đọc và tăng tối ưu diện tích hiển thị.
1. Asia = Sales[Sales$Region=="Asia",]
2. q_unit <- quantile(Asia$Units.Sold, probs = c(0.25, 0.75))
3. q_profit <- quantile(Asia$Total.Profit, probs = c(0.25, 0.75))
Dòng 1: Lọc dữ liệu bán hàng thuộc khu vực Châu Á để phục vụ phân tích riêng cho thị trường này. Dòng 2: Tính các giá trị tứ phân vị cho biến số lượng bán trong khu vực Châu Á bằng hàm quantile với tham số xác suất 0.25 và 0.75. Dòng 3: Tính các giá trị tứ phân vị cho biến lợi nhuận trong khu vực Châu Á bằng hàm quantile với tham số xác suất 0.25 và 0.75.
1. Asia$PhatTrien <- ifelse(
2. Asia$Units.Sold < q_unit[1] & Asia$Total.Profit < q_profit[1], "Phát triển chậm",
3. ifelse( Asia$Units.Sold <= q_unit[2] & Asia$Total.Profit <= q_profit[2], "Phát triển trung bình", "Phát triển tốt" ))
4. freq_table <- Asia %>% count(Nhom = PhatTrien) %>% mutate(Ty_le = round(100 * n / sum(n), 2))
Dòng 1–3: Phân loại các đơn hàng thuộc khu vực Châu Á dựa trên hai biến số lượng bán và lợi nhuận, sử dụng các giá trị tứ phân vị để gán nhãn phát triển cho từng đơn hàng: “Phát triển chậm” nếu cả số lượng bán lẫn lợi nhuận đều dưới mức thấp nhất , “Phát triển trung bình” nếu cả hai nằm trong khoảng giữa, và “Phát triển tốt” nếu vượt qua ngưỡng cao cả về số lượng lẫn lợi nhuận. Việc này giúp nhanh chóng xác định nhóm đơn hàng theo tốc độ phát triển tổng thể trong thị trường. Dòng 4: Tạo bảng tần suất (frequency table) cho từng nhóm phát triển vừa gán ở trên, tính thêm tỷ lệ phần trăm để dễ nhận diện mức độ phổ biến từng nhóm so với toàn bộ đơn hàng
1. Sold_asia <- Asia %>%
2. group_by(Country, Item.Type) %>%
3. summarise(Mean_Profit = mean(Total.Profit, na.rm = TRUE),Min_Profit = min(Total.Profit, na.rm = TRUE), Max_Profit = max(Total.Profit, na.rm = TRUE), Var_Profit = var(Total.Profit, na.rm = TRUE))
4. ggplot(Asia, aes(x = Item.Type, y = Total.Profit, fill = PhatTrien)) +
5. geom_col(width = 0.6, position = "dodge") +
6. scale_fill_manual(values = c( "Phát triển chậm" = "#ff9999", "Phát triển trung bình" = "#ffd966", "Phát triển tốt" = "#90ee90")) +
7. theme_minimal() +
8. labs( title = "Lợi nhuận trung bình theo loại hàng và mức phát triển",x = "Loại hàng", y = "Lợi nhuận trung bình", fill = "Mức phát triển" ) +
9. theme( axis.text.x = element_text(angle = 30, hjust = 1),axis.title.x = element_text(face = "bold", vjust = -0.2) )
Nhận xét:Biểu đồ thể hiện rõ mức lợi nhuận trung bình của từng loại hàng tại khu vực Châu Á, xét theo ba nhóm mức độ phát triển: phát triển chậm, trung bình và tốt. Các sản phẩm như Household, Office Supplies, và Clothes có mức lợi nhuận trung bình cao nhất trong nhóm “phát triển tốt”. Biểu đồ cho thấy sự phân hóa lợi nhuận rõ rệt giữa các loại mặt hàng và giữa các mức phát triển. Doanh nghiệp nên tập trung nguồn lực vào các sản phẩm đang mang lại lợi nhuận cao (thuộc nhóm “phát triển tốt”) để duy trì và mở rộng thị phần, đồng thời cân nhắc các biện pháp hỗ trợ, quảng bá hoặc điều chỉnh chiến lược với các sản phẩm đạt hiệu quả thấp để cải thiện hiệu quả kinh doanh toàn hệ thống.
Giải thích:Dòng 1–3: nhóm dữ liệu khu vực Châu Á theo từng quốc gia và loại sản phẩm, sau đó tính các chỉ số lợi nhuận cho từng nhóm: trung bình, nhỏ nhất, lớn nhất và phương sai. Dòng 4-6: trực quan hóa lợi nhuận của các đơn hàng từng loại sản phẩm tại Châu Á dưới dạng biểu đồ cột, mỗi cột đại diện một sản phẩm và mức phát triển được phân biệt bằng màu sắc: “Phát triển chậm” thể hiện bằng màu đỏ nhạt, “Phát triển trung bình” bằng vàng và “Phát triển tốt” bằng xanh lá nhạt. Biểu đồ được tối giản hóa phông nền, nhãn trục X xoay nghiêng, tiêu đề và nhãn rõ ràng, giúp dễ dàng nhận biết nhóm sản phẩm có lợi nhuận nổi bật và mức độ phát triển của từng loại hàng.
1. sales_2015_online <- Sales[Sales$Sales.Channel == "Online" & Sales$Year == "2015", ]
2. bottom10_countries <- sales_2015_online %>% group_by(Country) %>%
3. summarise(TotalRevenue = sum(Total.Revenue)) %>%
4. arrange(TotalRevenue) %>% slice_tail(n = 10) %>%
5. mutate(Top3 = ifelse(row_number() <= 3, "Top 3 Thấp nhất", "Others"))
6. ggplot(bottom10_countries, aes(x = reorder(Country, TotalRevenue), y = TotalRevenue)) +
7. geom_bar(aes(y = max(TotalRevenue)), stat = "identity", fill = "gray90") +
8. geom_bar(stat = "identity", aes(fill = TotalRevenue)) +
9. scale_fill_gradient(low = "lightcoral", high = "darkred") +
10. geom_bar( stat = "identity", data = subset(bottom10_countries, Top3 == "Top 3 Thấp nhất"), aes(fill = TotalRevenue), color = "gold", linewidth = 1.2 ) +
11. geom_text(aes(label = comma(TotalRevenue, big.mark = ".", decimal.mark = ",")), hjust = 1, size = 3.5, color = "black") +
12. geom_hline(yintercept = mean(bottom10_countries$TotalRevenue),
13. linetype = "dashed", color = "blue", linewidth = 0.8) +
14. coord_flip() +
15. scale_y_continuous(labels = function(x) comma(x, big.mark = ".", decimal.mark = ",")) +
16. labs( title = "Top 10 Quốc gia có doanh thu online thấp", x = "Quốc gia", y = "Tổng doanh thu", fill = "Total Revenue" ) +
17. theme_minimal() +
18. theme(legend.position = "right", plot.title = element_text(face = "bold", size = 17) )
Nhận xét:Biểu đồ thể hiện top 10 quốc gia có doanh thu online thấp nhất, cụ thể Malta, Bulgaria và Maldives nằm cuối bảng với doanh thu chỉ khoảng 68 đến 70 triệu, thấp hơn rõ rệt so với các quốc gia khác như Senegal hay Portugal. Mức doanh thu online của những quốc gia này cho thấy tiềm năng thị trường thương mại điện tử còn hạn chế, hoặc có thể do thói quen tiêu dùng chưa chuyển dịch mạnh sang kênh online. Doanh nghiệp cần nghiên cứu đầu tư nâng cao nhận thức và cải thiện hạ tầng để thúc đẩy tăng trưởng doanh thu tại các thị trường này, đặc biệt nhóm nằm dưới ngưỡng 75 triệu.
Giải thích:Dòng 1–4: Lọc dữ liệu bán hàng online năm 2015 để tập trung vào phân tích hiệu quả kênh bán hàng. Dòng 5–6: Nhóm dữ liệu theo quốc gia, tính tổng doanh thu từng nước từ kênh online, sắp xếp doanh thu tăng dần và lấy ra 10 quốc gia doanh thu thấp nhất. Dòng 6-18: Trực quan hóa kết quả bằng biểu đồ cột ngang. Mỗi cột thể hiện tổng doanh thu online tại từng quốc gia, hai lớp màu: lớp nền xám cho chiều cao lớn nhất, lớp chính dùng màu chuyển từ nhạt đến đậm (lightcoral – darkred) theo giá trị doanh thu. Ba quốc gia thấp nhất được viền vàng để nhấn mạnh, đồng thời các số liệu được hiển thị trực tiếp trên từng cột. Đường kẻ ngang biểu diễn giá trị trung bình toàn nhóm 10 làm chuẩn để so sánh, trục tung được chuyển thành ngang giúp nhãn quốc gia dễ đọc.
1. region_rev <- Sales %>% group_by(Region) %>% summarise(TotalRevenue = sum(Total.Revenue))
2. region_rev <- region_rev %>% arrange(desc(Region)) %>%
3. mutate( percent = TotalRevenue / sum(TotalRevenue) * 100, ymax = cumsum(TotalRevenue), ymin = ymax - TotalRevenue,midpoint = (ymax + ymin) / 2 )
4. ggplot(region_rev, aes(x = 2, y = TotalRevenue, fill = Region)) +
5. geom_bar(stat = "identity", width = 1.5, color = "black") +
6. scale_fill_manual(values = c("#FF9999", "#66B2FF", "#99FF99", "#FFCC66", "#CC99FF", "#8C564B", "#66FFCC")) +
7. geom_text(aes(label = paste0(round(percent, 1), "%")), position = position_stack(vjust = 0.5), size = 3.5, color = "black", fontface = "bold") +
8. coord_polar(theta = "y") +
9. xlim(0.5, 3) +
10. annotate("text", x = 0.5, y = 0,label = paste0("Tổng: ", comma_vn(sum(region_rev$TotalRevenue))), size = 4, fontface = "bold",color = "black") +
11. labs(title = "Tỷ lệ doanh thu theo vùng") +
12. theme_void() +
13. theme(plot.title = element_text(size = 22, face = "bold", hjust = 0.5),legend.position = "bottom",legend.box = "horizontal",legend.justification = "center",legend.direction = "horizontal" )
Nhận xét: Nhìn vào thị phần, hai khu vực Sub-Saharan Africa và Europe chiếm tổng cộng hơn 51% thị trường doanh thu toàn cầu, cho thấy độ tập trung rất cao tại hai khu vực này. Trong khi đó, các khu vực khác đều dưới 15% thị phần; North America là khu vực nhỏ nhất với tỷ trọng chỉ 2.2%. Kết quả này cho thấy doanh nghiệp muốn tối ưu hóa nguồn lực hoặc lựa chọn thị trường trọng điểm nên ưu tiên đầu tư lớn nhất vào Sub-Saharan Africa và Europe, đồng thời cần chiến lược phát triển trung hạn cho các thị trường tiềm năng đang phát triển.
Giải thích:Đoạn 1-3: Xử lý dữ liệu để lấy tổng doanh thu từng vùng, sắp xếp lại thứ tự vùng , tính phần trăm từng vùng, rồi tạo thêm các biến phụ (ymax, ymin, midpoint) nhằm hỗ trợ cho các dạng biểu đồ bán nguyệt, donut. Đoạn 4-5: Khởi tạo biểu đồ với ggplot2. Trục x đặt giá trị 2 để tạo “lõi” cho hình tròn, trục y là tổng doanh thu theo vùng; sử dụng geom_bar để vẽ các thanh dọc (. Các cột này sẽ tạo thành các lát cắt trên biểu đồ tròn khi chuyển sang trục polar. Đoạn 6-7: Áp dụng bảng màu tùy chỉnh để phân biệt các vùng; thêm nhãn phần trăm trên từng lát cắt, đặt giữa mỗi sector bằng position_stack(vjust = 0.5) nhằm hiện tỷ trọng từng vùng mà không cần nhìn sang legend. Mọi phần trăm được căn chỉnh đậm, rõ nét. Đoạn 8-9: Sử dụng coord_polar(theta = “y”) để chuyển sang biểu đồ tròn.
1. ggplot(Sales, aes(x = `Total.Cost`)) +
2. geom_histogram(bins = 30, fill = "#56B4E9", color = "white", alpha = 0.8) +
3. geom_vline(aes(xintercept = mean(`Total.Profit`, na.rm = TRUE)),
4. color = "red", linewidth = 1) +
5. geom_text(aes(x = mean(`Total.Profit`, na.rm = TRUE),
6. y = 50,
7. label = paste0("Trung bình = ",
8. label_number(big.mark = ",", accuracy = 1)(mean(`Total.Profit`, na.rm = TRUE)))),
9. color = "red", hjust = -0.1,vjust = -25, size = 3.8) +
10. scale_x_continuous(labels = label_number(big.mark = ",", accuracy = 1)) +
11. labs(title = "Phân bố chi phí",
12. x = "Chi phí",
13. y = "Tần suất") +
14. theme_minimal(base_size = 13) +
15. theme(panel.grid.minor = element_blank())
Nhận xét: Biểu đồ phân bố chi phí trên phản ánh sự khác biệt lớn về chi phí giữa các mảng hoạt động của doanh nghiệp đó. Cụ thể, phần lớn các mảng có chi phí hoạt động thấp, thể hiện qua tần suất cao ở nhóm chi phí nhỏ, trong khi một số mảng nhất định có chi phí rất cao, khiến biểu đồ bị lệch phải mạnh và làm cho giá trị trung bình chi phí cao hơn đáng kể so với phần lớn các mảng còn lại. Điều này cho thấy doanh nghiệp đang phân bổ nguồn lực không đồng đều giữa các mảng kinh doanh. Một số mảng có thể thuộc lĩnh vực đòi hỏi đầu tư lớ . Mô hình này cho thấy chiến lược đa dạng hóa của doanh nghiệp – chấp nhận chi phí cao ở một số lĩnh vực để mở rộng thị phần hoặc phát triển dài hạn, đồng thời duy trì các mảng chi phí thấp để bảo đảm dòng tiền ổn định và hiệu quả tổng thể.
Giải thích:Dòng 1–2: Biểu đồ được tạo với trục X là biến Chi phí từ bảng Sales. Lệnh geom_histogram chia ra 30 khoảng để thể hiện phân bố, và dùng màu xanh nhạt cho các cột, viền trắng giúp các cột tách biệt rõ ràng. Dòng 3–5: Thêm đường dọc màu đỏ tại vị trí giá trị trung bình của biến Lợi nhuận , nhằm so sánh vị trí trung bình so với phân bố chi phí. Dòng 10: Định dạng trục X bằng cách thêm dấu phẩy phân cách hàng nghìn, giúp số liệu lớn dễ đọc hơn. Dòng 11–13: Thiết lập tiêu đề “Phân bố chi phí” và nhãn trục giúp biểu đồ rõ ý nghĩa. Trục Y thể hiện tần suất.
1. top_items <- Sales %>%
2. group_by(Item.Type) %>%
3. summarise(Total_Cost=sum(Total.Cost)) %>%
4. arrange(Total_Cost) %>%
5. slice_head(n=10)
6. top_items <- top_items %>%
7. mutate(Share = Total_Cost / sum(Total_Cost))
8. ggplot(top_items, aes(x = reorder(Item.Type, Total_Cost), y = Total_Cost)) +
9. geom_rect(aes(xmin = -Inf, xmax = Inf, ymin = 0, ymax = Inf),
10. fill = "#f9fbfd", alpha = 0.4, inherit.aes = FALSE) +
11. geom_col(aes(fill = Total_Cost), width = 0.6, alpha = 0.95, show.legend = FALSE) +
12. geom_hline(yintercept = mean(top_items$Total_Cost),
13. linetype = "dashed", color = "#457b9d", alpha = 0.7) +
14. geom_text(aes(label = paste0(round(Share * 100, 1), "%")),
15. color = "black", fontface = "bold", size = 3.5,
16. hjust = 1.15, vjust = 0.5) +
17.
18. scale_fill_gradient(low = "#a8dadc", high = "#f4a261") +
19. scale_y_continuous(labels = comma_vn) +
20.
21. coord_flip() +
22. labs(
23. title = "Top 10 sản phẩm thấp nhất",
24. x = "Loại sản phẩm",
25. y = "Chi phí"
26. ) +
27. theme_minimal(base_size = 13) +
28. theme(
29. plot.title = element_text(face = "bold", hjust = 0.5, color = "#264653"),
30. axis.text = element_text(color = "#2d3436"),
31. panel.grid.major.y = element_line(color = "white"),
32. panel.grid.minor = element_blank(),
33. plot.background = element_rect(fill = "white", color = NA)
34. )
Nhận xét:Biểu đồ top 10 sản phẩm có chi phí thấp nhất cho thấy nhóm Meat và Cosmetics lại chiếm tỷ trọng chi phí lớn nhất, lần lượt là 29,8% và 21,6% tổng chi phí của nhóm này. Ngược lại, các sản phẩm như Beverages và Fruits chỉ chiếm tỷ trọng rất nhỏ, dưới 3%. Điều này cho thấy trong nhóm các sản phẩm thấp nhất về chi phí, vẫn có sự tập trung chi phí lớn ở một số nhóm chính, và doanh nghiệp có thể cân nhắc điều chỉnh cung ứng hoặc chiến lược giá cho những sản phẩm chiếm tỷ trọng cao này để cải thiện hiệu quả tài chính.
Giải thích:Đoạn 1-7: Tổng hợp chi phí sản phẩm theo loại bằng các bước xử lý dplyr, lấy 10 sản phẩm có tổng chi phí thấp nhất và tính thêm tỷ trọng từng loại. Đoạn 8-11: Vẽ biểu đồ cột với ggplot2, xếp thứ tự sản phẩm từ thấp lên cao và vẽ nền nhạt phía sau. Các cột màu sắc chuyển từ xanh sang cam thể hiện mức độ tăng chi phí. Thêm đường ngang tại giá trị trung bình để so sánh sản phẩm nào thấp hơn/ngang bằng/tăng hơn chi phí chung toàn nhóm.
1. comma_vn <- function(x) format(x, big.mark = ".", decimal.mark = ",", scientific = FALSE)
2. price_detail <- Sales %>% group_by(Country, Item.Type) %>%
3. summarise(Price = sum(Unit.Price, na.rm = TRUE), .groups = "drop")
4. top_countries_list <- price_detail %>% group_by(Country) %>%summarise(Total = sum(Price), .groups = "drop") %>% arrange(desc(Total)) %>%slice(1:10) %>%
5. pull(Country)
6. price_detail_top <- price_detail %>%filter(Country %in% top_countries_list) %>%mutate(Country = factor(Country, levels = rev(top_countries_list))) %>%group_by(Country) %>%mutate(Country_Total = sum(Price)) %>%ungroup()
7. ggplot(price_detail_top, aes(x = Country, y = Price, fill = Item.Type)) +
8. geom_col(position = "stack", width = 0.7, color = "black", linewidth = 0.3) +
9. geom_text( aes(label = ifelse(Price > quantile(Price, 0.75), comma_vn(round(Price, 0)), "")),position = position_stack(vjust = 0.5), size = 2.5, color = "black", fontface = "bold") +
10. geom_text( aes(y = Country_Total, label = comma_vn(round(Country_Total, 0)), group = Country), vjust = -0.5, size = 3, fontface = "bold", color = "darkblue" ) +
11. geom_hline(yintercept = mean(price_detail_top$Country_Total), linetype = "dashed", color = "red", linewidth = 0.8, alpha = 0.7) +
12. coord_flip(clip = "off") +
13. scale_fill_brewer(palette = "Set3", name = "Loại sản phẩm") +
14. scale_y_continuous(labels = comma_vn, expand = expansion(mult = c(0, 0.12))) +
15. labs(title = "Top 10 Quốc gia có giá bán sản phẩm cao", subtitle = "Phân tách theo loại sản phẩm", x = "Quốc gia", y = "Tổng Giá bán", caption = "Nguồn: Dữ liệu 100,000 Sales Records" ) +
16. theme_minimal() +
17. theme( legend.position = "right", axis.text.y = element_text(size = 11, face = "bold"), plot.title = element_text(face = "bold", size = 14), plot.subtitle = element_text(size = 11, color = "gray50"))
Nhận xét:Biểu đồ cho thấy top 10 quốc gia có giá bán sản phẩm cao đa dạng về loại mặt hàng, với các nhóm hàng như Beverages, Cereal, Meat và Cosmetics chiếm tỉ trọng lớn trong cơ cấu giá bán ở phần lớn quốc gia. Tổng giá trị bán ra của các nước này đều vượt ngưỡng 150.000, cho thấy sự mạnh mẽ về sức mua hoặc giá bán trung bình cao trên thị trường địa phương. Điều này gợi ý doanh nghiệp nên tập trung khai thác các dòng sản phẩm cao cấp hoặc những nhóm mặt hàng có giá trị bán cao tại các thị trường này để tối đa hóa doanh thu.
Giải thích:Đoạn 2-3: Tính tổng giá bán theo quốc gia và loại sản phẩm bằng group_by kết hợp summarise, tạo bảng tổng hợp từng loại sản phẩm cho từng quốc gia. Sau đó, tách ra danh sách 10 quốc gia có tổng giá bán cao nhất bằng tiếp tục nhóm theo quốc gia, tính tổng, rồi sắp xếp và lấy 10 dòng đầu. Đoạn 4-6: Lọc ra dữ liệu của 10 quốc gia top, đặt lại thứ tự bằng factor(levels = rev(…)) . Đoạn 7-9: Vẽ biểu đồ cột nhóm (stacked bar) với ggplot2: trục x là quốc gia, trục y là tổng giá bán sản phẩm. geom_text đầu tiên chèn nhãn giá trị chi tiết bên trong cột , geom_text thứ hai chèn tổng giá bán từng quốc gia trên đỉnh cột, in đậm màu xanh đậm. Đoạn 10-12: Vẽ thêm đường hline ngang tại mức trung bình tổng giá bán nhằm giúp nhận diện quốc gia nào vượt chuẩn so với mặt bằng.
1. comma_vn <- function(x) format(x, big.mark = ".", decimal.mark = ",", scientific = FALSE)
2. region_rev <- Sales %>% group_by(Region) %>%summarise(TotalRevenue = sum(Total.Revenue), .groups = "drop") %>% arrange(desc(TotalRevenue)) %>%mutate(Percent = round(100 * TotalRevenue / sum(TotalRevenue), 1) )
3. ggplot(region_rev, aes(x = reorder(Region, -TotalRevenue), y = Percent, fill = Region)) +
4. geom_col(color = "black", linewidth = 0.7) +
5. geom_text(aes(label = paste0(Percent, "%")), vjust = -0.5, size = 4, color = "black", fontface = "bold") +
6. geom_hline(yintercept = mean(region_rev$Percent), linetype = "dashed", color = "red", linewidth = 0.8) +
7. scale_fill_manual(values = c("#FF9999", "#66B2FF", "#99FF99", "#FFCC66", "#CC99FF", "#8C564B", "#66FFCC")) +
8. scale_y_continuous(labels = function(x) paste0(x, "%"), limits = c(0, max(region_rev$Percent) * 1.1)) +
9. labs(title = "Tỷ lệ doanh thu theo vùng",x = "Vùng", y = "Phần trăm (%)") +
10. theme_minimal(base_size = 13) +
11. theme(plot.title = element_text(size = 16, face = "bold", hjust = 0.5), axis.text.x = element_text(angle = 45, hjust = 1),legend.position = "none")
Nhận xét:Biểu đồ cho thấy Sub-Saharan Africa và Europe là hai khu vực có tỷ lệ doanh thu cao nhất, chiếm lần lượt 26,2% và 25,6% tổng doanh thu toàn thị trường. Ngược lại, North America đóng góp rất nhỏ, chỉ đạt 2,2%, thể hiện sự chênh lệch rõ nét về sức mua hoặc hiệu quả kinh doanh giữa các khu vực. Đây là cơ sở để doanh nghiệp ưu tiên khai thác và đầu tư phát triển tại các thị trường tỷ trọng lớn, đồng thời đánh giá lại chiến lược kinh doanh ở những vùng có doanh thu thấp.
Giải thích:Đoạn 2: Thống kê tổng doanh thu cho từng vùng bằng group_by rồi summarise, xếp thứ tự vùng giảm dần theo doanh thu, tính phần trăm tỷ lệ từng vùng trong tổng doanh thu. Đoạn 3-5: Vẽ biểu đồ cột với ggplot2, trục x là tên vùng, trục y là tỷ lệ %. Vùng có doanh thu lớn nhất sẽ đứng ngoài cùng bên trái. Đoạn 6-7: Vẽ đường ngang mốc tỷ lệ trung bình toàn thị trường (geom_hline), hỗ trợ so sánh tổng quan các vùng có tỷ trọng cao/thấp so với trung bình. Đoạn 8-9: Định dạng trục y thành % và giới hạn tối đa lên một chút để các nhãn không bị cắt, đồng thời đặt tiêu đề, nhãn trục rõ ràng phục vụ báo cáo.
1. library(readxl)
2. file = ("C:/Users/My Asus/Downloads/hsg.xlsx")
3. HSG <- read_excel(path = file)
1. str(HSG)
## tibble [10 × 19] (S3: tbl_df/tbl/data.frame)
## $ Năm : num [1:10] 2015 2016 2017 2018 2019 ...
## $ Phải trả người bán ngắn hạn : num [1:10] 555161842884 1501886154837 3415707867150 1111659624255 1370637850790 ...
## $ Chi phí phải trả ngắn hạn : num [1:10] 81556360439 187888512542 62825939966 117856182101 92362758133 ...
## $ Vay và nợ thuê tài chính ngắn hạn : num [1:10] 4400210324546 4102697779164 7402317620460 9010977033379 5706275512506 ...
## $ Vốn cổ phần : num [1:10] 1007907900000 1965398290000 3499966830000 3849903280000 4234694890000 ...
## $ Lợi nhuận sau thuế chưa phân phối : num [1:10] 1531127724105 1753131906267 1618854251238 1323418124868 1539503023643 ...
## $ Tiền : num [1:10] 276553474303 292227797476 576477183208 171516367114 222120606665 ...
## $ Các khoản tương đương tiền : num [1:10] 140000000 143521875 143521875 143521875 143521875 ...
## $ Các khoản phải thu ngắn hạn : num [1:10] 755197646602 1827514998306 1097734614933 7860565817787 5167377333616 ...
## $ Tài sản cố định hữu hình : num [1:10] 3403033912877 6396829534741 4010721553262 1591695704971 1441875639868 ...
## $ Các khoản phải thu dài hạn : num [1:10] 25000000000 1458000000 28470549901 268984943607 292077985517 ...
## $ Lưu chuyển tiền thuần từ HĐKD : num [1:10] 1280225410487 1641219255869 -2173431969202 499984886725 5181076080821 ...
## $ Tiền thu từ đi vay : num [1:10] 13314828925538 12715960175942 27410327886870 33719297189430 20572520273479 ...
## $ Doanh thu bán hàng và cung cấp dịch vụ : num [1:10] 17469894530725 18006498541322 26336984183123 34570344557164 28081303783088 ...
## $ Giá vốn hàng bán và cung cấp dịch vụ : num [1:10] -14869355353248 -13717393786963 -21730791206018 -30464290088385 24836155036672 ...
## $ Lợi nhuận gộp về bán hàng và cung cấp dịch vụ: num [1:10] 2577516224574 4176321693990 4418253629261 3977139259876 3198620082003 ...
## $ Chi phí bán hàng : num [1:10] -864210788876 -1139602275640 -1512517323076 -1816042397184 1748882841240 ...
## $ Chi phí quản lý doanh nghiệp : num [1:10] -511797744891 -900715660782 -801479758048 -895579880506 470700688884 ...
## $ Lợi nhuận thuần từ hoạt động kinh doanh : num [1:10] 808446738155 1918748102484 1568992697472 474797169857 239566040636 ...
Nhận xét: bộ dữ liệu gồm 10 quan sát và 19 biến, cả 19 biến đều hiển thị dưới dạng số là numeric
1. names(HSG)
## [1] "Năm"
## [2] "Phải trả người bán ngắn hạn"
## [3] "Chi phí phải trả ngắn hạn"
## [4] "Vay và nợ thuê tài chính ngắn hạn"
## [5] "Vốn cổ phần"
## [6] "Lợi nhuận sau thuế chưa phân phối"
## [7] "Tiền"
## [8] "Các khoản tương đương tiền"
## [9] "Các khoản phải thu ngắn hạn"
## [10] "Tài sản cố định hữu hình"
## [11] "Các khoản phải thu dài hạn"
## [12] "Lưu chuyển tiền thuần từ HĐKD"
## [13] "Tiền thu từ đi vay"
## [14] "Doanh thu bán hàng và cung cấp dịch vụ"
## [15] "Giá vốn hàng bán và cung cấp dịch vụ"
## [16] "Lợi nhuận gộp về bán hàng và cung cấp dịch vụ"
## [17] "Chi phí bán hàng"
## [18] "Chi phí quản lý doanh nghiệp"
## [19] "Lợi nhuận thuần từ hoạt động kinh doanh"
1. dim(HSG)
## [1] 10 19
Nhận xét: Kết quả cho thấy bộ dữ liệu gồm 10 dòng và 19 biến.
Giải thích:
summary(HSG[[" "]]): Tạo ra bảng tóm tắt thống kê cho biến chứa các giá trị như: Min (giá trị nhỏ nhất), 1st Qu. (phân vị thứ nhất – tứ phân vị thứ nhất), Median (Trung vị), Mean (Giá trị trung bình), 3rd Qu. (tứ phân vị thứ ba), Max (giá trị lớn nhất).format(..., big.mark = ".", decimal.mark = ","): Định dạng lại các kết quả thống kê vừa tính, sử dụng dấu chấm “.” để phân cách hàng nghìn và dấu phẩy “,” cho phần thập phân, phù hợp với quy chuẩn số ở Việt Nam.
1. format(summary(HSG[["Tiền"]]), big.mark = ".", decimal.mark = ",", scientific = FALSE)
## Min. 1st Qu. Median Mean
## "171.516.367.114" "250.687.476.019" "348.747.468.446" "376.374.876.074"
## 3rd Qu. Max.
## "495.339.485.898" "597.436.771.510"
Nhận xét: Dòng tiền của Hoa Sen group đi chủ yếu là từ khoảng 250.687.476.019 đến 495.339.485.898, cho thấy khối lượng tiền trong doanh nghiệp đủ lớn.Nhìn chung, tiền mặt có xu hướng tăng theo thời gian, tuy nhiên vẫn tồn tại một số năm thấp hơn, cần chú ý đến quản lý dòng tiền và rủi ro thanh khoản.
1. format(summary(HSG[["Vay và nợ thuê tài chính ngắn hạn"]]), big.mark = ".", decimal.mark = ",", scientific = FALSE)
## Min. 1st Qu. Median Mean
## "2.936.344.523.958" "4.177.075.915.510" "4.918.998.936.304" "5.230.646.227.048"
## 3rd Qu. Max.
## "5.620.727.747.666" "9.010.977.033.379"
Nhận xét: Mức vay và nợ thấp nhất là2.936.344.523.958, trong khi mức cao nhất lên tới9.010.977.033.379, cho thấy biến động rất lớn trong 10 năm qua. Giá trị trung bình 5.230.646.227.048, cao hơn giá trị trung vị 4.918.998.936.304, chứng tỏ dữ liệu lệch phải, tức một số năm nợ tăng đột biến kéo trung bình lên. Khoảng giữa 1st Qu. 4.177.075.915.510 và 3rd Qu.5.620.727.747.666 cũng khá rộng, cho thấy sự phân tán đáng kể trong các năm, nghĩa là mức nợ không đồng đều và có sự biến động theo từng kỳ.
1. format(summary(HSG[["Vốn cổ phần"]]), big.mark = ".", decimal.mark = ",", scientific = FALSE)
## Min. 1st Qu. Median Mean
## "1.007.907.900.000" "3.587.450.942.500" "4.340.473.510.000" "4.223.913.832.000"
## 3rd Qu. Max.
## "5.719.117.135.000" "6.159.823.090.000"
Nhận xét: Vốn cổ phần thấp nhất1.007.907.900.000, trong khi cao nhất là 6.159.823.090.000, cho thấy quy mô vốn cổ phần tăng đáng kể trong 10 năm qua. Giá trị trung bình 4.223.913.832.000, gần bằng giá trị trung vị4.340.473.510.000, chứng tỏ dữ liệu khá cân đối và không có sự lệch quá lớn.cho thấy doanh nghiệp đã huy động thêm vốn từ cổ đông hoặc tăng vốn điều lệ, góp phần tăng cường khả năng tài chính
1. format(summary(HSG[["Tài sản cố định hữu hình"]]), big.mark = ".", decimal.mark = ",", scientific = FALSE)
## Min. 1st Qu. Median Mean
## " 848.743.235.444" "1.047.747.456.742" "1.516.785.672.420" "2.470.562.104.148"
## 3rd Qu. Max.
## "3.786.692.305.506" "6.396.829.534.741"
Nhận xét: Mức thấp nhất là khoảng 848.743.235.444, trong khi mức cao nhất lên tới 6.396.829.534.741, cho thấy biến động rất lớn trong giá trị tài sản cố định qua các năm. Giá trị trung bình khoảng 2.470.562.104.148, cao hơn giá trị trung vị1.516.785.672.420, chứng tỏ dữ liệu lệch phải, nghĩa là có một số năm HSG đầu tư mạnh vào tài sản cố định, kéo trung bình lên cao. Tài sản cố định hữu hình có xu hướng tăng theo thời gian, phản ánh doanh nghiệp mở rộng năng lực sản xuất, đầu tư máy móc, nhà xưởng
1. format(summary(HSG[["Lưu chuyển tiền thuần từ HĐKD"]]), big.mark = ".", decimal.mark = ",", scientific = FALSE)
## Min. 1st Qu. Median
## "-2.173.431.969.202" " 695.045.017.666" " 1.568.647.852.184"
## Mean 3rd Qu. Max.
## " 1.332.995.746.193" " 2.048.547.688.661" " 5.181.076.080.821"
Nhận xét: Mức thấp nhất là khoảng -2.173.431.969.202, trong khi mức cao nhất lên tới5.181.076.080.821, cho thấy biến động cực kỳ lớn trong dòng tiền từ HĐKD qua các năm. Giá trị trung bình khoảng 1.332.995.746.193, thấp hơn giá trị trung vị1.568.647.852.184, cho thấy dữ liệu có vài năm dòng tiền âm, kéo trung bình xuống dưới mức trung bình. Nhìn chung, dòng tiền từ HĐKD thường dương, nhưng vẫn có năm âm, cho thấy doanh nghiệp đôi khi gặp áp lực thanh khoản hoặc chi phí hoạt động vượt thu nhập.
1. format(summary(HSG[["Doanh thu bán hàng và cung cấp dịch vụ"]]), big.mark = ".", decimal.mark = ",", scientific = FALSE)
## Min. 1st Qu. Median
## "17.469.894.530.725" "26.694.027.043.919" "30.082.800.738.072"
## Mean 3rd Qu. Max.
## "32.327.475.286.297" "38.554.689.827.340" "50.090.135.318.501"
Nhận xét: Mức thấp nhất là khoảng17.469.894.530.725, trong khi mức cao nhất đạt tới50.090.135.318.501, cho thấy doanh thu biến động đáng kể trong 10 năm qua. Giá trị trung bình khoảng 32.327.475.286.297, cao hơn giá trị trung vị 30.082.800.738.072, chứng tỏ doanh thu lệch phải, tức có một vài năm doanh thu tăng đột biến kéo trung bình lên.Nhìn chung, doanh thu có xu hướng tăng theo thời gian, phản ánh HSG đang mở rộng hoạt động kinh doanh, tăng thị phần hoặc nâng cao hiệu quả bán hàng
1. format(summary(HSG[["Giá vốn hàng bán và cung cấp dịch vụ"]]), big.mark = ".", decimal.mark = ",", scientific = FALSE)
## Min. 1st Qu. Median
## "-35.008.227.341.981" "-26.875.211.951.759" "-14.293.374.570.106"
## Mean 3rd Qu. Max.
## " -1.201.537.059.904" " 24.352.986.818.860" " 44.771.944.789.711"
Nhận xét: Mức thấp nhất là khoảng-35.008.227.341.981, trong khi mức cao nhất lên tới44.771.944.789.711, cho thấy biến động cực kỳ lớn trong giá vốn qua các năm. Giá trị trung bình khoảng-1.201.537.059.904, thấp hơn giá trị trung vị -14.293.374.570.106, chứng tỏ dữ liệu lệch phải rất mạnh. hoảng giữa 1st Qu.-26.875.211.951.759 và 3rd Qu. 24.352.986.818.860 cực kỳ rộng, thể hiện sự phân tán phi thường, có năm chi phí vượt trội hoặc được điều chỉnh kế toán. Bên cạnh đó cũng cho thấy cho thấy có những năm chi phí thực tế cao, nhưng cũng có những năm điều chỉnh kế toán lớn, ảnh hưởng tới biên lợi nhuận gộp.
1. format(summary(HSG[["Lợi nhuận thuần từ hoạt động kinh doanh"]]), big.mark = ".", decimal.mark = ",", scientific = FALSE)
## Min. 1st Qu. Median Mean
## " 96.130.196.549" " 366.015.397.238" " 659.530.295.552" "1.224.336.041.006"
## 3rd Qu. Max.
## "1.521.476.626.436" "4.917.382.392.261"
Nhận xét: Trong 10 năm qua, lợi nhuận thuần dao động từ khoảng 96.130.196.5496 tỷ đến 4.917.382.392.261, cho thấy biến động rất lớn giữa các năm. Giá trị trung bình khoảng 1.224.336.041.006, cao hơn giá trị trung vị 659.530.295.552, chứng tỏ dữ liệu lệch phải, tức có một vài năm lợi nhuận rất cao kéo trung bình lên. Khoảng giữa 1st Qu.366.015.397.238 và 3rd Qu.1.521.476.626.436 khá rộng, phản ánh sự phân tán đáng kể trong lợi nhuận qua các năm. Nhìn chung, HSG có khả năng tạo lợi nhuận thuần dương từ hoạt động kinh doanh, đồng thời có những năm lợi nhuận tăng mạnh, phản ánh hiệu quả kinh doanh tốt nhờ doanh thu tăng, chi phí được kiểm soát và quản lý dòng tiền hợp lý.
1. sapply(HSG,function(HSG) sum(is.na(HSG)))
## Năm
## 0
## Phải trả người bán ngắn hạn
## 0
## Chi phí phải trả ngắn hạn
## 0
## Vay và nợ thuê tài chính ngắn hạn
## 0
## Vốn cổ phần
## 0
## Lợi nhuận sau thuế chưa phân phối
## 0
## Tiền
## 0
## Các khoản tương đương tiền
## 0
## Các khoản phải thu ngắn hạn
## 0
## Tài sản cố định hữu hình
## 0
## Các khoản phải thu dài hạn
## 0
## Lưu chuyển tiền thuần từ HĐKD
## 0
## Tiền thu từ đi vay
## 0
## Doanh thu bán hàng và cung cấp dịch vụ
## 0
## Giá vốn hàng bán và cung cấp dịch vụ
## 0
## Lợi nhuận gộp về bán hàng và cung cấp dịch vụ
## 0
## Chi phí bán hàng
## 0
## Chi phí quản lý doanh nghiệp
## 0
## Lợi nhuận thuần từ hoạt động kinh doanh
## 0
Nhận xét: Kết quả kiểm tra trả về toàn bộ giá trị bằng 0, nghĩa là không có bất kỳ giá trị thiếu nào trong 19 cột dữ liệu.
Giải thích:
sapply(...): áp dụng kiểm tra cho từng cột trong bảng HSG , trả về một số cho mỗi cột.sum(is.na(HSG)): đếm tổng số giá trị bị thiếu trong mỗi cột, các giá trị thiếu được hàm is.na trả về TRUE (TRUE được tính là 1, FALSE là 0). Khi toàn bộ số lượng NA là 0, khẳng định dữ liệu đầy đủ, không có trường hợp bị trống, đảm bảo phân tích sau luôn chính xác và liền mạch.
1. HSG[duplicated(HSG),]
Nhận xét:Kết quả hiển thị là một bảng rỗng (# A tibble: 0 x 19), nghĩa là không có dòng dữ liệu nào bị trùng lặp.
Giải thích:
duplicated(HSG): kiểm tra từng dòng của bảng, trả về TRUE nếu dòng này trùng hoàn toàn với dòng phía trước.HSG[duplicated(HSG),]: lọc ra các dòng trùng, nếu bảng kết quả rỗng thì dữ liệu không bị lặp lại, tuyệt đối duy nhất.
1. scale <- function(x) {
2. if (!is.numeric(x)) {
3. message("Cột không phải dạng số. Không thể chuẩn hóa.")
4. return(NULL)}
5. if (max(x) == min(x)) {
6. message("Tất cả giá trị giống nhau. Trả về toàn 0.")
7. return(rep(0, length(x))) }
8. scaled <- (x - min(x)) / (max(x) - min(x))
9. return(scaled)}
Nhận xét:Việc chuẩn hóa giúp đưa các biến về cùng thang đo, thuận tiện khi so sánh hoặc vẽ biểu đồ. Đây là bước cần thiết trong các phân tích thống kê hoặc mô hình hóa vì nó giúp loại bỏ sự khác biệt về đơn vị đo lường giữa các biến.
Giải thích:
- Dòng số 1:scale <- function(x){ ... }: Định nghĩa một hàm tên là scale, nhận đối số là biến x (có thể là một vector). - Dòng số 2:if (!is.numeric(x)) { ... }: Kiểm tra nếu x không phải là kiểu số (numeric), thì: message(“Cot khong phai dang so. Khong the chuan hoa.”): Thông báo trên màn hình rằng cột không phải dạng số.return(NULL): Trả về giá trị rỗng, kết thúc hàm (không báo lỗi). - Dòng số 5:if (max(x) == min(x)) { ... }: Kiểm tra nếu tất cả giá trị trong x đều giống nhau (giá trị lớn nhất bằng giá trị nhỏ nhất):message("Tat ca gia tri giong nhau. Tra ve toan 0."): Thông báo trên màn hình.return(rep(0, length(x))): Trả về một vector toàn giá trị 0, độ dài bằng độ dài của x. - Dòng số 8:scaled <- (x - min(x)) / (max(x) - min(x)): Đây là công thức chuẩn hóa min-max, đưa mọi giá trị về khoảng từ 0 đến 1. Từng phần tử sẽ lấy giá trị trừ giá trị nhỏ nhất rồi chia cho hiệu số lớn nhất - nhỏ nhất - Dòng số 9:return(scaled): Trả về vector đã chuẩn hóa.
Giải thích:
1. ggplot(HSG, aes(y = HSG[["Tiền"]])) +
2. geom_boxplot(fill = "lightblue") +
3. scale_y_continuous(labels = scales::comma_format(big.mark = ".", decimal.mark = ",")) +
4. labs(title = "Boxplot Tiền ", y = "Tiền (VNĐ)") +
5. theme_minimal()
>Nhận xét: Biểu đồ boxplot thể hiện khá ổn định,
không xuất hiện điểm bất thường, cho thấy các giá trị doanh thu nằm
trong phạm vi hợp lý và không có số liệu nào quá xa trung bình. Khoảng
giữa tứ phân vị thứ nhất và tứ phân vị thứ ba khá rộng, phản ánh mức
biến động doanh thu có thể thay đổi giữa các năm. Nhìn chung, HSG duy
trì được nguồn tiền ổn định, hợp lý, cho thấy quản lý tài chính an toàn
và hiệu quả.
1. ggplot(HSG, aes(y = HSG[["Vay và nợ thuê tài chính ngắn hạn"]])) +
2. geom_boxplot(fill = "lightblue") +
3. scale_y_continuous(labels = scales::comma_format(big.mark = ".", decimal.mark = ",")) +
4. labs(title = "Boxplot Vay và nợ thuê tài chính ngắn hạn", y = "Tiền (VNĐ)") +
5. theme_minimal()
>Nhận xét: Biểu đồ boxplot có mức ổn định và tính
tập trung khá tốt, tuy nhiên xuất hiện một điểm ngoại lai phía trên, cho
thấy có một kỳ phát sinh khoản vay hoặc nợ thuê tài chính ngắn hạn cao
bất thường so với các năm còn lại. Khoảng giữa tứ phân vị thứ nhất và tứ
phân vị thứ ba tương đối rộng, phản ánh sự biến động nhất định nhưng vẫn
kiểm soát được. Nhìn chung, HSG duy trì ngưỡng vay và nợ tài chính phù
hợp, ngoại trừ một năm có số liệu đột biến, còn lại mức nợ luôn nằm
trong phạm vi an toàn và ổn định.
1. ggplot(HSG, aes(y = HSG[["Vốn cổ phần"]])) +
2. geom_boxplot(fill = "lightblue") +
3. scale_y_continuous(labels = scales::comma_format(big.mark = ".", decimal.mark = ",")) +
4. labs(title = "Boxplot Vốn cổ phần", y = "Tiền (VNĐ)") +
5. theme_minimal()
Nhận xét:Biểu đồ boxplot có phân bố khá đều, các giá trị chủ yếu tập trung trong khoảng giữa tứ phân vị thứ nhất và thứ ba, cho thấy mức vốn cổ phần ổn định qua các thời kỳ. Không xuất hiện điểm ngoại lai, phản ánh HSG duy trì nguồn vốn cổ phần ổn định, vững chắc và không có biến động đột biến về mặt vốn góp. Khoảng giữa các tứ phân vị cũng tương đối rộng, chứng tỏ doanh nghiệp vẫn chủ động trong việc điều chỉnh và bổ sung nguồn vốn khi cần thiết, đảm bảo sự linh hoạt và ổn định trong phát triển.
1. ggplot(HSG, aes(y = HSG[["Tài sản cố định hữu hình"]])) +
2. geom_boxplot(fill = "lightblue") +
3. scale_y_continuous(labels = scales::comma_format(big.mark = ".", decimal.mark = ",")) +
4. labs(title = "Boxplot Tài sản cố định hữu hình", y = "Tiền (VNĐ)") +
5. theme_minimal()
Nhận xét:Biểu đồ boxplot thể hiện dữ liệu phân bố khá rộng, với khoảng giữa tứ phân vị thứ nhất và tứ phân vị thứ ba khá lớn, phản ánh sự biến động nhất định về tài sản cố định qua các năm. Không xuất hiện điểm ngoại lai, cho thấy các giá trị đều nằm trong phạm vi hợp lý và không có sự đột biến bất thường về mặt đầu tư tài sản cố định. Nhìn chung, HSG quản lý tài sản cố định hữu hình tương đối an toàn, ổn định và linh hoạt trước yêu cầu phát triển kinh doanh.
1. ggplot(HSG, aes(y = HSG[["Lưu chuyển tiền thuần từ HĐKD"]])) +
2. geom_boxplot(fill = "lightblue") +
3. scale_y_continuous(labels = scales::comma_format(big.mark = ".", decimal.mark = ",")) +
4. labs(title = "Boxplot Lưu chuyển tiền thuần từ HĐKD", y = "Tiền (VNĐ)") +
5. theme_minimal()
Nhận xét:Biểu đồ boxplot thể hiện sự phân bố khá gần, tuy nhiên tồn tại một số điểm ngoại lai ở cả phía trên và phía dưới, phản ánh có những năm doanh nghiệp ghi nhận dòng tiền kinh doanh tăng vọt hoặc âm bất thường. Khoảng giữa tứ phân vị thứ nhất và tứ phân vị thứ ba khá hẹp, cho thấy dòng tiền thuần từ kinh doanh chủ yếu ổn định qua các năm. Nhìn chung, doanh nghiệp duy trì khả năng tạo dòng tiền dương từ hoạt động kinh doanh, chỉ có một số biến động đột xuất được phản ánh qua các điểm outlier.
1. ggplot(HSG, aes(y = HSG[["Doanh thu bán hàng và cung cấp dịch vụ"]])) +
2. geom_boxplot(fill = "lightblue") +
3. scale_y_continuous(labels = scales::comma_format(big.mark = ".", decimal.mark = ",")) +
4. labs(title = "Boxplot Doanh thu bán hàng và cung cấp dịch vụ", y = "Tiền (VNĐ)") +
5. theme_minimal()
Nhận xét:Biểu đồ boxplot cho thấy dữ liệu phân bố khá rộng, với khoảng giữa tứ phân vị thứ nhất và tứ phân vị thứ ba không quá rộng, phản ánh sự dao động doanh thu giữa các kỳ kinh doanh. Không xuất hiện điểm ngoại lai, thể hiện các mốc doanh thu nằm trong phạm vi hợp lý và không có sự đột biến bất thường. Nhìn chung, doanh nghiệp duy trì được quy mô doanh thu ổn định với biên độ dao động vừa phải, thể hiện năng lực bán hàng, cung cấp dịch vụ bền vững và triển vọng tăng trưởng tích cực.
1. ggplot(HSG, aes(y = HSG[["Giá vốn hàng bán và cung cấp dịch vụ"]])) +
2. geom_boxplot(fill = "lightblue") +
3. scale_y_continuous(labels = scales::comma_format(big.mark = ".", decimal.mark = ",")) +
4. labs(title = "Boxplot Giá vốn hàng bán và cung cấp dịch vụ", y = "Tiền (VNĐ)") +
5. theme_minimal()
Nhận xét:Biểu đồ boxplot thể hiện biến động lớn về giá vốn giữa các kỳ kinh doanh. Không xuất hiện điểm ngoại lai, cho thấy các giá trị giá vốn đều nằm trong phạm vi hợp lý, không có năm nào ghi nhận chi phí bất thường quá cao hoặc quá thấp so với mặt bằng chung. Nhìn chung, doanh nghiệp duy trì quản lý chi phí giá vốn ổn định, dù còn biến động mạnh phù hợp với quy mô doanh thu từng kỳ.
1. ggplot(HSG, aes(x = "", y = HSG[["Lợi nhuận thuần từ hoạt động kinh doanh"]])) +
2. geom_boxplot(fill = "lightblue") +
3. scale_y_continuous(labels = scales::comma_format(big.mark = ".", decimal.mark = ",")) +
4. labs(title = "Boxplot Lợi nhuận thuần từ hoạt động kinh doanh", y = "Tiền (VNĐ)") +
5. theme_minimal()
Nhận xét:Biểu đồ boxplot thể hiện dữ liệu tập trung chủ yếu ở mức dưới 2.000 tỷ đồng, với khoảng giữa tứ phân vị thứ nhất và tứ phân vị thứ ba không quá rộng, cho thấy mức lợi nhuận kinh doanh nhìn chung ổn định qua các năm. Tuy nhiên có xuất hiện một điểm ngoại lai phía trên, cho thấy một kỳ doanh nghiệp ghi nhận lợi nhuận đột biến tăng cao so với mặt bằng chung. Nhìn tổng thể, biên lợi nhuận được duy trì tốt, được kiểm soát ổn định, ngoại trừ năm đặc biệt có lợi nhuận vọt lên mạnh mẽ phản ánh sự thuận lợi bất thường hoặc phát sinh ngoại lệ kinh doanh tích cực.
1. colnames(HSG) <- c("nam","Phai tra nguoi ban ngan han","chi phi phai tra ngan han", "vay va no thue tai chinh", "von co phan", "LNSTCPP","tien","Cac khoan tuong duong tien","cac khoan phai thu ngan han","TSCD","cac khoan phai thu dai han", "luu chuyen tien thuan", "tien thu di vay","doanh thu ban hang","gia von", "loi nhuan gop","chi phi ban hang", "chi phi qly doanh nghiep", "loi nhuan thuan")
1. nam_moi <- max(HSG$nam)
2. df3 <- HSG %>% filter(nam == nam_moi) %>%
3. select(`cac khoan phai thu dai han`, tien, TSCD) %>%
4. pivot_longer(everything(), names_to = "KhoanMuc", values_to = "GiaTri") %>%
5. mutate(
6. KhoanMuc = recode(KhoanMuc, "cac khoan phai thu dai han" = "Phải thu dài hạn", "tien" = "Tiền mặt", "TSCD" = "Tài sản cố định"), TyLe = round(GiaTri / sum(GiaTri) * 100, 2))
7. names(df3) <- c("Khoản mục", "Giá trị", "Tỷ lệ (%)")
8. knitr::kable(df3, caption = "Cơ cấu tài sản năm mới nhất", align = "c")
| Khoản mục | Giá trị | Tỷ lệ (%) |
|---|---|---|
| Phải thu dài hạn | 214837184200 | 4.55 |
| Tiền mặt | 597436771510 | 12.64 |
| Tài sản cố định | 3914578436382 | 82.82 |
Nhận xết: Lấy ra những năm có giá trị 3 danh mục là lớn nhất trong mục tài sản. Ta dễ thấy, Cơ cấu tài sản của doanh nghiệp cho thấy tài sản cố định chiếm tỷ trọng áp đảo hơn 82,82%, trong khi tiền mặt chỉ chiếm khoảng 12,64% và các khoản phải thu dài hạn chiếm tỷ trọng nhỏ khoảng 4,55̀%. Điều này phản ánh phù hợp khi doanh nghiệp hoạt động trong lĩnh vực thép vì có cường độ đầu tư lớn vào tài sản cố định
Giải thích: Đoạn 2: Xác định năm mới nhất trong bảng dữ liệu bằng cách lấy giá trị lớn nhất của cột nam. Đoạn 3: Lọc dữ liệu chỉ giữ lại các dòng năm mới nhất (bằng hàm filter), Chọn riêng ba cột đại diện cho các khoản mục tài sản lớn: ‘các khoản phải thu dài hạn’, ‘tiền’, ‘tài sản cố định’. Đoạn 4: Chuyển bảng từ dạng rộng sang dạng dài bằng hàm pivot_longer – gộp ba cột thành hai cột: cột tên khoản mục và cột giá trị .
1. df2 <- HSG %>% select(nam, `vay va no thue tai chinh`, `von co phan`) %>%
2. group_by(nam) %>% summarise(`vay nợ` = sum(`vay va no thue tai chinh`, na.rm = TRUE),`vốn cổ phần` = sum(`von co phan`, na.rm = TRUE), ty_le_no_von = ifelse(sum(`von co phan`, na.rm = TRUE) == 0, NA, sum(`vay va no thue tai chinh`, na.rm = TRUE) / sum(`von co phan`, na.rm = TRUE))) %>%
3. mutate(`vay nợ` = comma(`vay nợ`, big.mark = ".", decimal.mark = ","),`vốn cổ phần` = comma(`vốn cổ phần`, big.mark = ".", decimal.mark = ","),`tỷ lệ nợ vốn` = round(ty_le_no_von, 2) )
4. knitr:::kable(df2)
| nam | vay nợ | vốn cổ phần | ty_le_no_von | tỷ lệ nợ vốn |
|---|---|---|---|---|
| 2015 | 4.400.210.324.546 | 1.007.907.900.000 | 4.3656869 | 4.37 |
| 2016 | 4.102.697.779.164 | 1.965.398.290.000 | 2.0874638 | 2.09 |
| 2017 | 7.402.317.620.460 | 3.499.966.830.000 | 2.1149679 | 2.11 |
| 2018 | 9.010.977.033.379 | 3.849.903.280.000 | 2.3405723 | 2.34 |
| 2019 | 5.706.275.512.506 | 4.234.694.890.000 | 1.3475057 | 1.35 |
| 2020 | 5.083.484.041.845 | 4.446.252.130.000 | 1.1433189 | 1.14 |
| 2021 | 4.754.513.830.764 | 4.934.818.960.000 | 0.9634627 | 0.96 |
| 2022 | 3.545.557.150.716 | 5.980.549.860.000 | 0.5928480 | 0.59 |
| 2023 | 2.936.344.523.958 | 6.159.823.090.000 | 0.4766930 | 0.48 |
| 2024 | 5.364.084.453.144 | 6.159.823.090.000 | 0.8708179 | 0.87 |
Nhận xét: Bảng số liệu cho thấy tỷ lệ nợ trên vốn của doanh nghiệp giảm mạnh qua các năm, từ mức rất cao 4,37 lần năm 2015 xuống chỉ còn 0,87 lần năm 2024. Điều này phản ánh HSG đã dần giảm phụ thuộc vào vốn vay, chuyển sang cơ cấu tài chính an toàn hơn. Việc nợ giảm và vốn chủ sở hữu tăng cho thấy doanh nghiệp đang nâng cao khả năng tự chủ tài chính, giảm rủi ro lãi vay và cải thiện sức khỏe tài chính tổng thể. Đây là dấu hiệu tích cực về mặt ổn định và bền vững trong dài hạn.
Giải thích: Đoạn 1 dùng select để lấy các biến “năm”, “vay và nợ thuê tài chính”, và “vốn cổ phần” trong bảng dữ liệu HSG. Đoạn 2, dùng group_by(nam) để nhóm dữ liệu theo từng năm ,dùng summarise để tính: Tổng vay nợ tài chính (vay nợ) bằng tổng các giá trị trong nhóm, Tổng vốn cổ phần (vốn cổ phần) bằng tổng các giá trị trong nhóm, Tỷ lệ nợ/vốn cổ phần (ty_le_no_von) bằng cách chia tổng vay nợ cho tổng vốn cổ phần từng năm. Thêm kiểm tra trường hợp vốn bằng 0 để tránh chia cho 0 ra lỗi. Đoạn 3 dùng mutate để định dạng số liệu theo kiểu Việt Nam: dấu chấm phân tách nghìn, dấu phẩy cho thập phân. Giá trị tỷ lệ nợ/vốn được làm tròn tới hai số thập phân.
1. library(scales)
2. df_group <- HSG %>% select(nam, LNSTCPP, `von co phan`) %>%
3. pivot_longer(-nam, names_to = "Chitieu", values_to = "giatri") %>%
4. mutate( Chitieu = recode(Chitieu, LNSTCPP = 'LNSTCPP', `von co phan` = 'Vốn cổ phần'), giatri_hienthi = comma(giatri, big.mark = ".", decimal.mark = ",") ) %>%
5. group_by(nam) %>% mutate(la_max = giatri == max(giatri)) %>% ungroup()
6. knitr::kable(head(df_group, 10), caption = "So sánh LNSTCPP và Vốn cổ phần theo năm", align = "c")
| nam | Chitieu | giatri | giatri_hienthi | la_max |
|---|---|---|---|---|
| 2015 | LNSTCPP | 1531127724105 | 1.531.127.724.105 | TRUE |
| 2015 | Vốn cổ phần | 1007907900000 | 1.007.907.900.000 | FALSE |
| 2016 | LNSTCPP | 1753131906267 | 1.753.131.906.267 | FALSE |
| 2016 | Vốn cổ phần | 1965398290000 | 1.965.398.290.000 | TRUE |
| 2017 | LNSTCPP | 1618854251238 | 1.618.854.251.238 | FALSE |
| 2017 | Vốn cổ phần | 3499966830000 | 3.499.966.830.000 | TRUE |
| 2018 | LNSTCPP | 1323418124868 | 1.323.418.124.868 | FALSE |
| 2018 | Vốn cổ phần | 3849903280000 | 3.849.903.280.000 | TRUE |
| 2019 | LNSTCPP | 1539503023643 | 1.539.503.023.643 | FALSE |
| 2019 | Vốn cổ phần | 4234694890000 | 4.234.694.890.000 | TRUE |
Nhận xét: dữ liệu cho thấy doanh nghiệp có cấu trúc tài chính rất vững mạnh khi vốn cổ phần tăng trưởng đều và liên tục là chỉ tiêu lớn nhất mỗi năm. LNSTCPP cũng duy trì ở mức cao, cho thấy khả năng sinh lời tốt qua các năm. Điều này phản ánh nền tảng nội lực tài chính mạnh, giúp doanh nghiệp có nhiều cơ hội mở rộng sản xuất, tăng đầu tư hoặc nâng cao sức cạnh tranh trên thị trường.
Giải thích: Đoạn 2: Lấy các cột năm, LNSTCPP, vốn cổ phần từ bảng HSG. Đoạn 3: Chuyển bảng từ dạng rộng sang dài bằng pivot_longer, nghĩa là từ mỗi năm có hai cột thành mỗi năm nhiều dòng, mỗi dòng là một chỉ tiêu và giá trị tương ứng. Đoạn 4: Chuẩn hóa tên hiển thị tiếng Việt dễ đọc hơn. Định dạng giá trị để dễ nhìn trong bảng hoặc biểu đồ với hàm comma. Đoạn 5: Nhóm theo năm rồi xác định mỗi giá trị từng năm có phải là giá trị lớn nhất của năm đó không.
1. HSG %>%
2. summarise(min_TSCD = comma(min(TSCD, na.rm = TRUE), big.mark = ".", decimal.mark = ","),max_TSCD = comma(max(TSCD, na.rm = TRUE), big.mark = ".", decimal.mark = ","), mean_TSCD = comma(round(mean(TSCD, na.rm = TRUE), 0), big.mark = ".", decimal.mark = ","),sd_TSCD = comma(round(sd(TSCD, na.rm = TRUE), 0), big.mark = ".", decimal.mark = ",") )
Nhận xét: Dữ liệu cho thấy tài sản cố định (TSCĐ) của doanh nghiệp có sự chênh lệch đáng kể giữa các thời điểm hoặc đơn vị quan sát. Giá trị tối thiểu đạt 848,7 tỷ đồng, trong khi giá trị tối đa lên đến khoảng 6.396,8 tỷ đồng, phản ánh mức độ đầu tư rất khác nhau vào tài sản cố định trong giai đoạn phân tích. Giá trị trung bình khoảng 2.470,6 tỷ đồng cho thấy doanh nghiệp duy trì mức đầu tư tương đối lớn vào cơ sở vật chất, máy móc, thiết bị sản xuất. Tuy nhiên, độ lệch chuẩn lên tới 1.868,7 tỷ đồng cũng cho thấy sự biến động mạnh về quy mô TSCĐ, có thể xuất phát từ các giai đoạn mở rộng, nâng cấp tài sản hoặc thanh lý thiết bị cũ. Mức chênh lệch này phản ánh chiến lược đầu tư linh hoạt của doanh nghiệp, song cũng đặt ra yêu cầu quản trị vốn cố định hiệu quả nhằm đảm bảo cân bằng giữa chi phí đầu tư và hiệu suất sử dụng tài sản.
Giải thích: Sử dụng toán tử pipe cho bộ dữ liệu HSG thực hiện các bước tiếp theo. Dòng 2:
summarise(): tính các thống kê cơ bản như min, max, trung bình và độ lệch chuẩn.comma(): giúp bộ dữ liệu có phân cách hàng nghìn.
1. HSG %>%filter(`von co phan` > mean(`von co phan`, na.rm = TRUE)) %>% select(nam, `von co phan`) %>% mutate(`vốn cổ phần` = comma(`von co phan`, big.mark = ".", decimal.mark = ","))
Nhận xét: có nhiều năm liên tiếp từ 2019 đến 2024 mà doanh nghiệp có mức vốn cổ phần vượt trung bình. Điều này phản ánh xu hướng tăng cường thu hút và bổ sung vốn từ cổ đông trong thời gian gần đây, giúp doanh nghiệp cải thiện tiềm lực tài chính rõ nét hơn so với các năm trước đó. Việc duy trì vốn cổ phần trên trung bình liên tục với nhiều năm cho thấy sự tin tưởng của cổ đông gia tăng, đồng thời tạo nền tảng vững chắc để công ty đầu tư, mở rộng và chống chọi tốt hơn trước biến động thị trường. . Giải thích:
filter(...): lọc các hàng có doanh thu lớn hơn trung bình.select(...): chỉ giữ cột doanh thu ban hang trong kết quả.na.rm = TRUE: bỏ qua các giá trị NA khi tính trung bình.
1. summary(HSG$`chi phi ban hang`)
## Min. 1st Qu. Median Mean 3rd Qu.
## -3344662264465 -1740161128657 -1001906532258 -680355282 2103033015892
## Max.
## 3832642500065
1. HSG$`Phân loại chi phí bán hàng` <- ifelse(HSG$`chi phi ban hang` < -1740161128657, "Chi phí thấp", ifelse( HSG$`chi phi ban hang` < 2103033015892, "Chi phí trung bình", "Chi phí cao"))
2. HSG$`Phân loại chi phí bán hàng` <- factor(HSG$`Phân loại chi phí bán hàng`,levels = c("Chi phí thấp", "Chi phí trung bình", "Chi phí cao"))
3. table(HSG$`Phân loại chi phí bán hàng`)
##
## Chi phí thấp Chi phí trung bình Chi phí cao
## 3 4 3
Nhận xét: kết quả phân loại chi phí bán hàng của doanh nghiệp cho thấy sự phân bố tương đối cân đối giữa ba nhóm chi phí: 3 trường hợp có chi phí thấp, 4 trường hợp thuộc nhóm chi phí trung bình, và 3 trường hợp có chi phí cao. Điều này phản ánh rằng mức chi tiêu cho hoạt động bán hàng của doanh nghiệp không tập trung quá lớn ở một nhóm nhất định, mà dao động linh hoạt theo từng giai đoạn kinh doanh hoặc chiến lược thị trường.Cấu trúc phân bổ này cho thấy doanh nghiệp có sự linh hoạt trong chiến lược chi tiêu, biết cân đối giữa hiệu quả kinh doanh và khả năng tài chính, qua đó góp phần ổn định lợi nhuận và duy trì sức cạnh tranh trên thị trường.
Giải thích: Đoạn 1 dùng hàm summary để thống kê và có được tứ phân vị một và ba. Đoạn2 dùng hàm if để xác định và phân loại chi phí bán hàng.Đoạn 3 là chuẩn hóa biến phân loại băng factor.
1. q <- quantile(HSG$`doanh thu ban hang`, probs = c(0.25, 0.5, 0.75), na.rm = TRUE)
2. HSG <- HSG %>% mutate( `nhom doanh thu` = case_when( `doanh thu ban hang` <= q[1] ~ "Doanh thu yếu", `doanh thu ban hang` <= q[2] ~ "Doanh thu trung bình", `doanh thu ban hang` <= q[3] ~ "Doanh thu khá", TRUE ~ "Doanh thu cao" ), `nhom doanh thu` = factor(`nhom doanh thu`, levels = c( "Doanh thu cao", "Doanh thu khá", "Doanh thu trung bình", "Doanh thu yếu")) )
3. HSG_quartile <- HSG %>% group_by(`nhom doanh thu`) %>% summarise( total_loi_nhuan = sum(`loi nhuan thuan`, na.rm = TRUE), so_luong = n(), .groups = "drop" ) %>%
4. mutate( `tong loi nhuan` = scales::comma(total_loi_nhuan, big.mark = ".", decimal.mark = ","), percentage = total_loi_nhuan / sum(total_loi_nhuan) * 100, label = paste0(`nhom doanh thu`, "\n", round(percentage, 1), "%"))
5. names(HSG_quartile) <- c("Nhóm doanh thu", "Tổng lợi nhuận", "Số lượng", "Hiển thị lợi nhuận", "Tỷ lệ (%)", "Nhãn")
6. knitr::kable(HSG_quartile, caption = "Phân nhóm tổng lợi nhuận theo doanh thu", align = "c")
| Nhóm doanh thu | Tổng lợi nhuận | Số lượng | Hiển thị lợi nhuận | Tỷ lệ (%) | Nhãn |
|---|---|---|---|---|---|
| Doanh thu cao | 5757751051574 | 3 | 5.757.751.051.574 | 47.027539 | Doanh thu cao |
| 47% | |||||
| Doanh thu khá | 570927366406 | 2 | 570.927.366.406 | 4.663159 | Doanh thu khá |
| 4.7% | |||||
| Doanh thu trung bình | 1618494453964 | 2 | 1.618.494.453.964 | 13.219365 | Doanh thu trung bình |
| 13.2% | |||||
| Doanh thu yếu | 4296187538111 | 3 | 4.296.187.538.111 | 35.089938 | Doanh thu yếu |
| 35.1% |
Nhận xét:Bảng dữ liệu cho thấy nhóm doanh thu cao đem lại tổng lợi nhuận lớn nhất, chiếm hơn 47% toàn bộ lợi nhuận, kế tiếp là doanh thu yếu (35%) và doanh thu trung bình (13%), còn doanh thu khá đóng góp còn khá nhỏ (4.6%). Điều này phản ánh doanh nghiệp phụ thuộc chủ yếu vào những phân khúc thị trường đem lại doanh thu vượt trội, trong khi các nhóm còn lại tuy số lượng lớn nhưng hiệu quả sinh lời chưa cao. Doanh nghiệp cần đẩy mạnh cải thiện hiệu quả ở nhóm doanh thu trung bình và khá nhằm đa dạng hóa rủi ro, không bị chi phối bởi một nhóm doanh thu lớn duy nhất.
Giải thích: Đoạn 1 dùng hàm quantile() với tham số probs = c(0.25, 0.5, 0.75) để lấy giá trị ngưỡng cho ba phần tư: 25% , 50% , 75% của cột doanh thu bán hàng. Đoạn 2: sử dụng mutate và case_when() để gán nhãn nhóm doanh thu cho từng dòng: Nếu doanh thu nhỏ hơn hoặc bằng Q1: “Doanh thu yếu”. Từ Q1 đến Q2: “Doanh thu trung bình”. Từ Q2 đến Q3: “Doanh thu khá”. Lớn hơn Q3: “Doanh thu cao”. Đoạn 3 nhóm dữ liệu theo loại doanh thu vừa gán; tính tổng lợi nhuận thuần , số lượng dòng từng nhóm , và định dạng giá trị lợi nhuận cho dễ đọc. Đoạn 4: tính tỷ lệ phần trăm đóng góp của từng nhóm vào tổng lợi nhuận (percentage) để thấy nhóm nào mang lại lợi nhuận lớn nhất.Tạo thêm cột nhãn thuận tiện cho trực quan hóa, bao gồm tên nhóm doanh thu và phần trăm đóng góp.
1. HSG %>% summarise( min_VCP = comma(min(`von co phan`, na.rm = TRUE), big.mark = ".", decimal.mark = ","), max_VCP = comma(max(`von co phan`, na.rm = TRUE), big.mark = ".", decimal.mark = ","), mean_VCP = comma(round(mean(`von co phan`, na.rm = TRUE), 0), big.mark = ".", decimal.mark = ","), sd_VCP = comma(round(sd(`von co phan`, na.rm = TRUE), 0), big.mark = ".", decimal.mark = ",") ) %>%
2. kable(caption = "Thống kê vốn cổ phần", align = 'c')
| min_VCP | max_VCP | mean_VCP | sd_VCP |
|---|---|---|---|
| 1.007.907.900.000 | 6.159.823.090.000 | 4.223.913.832.000 | 1.739.852.032.633 |
Nhận xét: Trong giai đoạn phân tích, vốn cổ phần của doanh nghiệp dao động lớn: giá trị nhỏ nhất đạt khoảng 1.008 tỷ, giá trị cao nhất lên đến hơn 6.160 tỷ. Giá trị trung bình là 4.224 tỷ và độ lệch chuẩn gần 1.740 tỷ cho thấy sự biến động mạnh theo từng năm. Mức tăng trưởng vốn cổ phần không đều, có những năm vốn tăng vọt hẳn so với mặt bằng chung, phản ánh được các đợt tăng vốn hoặc gọi vốn mới của doanh nghiệp. Độ lệch chuẩn cao cho thấy cơ cấu vốn thay đổi đáng kể qua các năm, cần theo dõi kỹ về hiệu quả sử dụng vốn góp và sự tin tưởng của cổ đông đối với doanh nghiệp.
Giải thích: Sử dụng toán tử pipe cho bộ dữ liệu HSG thực hiện các bước tiếp theo.
summarise(): tính các thống kê cơ bản như min, max, trung bình và độ lệch chuẩn.comma(): giúp bộ dữ liệu có phân cách hàng nghìn.
1. HSG_growth <- HSG %>%arrange(nam) %>%mutate(across(where(is.numeric),~ (.x / lag(.x) - 1) * 100, .names = "growth_{.col}"))
2. HSG_growth %>%select(nam, `growth_gia von`, `growth_doanh thu ban hang`, `growth_loi nhuan thuan`) %>% mutate( across( where(is.numeric), ~ comma(., big.mark = ",", decimal.mark = ".") ))
Nhận xét: tính tốc độ phát triển của năm này so với năm trước, tại năm 2015 không có năm trước nên trả về NA. Tại năm 2016, tốc dộ phát triển giá vốn là -7.747 tức là giảm 7% so với năm trước đó. Tương tự là doanh thu là 3.07, tức là hơn 3.07% so với năm trước đó. Việc này đánh giá được tỷ trọng tăng giảm của từng danh mục để HSG sẽ có những điều chỉnh phù hợp
Giải thích: Đoạn 1: Sắp xếp lại dữ liệu theo năm, rồi tính tỷ lệ tăng trưởng từng cột số (“growth”) với hàm mutate(across(…)). Công thức tăng trưởng là: so sánh từng giá trị với giá trị năm trước bằng (.x / lag(.x) - 1) * 100, cho ra phần trăm thay đổi qua mỗi năm. Cách dùng lag này đúng chuẩn cho phân tích tăng trưởng qua chuỗi thời gian với dplyr, tương tự như giải pháp công khai trên Stack Overflow và Posit Community. Đoạn 2: Trích ra các cột năm và cột tăng trưởng chính (giá vốn, doanh thu, lợi nhuận), rồi dùng hàm comma() để định dạng kết quả theo kiểu số tiếng Việt (dấu phẩy là thập phân, dấu chấm là ngăn cách nghìn), giúp trình bày bảng số rõ ràng trong báo cáo.
1. HSG %>%
2. mutate( total_assets = `tien` + `Cac khoan tuong duong tien` + `cac khoan phai thu dai han` + `cac khoan phai thu ngan han` + `TSCD` ) %>%
3. group_by(nam) %>%summarise( pct_tien = round(sum(`tien`, na.rm = TRUE) / sum(total_assets, na.rm = TRUE) * 100, 2), pct_TSCD = round(sum(`TSCD`, na.rm = TRUE) / sum(total_assets, na.rm = TRUE) * 100, 2) ) %>%
4. rename( "Tỷ trọng Tiền (%)" = pct_tien, "Tỷ trọng TSCD (%)" = pct_TSCD ) %>%
5. kable(caption = "Tỷ trọng Tiền & Tài sản cố định theo năm", align = 'c')
| nam | Tỷ trọng Tiền (%) | Tỷ trọng TSCD (%) |
|---|---|---|
| 2015 | 6.20 | 76.30 |
| 2016 | 3.43 | 75.10 |
| 2017 | 10.09 | 70.20 |
| 2018 | 1.73 | 16.09 |
| 2019 | 3.12 | 20.24 |
| 2020 | 5.83 | 13.95 |
| 2021 | 3.02 | 6.98 |
| 2022 | 2.47 | 10.34 |
| 2023 | 5.06 | 8.58 |
| 2024 | 7.74 | 50.73 |
Nhận xét: Bảng số liệu cho thấy tỷ trọng tiền mặt trong tổng tài sản của doanh nghiệp biến động mạnh qua các năm, có thời điểm tăng vọt 2017 đạt 10,09% rồi giảm sâu, đến các năm 2022-2023 lại duy trì ở mức thấp 2,47% - 5,06%, nhưng năm 2024 tăng lại lên 7,74%. Ngược lại, tỷ trọng tài sản cố định chiếm ưu thế tuyệt đối các năm đầu nhưng sau năm 2018 giảm nhanh, còn năm 2024 chỉ còn 50,73%, giảm so với giai đoạn trước. Điều này phản ánh doanh nghiệp tích cực chuyển dịch cơ cấu tài sản, giảm phụ thuộc vào TSCD và tăng tỷ trọng tiền mặt nhằm đảm bảo khả năng thanh khoản, linh hoạt hơn với rủi ro thị trường.
Giải thích: HSG %>% để dùng pipe để truyền dữ liệu HSG vào các bước tiếp theo.
group_by(nam):ngom dữ liệu theo cột nam (theo từng năm).summarise(...):tính tổng các chỉ tiêu trong từng danh mục trong tài sản chia cho tổng tài sản và bỏ giá trị NA, sau đó nhân 100 để chuyển sang phần trăm.
1. avg_data <- HSG %>%group_by(nam) %>%
2. summarise(avg_tienmat = mean(tien, na.rm = TRUE), avg_tuongduongtien = mean(`Cac khoan tuong duong tien`, na.rm = TRUE) ) %>%
3. pivot_longer(cols = c(avg_tienmat, avg_tuongduongtien), names_to = "Chỉ_tiêu", values_to = "Giá_trị" ) %>%
4. mutate( Gia_tri_hienthi = comma(Giá_trị, big.mark = ".", decimal.mark = ","))
5. knitr::kable(avg_data)
| nam | Chỉ_tiêu | Giá_trị | Gia_tri_hienthi |
|---|---|---|---|
| 2015 | avg_tienmat | 276553474303 | 276.553.474.303 |
| 2015 | avg_tuongduongtien | 140000000 | 140.000.000 |
| 2016 | avg_tienmat | 292227797476 | 292.227.797.476 |
| 2016 | avg_tuongduongtien | 143521875 | 143.521.875 |
| 2017 | avg_tienmat | 576477183208 | 576.477.183.208 |
| 2017 | avg_tuongduongtien | 143521875 | 143.521.875 |
| 2018 | avg_tienmat | 171516367114 | 171.516.367.114 |
| 2018 | avg_tuongduongtien | 143521875 | 143.521.875 |
| 2019 | avg_tienmat | 222120606665 | 222.120.606.665 |
| 2019 | avg_tuongduongtien | 143521875 | 143.521.875 |
| 2020 | avg_tienmat | 479446944895 | 479.446.944.895 |
| 2020 | avg_tuongduongtien | 750000000 | 750.000.000 |
| 2021 | avg_tienmat | 405267139417 | 405.267.139.417 |
| 2021 | avg_tuongduongtien | 750000000 | 750.000.000 |
| 2022 | avg_tienmat | 242065476591 | 242.065.476.591 |
| 2022 | avg_tuongduongtien | 750000000 | 750.000.000 |
| 2023 | avg_tienmat | 500636999566 | 500.636.999.566 |
| 2023 | avg_tuongduongtien | 750000000 | 750.000.000 |
| 2024 | avg_tienmat | 597436771510 | 597.436.771.510 |
| 2024 | avg_tuongduongtien | 4635027767 | 4.635.027.767 |
Nhận xét: Bảng số liệu cho thấy giá trị tiền mặt của doanh nghiệp trong các năm đều tăng trưởng đáng kể, từ 276 tỷ năm 2015 lên hơn 576 tỷ vào 2017. Tuy nhiên, giá trị tương đương tiền không tăng mà lại giảm dần, từ 140 tỷ năm 2015 xuống chỉ còn 143 tỷ trong giai đoạn 2016-2017. Điều này phản ánh doanh nghiệp ưu tiên duy trì tính thanh khoản bằng tiền mặt thực so với các khoản đầu tư ngắn hạn tương đương tiền, giúp đảm bảo tốt khả năng thanh toán, ứng phó rủi ro thanh khoản trong bối cảnh biến động thị trường.
Giải thích: Dòng 1-2 tạo bảng dữ liệu trung gian avg_data từ bảng HSG. Dữ liệu được nhóm theo năm (group_by(nam)), sau đó tóm tắt hai chỉ tiêu quan trọng là tiền mặt và các khoản tương đương tiền, bằng cách tính giá trị trung bình cho mỗi nhóm năm (summarise(avg_tienmat = mean(tien, na.rm = TRUE), avg_tuongduongtien = mean(Cac khoan tuong duong tien, na.rm = TRUE))). Đoạn 2-3: Sử dụng pivot_longer để chuyển dữ liệu từ dạng rộng sang dài.
1. ty_suat <- HSG %>% mutate(`Tỷ suất lợi nhuận gộp (%)` = round(`loi nhuan gop` / `doanh thu ban hang` * 100, 2), `Tỷ suất lợi nhuận thuần (%)` = round(`loi nhuan thuan` / `doanh thu ban hang` * 100, 2) ) %>%
2. mutate( `Tỷ suất lợi nhuận gộp (%)` = number(`Tỷ suất lợi nhuận gộp (%)`, decimal.mark = ".",big.mark = ","),
3. `Tỷ suất lợi nhuận thuần (%)` = number(`Tỷ suất lợi nhuận thuần (%)`,decimal.mark = ".", big.mark = ",")) %>%
4. select(nam, `Tỷ suất lợi nhuận gộp (%)`, `Tỷ suất lợi nhuận thuần (%)`)
5. knitr::kable(ty_suat, caption = "Tỷ suất lợi nhuận theo năm", align = 'c')
| nam | Tỷ suất lợi nhuận gộp (%) | Tỷ suất lợi nhuận thuần (%) |
|---|---|---|
| 2015 | 14.75 | 4.63 |
| 2016 | 23.19 | 10.66 |
| 2017 | 16.78 | 5.96 |
| 2018 | 11.50 | 1.37 |
| 2019 | 11.39 | 0.85 |
| 2020 | 16.67 | 4.97 |
| 2021 | 18.11 | 10.04 |
| 2022 | 9.86 | 0.66 |
| 2023 | 9.54 | 0.30 |
| 2024 | 10.69 | 1.28 |
Nhận xét: Bảng số liệu cho thấy tỷ suất lợi nhuận gộp và lợi nhuận thuần của doanh nghiệp biến động khá mạnh qua các năm, cao nhất vào năm 2016 là lợi nhuận gộp 23,19%, lợi nhuận thuần 10,66%, sau đó giảm mạnh các năm 2018-2019, đặc biệt tỷ suất lợi nhuận thuần năm 2019 chỉ còn 0,85%. Những năm gần đây, tỷ suất lợi nhuận gộp và thuần đều phục hồi về mức khá tốt, lần lượt đạt 16,67% và 4,97%. Điều này cho thấy doanh nghiệp có khả năng cải thiện hiệu quả hoạt động, nhưng cần tiếp tục kiểm soát chi phí và nâng cao biên lợi nhuận bền vững hơn trong thời gian tới.
Giải thích:Dòng 1: Sử dụng mutate để tính hai chỉ số tỷ suất lợi nhuận. Dòng 2: Định dạng lại kết quả vừa tính bằng hàm number(…) để tất cả giá trị tỷ suất đều có dấu chấm ngăn cách phần thập phân và dấu phẩy phân cách hàng nghìn. Dòng 3: Lọc lại bảng chỉ giữ các cột chính: năm, tỷ suất lợi nhuận gộp, tỷ suất lợi nhuận thuần để sẵn sàng xuất hoặc trình bày, rồi dùng head xem nhanh kết quả vừa xử lý.
1. ty_le_cp <- HSG %>%
2. mutate(`Tỷ lệ chi phí bán hàng (%)` = round(`chi phi ban hang` / `doanh thu ban hang` * 100, 2),
3. `Tỷ lệ chi phí quản lý DN (%)` = round(`chi phi qly doanh nghiep` / `doanh thu ban hang` * 100, 2) ) %>%
4. mutate( `Tỷ lệ chi phí bán hàng (%)` = number(`Tỷ lệ chi phí bán hàng (%)`, decimal.mark = ".", big.mark = ","), `Tỷ lệ chi phí quản lý DN (%)` = number(`Tỷ lệ chi phí quản lý DN (%)`,decimal.mark = ".", big.mark = ",") ) %>%
5. select(nam, `Tỷ lệ chi phí bán hàng (%)`, `Tỷ lệ chi phí quản lý DN (%)`)
6. knitr::kable(head(ty_le_cp, 6), caption = "Tỷ lệ chi phí bán hàng & quản lý theo năm", align = "c")
| nam | Tỷ lệ chi phí bán hàng (%) | Tỷ lệ chi phí quản lý DN (%) |
|---|---|---|
| 2015 | -4.95 | -2.93 |
| 2016 | -6.33 | -5.00 |
| 2017 | -5.74 | -3.04 |
| 2018 | -5.25 | -2.59 |
| 2019 | 6.23 | 1.68 |
| 2020 | 8.00 | 1.66 |
Nhận xét: Bảng số liệu cho thấy tỷ lệ chi phí bán hàng và chi phí quản lý doanh nghiệp trên doanh thu đều âm khá sâu giai đoạn 2015-2018. Tuy nhiên từ 2019 trở đi, hai tỷ lệ này đảo chiều dương và tăng vọt: năm 2020, tỷ lệ chi phí bán hàng và quản lý lần lượt lên 8% và 1,66%. Điều này phản ánh doanh nghiệp đã gia tăng đầu tư cho bán hàng, quản lý, có thể nhằm thúc đẩy doanh thu hoặc tái cấu trúc vận hành, nhưng cần kiểm soát tốt để không ảnh hưởng tiêu cực đến hiệu quả lợi nhuận sau này.
Giải thích:Dòng 1: Tạo ra một bảng mới tên ty_le_cp bằng cách thao tác trên bảng dữ liệu HSG. Dòng 2–3: Sử dụng mutate để thêm hai cột mới vào bảng. Dòng 5: Dùng thêm một mutate nữa để định dạng lại hai cột vừa tạo. Dòng 6: Giữ lại ba cột chính: năm, tỷ lệ chi phí bán hàng, tỷ lệ chi phí quản lý doanh nghiệp để phục vụ cho bước xem nhanh hoặc xuất dữ liệu.
1. HSG %>% mutate(`ROA (%)` = round(`LNSTCPP` / (tien + `Cac khoan tuong duong tien` + `cac khoan phai thu ngan han` + TSCD + `cac khoan phai thu dai han`) * 100, 2), `ROA (%) (định dạng)` = scales::comma(`ROA (%)`, big.mark = ".", decimal.mark = ",")) %>%
2. select(nam, `ROA (%) (định dạng)`)
1. knitr::kable(head(ty_le_cp, 6), caption = "Tỷ lệ chi phí bán hàng & quản lý theo năm", align = "c")
| nam | Tỷ lệ chi phí bán hàng (%) | Tỷ lệ chi phí quản lý DN (%) |
|---|---|---|
| 2015 | -4.95 | -2.93 |
| 2016 | -6.33 | -5.00 |
| 2017 | -5.74 | -3.04 |
| 2018 | -5.25 | -2.59 |
| 2019 | 6.23 | 1.68 |
| 2020 | 8.00 | 1.66 |
Nhận xét: Bảng số liệu cho thấy ROA của doanh nghiệp biến động mạnh nhiều năm liên tiếp: sau khi giảm từ 34,33% năm 2015 xuống 13,38% năm 2018, doanh nghiệp phục hồi rất mạnh, ROA thăng lên 21,61% từ 2019 và đạt mức rất cao ở các năm 2022-2024. Đây là dấu hiệu tích cực cho thấy hiệu quả sử dụng tài sản được cải thiện mạnh, doanh nghiệp đã chuyển hóa tốt tài sản thành lợi nhuận. Để duy trì mức ROA lý tưởng này, doanh nghiệp cần tiếp tục kiểm soát tài sản, nâng cao hiệu quả đầu tư và vận hành tài sản dài hạn.
Giải thích: mutate() tạo ra hai biến mới: ROA (%): Được tính bằng LNSTCPP và tổng tài sản, rồi nhân với 100 để ra tỷ lệ phần trăm. Hàm round(…, 2) làm tròn kết quả đến 2 chữ số sau dấu phẩy. ROA (%) (định dạng): Dùng hàm scales::comma() để có dấu chấm là dấu ngăn cách phần nghìn (big.mark = “.”), dấu phẩy là dấu thập phân (decimal.mark = “,”). select(nam, ROA (%) (định dạng)): Chỉ giữ lại hai cột: năm và ROA đã được trình bày đẹp cho kết quả cuối cùng.
1. library(dplyr)
2. HSG %>% mutate(`Tỷ lệ chi phí bán hàng (%)` = round(`chi phi ban hang` / `doanh thu ban hang` * 100, 2)) %>%
3. filter(`Tỷ lệ chi phí bán hàng (%)` > 20) %>%
4. select(nam, `doanh thu ban hang`, `chi phi ban hang`, `Tỷ lệ chi phí bán hàng (%)`)
Nhận xét: Không có chi phí hay doanh thu vượt ngưỡng. Chứng minh năng lực quản trị chi phí bán hàng của doanh nghiệp ở mức tốt, hiệu quả sử dụng chi phí bán hàng cao và ít gây áp lực lên lợi nhuận. Doanh nghiệp duy trì mức chi phí bán hàng hợp lý giúp tối ưu hóa lợi nhuận, tăng sức cạnh tranh trên thị trường và đảm bảo hiệu quả kinh doanh ổn định, ngay cả trong giai đoạn mở rộng hoặc chịu biến động vĩ mô. Đây là điểm mạnh cần được duy trì trong chiến lược phát triển dài hạn của doanh nghiệp.
Giải thích:Dòng 2: Dùng hàm mutate để tạo thêm một cột mới gọi là “Tỷ lệ chi phí bán hàng (%)” cho mỗi dòng dữ liệu. Dòng 3: Dùng filter giữ lại các dòng mà tỷ lệ chi phí bán hàng lớn hơn 20. Dòng 4: Chọn ra 4 cột cần xem và tỷ lệ chi phí bán hàng vừa tính.
1. HSG %>%
2. mutate(`ROE (%)` = round(`loi nhuan thuan` / `von co phan` * 100, 2)) %>%
3. mutate(`Hiệu quả sử dụng vốn` = case_when( `ROE (%)` > 20 ~ "Xuất sắc",`ROE (%)` > 10 ~ "Khá", `ROE (%)` > 5 ~ "Trung bình", TRUE ~ "Yếu" )) %>%
4. select(nam, `ROE (%)`, `Hiệu quả sử dụng vốn`) %>%rename(`Năm` = nam)
Nhận xét: Bảng số liệu cho thấy hiệu quả sử dụng vốn: ROE tỷ suất lợi nhuận trên vốn chủ sở hữu của doanh nghiệp giai đoạn 2015-2017 và năm 2020-2021 rất xuất sắc, duy trì ROE trên 30%, thậm chí năm 2021 đạt xấp xỉ 100%. Tuy nhiên, ROE giảm mạnh trong các năm 2018-2019 chỉ còn mức trung bình, và đặc biệt các năm 2022-2023 chạm mức thấp nhất, cho thấy hiệu quả sử dụng vốn sụt giảm rõ rệt. Đến năm 2024, ROE phục hồi dần nhưng vẫn chỉ đạt mức trung bình; doanh nghiệp có thể cần xem xét lại chiến lược tái đầu tư, sử dụng vốn chủ sở hữu và đẩy mạnh sáng tạo tăng trưởng để nâng cao hiệu suất sinh lời từ nguồn vốn.
Giải thích: ạo cột “ROE (%)” bằng cách lấy lợi nhuận thuần chia cho vốn cổ phần rồi chuyển thành phần trăm. Dựa vào giá trị ROE từng năm, code gán nhãn hiệu quả cho các nhóm. Chỉ giữ lại ba cột: Năm, ROE (%) và nhóm hiệu quả để tiện xuất ra hoặc xem xét dữ liệu. Đổi tên cột ‘nam’ thành ‘Năm’ nhằm dễ đọc trên báo cáo.
1. HSG %>%
2. mutate(`Nhóm vay nợ` = cut(`vay va no thue tai chinh`,breaks = quantile(`vay va no thue tai chinh`, probs = 0:3/3, na.rm = TRUE), labels = c("Nhỏ", "Vừa", "Lớn"), include.lowest = TRUE) ) %>%
3. group_by(nam, `Nhóm vay nợ`) %>%
4. summarise( `Tổng LC Tiền thuần` = sum(`luu chuyen tien thuan`, na.rm = TRUE), .groups = "drop") %>%
5. rename(`Năm` = nam) %>%
6. mutate(`Tổng LC Tiền thuần` = number(`Tổng LC Tiền thuần`, decimal.mark = ".", big.mark = ",") )
Nhận xét: khi nhóm vay nợ lớn (năm 2017), dòng tiền thuần âm mạnh, phản ánh rủi ro quá tải tài chính, chi phí lãi vay cao hoặc đầu tư vượt khả năng tạo dòng tiền ngắn hạn. Giai đoạn 2019 trở đi, dù xuất hiện những năm dòng tiền thuần âm hoặc dương xen kẽ, nhưng các năm có nhóm vay nợ vừa hoặc nhỏ lại có kết quả tốt hơn, cho thấy doanh nghiệp nên ưu tiên kiểm soát quy mô vay nợ ở mức vừa phải, tránh tăng trưởng nóng bằng vốn vay lớn để bảo vệ dòng tiền hoạt động bền vững.
Giải thích: Dòng 2: Dùng hàm cut để chia giá trị vay nợ thuê tài chính thành ba nhóm: ‘Nhỏ’, ‘Vừa’ và ‘Lớn’. Dòng 3: Dùng group_by(nam, Nhóm vay nợ) để gom từng dòng theo cả năm và nhóm độ lớn của vay nợ.Dòng 4: Dùng summarise để lấy tổng của cột lưu chuyển tiền thuần (“luu chuyen tien thuan”) với sum(…, na.rm=TRUE) trong từng nhóm và năm. .
1. HSG %>% mutate(z_loi_nhuan = scale(`loi nhuan thuan`), z_doanh_thu = scale(`doanh thu ban hang`), z_tscd = scale(TSCD), z_score = z_loi_nhuan + z_doanh_thu + z_tscd ) %>%
2. arrange(desc(z_score)) %>% select(nam, `loi nhuan thuan`, `doanh thu ban hang`, TSCD, z_score) %>%
3. head(5) %>%
4. mutate(across(c(`loi nhuan thuan`, `doanh thu ban hang`, TSCD), ~scales::number(.x, decimal.mark=".", big.mark=","))) %>%
5. rename( `Năm` = nam,`Lợi nhuận thuần` = `loi nhuan thuan`,`Doanh thu bán hàng` = `doanh thu ban hang`)
Nhận xét: Doanh nghiệp có các năm 2021, 2016, 2024, 2017, 2022 với z_score đều lớn hơn 1, chứng tỏ khả năng thanh toán và tiềm lực tài chính an toàn. Đây là tín hiệu tích cực về sức mạnh tài chính và triển vọng phát triển ổn định của doanh nghiệp.
1. q <- quantile(HSG$`vay va no thue tai chinh`, probs=c(0, 1/3, 2/3, 1), na.rm=TRUE)
2. HSG$`Phân loại nợ vay & thuê TC` <- cut(HSG$`vay va no thue tai chinh`, breaks = q, include.lowest = TRUE,labels = c("Nợ thấp", "Nợ trung bình", "Nợ cao"))
3. HSG$`Phân loại nợ vay & thuê TC` <- factor( HSG$`Phân loại nợ vay & thuê TC`, levels = c("Nợ thấp", "Nợ trung bình", "Nợ cao"))
4. table(HSG$`Phân loại nợ vay & thuê TC`)
##
## Nợ thấp Nợ trung bình Nợ cao
## 4 3 3
Nhận xét: Dữ liệu cho thấy doanh nghiệp có 4 năm nợ thấp, 3 năm nợ trung bình và 3 năm nợ cao. Phân nhóm này giúp đánh giá rủi ro và cơ cấu tài chính, cho thấy doanh nghiệp giữ được tỷ lệ nợ trung bình - thấp chủ yếu trong chu kỳ hoạt động, hạn chế áp lực tài chính vượt ngưỡng an toàn.
Giải thích:Đoạn 1: Tính các ngưỡng phân loại cho khoản ‘vay và nợ thuê tài chính’ thành ba nhóm. Đoạn 2: Sử dụng hàm cut() để gán mỗi giá trị ‘vay và nợ thuê tài chính’ cho một nhóm: “Nợ thấp”, “Nợ trung bình”, hoặc “Nợ cao”, dựa trên các ngưỡng vừa tính ở Đoạn 1. Đoạn 3: Chuyển cột phân loại về kiểu dữ liệu factor và sắp xếp thứ tự các nhóm theo mong muốn (“Nợ thấp”, “Nợ trung bình”, “Nợ cao”).
1. HSG %>% filter(`Phân loại nợ vay & thuê TC` == "Nợ cao") %>%
2. arrange(desc(`luu chuyen tien thuan`)) %>%
3. select(nam, `luu chuyen tien thuan`) %>%head(3) %>%
4. mutate(`luu chuyen tien thuan` = scales::number(`luu chuyen tien thuan`, decimal.mark=".", big.mark=",")) %>%
5. rename(`Năm` = nam)
Nhận xét: Trong 3 năm từ 2017 đến 2019, dòng tiền thuần của doanh nghiệp biến động mạnh: năm 2017 âm lớn do chi ra đầu tư hoặc trả nợ nhiều, 2018 phục hồi dương nhẹ, còn 2019 tăng bứt phá mạnh mẽ đạt trên 5.181 tỷ đồng. Điều này cho thấy doanh nghiệp có khả năng xoay chuyển dòng tiền tốt nhưng cần duy trì ổn định dòng tiền dương để giảm rủi ro tài chính.
Giải thích Đoạn 1: Lọc ra các dòng thuộc nhóm “Nợ cao” theo cột phân loại nợ vay và thuê tài chính đã chuẩn bị từ bước trước. Chỉ những dòng có giá trị nợ lớn nhất mới được giữ lại. Đoạn 2: Sắp xếp các dòng kết quả giảm dần theo giá trị lưu chuyển tiền thuần. Đoạn 3: Chỉ giữ lại hai cột chính: năm và lưu chuyển tiền thuần. Lấy ra ba dòng đầu tiên sau khi đã lọc và sắp xếp – tức là top 3 năm có lưu chuyển tiền thuần cao nhất trong nhóm nợ cao.
1. long_df <- HSG %>%
2. select(`Năm` = nam, `Lợi nhuận sau thuế chưa phân phối` = LNSTCPP, `Vốn cổ phần` = `von co phan`) %>%
3. pivot_longer( cols = c(`Lợi nhuận sau thuế chưa phân phối`, `Vốn cổ phần`), names_to = "Chỉ tiêu", values_to = "Giá trị" )
4. max_val <- max(long_df$`Giá trị`, na.rm = TRUE)
5. ggplot(long_df, aes(x = factor(`Năm`), y = `Giá trị`, fill = `Chỉ tiêu`)) +
6. geom_col(position = position_dodge(width = 0.8), width = 0.7, alpha = 0.9) +
7. geom_text(
8. aes( label = comma(`Giá trị`, big.mark = ".", decimal.mark = ","), y = `Giá trị` + max_val * 0.04 ), position = position_dodge(width = 0.8), hjust = 0, size = 3, color = "black", fontface = "bold" ) +
9. labs( title = "So sánh Lợi nhuận sau thuế chưa phân phối và Vốn cổ phần", x = "Năm", y = "Giá trị (VNĐ)",fill = "Chỉ tiêu" ) +
10. scale_y_continuous(labels = comma_format(big.mark = ".", decimal.mark = ","),limits = c(0, max_val * 1.15) ) +
11. coord_flip(clip = "off") +
12. theme_minimal(base_size = 13) +
13. theme( plot.title = element_text(face = "bold", size = 15), legend.position = "bottom", axis.text.y = element_text(size = 11), plot.margin = margin(10, 40, 10, 10) )
Nhận xét:Biểu đồ cho thấy lợi nhuận sau thuế chưa phân phối của HSG tăng dần qua các năm, đặc biệt từ năm 2020 trở đi, song song với sự gia tăng của vốn cổ phần. Điều này cho thấy doanh nghiệp đang hoạt động hiệu quả hơn, tích lũy được nhiều lợi nhuận giữ lại để tái đầu tư thay vì phải tăng vốn thông qua phát hành cổ phiếu mới. Tỷ trọng lợi nhuận giữ lại ngày càng lớn phản ánh khả năng sinh lời và tự chủ tài chính của HSG được cải thiện rõ rệt, góp phần củng cố nền tảng tài chính vững chắc cho các giai đoạn tăng trưởng tiếp theo.
Giải thích:Đoạn 1–3: Tạo bảng dữ liệu long_df bằng các rút trích các cột liên quan: năm, lợi nhuận sau thuế chưa phân phối, vốn cổ phần. Dùng pivot_longer chuyển từ dạng rộng sang dài: mỗi dòng là một chỉ tiêu với cột giá trị mới. Đoạn 4: Tìm giá trị lớn nhất trong cột ‘Giá trị’ để phục vụ cho việc đặt nhãn và giới hạn trục trong biểu đồ. Đoạn 5–13: Vẽ biểu đồ cột so sánh bằng ggplot2: Trục ngang là năm, trục dọc là giá trị từng chỉ tiêu, tách thành nhóm với màu fill khác biệt. geom_col vẽ cột, geom_text hiện nhãn giá trị phân cách hàng nghìn. Đặt tiêu đề, nhãn tên trục, tên nhóm fill, định dạng số liệu và giới hạn trục y rõ ràng. Dùng coord_flip để cột nằm ngang. Tuỳ chỉnh theme, cỡ chữ, margin, vị trí legend giúp biểu đồ dễ nhìn và chuyên nghiệp.
1. ggplot(HSG, aes(x = nam, y = `doanh thu ban hang`)) +
2. geom_area(fill = "#00b4d8", alpha = 0.25) +
3. geom_line(color = "#00b4d8", size = 2.2, linetype = "solid") +
4. geom_point(color = "#ffb703", fill = "white", size = 5, shape = 21, stroke = 2.5) +
5. geom_rug(sides = "b", color = "#0a9396", alpha = 0.45, length = unit(0.08, "npc")) +
6. geom_text(
7. aes(label = paste0( scales::comma(round(`doanh thu ban hang`/1e9, 1), big.mark = ".", decimal.mark = ","), " tỷ"), y = `doanh thu ban hang` + 0.07 * max(`doanh thu ban hang`) ), size = 3,fontface = "bold",color = "#023e8a") +
8. labs( title = "Doanh thu từng năm", x = "Năm", y = "Doanh thu (tỷ VNĐ)" ) +
9. scale_x_continuous(breaks = HSG$nam) +
10. scale_y_continuous( labels = function(x) paste0( scales::comma(round(x/1e9, 1), big.mark = ".", decimal.mark = ","), " tỷ" )) +
11. theme_minimal(base_size = 16) +
12. theme( plot.title = element_text(face = "bold", size = 18, hjust = 0.5))
Nhận xét:Biểu đồ cho thấy doanh nghiệp có tốc độ tăng trưởng doanh thu mạnh mẽ và rõ rệt trong suốt giai đoạn 2015–2024. Từ mức dưới 20.000 tỷ VNĐ năm 2015, doanh thu đã liên tục gia tăng, đạt đỉnh trên 50.000 tỷ VNĐ vào năm 2022. Đặc biệt, giai đoạn 2020–2022 ghi nhận sự bứt phá lớn, phản ánh thành công trong việc mở rộng thị trường, nâng cao năng lực sản xuất kinh doanh hoặc tận dụng tốt các cơ hội đầu tư. Tuy nhiên, sau khi đạt đỉnh, doanh thu có dấu hiệu điều chỉnh giảm vào 2023 nhưng nhanh chóng phục hồi mạnh mẽ trở lại vào năm 2024, cho thấy doanh nghiệp có khả năng thích ứng tốt với biến động thị trường và tiếp tục duy trì xu hướng tăng trưởng ổn định. Kết quả này là minh chứng cho uy tín, hiệu quả vận hành cũng như tiềm lực phát triển dài hạn của doanh nghiệp.
Giải thích:Đoạn 1–2: geom_area(…) vẽ nền màu dưới đường đồ thị, thể hiện lượng “tích lũy” hoặc xu hướng lên xuống của doanh thu từng năm. Tham số fill và alpha dùng tùy chỉnh màu và độ trong suốt, giúp dễ nhìn nền biểu đồ. Đoạn 3: geom_line(…) vẽ đường nối các điểm doanh thu, cho thấy xu hướng doanh thu tăng giảm qua từng năm. Tham số color, size, linetype tùy chỉnh màu đậm nhạt, kích thước và kiểu đường. Đoạn 4: geom_point(…) đặt các điểm dữ liệu nổi bật trên đường đồ thị. Tùy chỉnh màu viền và nền điểm để nhấn mạnh từng năm, tăng khả năng nhận diện trên biểu đồ. Đoạn 5: geom_rug(…) vẽ các vạch ngắn ở đáy trục X, giúp thể hiện tập trung các điểm dữ liệu, hỗ trợ cho việc nhận diện năm nào có giá trị đáng chú ý. Đoạn 6–7: geom_text(…) thêm nhãn số nổi trên mỗi cột/hàng, hiển thị doanh thu từng năm dưới dạng số đã chuyển sang “tỷ” đồng. Tùy chỉnh vị trí nhãn bằng tham số y, cỡ chữ và màu chữ để nhãn dễ đọc nhưng không quá nổi bật. Đoạn 8: labs(…) chỉnh tiêu đề, tên trục và nhãn thuyết minh cho biểu đồ làm rõ nghĩa của mỗi thông tin trên biểu đồ. Đoạn 9: scale_x_continuous(…) tùy chỉnh vị trí các năm (trục X), đảm bảo từng năm xuất hiện rõ ràng. Đoạn 10-12: scale_y_continuous(…) format nhãn trục Y hiển thị giá trị doanh thu chuyển sang tỷ đồng và định dạng đẹp.
1. df2 <- HSG %>%
2. select(nam, `luu chuyen tien thuan`, `tien thu di vay`) %>%
3. pivot_longer(-nam, names_to = "KhoanMuc", values_to = "giatri") %>%
4. mutate(nam = as.factor(nam),KhoanMuc = recode(KhoanMuc,"luu chuyen tien thuan" = "Lưu chuyển tiền thuần", "tien thu di vay" = "Tiền thu đi vay") )
5. label_points <- df2 %>%group_by(KhoanMuc) %>%
6. filter(giatri == max(giatri) | giatri == min(giatri)) %>%
7. ungroup()
8. ggplot(df2, aes(x= nam, y= giatri, fill= KhoanMuc))+
9. geom_col(position="dodge", width= 0.6, alpha= 0.64)+
10. geom_text(data= label_points,aes(label= scales::comma(giatri, big.mark= ".", decimal.mark= ",")),
11. position= position_dodge(width= 0.6),vjust=-0.23,size = 2.9, fontface= "bold",color= "#B5179E") +
12. scale_fill_brewer(palette= "Accent")+
13. scale_y_continuous(labels= comma,expand= expansion(mult= c(0, 0.13)))+
14. labs(title= "Lưu chuyển tiền thuần & Tiền thu đi vay từng năm", x= "Năm", y= "Giá trị(VNĐ)", fill= "Khoảnmục" ) +
15. theme_minimal(base_size= 11)+
16. theme( plot.title= element_text(face= "bold",size= 13, hjust= 0.5),axis.text.x= element_text(size= 9),axis.text.y= element_text(size= 9),legend.position= "bottom") +
17. coord_flip()
Nhận xét:Biểu đồ cho thấy tiền thu đi vay của HSG luôn ở mức rất cao so với lưu chuyển tiền thuần, đặc biệt nổi bật vào năm 2021 với giá trị vay đạt hơn 38 nghìn tỷ đồng. Điều này cho thấy doanh nghiệp phụ thuộc khá nhiều vào nguồn vốn vay để tài trợ cho hoạt động sản xuất, kinh doanh. Tuy nhiên, lưu chuyển tiền thuần dương qua hầu hết các năm cho thấy HSG vẫn duy trì được khả năng tạo ra tiền mặt, đảm bảo dòng tiền hoạt động ổn định. Xét về kinh tế, doanh nghiệp cần tiếp tục cân đối giữa vay nợ và dòng tiền tự tạo để giảm rủi ro tài chính trong dài hạn.
Giải thích:Đoạn 1–3: Tạo bảng df2 chỉ gồm năm, lưu chuyển tiền thuần và tiền thu đi vay, rồi dùng pivot_longer chuyển từ bảng rộng sang bảng dài, giúp gộp thành hai cột: tên khoản mục (KhoanMuc) và giá trị (giatri). Đoạn 3-4: Chỉnh dữ liệu: đổi kiểu cột năm sang factor (dạng nhóm), đổi tên các khoản mục thành tiếng Việt để dễ hiểu khi trình bày, giữ lại cột mới gọn gàng. Đoạn 5-7: Tạo bảng label_points để tìm và lưu giá trị lớn nhất và nhỏ nhất cho từng khoản mục, từ đó gắn nhãn nổi bật lên biểu đồ (giúp nhận diện dễ dàng các năm nổi và năm thấp nhất của từng khoản). Đoạn 8-17: Vẽ biểu đồ cột ngang bằng ggplot2: Dùng coord_flip để đảo trục, biểu đồ cột nằm ngang giúp khi tên năm dài hoặc số nhóm nhiều thì vẫn dễ nhìn.
1. HSG_profit <- HSG %>%
2. select(nam, LNSTCPP = `LNSTCPP`, LoiNhuanThuan = `loi nhuan thuan`)
3. label_LNSTCPP <- HSG_profit %>%
4. filter(nam == max(nam) | LNSTCPP == max(LNSTCPP) | LNSTCPP == min(LNSTCPP)) %>%
5. mutate(LabelType = case_when(nam == max(nam) ~ "Cuối năm", LNSTCPP == max(LNSTCPP) ~ "Cao nhất",LNSTCPP == min(LNSTCPP) ~ "Thấp nhất" ))
6. label_LoiNhuanThuan <- HSG_profit %>%filter(nam == max(nam) | LoiNhuanThuan == max(LoiNhuanThuan) | LoiNhuanThuan == min(LoiNhuanThuan)) %>%
7. mutate(LabelType = case_when( nam == max(nam) ~ "Cuối năm", LoiNhuanThuan == max(LoiNhuanThuan) ~ "Cao nhất", LoiNhuanThuan == min(LoiNhuanThuan) ~ "Thấp nhất" ))
Giải thích: -
HSG_profit <- HSG %>% select(nam, LNSTCPP = 'LNSTCPP', LoiNhuanThuan = 'loi nhuan thuan'): tạo bảng dữ liệu tóm gọn chỉ chứa ba cột chính: năm (nam), lợi nhuận sau thuế chưa phân phối (LNSTCPP) và lợi nhuận thuần (LoiNhuanThuan).label_LNSTCPP <- HSG_profit %>% filter(...) %>% mutate(LabelType = case_when(...))Lọc ra các dòng đặc biệt (năm cuối, cực đại và cực tiểu) cho LNSTCPP để gắn nhãn nổi bật trên biểu đồ. Dùngcase_whenphân loại nhãn: “Cuối năm”, “Cao nhất”, “Thấp nhất”.label_LoiNhuanThuan <- HSG_profit %>% filter(...) %>% mutate(LabelType = case_when(...))Lọc ra các dòng đặc biệt (năm cuối, cực đại và cực tiểu) cho biến “loi nhuan thuan” để gắn nhãn nổi bật trên biểu đồ. Dùngcase_whenphân loại nhãn: “Cuối năm”, “Cao nhất”, “Thấp nhất”.
1. ggplot(HSG_profit, aes(x = nam)) +
2. geom_ribbon(aes(ymin = pmin(LNSTCPP, LoiNhuanThuan), ymax = pmax(LNSTCPP, LoiNhuanThuan)), fill = "#d1e7dd", alpha = 0.38 ) +
3. geom_line(aes(y = LNSTCPP, color = "LNSTCPP", linetype = "LNSTCPP"), size = 2.3) +
4. geom_line(aes(y = LoiNhuanThuan, color = "LoiNhuanThuan", linetype = "LoiNhuanThuan"), size = 2.3)+
5. geom_point(aes(y = LNSTCPP, fill = "LNSTCPP"), size = 4.2, shape = 21, color = "#495057") +
6. geom_point(aes(y = LoiNhuanThuan, fill = "LoiNhuanThuan"), size = 4.2, shape = 21, color ="#495057") +
7. ggrepel::geom_label_repel( data = label_LNSTCPP, aes(x = nam, y = LNSTCPP, label =paste0(comma(LNSTCPP, big.mark = ".", decimal.mark = ","), "\n", LabelType)), family = "Arial", fontface = "bold", fill = "#f8bbd0", color = "#6d6875", size = 4.3, box.padding = 0.33, point.padding = 0.6, min.segment.length = 0.2, max.overlaps = 8, inherit.aes = FALSE ) +
8. ggrepel::geom_label_repel( data = label_LoiNhuanThuan, aes(x = nam, y = LoiNhuanThuan, label = paste0(comma(LoiNhuanThuan, big.mark = ".", decimal.mark = ","), "\n", LabelType)), family = "Arial", fontface = "bold", fill = "#cebbf7", color = "#b5838d", size = 4.3, box.padding = 0.33, point.padding = 0.6, min.segment.length = 0.2, max.overlaps = 8,inherit.aes = FALSE) +
9. scale_color_manual( values = c("LNSTCPP" = "#6d6875", "LoiNhuanThuan" = "#b5838d"),labels = c("LNSTCPP" = "LNSTCPP (nét đứt)", "LoiNhuanThuan" = "Lợi nhuận thuần (nét liền)"),name = "Chỉ tiêu" ) +
10. scale_fill_manual( values = c("LNSTCPP" = "#f8bbd0", "LoiNhuanThuan" = "#cebbf7"),labels = c("LNSTCPP" = "LNSTCPP (nét đứt)", "LoiNhuanThuan" = "Lợi nhuận thuần (nét liền)"),name = "Chỉ tiêu" ) +
11. scale_linetype_manual(values = c("LNSTCPP" = "dotted", "LoiNhuanThuan" = "solid"),labels = c("LNSTCPP" = "LNSTCPP (nét đứt)", "LoiNhuanThuan" = "Lợi nhuận thuần (nét liền)"), name = "Chỉ tiêu") +
12. labs( title = "Biến động LNSTCPP & Lợi nhuận thuần", x = "Năm", y = "Giá trị" ) +
13. theme_minimal(base_size = 14, base_family = "Arial") +
14. theme( plot.title = element_text(face = "bold", size = 18, hjust = 0.5), legend.position = "bottom", legend.title = element_text(size = 15, face = "bold", family = "Arial"),legend.text = element_text(size = 13, family = "Arial"), legend.key.width = unit(2.5, "lines"),legend.key.height = unit(1.3, "lines") )
Nhận xét:Biểu đồ “Biến động LNSTCPP & Lợi nhuận thuần theo năm” cho thấy dù cả hai chỉ tiêu đều có xu hướng tăng trưởng trong giai đoạn 2019–2021, nhưng sự biến động và khác biệt giữa chúng ngày càng rõ rệt ở giai đoạn sau. Lợi nhuận thuần (nét đứt) tăng mạnh vượt trội trong thời kỳ đỉnh cao, thể hiện hiệu quả sản xuất kinh doanh được cải thiện, nhưng lại giảm sâu ở các năm gần nhất, phản ánh áp lực chi phí hoặc biến động lợi nhuận từ các yếu tố bất thường. Trong khi đó, LNSTCPP (nét liền) có xu hướng ổn định hơn, cho thấy doanh nghiệp có chính sách trích lập và phân phối lợi nhuận giữ lại phù hợp, đảm bảo năng lực tái đầu tư và tích lũy vốn. Tuy nhiên, độ chênh lệch lớn giữa hai chỉ tiêu ở một số năm cũng cảnh báo về chiến lược phân phối lợi nhuận cần được rà soát để cân bằng giữa lợi ích cổ đông, tái đầu tư và an toàn tài chính dài hạn.
Giải thích:
ggplot(HSG_profit, aes(x = nam)):Đây là bước khởi tạo biểu đồ ggplot2, ánh xạ trục hoành là năm. Toàn bộ các lớp bổ sung sẽ được vẽ trên nền này, đảm bảo dữ liệu chọn đúng theo từng năm.geom_ribbon(...):Vẽ vùng tô màu giữa hai đường LNSTCPP và Lợi nhuận thuần qua các năm. Tác dụng là làm nổi bật khoảng cách hoặc mức chênh lệch giữa hai loại chỉ tiêu tài chính, giúp người xem nhận diện “giá trị vùng” giữa hai cột mốc.geom_line(aes(y = LNSTCPP, color = "LNSTCPP", linetype = "LNSTCPP"), ...): Vẽ đường biểu diễn LNSTCPP trên biểu đồ, màu xám và nét đứt (dotted), giúp phân biệt dễ dàng với Lợi nhuận thuần. Kích thước to rõ thể hiện rõ biến đổi qua các năm.geom_line(aes(y = LoiNhuanThuan, color = "LoiNhuanThuan", linetype = "LoiNhuanThuan"), ...): Vẽ đường Lợi nhuận thuần, sử dụng màu tím và nét liền (solid), đối lập trực quan với LNSTCPP. Đường này cho thấy rõ xu hướng tăng giảm của lợi nhuận thuần.geom_point(…):Chèn các điểm tròn lên từng giá trị LNSTCPP và Lợi nhuận thuần, với màu nền và viền rõ ràng giúp nhấn mạnh từng điểm dữ liệu cụ thể, tránh bị lẫn khi có nhiều năm và giá trị gần nhau.ggrepel::geom_label_repel(…): Gắn nhãn “Cuối năm”, “Cao nhất”, “Thấp nhất” cho LNSTCPP và Lợi nhuận thuần. Sử dụng ggrepel để nhãn không bị đè nhau giúp biểu đồ rõ ràng, thẩm mỹ.scale_color_manual(…), scale_fill_manual(…), scale_linetype_manual(…):Định nghĩa màu, kiểu nét, và màu fill cho từng nhóm chỉ tiêu với chú thích bằng tiếng Việt, đảm bảo legend chính xác, người xem phân biệt nhanh các loại dữ liệu.labs(title = …, x = …, y = …): Đặt tiêu đề và nhãn trục rõ ràng cho biểu đồ, ngay từ cái nhìn đầu tiên người đọc biết nội dung muốn truyền tải là diễn biến lợi nhuận thuần và LNSTCPP.theme_minimal(…) + theme(…)`: Sử dụng giao diện hiện đại, tối giản và chỉnh sửa kích thước chữ, font, vị trí legend giúp biểu đồ phù hợp phục vụ thuyết trình, báo cáo tài chính chuyên nghiệp.
1. nam_moi <- max(HSG$nam)
2. df3 <- HSG %>%filter(nam == nam_moi) %>% select(`cac khoan phai thu ngan han`, tien, TSCD) %>% pivot_longer(everything(), names_to = "KhoanMuc", values_to = "giatri") %>% mutate(KhoanMuc = recode(KhoanMuc, "cac khoan phai thu ngan han" = "Phải thu ngắn hạn", "tien" = "Tiền mặt","TSCD" = "Tài sản cố định"), tyle = giatri / sum(giatri) )
Giải thích:
nam_moi <- max(HSG$nam): Dòng này lấy ra năm lớn nhất trong dữ liệu (tức là năm mới nhất hiện có).filter(nam == nam_moi): Chỉ giữ lại dữ liệu của năm mới nhất.select(...): Chọn đúng ba loại tài sản cần phân tích tỉ trọng.pivot_longer(...): “Kéo” dữ liệu từ dạng bảng ngang sang bảng dọc (mỗi dòng là một tài sản - cần cho pie chart).mutate(KhoanMuc = recode(...)): Đổi tên từng loại tài sản thành tiếng Việt dễ đọc trên chart.mutate(tyle = giatri / sum(giatri)): Tính tỉ trọng từng loại tài sản trên tổng tài sản, dùng làm giá trị y cho pie chart
1. pie_colors <- c("Phải thu ngắn hạn" = "#A3CEF1", "Tiền mặt" = "#FFC8DD", "Tài sản cố định" = "#B9FBC0")
2. ggplot(df3, aes(x = "", y = tyle, fill = KhoanMuc)) +
3. geom_col(width = 1, color = "gray95") +
4. coord_polar(theta = "y") +
5. geom_text(aes(label = scales::percent(tyle, accuracy = 0.1)),position = position_stack(vjust = 0.66), size = 6, family = "Arial", fontface = "bold", color = "#333") +
6. scale_fill_manual(values = pie_colors) +
7. theme_void(base_family = "Arial") +
8. labs(title = paste("Tỷ trọng tài sản chính năm", nam_moi), fill = "Khoản mục") +
9. theme(plot.title = element_text(face = "bold", size = 18, hjust = 0.5), legend.position = "right", legend.title = element_text(size = 15, face = "bold"))
>Nhận xét:Biểu đồ “Tỷ trọng tài sản chính năm 2024”
cho thấy tài sản cố định chiếm ưu thế trong tổng cơ cấu tài sản của
doanh nghiệp với tỷ lệ 52,2%. Điều này chứng tỏ doanh nghiệp tập trung
nguồn lực cho tài sản phục vụ sản xuất kinh doanh dài hạn, củng cố nền
tảng phát triển ổn định trong tương lai. Khoản phải thu ngắn hạn chiếm
tỷ trọng khá lớn (39,8%), phản ánh hoạt động bán hàng mở rộng và khả
năng chiếm lĩnh thị trường, nhưng cũng đặt ra yêu cầu quản trị công nợ
chặt chẽ để đảm bảo dòng tiền lành mạnh. Tiền mặt chỉ chiếm 8%, tuy thấp
nhưng hợp lý nếu doanh nghiệp tận dụng được hiệu quả nguồn vốn nhàn rỗi
thay vì để tồn quỹ lớn, đồng thời hàm ý mức thanh khoản vẫn được duy trì
ở mức đủ an toàn cho các giao dịch ngắn hạn. Cơ cấu này giúp doanh
nghiệp tận dụng tối đa sức mạnh tài sản nhưng cần kiểm soát tốt rủi ro
từ các khoản phải thu.
Giải thích:
pie_colors: Đặt màu tròn đặc trưng cho từng loại tài sản, giúp nhìn chart không bị rối/đơn điệu.ggplot(df3, aes(x = ““, y = tyle, fill = KhoanMuc)): Khởi tạo plot — pie chart không có trục x, phân theo tỉ trọng y từng nhóm màu fill theo khoản mục.geom_col(width = 1, color =”gray95”): Tô từng phần tỉ trọng bằng “bar hình tròn” quanh điểm gốc (màu viền xám nhạt cho chart sáng).coord_polar(theta = “y”): Chuyển biểu đồ cột thành biểu đồ hình tròn, mỗi phần tương ứng tỉ trọng.geom_text(…): Gắn % lớn dễ đọc ngay trên lát pie (phần rìa, không bị che rối).scale_fill_manual(values = pie_colors): Gán đúng màu sắc cho từng nhóm tài sản.theme_void(base_family = “Arial”): Loại toàn bộ trục/grid, font chữ Arial đẹp cho tiếng Việt.labs(title = …, fill = “Khoản mục”): Tiêu đề tự động cập nhật đúng năm mới nhất, chú thích màu từng “lát” rõ ràng.theme(…)`: Chỉnh style tiêu đề lớn, legend đặt phải, legend to/nổi.
1. library(ggplot2)
2. library(scales)
3. ggplot(HSG, aes(x=nam, y=`luu chuyen tien thuan`)) +
4. geom_step(color="#FF99C8", linewidth=2.1, direction="hv") +
5. geom_point(size=5.6, fill="#B9FBC0", color="#FF99C8", shape=21) +
6. geom_text(aes(label=scales::comma(`luu chuyen tien thuan`, big.mark=".", decimal.mark=",")),vjust=2.2, hjust=0.5, angle=37, size=2.5, fontface="bold", family="Arial", color="black" ) +
7. scale_x_continuous( breaks = HSG$nam, labels = HSG$nam ) +
8. labs(title="Lưu chuyển tiền thuần bậc thang từng năm", x="Năm", y="Giá trị") +
9. theme_light(base_family="Arial", base_size=15) +
10. theme( plot.title=element_text(face="bold", size=18, hjust=0.5), axis.text.x=element_text(margin=margin(t=17)), plot.margin=margin(t=20, r=40, b=120, l=30) ) +
11. coord_cartesian(clip = "off")
>Nhận xét:Biểu đồ “Lưu chuyển tiền thuần bậc thang
từng năm” phản ánh tình hình biến động dòng tiền thực tế của doanh
nghiệp qua các giai đoạn. Có những năm ghi nhận giá trị dương cao như
2019, 2020 và 2023 cho thấy hoạt động sản xuất kinh doanh tạo ra dòng
tiền mạnh, giúp tăng thanh khoản, mở rộng đầu tư hoặc đáp ứng nhu cầu
trả nợ. Tuy nhiên, những năm như 2017 và 2024 lại ghi nhận dòng tiền
thuần âm lớn, phản ánh doanh nghiệp đối mặt với tình trạng chi vượt thu,
có thể do tăng cường đầu tư, thanh toán công nợ hoặc gặp khó khăn trong
chuyển hóa kết quả kinh doanh thành tiền mặt. Sự dao động mạnh của dòng
tiền thể hiện chu kỳ kinh doanh có nhiều biến động, đòi hỏi doanh nghiệp
phải tăng cường quản trị dòng tiền, kiểm soát thu chi cũng như dự phòng
tài chính hợp lý để đảm bảo ổn định và phát triển bền vững.
Giải thích:
ggplot(HSG, aes(x = HSG$nam, y = luu chuyen tien thuan))Khởi tạo biểu đồ, trục x là giá trị năm từ dataframe , trục y là dòng tiền thuần từng năm.geom_step(color="#FF99C8", size=2.1, direction="hv")Vẽ đường bậc thang cho biến động dòng tiền qua thời gian, mỗi “bậc” là một kỳ (năm), màu hồng nhạt, nét dày giúp nhận biết rõ các bước nhảy (giá trị giữ nguyên ngang trước khi đứng chuyển lên/xuống).geom_point(size=5.6, fill="#B9FBC0", color="#FF99C8", shape=21)Đặt chấm tròn lớn lên mỗi giá trị năm trong chuỗi, màu viền và fill đối lập giúp điểm không bị chìm trên nền chart.geom_text(aes(label=comma(luu chuyen tien thuan, big.mark=".", decimal.mark=",")), vjust=2.2, hjust=0.5, angle=35, size=2.5, fontface="bold", family="Arial", color="black")Gắn nhãn số dưới chấm, định dạng đúng theo nguyên tắc kế toán, xoay chữ góc 35 độ để các giá trị số không bị trùng nhau trên trục x, font đậm, size vừa nhìn rõ.scale_x_continuous(breaks = HSG$nam, labels = HSG$nam)Chỉnh trục x hiển thị đúng từng năm , đảm bảo mỗi kỳ đều được nhận diện rõ.labs(title="Dòng tiền thuần bậc thang từng năm", x="Năm", y="Giá trị")Đặt tiêu đề lớn, tên trục x/y đúng và đẹp.theme_light(base_family="Arial", base_size=15)Sử dụng theme sáng, font sang đẹp, chữ lớn vừa phải.theme(plot.title=element_text(face="bold", size=18, hjust=0.5) axis.text.x=element_text(margin=margin(t=17)), plot.margin=margin(t=20, r=40, b=120, l=30))Tiêu đề đậm nét, căn giữa, tăng margin trục x cho label, margin dưới/phải/trái cho không bị rối mắt và chuyên nghiệp.coord_cartesian(clip = "off")Cho phép các nhãn và điểm vẽ vượt ra ngoài vùng chart mà không bị cắt, tăng thẩm mỹ và bảo toàn toàn bộ thông tin.
1. df_group <- HSG %>%select(nam, TSCD, tien) %>%pivot_longer(-nam, names_to = "Chitieu", values_to = "giatri") %>% mutate( Chitieu = recode(Chitieu, 'TSCD' = 'TSCĐ', 'tien' = 'Tiền mặt'), la_max = giatri == max(giatri)) %>%
2. ungroup()
Giải thích:
select(nam, TSCD, tien): Chỉ lấy các biến cần phân tích, giúp đơn giản hóa dataset và tăng tính tối ưu cho vẽ nhóm bar.pivot_longer(-nam, ...): Chuyển từ dạng bảng ngang, mỗi năm một dòng, hai chỉ tiêu là hai cột TSCD/tien thành bảng dọc: mỗi dòng là một giá trị “năm - chỉ tiêu - giá trị”. Cần thao tác này vì ggplot2 hoạt động trực quan nhất với dữ liệu “long format”, đặc biệt khi vẽ bar nhóm.mutate(Chitieu = recode(...)): Đổi tên tiếng Việt dễ đọcla_max = giatri == max(giatri): Đánh dấu trong từng năm dòng nào là lớn nhất (TRUE). Thao tác này sau khigroup_bynăm sẽ cho đúng logic: duy nhất bar giá trị lớn nhất mỗi năm mới TRUE. Dùng để tạo hiệu ứng nhãn số nổi bật.group_by(nam): Đảm bảo mọi tính toán so sánh max đều thực hiện trong từng năm.ungroup(): Thoát chế độ nhóm sau biến đổi, giúp ggplot2 nhận diện đúng từng dòng là một bar độc lập.
1. ggplot(df_group, aes(x = nam, y = giatri, fill = Chitieu)) +
2. geom_col(position = position_dodge(width = 0.7), width = 0.55, color = "#dee2e6", alpha = 0.85) +
3. geom_text(aes(label = scales::comma(giatri, big.mark = ".", decimal.mark = ","),hjust =ifelse(la_max, 1.1, 0) ), position = position_dodge(width = 0.7),nudge_y = 0.5, size = 2.4, fontface = "bold", family = "Arial" ) +
4. geom_vline(xintercept = df_group$nam + 0.5, color = "gray87", linetype = "dotted") +
5. scale_fill_manual(values = c("TSCĐ"="#B5179E", "Tiền mặt"="#48CAE4")) +
6. scale_x_continuous(breaks = unique(df_group$nam)) +
7. labs(title = "So sánh TSCĐ vs Tiền mặt từng năm",x = "Năm", y = "Giá trị", fill = "Chỉ tiêu") +
8. theme_minimal(base_size = 10, base_family = "Arial") +
9. theme( plot.title = element_text(face = "bold", size = 13, hjust = 0.5), legend.position = "bottom",plot.margin = margin(r = 40)) +
10. coord_flip()
>Nhận xét:Biểu đồ so sánh TSCĐ (tài sản cố định) và
tiền mặt qua các năm cho thấy cơ cấu tài sản doanh nghiệp có sự chênh
lệch lớn và biến động theo từng giai đoạn. Nhìn chung, giá trị tiền mặt
thường vượt trội đáng kể so với TSCĐ, đặc biệt trong các năm như 2015,
2016 và 2018, cho thấy doanh nghiệp ưu tiên dự trữ vốn lưu động cao hoặc
còn thận trọng trong việc đầu tư dài hạn. Tuy nhiên, giai đoạn 2023–2024
lại ghi nhận TSCĐ tăng lên đáng kể, thu hẹp khoảng cách với tiền mặt,
phản ánh xu hướng đẩy mạnh đầu tư vào tài sản sản xuất, cơ sở vật chất
nhằm nâng cao năng suất hoặc mở rộng hoạt động kinh doanh. Sự chuyển
dịch này giúp doanh nghiệp linh hoạt thích ứng với môi trường kinh
doanh, đồng thời cũng đặt ra yêu cầu tiếp tục quản trị dòng tiền hiệu
quả để đảm bảo cân bằng thanh khoản và đầu tư phát triển lâu dài.
Giải thích:
ggplot(df_group, aes(x = nam, y = giatri, fill = Chitieu))Khởi tạo biểu đồ bar nhóm, x là năm, y là giá trị chỉ tiêu (TSCĐ hoặc Tiền mặt), fill là màu.geom_col(position = position_dodge(width = 0.7), width = 0.55, color = "#dee2e6", alpha = 0.85)Vẽ bar nhóm (ngang), đặt cạnh nhau với width = 0.55, màu viền xám nhạt, alpha làm màu nền cột dịu và chuyên nghiệp.geom_text(aes( label = scales::comma(giatri, big.mark = ".", decimal.mark = ","), hjust = ifelse(la_max, 1.1, 0) ), position = position_dodge(width = 0.7), nudge_y = 0.5, size = 2.4, fontface = "bold", family = "Arial")Vẽ nhãn chính xác trên từng cột. Chỉ cột cao nhất (la_max==TRUE) thì nhãn canh lề phải (hjust = 1.1), còn lại canh trái (hjust = 0).nudge_y = 0.5: Đẩy nhãn lên phía trên cột cho dễ nhìn.geom_vline(xintercept = df_group$nam + 0.5, color = "gray87", linetype = "dotted")Vẽ đường dọc phân biệt nhóm năm, giúp chart không bị rối thông tin nhiều năm.scale_fill_manual(values = c("TSCĐ"="#B5179E", "Tiền mặt"="#48CAE4"))đặt màu cho từng nhóm bar, tăng độ nhận diện và dễ phân biệt.scale_x_continuous(breaks = unique(df_group$nam))Đảm bảo các năm đều có chú thích, không bị trùng hoặc mất label nhất là khi quay ngang.labs(title = "So sánh TSCĐ vs Tiền mặt từng năm", x = "Năm", y = "Giá trị", fill = "Chỉ tiêu")Tiêu đề báo cáo rõ ràng, chú thích nhóm màu bar.theme_minimal(base_size = 10, base_family = "Arial")Layout tối giản, mọi thành phần đều hài hòa, font Arial cho tiếng Việt.theme(plot.title = element_text(face = "bold", size = 13, hjust = 0.5), legend.position = "bottom", plot.margin = margin(r = 40))chỉnh title to, đậm, căn giữa; legend phía dưới dễ truy cập hơn; margin phải lớn cho xuất file hình không bị cắt nhãn.coord_flip()Xoay chart từ dọc (vertical) sang ngang (horizontal), giúp đọc năm và số rõ ràng số nhiều.
1. years <- sort(unique(HSG$nam))
2. n_years <- length(years)
3. palette_paired <- colorRampPalette(brewer.pal(12, "Paired"))(n_years)
Giải thích:
years <- sort(unique(HSG$nam)): Lấy danh sách tất cả năm duy nhất, sắp xếp tăng dần, đảm bảo các đánh dấu/legend trùng khớp dữ liệu.n_years <- length(years): Xác định số lượng năm để phối màu động, đảm bảo mỗi năm một màu riêng.palette_paired <- colorRampPalette(brewer.pal(12, "Paired"))(n_years): Sử dụng hàm colorRampPalette phối đủ màu cho từng năm bằng bộ Paired (12 màu gốc), màu sẽ tươi trẻ và không bị trùng kể cả số năm > 7.
1. ggplot(HSG, aes(x = `von co phan`, y = `loi nhuan thuan`, color = as.factor(nam))) +
2. geom_point(size = 4, alpha = 0.7, position = position_jitter(width = 0.5)) +
3. geom_smooth(method = "lm", se = FALSE, color = "#E09EA6", size = 1.3) +
4. scale_x_continuous( labels = scales::comma_format(big.mark = "."), expand = expansion(mult = c(0.12, 0.16)), breaks = pretty(HSG$`von co phan`, n = 7) ) +
5. scale_y_continuous(labels = scales::comma_format(big.mark = ".")) +
6. scale_color_manual( name = "Năm", values = setNames(palette_paired, years) ) +
7. labs( title = "Vốn cổ phần và Lợi nhuận sau thuế", x = "Vốn cổ phần (VNĐ)", y = "Lợi nhuận sau thuế (VNĐ)" ) +
8. theme_minimal(base_size = 11) +
9. theme(plot.title = element_text(face = "bold", size = 13, hjust = 0.5), axis.text.x = element_text(size = 9, angle = 25, vjust = 0.6), axis.text.y = element_text(size = 9), legend.position = "bottom", legend.text = element_text(size = 9), legend.title = element_text(size = 10, face = "bold"), plot.margin = margin(r = 15, l = 10, t = 10, b = 15) )
Nhận xét: Biểu đồ “Vốn cổ phần và Lợi nhuận sau thuế” cho thấy xu hướng nghịch đảo giữa quy mô vốn cổ phần và hiệu quả sinh lợi của doanh nghiệp trong các năm gần đây. Mặc dù vốn cổ phần ngày càng tăng mạnh, song lợi nhuận sau thuế lại có xu hướng giảm nhẹ hoặc biến động không đồng thuận với mức tăng vốn. Đường xu hướng đi xuống thể hiện rằng việc tăng vốn chưa thực sự mang lại hiệu quả tối ưu cho hoạt động kinh doanh, hoặc có thể doanh nghiệp chưa tận dụng tốt nguồn vốn bổ sung để tạo ra lợi nhuận bền vững. Một số năm ghi nhận vốn lớn nhưng lợi nhuận sau thuế chỉ ở mức trung bình, cho thấy cần xem xét lại chiến lược đầu tư và quản lý chi phí, cũng như phát huy tối đa năng lực khai thác vốn để thúc đẩy hiệu quả tài chính. Để cải thiện, doanh nghiệp nên tập trung tối ưu hóa sử dụng vốn, tăng năng suất và kiểm soát chi phí vận hành tốt hơn nhằm chuyển hóa nguồn vốn thành giá trị thực cho cổ đông.
**Giải thích:*
ggplot(HSG, aes(x = von co phan, y = loi nhuan thuan, color = as.factor(nam)))Tạo biểu đồ với trục x là vốn cổ phần, trục y là lợi nhuận sau thuế, mỗi năm có một màu riêng khi lên chart.geom_point(size = 4, alpha = 0.7, position = position_jitter(width = 0.5))Vẽ các điểm tán xạ, size vừa đủ nhìn rõ, alpha làm điểm không quá đậm, position_jitter giúp các điểm không đè lên nhau khi cùng giá trị.geom_smooth(method = "lm", se = FALSE, color = "#E09EA6", size = 1.3)Vẽ đường xu hướng hồi quy tuyến tính (linear model), màu hồng pastel, size giảm cho vừa đẹp, không lấn át điểm. se = FALSE: Không vẽ khoảng tin cậy, giúp chart sáng và hấp dẫn hơn.scale_x_continuous(labels = scales::comma_format(big.mark = "."), expand = expansion(mult = c(0.12, 0.16)), breaks = pretty(HSG$von co phan, n = 7))Định dạng trục x kiểu số chuẩn nguyên tắc kế toán, đặt khoảng lệ vừa phải để điểm/đường không bị cắt, break làm tick chuẩn, đọc thuận mắt.scale_y_continuous(labels = scales::comma_format(big.mark = "."))Định dạng y có ngăn cách theo kế toán , dễ đọc với tiền tỉ, trăm triệu.scale_color_manual(name = "Năm", values = setNames(palette_paired, years))Đặt màu cho từng năm, legend tên rõ ràng, màu đồng bộ với dữ liệu.labs(title = "Vốn cổ phần và Lợi nhuận sau thuế", x = "Vốn cổ phần (VNĐ)", y = "Lợi nhuận sau thuế (VNĐ)")Đặt tiêu đề chart, tên trục x/y chuẩn báo cáo kế toán.theme_minimal(base_size = 11)Layout nhẹ, giảm thông tin thừa, font size nhỏ giúp chart gọn cho báo cáo, slide.theme(... plot.margin = margin(...))Tiêu đề to vừa phải, trục x/y nhỏ, legend nhỏ cho gọn chart, margins chuẩn để text và điểm không bị tràn ra ngoài hình khi chèn vào file báo cáo.
1. debt_data <- HSG %>%select(nam, `Phai tra nguoi ban ngan han`, `vay va no thue tai chinh`) %>% pivot_longer( cols = -nam, names_to = "khoan_no", values_to = "gia_tri" ) %>%group_by(nam) %>% mutate( tong_no = sum(gia_tri, na.rm = TRUE), tile = gia_tri / tong_no * 100, tile_lab = paste0(round(tile, 1), "%"))
1. ggplot(debt_data, aes(x = factor(nam), y = gia_tri, fill = khoan_no)) +
2. geom_col(position = "stack", width = 0.7, alpha = 0.95) +
3. geom_text(aes(label = tile_lab), position = position_stack(vjust = 0.5), size = 4, color ="black", family = "Arial") +
4. coord_flip() +
5. scale_fill_brewer(palette = "Set2") +
6. scale_y_continuous(labels = scales::label_number(scale_cut = scales::cut_short_scale())) +
7. labs( title = "Các khoản nợ ngắn hạn", x = "Năm", y = "Giá trị (tỷ VNĐ)", fill = "Khoản nợ" ) +
8. theme( plot.title = element_text(face = "bold", size = 30), plot.subtitle = element_text(color = "gray30", size = 20), axis.title = element_text(size = 22), axis.text = element_text(size = 20), legend.position = "bottom", legend.title = element_text(size = 22), legend.text = element_text(size = 10), panel.grid.major.y = element_blank(), panel.grid.minor = element_blank()) +
9. geom_hline(yintercept = 0, color = "gray60", linetype = "dashed", linewidth = 0.7)
>Nhận xét: Biểu đồ cho thấy cơ cấu nợ ngắn hạn của
HSG đã thay đổi rõ rệt qua các năm: giai đoạn trước 2021, tỷ trọng vay
và nợ thuê tài chính chiếm ưu thế tuyệt đối (đến 88,8%), còn phải trả
người bán ngắn hạn chỉ chiếm phần nhỏ. Tuy nhiên, từ 2021 đến 2024, tỷ
trọng phải trả người bán ngắn hạn tăng đáng kể, thậm chí vượt cả vay và
nợ ở năm 2023 (49,6%), thể hiện doanh nghiệp đã chủ động kéo dài thời
gian thanh toán với nhà cung cấp để tận dụng nguồn vốn ngắn hạn không
chi phí. Xu hướng này giúp doanh nghiệp giảm bớt áp lực chi phí vốn vay
nhưng cũng tiềm ẩn rủi ro về khả năng thanh toán nếu không kiểm soát tốt
dòng tiền.
Giải thích: Đoạn 2-3: Dùng ggplot khởi tạo biểu đồ cột xếp chồng (geom_col(position = “stack”)) để giá trị của các khoản nợ chồng lên nhau theo từng năm, biểu diễn kết cấu các loại nợ chính trong cơ cấu tài chính doanh nghiệp. Dùng geom_text(position_stack(vjust = 0.5)) để chèn nhãn tỷ lệ % ngay trong mỗi phần cột, nhãn đặt ở giữa từng thành phần giúp đọc nhanh tỷ trọng từng khoản nợ trong tổng nợ từng năm. Đoạn 6-7: Định dạng trục y với số lớn rút gọn và nhãn trục rõ ràng.
1. HSG$`phan loai doanh thu` <- ifelse(HSG$`doanh thu ban hang` < 28000000000000, "Doanh thu yếu",
2. ifelse( HSG$`doanh thu ban hang` < 40000000000000, "Doanh thu ổn", "Doanh thu tốt"))
3. HSG$`phan loai doanh thu`<- factor(HSG$`phan loai doanh thu`,levels = c("Doanh thu tốt","Doanh thu ổn", "Doanh thu yếu"))
1. HSG$`phan loai doanh thu` <- factor(HSG$`phan loai doanh thu`, levels = c("Doanh thu tốt", "Doanh thu ổn", "Doanh thu yếu"))
2. ggplot(HSG, aes(x = `doanh thu ban hang` / 1e12, y = `chi phi ban hang` / 1e12)) +
3. geom_point(aes(color = `phan loai doanh thu`), size = 3, alpha = 0.6) +
4. geom_smooth(method = "lm", se = FALSE, color = "black") +
5. geom_text( aes(label = round(`chi phi ban hang` / 1e12, 1)),check_overlap = TRUE, vjust = -1, size = 3 ) +
6. geom_density2d(color = "blue") +
7. geom_rug(alpha = 0.3) +
8. geom_hline(yintercept = mean(HSG$`chi phi ban hang` / 1e12), linetype = "dashed") +
9. labs( title = "Doanh thu và Chi phí bán hàng theo phân loại doanh thu", x = "Doanh thu bán hàng (nghìn tỷ đồng)", y = "Chi phí bán hàng (nghìn tỷ đồng)", color = "Phân loại doanh thu" ) +
10. theme_minimal()
Nhận xét: Biểu đồ thể hiện mối quan hệ giữa doanh thu bán hàng và chi phí bán hàng theo từng phân khúc doanh thu. Các điểm của nhóm “Doanh thu tốt” thường nằm phía trên đường hồi quy, tức là chi phí bán hàng tăng tương ứng với doanh thu nhưng vẫn giữ được khoảng cách tích cực, trong khi nhóm “Doanh thu ồn” xuất hiện cả các điểm chi phí thấp lẫn cao, cho thấy hiệu suất kiểm soát chi phí chưa đều. Nhóm “Doanh thu yếu” chủ yếu tập trung ở vùng doanh thu và chi phí thấp, phản ánh hoạt động kinh doanh còn hạn chế và cần tăng cường hiệu quả sử dụng chi phí để bứt phá hơn.
Giải thích:Đoạn 1: Tạo bảng tổng hợp dữ liệu với agg2. Sử dụng group_by để phân nhóm theo năm và theo phân loại doanh thu, sau đó dùng summarise để tính tổng lợi nhuận gộp của từng nhóm, giúp nhận diện cơ cấu lợi nhuận gộp theo thời gian và loại thị trường. Đoạn 4-7: Thêm các đường line, điểm và đường xu hướng mềm hóa Đoạn 8-9: Sử dụng facet_wrap để tách mỗi nhóm phân loại doanh thu thành một biểu đồ nhỏ độc lập.
1. agg2 <- HSG %>% group_by(nam, `phan loai doanh thu`) %>% summarise(TotalPro= sum(`loi nhuan gop`, na.rm = TRUE), .groups = "drop")
2. ggplot(agg2, aes(x =nam, y = TotalPro, fill = `phan loai doanh thu`)) +
3. geom_area(alpha = 0.1, position = "identity") +
4. geom_line(aes(color = `phan loai doanh thu`), linewidth = 0.8) +
5. geom_point(size = 1.8) +
6. geom_smooth(method = "loess", se = TRUE, linetype = "dashed") +
7. geom_ribbon(aes(ymin = pmax(0, TotalPro - TotalPro*0.08), ymax = TotalPro + TotalPro*0.08), alpha = 0.05) +
8. facet_wrap(~ `phan loai doanh thu`, scales = "free_y") +
9. labs(title = "Xu hướng lợi nhuận gộp theo phân loại thị trường", x = "Năm", y = "Giá vốn") + scale_x_continuous(breaks = scales::breaks_pretty(n = 3))+ scale_y_continuous(labels =scales::label_number(big.mark = ","))+
10. theme_minimal(base_size = 11) +
11. theme(legend.position = "none", plot.title = element_text(face = "bold", hjust = 0.5),plot.subtitle = element_text(hjust = 0.5))
Nhận xét:Các phân khúc thị trường cho thấy xu hướng lợi nhuận gộp có sự khác biệt rõ rệt: thị trường doanh thu tốt có giá vốn biến động mạnh, nhưng lợi nhuận gộp giảm dần qua thời gian. Nhóm doanh thu ổn ghi nhận sự tăng trưởng lại sau thời kỳ giảm, còn nhóm doanh thu yếu có tốc độ tăng giá vốn nhưng cũng đạt lợi nhuận gộp ổn định từ năm 2018 trở đi. Điều này cho thấy doanh nghiệp cần tập trung kiểm soát chi phí ở nhóm doanh thu tốt, đồng thời mở rộng thị phần ở các nhóm ổn và yếu để đảm bảo tăng trưởng lợi nhuận tổng thể.
Giải thích:Đoạn 2-3: Khởi tạo biểu đồ với ggplot2, gán trục x là năm, trục y là tổng lợi nhuận gộp, tô các nhóm doanh thu bằng fill. Vẽ phần diện tích cho mỗi nhóm phân loại doanh thu để minh họa khối lượng và xu hướng tổng lợi nhuận gộp từng nhóm qua thời gian.Đoạn 4-5: Thêm các đường nối cho từng nhóm để làm rõ tăng/giảm và các điểm dữ liệu thực theo các năm bằng geom_point. Đoạn 6-7: Vẽ geom_smooth cho từng nhóm doanh thu, giúp nhìn thấy xu hướng tổng thể của từng thị trường. Thêm dải ribbon cận trên/cận dưới dao động quanh mỗi đường (±8%) . Đoạn 8-9: Sử dụng facet_wrap để tách riêng từng nhóm phân loại doanh thu thành nhiều biểu đồ nhỏ.
1. ggplot(HSG, aes(x = nam)) +
2. geom_ribbon(aes(ymin = 0, ymax = `luu chuyen tien thuan`), fill = "#00BFC4", alpha = 0.4) +
3. geom_ribbon(aes(ymin = 0, ymax = `loi nhuan gop`), fill = "#F8766D", alpha = 0.3) +
4. geom_line(aes(y = `luu chuyen tien thuan`), color = "#00BFC4", linewidth = 1.2) +
5. geom_line(aes(y = `loi nhuan gop`), color = "#F8766D", linewidth = 1.2) +
6. geom_point(aes(y = `loi nhuan gop`), color = "#F8766D", size = 3) +
7. geom_text(aes(y = `loi nhuan gop`, label = label_number(scale_cut = cut_short_scale(), accuracy = 0.1, big.mark = ".", decimal.mark = "," )(`loi nhuan gop`)), vjust = -1, color = "#F8766D", size = 3.5)+
8. scale_x_continuous( breaks = unique(HSG$nam), labels = unique(HSG$nam) ) +
9. scale_y_continuous( labels = scales::label_number(big.mark = ".", decimal.mark = ",") ) +scale_y_continuous( labels = scales::label_number(scale_cut = scales::cut_short_scale()) )+
10. theme_minimal(base_size = 13) +
11. labs(title = "Dòng tiền và lợi nhuận theo năm", subtitle = "1T = 1 nghìn tỷ", x = "Năm", y = "Giá trị (VND)") +theme(legend.position = "none")
Nhận xét:Biểu đồ thể hiện sự biến động mạnh của dòng tiền qua các năm và sự tăng trưởng ổn định của lợi nhuận, đặc biệt đạt đỉnh vào năm 2021 rồi giảm nhẹ những năm sau. Có nhiều giai đoạn dòng tiền âm, cho thấy doanh nghiệp đầu tư lớn hoặc tăng chi phí ngoài hoạt động kinh doanh, nhưng vẫn duy trì lợi nhuận ở mức cao đa phần các năm. Điều này cho thấy doanh nghiệp quản lý tốt hiệu quả kinh doanh, tuy nhiên cần tiếp tục kiểm soát dòng tiền và cấu trúc chi phí để đảm bảo ổn định tài chính lâu dài
Giải thích:Đoạn 1-2: tạo biểu đồ với ggplot2, trục x là năm liên tục. Thêm hai lớp geom_ribbon: một lớp biểu diễn diện tích cho ‘Dòng tiền thuần’, một lớp cho ‘Lợi nhuận gộp’. Các dải màu này giúp trực quan hóa vùng giá trị và độ lớn từng khoản mục qua các năm. Đoạn 3-5: Vẽ thêm hai đường line: đường màu xanh cho ‘Dòng tiền thuần’, đường màu đỏ cho ‘Lợi nhuận gộp’, cùng với các điểm dữ liệu năm cho ‘Lợi nhuận gộp’. Cách kết hợp này vừa thể hiện xu hướng tổng thể, vừa nổi bật từng giá trị cụ thể theo năm.Đoạn 6-7: Chèn nhãn số trên từng điểm ‘Lợi nhuận gộp’, định dạng đúng kiểu Việt (dấu chấm hàng nghìn, dấu phẩy thập phân). Nhãn giúp người đọc chú ý tới từng mốc lợi nhuận quan trọng, tiện so sánh trực tiếp bằng mắt thường.Đoạn 8-9: Tùy chỉnh trục x là năm rời rạc, trục y có nhãn đẹp rõ ràng (dùng scales và format cho số lớn).
1. library(RColorBrewer)
2. HSG_char <- HSG %>% group_by(`phan loai doanh thu`) %>%
3. summarise(total_nganhan = sum(`cac khoan phai thu dai han`), .groups="drop") %>%
4. mutate( percentage = (total_nganhan / sum(total_nganhan )) * 100, label = paste0(`phan loai doanh thu`, "\n", round(percentage,1), "%") )
5. my_colors <- brewer.pal(n = nrow(HSG_char), name = "Paired")
1. ggplot(HSG_char, aes(x = 1, y = total_nganhan, fill = `phan loai doanh thu`)) +
2. geom_bar(stat = "identity", width = 0.9, color = "white", size = 0.5, alpha = 0.9) + # nhấn nhẹ
3. coord_polar(theta = "y") +
4. geom_text(aes(label = label), position = position_stack(vjust = 0.5), color = "black", size = 3, fontface = "bold") +
5. scale_fill_manual(values = my_colors) +
6. labs(title = "Phân bổ giá vốn theo loại doanh thu") +
7. theme_void() +
8. theme( legend.position = "right", plot.title = element_text(hjust=0.8, size=16, face="bold")) +
9. geom_bar(stat = "identity", width = 0.7, alpha = 0.5)
>Nhận xét:Biểu đồ cho thấy phần lớn giá vốn được
phân bổ cho nhóm “Doanh thu ổn”, chiếm 51,3% tổng giá trị, trong khi
nhóm “Doanh thu tốt” chỉ chiếm 23,5% và “Doanh thu yếu” là 25,2%. Điều
này phản ánh đa phần hoạt động sản xuất kinh doanh ở mức trung bình khá,
nhưng vẫn còn tiềm năng cải thiện khi tỷ lệ giá vốn ở nhóm doanh thu tốt
chưa đạt tối ưu. Doanh nghiệp cần tập trung nâng cao hiệu quả sản xuất
và tiêu thụ nhằm gia tăng tỷ lệ doanh thu tốt, tối ưu hóa cơ cấu chi phí
và gia tăng giá trị lợi nhuận.
Giải thích:Đoạn 1–4: Dùng dplyr để tổng hợp tổng giá trị ‘các khoản phải thu dài hạn’ theo từng nhóm phân loại doanh thu trong bảng HSG. Tính tỷ trọng (percentage) từng nhóm so với tổng toàn bộ, rồi tạo nhãn (label) hiển thị tên nhóm và phần trăm để đưa lên biểu đồ. Đoạn 5: Lấy một bảng màu với số màu đúng số nhóm từ bộ “Paired” của RColorBrewer. Đoạn 1–9 (tạo biểu đồ): Dùng ggplot vẽ bar chart một chiều với geom_bar theo hướng dọc (x = 1), rồi chuyển hệ tọa độ sang tròn bằng coord_polar(theta = “y”) để tạo biểu đồ tròn/circular (pie chart hoặc donut chart). geom_text gắn nhãn tỷ trọng ngay giữa sector, font in đậm và dễ nhìn. scale_fill_manual gán màu cho từng nhóm đúng với bảng màu vừa lấy, đảm bảo các mảng màu không bị trùng lặp. labs thêm tiêu đề giải thích, theme_void() xoá lưới, khung và trục dư thừa để biểu đồ hiện đại, tối giản hơn.
1. avg_data <- HSG %>% group_by(nam) %>%
2. summarise( `Phải trả người bán ngắn hạn` = mean(`Phai tra nguoi ban ngan han`, na.rm = TRUE), `Tiền` = mean(`tien`, na.rm = TRUE) ) %>%
3. pivot_longer(cols = c(`Phải trả người bán ngắn hạn`, `Tiền`), names_to = "Chỉ tiêu", values_to = "Giá trị")
4. ggplot(avg_data, aes(x = nam, y = `Giá trị`, color = `Chỉ tiêu`)) +
5. geom_line(aes(group = `Chỉ tiêu`), size = 1.0) +
6. geom_point(size = 2) +
7. geom_smooth(method = "loess", se = FALSE, linetype = "dashed") +
8. geom_area(aes(fill = `Chỉ tiêu`), alpha = 0.1, position = "identity") +
9. scale_y_continuous(labels = label_number(big.mark = ".", decimal.mark = ",")) +
10. labs( title = "Phải trả người bán ngắn hạn & Tiền theo năm", x = "Năm", y = "Giá trị trung bình (VNĐ)", color = "Chỉ tiêu", fill = "Chỉ tiêu" ) +
11. theme_minimal(base_size = 13) +
12. theme( legend.position = "bottom", plot.title = element_text(face = "bold", size = 14) ) +
13. scale_x_continuous( breaks = unique(HSG$nam), labels = unique(HSG$nam) )
Nhận xét:Biểu đồ cho thấy khoản phải trả người bán ngắn hạn tăng mạnh vào các năm 2017, 2021 và các năm gần đây, cao hơn hẳn so với giá trị tiền mặt mà doanh nghiệp nắm giữ. Trong khi đó, tiền mặt có xu hướng ổn định và tăng dần giai đoạn gần đây nhưng luôn duy trì ở mức thấp hơn nhiều so với tiền phải trả. Điều này cho thấy doanh nghiệp đang tận dụng tối đa tín dụng thương mại với nhà cung cấp nhưng cần cảnh giác với áp lực thanh toán lớn, đồng thời phải kiểm soát dòng tiền chặt chẽ để đảm bảo an toàn tài chính ngắn hạn.
Giải thích: Đoạn 1–3: Tạo bảng dữ liệu trung gian avg_data từ HSG. Dữ liệu được nhóm theo năm để tính giá trị trung bình của hai chỉ tiêu: “Phải trả người bán ngắn hạn” và “Tiền” cho từng năm. Sau đó, chuyển bảng từ dạng rộng sang dài bằng pivot_longer. Đoạn 4–8: Tạo biểu đồ đường bằng ggplot2 để minh họa xu hướng của hai chỉ tiêu qua các năm: geom_line: Vẽ đường nối các giá trị từng năm cho từng chỉ tiêu, cho thấy xu hướng tăng/giảm theo thời gian. geom_point: Đánh dấu từng điểm số liệu năm cụ thể, dễ nhận diện trên đồ thị. geom_smooth: Thêm đường làm mịn (loess), giúp thể hiện xu hướng dài hạn, giảm độ “gồ ghề” của chuỗi thời gian, rất hữu ích để phát hiện mẫu số liệu hoặc xu hướng ổn định. geom_area: Tạo nền nhạt dưới đường, giúp minh họa trực quan sự thay đổi khối lượng giá trị giữa các năm.
1. library(ggplot2)
2. library(dplyr)
3. comma_vn <- function(x) format(round(x, 0), big.mark = ".", decimal.mark = ",", scientific = FALSE)
4. hsg2 <- HSG %>%
5. mutate( Revenue = `doanh thu ban hang` / 1e9, GrossProfit = (`loi nhuan thuan`) / 1e9)
6. ggplot(hsg2, aes(x = factor(nam))) +
7. geom_col(aes(y = Revenue, fill = "Doanh thu"), width = 0.6, color = "grey80") +
8. geom_col(aes(y = GrossProfit, fill = "Lợi nhuận thuần"), width = 0.4, alpha = 0.90, color ="grey80") +
9. geom_text( aes(y = Revenue, label = format(Revenue, big.mark = ".", decimal.mark = ",", nsmall = 2)), vjust = -0.5, size = 3.2, color = "black" ) +
10. geom_text( aes(y = GrossProfit, label = format(GrossProfit, big.mark = ".", decimal.mark = ",",)),
11. vjust = -0.5, size = 3.2, color = "black") +
12. scale_fill_manual(values = c("Doanh thu" = "#A7C7E7", "Lợi nhuận thuần" = "#F7C6C7"),name = "" )+
13. scale_y_continuous(labels = comma_vn, expand = expansion(mult = c(0, 0.12))) +
14. labs( title = "Doanh thu và lợi nhuận thuần (tỷ VND)", x = "Năm", y = "Giá trị (tỷ VND)", fill = "") +
15. theme( legend.position = "bottom", legend.title = element_blank() )
Nhận xét: Biểu đồ cho thấy doanh thu của doanh nghiệp tăng trưởng khá ổn định từ 2015 đến 2021, đạt đỉnh vào năm 2021-2022 rồi giảm nhẹ những năm sau đó. Tuy vậy, lợi nhuận thuần luôn ở mức thấp so với doanh thu và có dấu hiệu sụt giảm. Đến năm 2024, doanh thu phục hồi khá mạnh nhưng lợi nhuận thuần vẫn chưa được cải thiện đáng kể, phản ánh hiệu quả hoạt động kinh doanh chưa thực sự tốt. Đây là tín hiệu doanh nghiệp cần kiểm soát tốt hơn chi phí và nâng cao hiệu quả để chuyển tăng trưởng doanh thu thành lợi nhuận.
Giải thích:Đoạn 6–8: Khởi tạo biểu đồ bằng ggplot (trục x: năm, trục y: giá trị), vẽ hai lớp cột: cột to cho doanh thu, cột nhỏ cho lợi nhuận gộp. Cách dùng hai geom_col với width khác nhau để các chỉ tiêu không che lấp nhau và rõ khác biệt. Đoạn 9–11: Gắn nhãn số lên từng cột bằng geom_text Đoạn 12–13: Tuỳ chỉnh màu fill cho hai lớp bằng palette thủ công, format lại nhãn trục y bằng hàm đã định nghĩa từ đầu để đồng nhất style báo cáo tài chính thực tế.
1. library(ggrepel)
2. step_data_2 <- HSG %>%
3. mutate( DoanhThu_Trieu = `doanh thu ban hang` / 1e6, LoiNhuanGop_Trieu = `loi nhuan gop` / 1e6 )
1. library(ggrepel)
2. ggplot(step_data_2, aes(x=nam, y = LoiNhuanGop_Trieu)) +
3. geom_step(color = "#0072B2", linewidth = 1.3) +
4. geom_ribbon(aes(ymin = 0, ymax = LoiNhuanGop_Trieu), fill = "#0072B2", alpha = 0.2) +
5. geom_step(aes(y = DoanhThu_Trieu), color = "#E69F00", linewidth = 1, linetype = "dashed") +
6. geom_point(color = "red", size = 3, shape = 21, fill = "white") +
7. geom_text_repel(aes(label = paste0(comma(LoiNhuanGop_Trieu, big.mark = ".", decimal.mark = ","), " triệu")), size = 3, color = "black", box.padding = 0.4, max.overlaps = Inf) +
8. scale_x_continuous(breaks = unique(step_data_2$nam),
9. labels = as.character(unique(step_data_2$nam)) )+
10. scale_y_continuous(labels = label_number(big.mark = ".", decimal.mark = ",")) +
11. theme_minimal(base_size = 13) +
12. labs( title = "Biểu đồ BẬC THANG – Doanh thu & Lợi nhuận gộp", subtitle = "Đường xanh: Lợi nhuận gộp | Đường cam: Doanh thu", x = "Năm", y = "Giá trị (triệu đồng)", caption = "Nguồn: Dữ liệu HSG (tính toán nội bộ)" ) +
13. theme( plot.title = element_text(face = "bold", size = 15), plot.subtitle = element_text(size = 12, color = "gray30"), legend.position = "none")
Nhận xét:Biểu đồ cho thấy doanh thu và lợi nhuận gộp của doanh nghiệp diễn biến không đồng đều qua các năm, trong đó doanh thu có các giai đoạn tăng mạnh đột biến rồi ngừng tăng hoặc giảm. Lợi nhuận gộp có xu hướng biến động cùng chiều với doanh thu nhưng mức tăng không đồng bộ, phản ánh áp lực chi phí hoặc thay đổi trong cơ cấu sản phẩm tiêu thụ từng năm. Việc duy trì doanh thu ở mức cao kết hợp cùng biên lợi nhuận ổn định là yếu tố then chốt giúp doanh nghiệp nâng cao hiệu quả kinh doanh bền vững qua các giai đoạn.
Giải thích:Đoạn 1-3: Tạo bảng mới (step_data_2) chuyển doanh thu bán hàng và lợi nhuận gộp sang đơn vị triệu đồng. Đoạn 6: Vẽ đường bước (đường bậc thang) biểu diễn giá trị lợi nhuận gộp từng năm bằng geom_step. . Đoạn 7: Dùng geom_ribbon để tô nền phía dưới đường lợi nhuận gộp. Dải màu này tạo cảm giác “đầy đặn” và làm nổi bật vùng dưới đường giá trị thực, tăng tính trực quan cho biểu đồ bậc thang (). Đoạn 8: Vẽ thêm đường bậc thang thứ hai cho doanh thu, định dạng khác biệt (màu cam, nét đứt), giúp so sánh hai chỉ tiêu trên cùng một biểu đồ mà vẫn dễ phân biệt. Đoạn 9: Đánh dấu các điểm lợi nhuận gộp từng năm bằng geom_point; màu đỏ, rỗng bên trong giúp các điểm dữ liệu nổi bật trên nền biểu đồ và không bị trùng với các đường vẽ.
1. long_df <- HSG %>%
2. select(`Năm` = nam,`Phải trả người bán ngắn hạn` = `Phai tra nguoi ban ngan han`, `Chi phí phải trả ngắn hạn` = `chi phi phai tra ngan han`) %>%
3. pivot_longer( cols = c(`Phải trả người bán ngắn hạn`, `Chi phí phải trả ngắn hạn`), names_to = "Chỉ tiêu", values_to = "Giá trị" )
4. max_val <- max(long_df$`Giá trị`, na.rm = TRUE)
1. ggplot(long_df, aes(x = factor(`Năm`), y = `Giá trị`, fill = `Chỉ tiêu`)) +
2. geom_col(position = position_dodge(width = 0.8), width = 0.7, alpha = 0.9) +
3. geom_text(aes(label = scales::comma(`Giá trị`, big.mark = ".", decimal.mark = ","),y = `Giá trị` + max_val * 0.04), position = position_dodge(width = 0.8), hjust = 0, size =3 , color = "black",fontface = "bold") +
4. labs(title = "Phải trả người bán và Chi phí phải trả",x = "Năm", y = "Giá trị (VNĐ)", fill = "Chỉ tiêu" ) +
5. scale_y_continuous( labels = scales::comma_format(big.mark = ".", decimal.mark = ","), limits = c(0, max_val * 1.15) ) +
6. coord_flip(clip = "off") +
7. theme_minimal(base_size = 15) +
8. theme(axis.text.x = element_text(angle = 45, vjust = 1, hjust = 1),plot.title = element_text(face = "bold", size = 15),legend.position = "bottom",axis.text.y = element_text(size = 11),plot.margin = margin(10, 40, 10, 10))
Nhận xét:Các khoản chi phí phải trả ngắn hạn và phải trả người bán ngắn hạn của doanh nghiệp đều có xu hướng tăng lên rõ rệt trong các năm gần đây, phản ánh quá trình mở rộng quy mô sản xuất, đầu tư hoặc tăng mua hàng hóa đầu vào. Việc các khoản phải trả này liên tục tăng cho thấy áp lực nghĩa vụ thanh toán ngắn hạn ngày một lớn, doanh nghiệp cần chủ động kiểm soát tốt nguồn tiền để đảm bảo khả năng thanh toán và tránh rủi ro mất cân đối tài chính. Tuy nhiên, điều này cũng thể hiện doanh nghiệp có uy tín với nhà cung cấp và tận dụng tốt nguồn vốn từ bên ngoài để tài trợ cho hoạt động kinh doanh ngắn hạn.
Giải thích:Đoạn 1: Khởi tạo biểu đồ với ggplot(long_df, aes(x = factor(Năm), y = Giá trị, fill = Chỉ tiêu)). Đoạn 2: Sử dụng geom_col(position = position_dodge(width = 0.8), width = 0.7, alpha = 0.9) để vẽ các cột và tách riêng cho từng chỉ tiêu trong mỗi năm (nhóm cột cạnh nhau). Đoạn 3-8: Dùng geom_text(…) để hiển thị giá trị cụ thể lên đầu mỗi cột.Đoạn 9: Áp dụng hàm labs(…) để thêm tiêu đề. Đoạn 11: Dùng coord_flip() để đảo trục: trục x thành trục dọc và trục y thành trục ngang, giúp tên năm dài hoặc nhiều nhóm vẫn dễ đọc.
1. HSG <- HSG %>% rename( "Vốn cổ phần" = "von co phan", "LNST chưa phân phối" = "LNSTCPP" )
2. VCSH_data <- HSG %>% select(nam, "Vốn cổ phần", "LNST chưa phân phối") %>%
3. pivot_longer(cols = -nam, names_to = "VCSH", values_to = "gia_tri") %>%
4. group_by(nam) %>%
5. mutate( tong_thu = sum(gia_tri, na.rm = TRUE), tile = gia_tri / tong_thu * 100, tile_lab = paste0(round(tile, 1), "%"))
1. ggplot(VCSH_data, aes(x = factor(nam), y = gia_tri, fill = VCSH)) +
2. geom_col(position = "stack", width = 0.7, alpha = 0.95) +
3. geom_text(aes(label = tile_lab), position = position_stack(vjust = 0.5), size = 3.6, color = "black") +
4. coord_flip() +
5. scale_fill_brewer(palette = "Set2", name = "Thành phần VCSH") +
6. scale_y_continuous(labels = label_number(scale_cut = cut_short_scale())) +
7. labs(title = "Cơ cấu VCSH của HSG theo giá trị thực tế", subtitle = "Hiển thị tỷ trọng (%) trong thanh, trục thể hiện giá trị gốc (VNĐ)",x = "Năm", y = "Giá trị (1T = 1 nghìn tỷ VND)" ) +
8. theme_minimal(base_size = 13) +
9. theme(plot.title = element_text(face = "bold", size = 16), plot.subtitle = element_text(color = "gray30"), legend.position = "bottom",panel.grid.major.y = element_blank(), panel.grid.minor = element_blank() ) +
10. geom_hline(yintercept = 0, color = "gray60", linetype = "dashed", linewidth = 0.4)
Nhận xét: Biểu đồ cho thấy cơ cấu vốn chủ sở hữu của HSG có sự thay đổi rõ rệt qua các năm. Tỷ trọng vốn cổ phần giảm dần, trong khi lợi nhuận sau thuế chưa phân phối tăng lên đáng kể, đặc biệt từ năm 2020 trở đi. Điều này phản ánh doanh nghiệp ngày càng tích lũy được nhiều lợi nhuận giữ lại, tăng khả năng tự chủ tài chính. Xét về kinh tế, xu hướng này cho thấy HSG đang phát triển bền vững hơn, ít phụ thuộc vào việc phát hành thêm cổ phần.
Giải thích: Đoạn 1-2: Tạo biểu đồ với ggplot2. Trục x là năm dưới dạng phân loại, trục y là giá trị tuyệt đối từng chỉ tiêu. Áp dụng geom_col(position = “stack”) để các giá trị chồng lên nhau theo từng loại vốn trong từng năm, biểu diễn đúng kết cấu VCSH. Đoạn 3-5: Dùng geom_text để chèn nhãn tỷ lệ % ngay bên trong cột, đặt ở vị trí giữa mỗi thành phần trong cột với tham số position_stack(vjust = 0.5). Đoạn 6: Sử dụng coord_flip() để xoay biểu đồ nằm ngang, giúp tên năm dễ đọc hơn khi có nhiều nhóm hoặc tên dài. Việc này thường được khuyến nghị cho biểu đồ cột nhiều nhóm.Đoạn 24: Vẽ thêm đường hline tại giá trị 0 để mốc nền dễ quan sát khi cột có thể có cả giá trị âm hoặc so sánh nhiều năm qua.
1. hsg3 <- hsg2 %>% mutate( Cash_norm = as.numeric(scale(tien)))
Tạo thêm một bảng hsg3 nhằm chuẩn hóa dòng tiền (cash) về khoảng [0,1] rồi nhân với max chi phí bán hàng mục đích là đưa đường tiền về cùng thang đo với doanh thu để vẽ chung mà vẫn giữ được hình dạng biến động thực của dòng tiền.
1. ggplot(hsg3, aes(x = factor(nam))) +
2. geom_col(aes(y = `chi phi ban hang`, fill = "Chi phí bán hàng"), alpha = 0.75) +
3. geom_line( aes(y = Cash_norm * max(`chi phi ban hang`, na.rm = TRUE), color = "Tiền (chuẩn hóa)"), size = 1.2, group = 1 ) +
4. geom_point( aes(y = Cash_norm * max(`chi phi ban hang`, na.rm = TRUE), color = "Tiền (chuẩn hóa)"), size = 3 ) +
5. geom_hline(yintercept = 0, colour = "grey40") +
6. scale_y_continuous( labels = function(x) format(x, big.mark = ".", decimal.mark = ",", scientific = FALSE), sec.axis = sec_axis( trans = ~ (. / max(hsg3$`chi phi ban hang`, na.rm = TRUE)),name = "Tiền (tỷ lệ đã chuẩn hóa)", labels = scales::number_format(accuracy = 0.01))) +
7. scale_fill_manual(values = c("Chi phí bán hàng" = "#A7C7E7")) +
8. scale_color_manual(values = c("Tiền (chuẩn hóa)" = "#e31a1c")) +
9. labs( title = "Chi phí bán hàng (cột) và Tiền (đường, đã chuẩn hóa)", x = "Năm", y = "Chi phí bán hàng (VND)", fill = "", color = "" ) +
10. theme_minimal() +
11. theme( legend.position = "top", legend.title = element_blank())
Nhận xét: Có thể thấy chi phí bán hàng biến động mạnh, đặc biệt tăng cao giai đoạn 2019–2022, sau đó giảm sâu vào năm 2023–2024. Trong khi đó, chỉ số tiền tăng giảm thất thường nhưng nhìn chung có xu hướng phục hồi mạnh từ năm 2023. Điều này cho thấy doanh nghiệp có thể đã cắt giảm chi phí bán hàng trong hai năm gần đây để tối ưu hiệu quả tài chính, đồng thời đạt được sự cải thiện về dòng tiền.
Giải thích: Đoạn 1-2: tạo biểu đồ với ggplot2, trục x là năm dưới dạng phân loại. Dùng geom_col để vẽ cột biểu diễn giá trị “Chi phí bán hàng” theo từng năm; mỗi cột có màu riêng do thiết lập với fill.Đoạn 3-4: Thêm đường và điểm hiển thị biến “Tiền (chuẩn hóa)”; biến này được scale về cùng bậc với cột bằng cách nhân với giá trị lớn nhất của “Chi phí bán hàng”. Việc này giúp biểu diễn hai đại lượng chênh nhau về đơn vị trên chung một biểu đồ mà vẫn đọc được tỷ lệ tương đối. Đoạn 5-6: Vẽ thêm đường ngang y=0 và chỉnh cấu hình trục y với format dấu chấm ngăn cách nghìn. Đặt thêm trục phụ (sec_axis) bên phải để hiển thị giá trị “Tiền” đã chuẩn hóa, sử dụng hàm chuyển đổi và định dạng số với hai số thập phân.
1. long_df <- HSG %>%select(`Năm` = nam, `Tiền` = tien, `Tài sản cố định` = TSCD) %>%
2. pivot_longer( cols = c(`Tiền`, `Tài sản cố định`), names_to = "Chỉ tiêu", values_to = "Giá trị")
3. max_val <- max(long_df$`Giá trị`, na.rm = TRUE)
1. ggplot(long_df, aes(x = factor(`Năm`), y = `Giá trị`, fill = `Chỉ tiêu`)) +
2. geom_col(position = position_dodge(width = 0.8), width = 0.7, alpha = 0.9) +
3. geom_text( aes(label = scales::comma(`Giá trị`, big.mark = ".", decimal.mark = ","),y = `Giá trị` + max_val * 0.04 ), position = position_dodge(width = 0.8), hjust = 0, size = 3,color = "black", fontface = "bold" ) +
4. labs(title = "So sánh Tiền và Tài sản cố định", x = "Năm", y = "Giá trị (VNĐ)", fill = "Chỉ tiêu") +
5. scale_y_continuous( labels = scales::comma_format(big.mark = ".", decimal.mark = ","), limits = c(0, max_val * 1.15)) +
6. coord_flip(clip = "off") +
7. theme_minimal(base_size = 13) +
8. theme( axis.text.x = element_text(angle = 45, vjust = 1, hjust = 1), plot.title = element_text(face = "bold", size = 15), legend.position = "bottom", axis.text.y = element_text(size = 11) )
Nhận xét: Qua các năm, tài sản cố định luôn chiếm tỷ trọng lớn hơn rất nhiều so với tiền mặt, cho thấy doanh nghiệp ưu tiên đầu tư dài hạn và mở rộng sản xuất. Tỷ trọng tiền tăng lên gần đây nhưng vẫn thấp, phản ánh doanh nghiệp vẫn giữ chiến lược tài sản chủ đạo là TSCD. Tuy nhiên, doanh nghiệp vẫn duy trì một lượng tiền mặt nhất định qua các năm, đảm bảo khả năng thanh toán và các hoạt động vận hành ổn định
Giải thích: Đoạn 1-2: Tạo dữ liệu và chuẩn hóa để vẽ biểu đồ với ggplot2. Dữ liệu được chuyển sang dạng dài với pivot_longer. Đoạn 3: Xác định giá trị lớn nhất của tất cả chỉ tiêu để dùng cài đặt giới hạn trục tung, đảm bảo biểu đồ không bị cắt cụt khi trình bày, đồng thời hỗ trợ đặt nhãn số ở vị trí hợp lý trên đầu cột. Đoạn 4-6: Dùng ggplot2 vẽ biểu đồ cột nhóm: trục x là năm (dạng phân loại), trục y là giá trị từng chỉ tiêu. Hàm geom_col(position = position_dodge()) làm các cột Tiền và Tài sản cố định cùng năm được đặt sát cạnh nhau để dễ so sánh. Hàm geom_text chèn nhãn số đã định dạng dấu chấm hàng nghìn, dấu phẩy thập phân.