LỜI CẢM ƠN

Chúng em xin bày tỏ lòng biết ơn đặc biệt đến ThS. Trần Mạnh Tường – người đã tận tình dìu dắt và truyền đạt kiến thức trong suốt thời gian qua. Nhờ sự hướng dẫn tâm huyết và những lời khuyên quý báu của Thầy, chúng em đã có thể hoàn thành bài báo cáo tiểu luận này một cách trọn vẹn nhất. Vô cùng trân trọng những bài học quý giá mà Thầy đã dành cho, không chỉ về kiến thức chuyên môn mà còn về thái độ học tập và làm việc nghiêm túc, trách nhiệm.

Chúng em nhận thức được rằng bài báo cáo này vẫn còn tồn tại một số hạn chế và thiếu sót. Xin chân thành mong nhận được những góp ý quý báu từ thầy để em có thể hoàn thiện bản thân và đạt được kết quả tốt hơn trong học tập và công việc sau này.

Cuối cùng, xin kính chúc quý thầy sức khỏe, dồi dào nhiệt huyết và thành công trong sự nghiệp trồng người. Chúng em xin chân thành cảm ơn!

LỜI CAM KẾT

Nhóm chúng em xin cam đoan số liệu và kết quả nghiên cứu trong bài tiểu luận này là trung thực và các thông tin trích dẫn trong báo cáo đã được chỉ rõ nguồn gốc rõ ràng và được phép công bố.

KẾT CẤU

Bài báo cáo tiểu luận của nhóm chúng em bao gồm 2 phần:

  • Phần 1: Phân tích tiêu thụ điện năng ở Vương quốc Anh: giai đoạn 2009 - 2024

  • Phần 2: Phân tích CTCP Chứng khoán SSI thông qua báo cáo tài chính: giai đoạn 2015 - 2024

Hai chương là hai phần nội dung tách biệt nhau

PHẦN 1: PHÂN TÍCH TIÊU THỤ ĐIỆN NĂNG Ở VƯƠNG QUỐC ANH: GIAI ĐOẠN 2009 - 2024

Ở phần 1, nhóm chúng em đã sử dụng bộ dữ liệu về lịch sử tiêu thụ điện năng ở Vương quốc Anh trong khoảng thời gian từ năm 2009 đến năm 2024 được lấy từ nguồn Kaggle - một nền tảng trực tuyến cho cộng đồng khoa học dữ liệu. Bộ dữ liệu được National Grid ESO - đơn vị vận hành hệ thống điện cho Vương quốc Anh thu thập và được cập nhật hai lần mỗi giờ, tức có nghĩa là có 48 mục mỗi ngày.

Cài đặt và tải các gói cần thiết

install.packages("dplyr", repos = "https://cran.rstudio.com/")
## package 'dplyr' successfully unpacked and MD5 sums checked
## 
## The downloaded binary packages are in
##  C:\Users\trngo\AppData\Local\Temp\RtmpQ3B9Mb\downloaded_packages
library(dplyr)
install.packages("lubridate", repos = "https://cran.rstudio.com/")
## package 'lubridate' successfully unpacked and MD5 sums checked
## 
## The downloaded binary packages are in
##  C:\Users\trngo\AppData\Local\Temp\RtmpQ3B9Mb\downloaded_packages
library(lubridate)
install.packages("ggplot2", repos = "https://cran.rstudio.com/")
## package 'ggplot2' successfully unpacked and MD5 sums checked
## 
## The downloaded binary packages are in
##  C:\Users\trngo\AppData\Local\Temp\RtmpQ3B9Mb\downloaded_packages
library(ggplot2)
install.packages("scales", repos = "https://cran.rstudio.com/")
## package 'scales' successfully unpacked and MD5 sums checked
## 
## The downloaded binary packages are in
##  C:\Users\trngo\AppData\Local\Temp\RtmpQ3B9Mb\downloaded_packages
library(scales)
install.packages("knitr", repos = "https://cran.rstudio.com/")
## package 'knitr' successfully unpacked and MD5 sums checked
## 
## The downloaded binary packages are in
##  C:\Users\trngo\AppData\Local\Temp\RtmpQ3B9Mb\downloaded_packages
library(knitr)
library(kableExtra)
options(repos = c(CRAN = "https://cran.rstudio.com/"))
install.packages("igraph")
## 
##   There is a binary version available but the source version is later:
##        binary source needs_compilation
## igraph  2.2.0  2.2.1              TRUE
## 
##   Binaries will be installed
## package 'igraph' successfully unpacked and MD5 sums checked
## 
## The downloaded binary packages are in
##  C:\Users\trngo\AppData\Local\Temp\RtmpQ3B9Mb\downloaded_packages
library(igraph)
install.packages("ggraph")
## package 'ggraph' successfully unpacked and MD5 sums checked
## 
## The downloaded binary packages are in
##  C:\Users\trngo\AppData\Local\Temp\RtmpQ3B9Mb\downloaded_packages
library(ggraph)
install.packages("treemapify")
## package 'treemapify' successfully unpacked and MD5 sums checked
## 
## The downloaded binary packages are in
##  C:\Users\trngo\AppData\Local\Temp\RtmpQ3B9Mb\downloaded_packages
library(treemapify)
install.packages("rnaturalearth")
## package 'rnaturalearth' successfully unpacked and MD5 sums checked
## 
## The downloaded binary packages are in
##  C:\Users\trngo\AppData\Local\Temp\RtmpQ3B9Mb\downloaded_packages
library(rnaturalearth)
install.packages("rnaturalearthdata")
## package 'rnaturalearthdata' successfully unpacked and MD5 sums checked
## 
## The downloaded binary packages are in
##  C:\Users\trngo\AppData\Local\Temp\RtmpQ3B9Mb\downloaded_packages
library(rnaturalearthdata)
library(sf)
install.packages("patchwork")
## package 'patchwork' successfully unpacked and MD5 sums checked
## 
## The downloaded binary packages are in
##  C:\Users\trngo\AppData\Local\Temp\RtmpQ3B9Mb\downloaded_packages
library(patchwork)
install.packages("tibble")
## package 'tibble' successfully unpacked and MD5 sums checked
## 
## The downloaded binary packages are in
##  C:\Users\trngo\AppData\Local\Temp\RtmpQ3B9Mb\downloaded_packages
library(tibble)
library(tidyr)
library(psych)
library(tidyverse)
install.packages("corrr")
## package 'corrr' successfully unpacked and MD5 sums checked
## 
## The downloaded binary packages are in
##  C:\Users\trngo\AppData\Local\Temp\RtmpQ3B9Mb\downloaded_packages
library(corrr)
install.packages("gganimate")
## package 'gganimate' successfully unpacked and MD5 sums checked
## 
## The downloaded binary packages are in
##  C:\Users\trngo\AppData\Local\Temp\RtmpQ3B9Mb\downloaded_packages
library(gganimate)
install.packages("gifski")
## package 'gifski' successfully unpacked and MD5 sums checked
## 
## The downloaded binary packages are in
##  C:\Users\trngo\AppData\Local\Temp\RtmpQ3B9Mb\downloaded_packages
library(gifski)

1. Giới thiệu bộ dữ liệu (10 thao tác)

Thao tác 1: Đọc dữ liệu từ tệp CSV

dataUK <- read.csv("dataUK.csv") # đọc dữ liệu từ tệp "dataUK.csv" và tạo ra một data frame tên là "dataUK" cho việc xử lý và phân tích ở các bước tiếp theo

Bộ dữ liệu đã được nhập vào.

Thao tác 2: Kiểm tra kích thước của bộ dữ liệu

dim(dataUK) # lấy một vector chứa 2 giá trị số nguyên: [số hàng, số cột] của data frame "dataUK".
## [1] 278512     19

Bộ dữ liệu có tất cả 278512 hàng (tức 278512 quan sát) và 19 cột (tức 19 biến).

Thao tác 3: Kiểm tra các giá trị bị thiếu (NA) trên mỗi cột

colSums(is.na(dataUK)) # dùng "is.na()" để xác định các giá trị thiếu, sau đó dùng "colSums()" để đếm số lượng các giá trị thiếu đó cho từng biến (cột) trong tệp dữ liệu "dataUK".
##           settlement_date         settlement_period               period_hour 
##                         0                         0                         0 
##                        nd                       tsd      england_wales_demand 
##                         0                         0                         0 
##  embedded_wind_generation    embedded_wind_capacity embedded_solar_generation 
##                         0                         0                         0 
##   embedded_solar_capacity               non_bm_stor      pump_storage_pumping 
##                         0                         0                         0 
##                  ifa_flow                 ifa2_flow              britned_flow 
##                         0                         0                         0 
##                moyle_flow            east_west_flow                 nemo_flow 
##                         0                         0                         0 
##                is_holiday 
##                         0

Bộ dữ liệu không có giá trị bị thiếu.

Thao tác 4: Kiểm tra số lượng quan sát trùng lặp

sum(duplicated(dataUK)) # dùng "duplicated()" để tìm tất cả các hàng trùng lặp, sau đó dùng "sum()" để đếm tổng số lượng các hàng trùng lặp đó trong tệp dữ liệu "dataUK".
## [1] 0

Bộ dữ liệu không có hiện tượng trùng lặp.

Thao tác 5: Kiểm tra cấu trúc bộ dữ liệu

str(dataUK) # hàm "str()" để in ra tóm tắt về kiểu đối tượng, số lượng quan sát (hàng), số lượng biến (cột), tên của từng biến, kiểu dữ liệu của từng biến, và một vài giá trị đầu tiên của mỗi biến.
## 'data.frame':    278512 obs. of  19 variables:
##  $ settlement_date          : chr  "01/01/2009 00:00" "01/01/2009 00:30" "01/01/2009 01:00" "01/01/2009 01:30" ...
##  $ settlement_period        : int  1 2 3 4 5 6 7 8 9 10 ...
##  $ period_hour              : chr  "00:00:00" "00:30:00" "01:00:00" "01:30:00" ...
##  $ nd                       : int  37910 38047 37380 36426 35687 35408 34322 33076 31970 31270 ...
##  $ tsd                      : int  38704 38964 38651 37775 37298 37135 36844 35678 34635 33934 ...
##  $ england_wales_demand     : int  33939 34072 33615 32526 31877 31604 30486 29390 28452 27842 ...
##  $ embedded_wind_generation : int  54 53 53 50 50 43 43 56 56 56 ...
##  $ embedded_wind_capacity   : int  1403 1403 1403 1403 1403 1403 1403 1403 1403 1403 ...
##  $ embedded_solar_generation: int  0 0 0 0 0 0 0 0 0 0 ...
##  $ embedded_solar_capacity  : int  0 0 0 0 0 0 0 0 0 0 ...
##  $ non_bm_stor              : int  0 0 0 0 0 0 0 0 0 0 ...
##  $ pump_storage_pumping     : int  33 157 511 589 851 967 1762 1842 1905 1904 ...
##  $ ifa_flow                 : int  2002 2002 2002 1772 1753 1754 1754 1755 1755 1754 ...
##  $ ifa2_flow                : int  0 0 0 0 0 0 0 0 0 0 ...
##  $ britned_flow             : int  0 0 0 0 0 0 0 0 0 0 ...
##  $ moyle_flow               : int  -161 -160 -160 -160 -160 -160 -160 -160 -160 -160 ...
##  $ east_west_flow           : int  0 0 0 0 0 0 0 0 0 0 ...
##  $ nemo_flow                : int  0 0 0 0 0 0 0 0 0 0 ...
##  $ is_holiday               : int  1 1 1 1 1 1 1 1 1 1 ...

Trong 19 biến, có 17 biến định lượng (int) và 2 biến định tính (chr).

Thao tác 6: Xem 10 dòng dữ liệu đầu tiên & Xem 10 dòng dữ liệu cuối cùng

head(dataUK, 10)
##     settlement_date settlement_period period_hour    nd   tsd
## 1  01/01/2009 00:00                 1    00:00:00 37910 38704
## 2  01/01/2009 00:30                 2    00:30:00 38047 38964
## 3  01/01/2009 01:00                 3    01:00:00 37380 38651
## 4  01/01/2009 01:30                 4    01:30:00 36426 37775
## 5  01/01/2009 02:00                 5    02:00:00 35687 37298
## 6  01/01/2009 02:30                 6    02:30:00 35408 37135
## 7  01/01/2009 03:00                 7    03:00:00 34322 36844
## 8  01/01/2009 03:30                 8    03:30:00 33076 35678
## 9  01/01/2009 04:00                 9    04:00:00 31970 34635
## 10 01/01/2009 04:30                10    04:30:00 31270 33934
##    england_wales_demand embedded_wind_generation embedded_wind_capacity
## 1                 33939                       54                   1403
## 2                 34072                       53                   1403
## 3                 33615                       53                   1403
## 4                 32526                       50                   1403
## 5                 31877                       50                   1403
## 6                 31604                       43                   1403
## 7                 30486                       43                   1403
## 8                 29390                       56                   1403
## 9                 28452                       56                   1403
## 10                27842                       56                   1403
##    embedded_solar_generation embedded_solar_capacity non_bm_stor
## 1                          0                       0           0
## 2                          0                       0           0
## 3                          0                       0           0
## 4                          0                       0           0
## 5                          0                       0           0
## 6                          0                       0           0
## 7                          0                       0           0
## 8                          0                       0           0
## 9                          0                       0           0
## 10                         0                       0           0
##    pump_storage_pumping ifa_flow ifa2_flow britned_flow moyle_flow
## 1                    33     2002         0            0       -161
## 2                   157     2002         0            0       -160
## 3                   511     2002         0            0       -160
## 4                   589     1772         0            0       -160
## 5                   851     1753         0            0       -160
## 6                   967     1754         0            0       -160
## 7                  1762     1754         0            0       -160
## 8                  1842     1755         0            0       -160
## 9                  1905     1755         0            0       -160
## 10                 1904     1754         0            0       -160
##    east_west_flow nemo_flow is_holiday
## 1               0         0          1
## 2               0         0          1
## 3               0         0          1
## 4               0         0          1
## 5               0         0          1
## 6               0         0          1
## 7               0         0          1
## 8               0         0          1
## 9               0         0          1
## 10              0         0          1
tail(dataUK, 10)
##         settlement_date settlement_period period_hour    nd   tsd
## 278503 05/12/2024 19:00                39    19:00:00 36248 37360
## 278504 05/12/2024 19:30                40    19:30:00 34942 36009
## 278505 05/12/2024 20:00                41    20:00:00 33594 34676
## 278506 05/12/2024 20:30                42    20:30:00 32220 33433
## 278507 05/12/2024 21:00                43    21:00:00 30535 32276
## 278508 05/12/2024 21:30                44    21:30:00 29114 31431
## 278509 05/12/2024 22:00                45    22:00:00 27204 29846
## 278510 05/12/2024 22:30                46    22:30:00 26006 28805
## 278511 05/12/2024 23:00                47    23:00:00 23908 26825
## 278512 05/12/2024 23:30                48    23:30:00 23217 26133
##        england_wales_demand embedded_wind_generation embedded_wind_capacity
## 278503                33642                     5291                   6622
## 278504                32600                     5367                   6622
## 278505                31452                     5373                   6622
## 278506                30212                     5379                   6622
## 278507                28652                     5378                   6622
## 278508                27212                     5377                   6622
## 278509                25477                     5486                   6622
## 278510                24428                     5594                   6622
## 278511                22590                     5575                   6622
## 278512                21958                     5556                   6622
##        embedded_solar_generation embedded_solar_capacity non_bm_stor
## 278503                         0                   17194           0
## 278504                         0                   17194           0
## 278505                         0                   17194           0
## 278506                         0                   17194           0
## 278507                         0                   17194           0
## 278508                         0                   17194           0
## 278509                         0                   17194           0
## 278510                         0                   17194           0
## 278511                         0                   17194           0
## 278512                         0                   17194           0
##        pump_storage_pumping ifa_flow ifa2_flow britned_flow moyle_flow
## 278503                    9     1950       986         1004       -451
## 278504                   13     1999       991         1004       -430
## 278505                    9     1918       939         1004       -310
## 278506                    8     1875       931         1004       -290
## 278507                  250      694       780         1002       -426
## 278508                  736      558       758         1003       -450
## 278509                  868     -193       263         1002       -450
## 278510                  944     -274       211          997       -450
## 278511                  864     -404       -77          280       -450
## 278512                  820     -415      -101          218       -450
##        east_west_flow nemo_flow is_holiday
## 278503            -52       999          0
## 278504            -24       999          0
## 278505           -163       999          0
## 278506           -315       999          0
## 278507           -465       999          0
## 278508           -531       999          0
## 278509           -531       949          0
## 278510           -531       943          0
## 278511           -522       338          0
## 278512           -530       292          0

Kết quả cho ra 10 dòng dữ liệu đầu tiên và 10 dòng dữ liệu cuối cùng.

Thao tác 7: Đếm tần suất của biến nhị phân

table(dataUK$is_holiday) # dùng hàm "table()" để đếm tần suất của các giá trị riêng biệt trong cột dữ liệu "is_holiday".
## 
##      0      1 
## 272272   6240

Trong 278512 quan sát của bộ dữ liệu, với biến nhị phân “is_holiday”, tần suất xuất hiện của giá trị 0 là 272272 và tần suất xuất hiện của giá trị 1 là 6240 (giá trị 0 biểu thị ngày thường, giá trị 1 biểu thị ngày lễ).

Thao tác 8: Kiểm tra thứu tự sắp xếp

is.unsorted(dataUK$settlement_period) # dùng hàm "is.unsorted()" để kiểm tra xem cột dữ liệu "settlement_period" có bị sắp xếp sai thứ tự hay không
## [1] TRUE

Kết quả cho thấy rằng cột dữ liệu “settlement_period” chưa được sắp xếp theo thứ tự tăng dần, tức là các giá trị trong cột này nằm lộn xộn, không có trật tự. Lý giải cho điều này là bởi vì dữ liệu được thu thập 2 lần mỗi giờ, tức là 48 lần mỗi ngày, và sang ngày hôm sau chu trình này tiếp tục diễn ra. Do đó, khi kiểm tra cột “settlement_period”, chúng ta sẽ thấy kết quả cho ra từ hàm “is.unsorted()” là TRUE.

Thao tác 9: Liệt kê tên các cột

names(dataUK) # dùng hàm "names()" để lấy ra một danh sách chuỗi văn bản (character vector), trong đó mỗi chuỗi là tên của một biến (cột) trong tệp dữ liệu "dataUK".
##  [1] "settlement_date"           "settlement_period"        
##  [3] "period_hour"               "nd"                       
##  [5] "tsd"                       "england_wales_demand"     
##  [7] "embedded_wind_generation"  "embedded_wind_capacity"   
##  [9] "embedded_solar_generation" "embedded_solar_capacity"  
## [11] "non_bm_stor"               "pump_storage_pumping"     
## [13] "ifa_flow"                  "ifa2_flow"                
## [15] "britned_flow"              "moyle_flow"               
## [17] "east_west_flow"            "nemo_flow"                
## [19] "is_holiday"

Danh sách tên của 19 biến, tương ứng với 19 cột trong bộ dữ liệu lần lượt là:

  1. settlement_date

  2. settlement_period

  3. period_hour

  4. nd

  5. tsd

  6. england_wales_demand

  7. embedded_wind_generation

  8. embedded_wind_capacity

  9. embedded_solar_generation

  10. embedded_solar_capacity

  11. non_bm_stor

  12. pump_storage_pumping

  13. ifa_flow

  14. ifa2_flow

  15. britned_flow

  16. moyle_flow

  17. east_west_flow

  18. nemo_flow

  19. is_holiday

Thao tác 10: Bảng tổng hợp các biến số

variable_summary <- data.frame( # dùng hàm "data.frame()"để xây dựng một khung dữ liệu (data frame) mới từ các vector (danh sách) có độ dài bằng nhau.
  Biến = c( # tạo một cột mới tên là "Biến" bằng cách sử dụng một vector ký tự chứa tên của 19 biến (cột) trong "dataUK".
    "settlement_date",
    "settlement_period", 
    "period_hour",
    "nd (National Demand)",
    "tsd (Transmission System Demand)",
    "england_wales_demand", 
    "embedded_wind_generation",
    "embedded_wind_capacity",
    "embedded_solar_generation",
    "embedded_solar_capacity",
    "non_bm_stor",
    "pump_storage_pumping",
    "ifa_flow",
    "ifa2_flow",
    "britned_flow", 
    "moyle_flow",
    "east_west_flow",
    "nemo_flow",
    "is_holiday"
  ),
  Ý_nghĩa = c( # tạo ra một cột tên là "Ý_nghĩa" bằng cách sử dụng một vector ký tự chứa nội dung mô tả chi tiết tương ứng với mỗi biến.
    "ngày ghi nhận dữ liệu theo định dạng dd/mm/yy",
    "chu kỳ nửa giờ cho sản lượng lịch sử đã xảy ra",
    "Giờ trong ngày (được làm tròn đến giờ tiếp theo)",
    "tổng sản lượng điện được đo đếm, nhưng không bao gồm sản lượng điện cần thiết để đáp ứng tải tại các trạm, bơm tích trữ và xuất khẩu liên kết, được tính bằng tổng sản lượng điện dựa trên công tơ đo đếm phát điện vận hành của National Grid ESO",
    "bằng nd cộng với sản lượng điện bổ sung cần thiết để đáp ứng tải tại các trạm, bơm tích trữ và xuất khẩu liên kết",
    "nhu cầu của Anh và xứ Wales, như nd ở trên nhưng dựa trên cơ sở Anh và xứ Wales",
    "ước tính sản lượng điện gió của Vương quốc Anh từ các trang trại gió không lắp đặt công tơ đo đếm Hệ thống Truyền tải. Các trang trại gió này được nhúng trong mạng lưới phân phối và không được ESO của National Grid ESO theo dõi. Tác dụng của chúng là giảm nhu cầu điện trong thời kỳ gió mạnh. Công suất thực tế của các máy phát điện này chưa được biết rõ, do đó, ước tính được đưa ra dựa trên mô hình tốt nhất của National Grid ESO",
    "là góc nhìn tốt nhất của National Grid ESO về công suất điện gió nhúng đã lắp đặt tính bằng GB. Thông tin này dựa trên thông tin công khai được tổng hợp từ nhiều nguồn khác nhau và không phải là góc nhìn chính thức. Nó phù hợp với ước tính sản lượng điện được cung cấp ở trên",
    "ước tính sản lượng điện mặt trời của GB từ các tấm pin quang điện. Các tấm pin này được lắp đặt trong lưới điện phân phối và không được National Grid ESO phát hiện. Tác dụng của chúng là giảm nhu cầu điện trong thời kỳ bức xạ mạnh. Công suất thực tế của các máy phát điện này chưa được biết rõ, do đó, ước tính được đưa ra dựa trên mô hình tốt nhất của National Grid ESO",
    "dành cho các đơn vị không được bao gồm trong định nghĩa máy phát điện ND. Điều này có thể ở dạng giảm phát điện hoặc giảm nhu cầu",
    "nhu cầu do bơm tại các đơn vị lưu trữ bơm thủy điện; -ve biểu thị tải bơm",
    "nhu cầu do bơm tại các đơn vị lưu trữ bơm thủy điện; -ve biểu thị tải bơm",
    "dòng chảy trên liên kết tương ứng, -ve biểu thị công suất xuất ra từ GB; +ve biểu thị công suất nhập vào GB",
    "lưu lượng trên liên kết tương ứng. -ve biểu thị công suất xuất ra từ Vương quốc Anh; +ve biểu thị công suất nhập vào Vương quốc Anh",
    "lưu lượng trên liên kết tương ứng. -ve biểu thị công suất nhập vào Vương quốc Anh; +ve biểu thị công suất xuất ra từ Vương quốc Anh",
    "dòng chảy trên liên kết tương ứng. -ve biểu thị công suất xuất ra từ GB; +ve biểu thị công suất nhập vào GB",
    "lưu lượng trên liên kết tương ứng. -ve biểu thị công suất xuất ra từ Vương quốc Anh; +ve biểu thị công suất nhập vào Vương quốc Anh",
    "lưu lượng trên liên kết tương ứng. -ve biểu thị công suất xuất ra từ Vương quốc Anh; +ve biểu thị công suất nhập vào Vương quốc Anh",
    "biến nhị phân (1 = Ngày lễ, 0 = Ngày thường)"
  ),
  Đơn_vị_tính = c( # tạo ra một cột tên là "Đơn_vị_tính" bằng cách sử dụng một vector ký tự chứa nội dung mô tả chi tiết tương ứng với mỗi biến.
    "",
    "",
    "",
    "MW",                      
    "MW",                       
    "MW",                       
    "MW",                      
    "MW",                       
    "MW",                     
    "MW",                       
    "MW",                      
    "MW",                       
    "MW",                       
    "MW",                       
    "MW",
    "MW",
    "MW",
    "MW",                     
    "Binary (0/1)"
  )
)
# Kết quả: Một khung dữ liệu mới tên là "variable_summary" được tạo ra, với 3 cột (Biến, Ý_nghĩa, Đơn_vị_tính) và 19 hàng.
kable(
  variable_summary, 
  caption = "**MÔ TẢ CÁC BIẾN TRONG BỘ DỮ LIỆU**", 
  align = c('l', 'l', 'c'),
  col.names.align = 'c',
  format = "html"
) # dùng hàm "kable" từ gói "knitr" để định dạng các bảng dữ liệu thành các định dạng đầu ra đẹp mắt và dễ đọc. Trong đó: "variable_summary" là đối số đầu tiên là khung dữ liệu cần hiển thị, "caption = "..."" là Thêm một tiêu đề mô tả cho bảng, "align = 'l'" là Căn chỉnh văn bản trong các cột sang trái (left).
MÔ TẢ CÁC BIẾN TRONG BỘ DỮ LIỆU
Biến Ý_nghĩa Đơn_vị_tính
settlement_date ngày ghi nhận dữ liệu theo định dạng dd/mm/yy
settlement_period chu kỳ nửa giờ cho sản lượng lịch sử đã xảy ra
period_hour Giờ trong ngày (được làm tròn đến giờ tiếp theo)
nd (National Demand) tổng sản lượng điện được đo đếm, nhưng không bao gồm sản lượng điện cần thiết để đáp ứng tải tại các trạm, bơm tích trữ và xuất khẩu liên kết, được tính bằng tổng sản lượng điện dựa trên công tơ đo đếm phát điện vận hành của National Grid ESO MW
tsd (Transmission System Demand) bằng nd cộng với sản lượng điện bổ sung cần thiết để đáp ứng tải tại các trạm, bơm tích trữ và xuất khẩu liên kết MW
england_wales_demand nhu cầu của Anh và xứ Wales, như nd ở trên nhưng dựa trên cơ sở Anh và xứ Wales MW
embedded_wind_generation ước tính sản lượng điện gió của Vương quốc Anh từ các trang trại gió không lắp đặt công tơ đo đếm Hệ thống Truyền tải. Các trang trại gió này được nhúng trong mạng lưới phân phối và không được ESO của National Grid ESO theo dõi. Tác dụng của chúng là giảm nhu cầu điện trong thời kỳ gió mạnh. Công suất thực tế của các máy phát điện này chưa được biết rõ, do đó, ước tính được đưa ra dựa trên mô hình tốt nhất của National Grid ESO MW
embedded_wind_capacity là góc nhìn tốt nhất của National Grid ESO về công suất điện gió nhúng đã lắp đặt tính bằng GB. Thông tin này dựa trên thông tin công khai được tổng hợp từ nhiều nguồn khác nhau và không phải là góc nhìn chính thức. Nó phù hợp với ước tính sản lượng điện được cung cấp ở trên MW
embedded_solar_generation ước tính sản lượng điện mặt trời của GB từ các tấm pin quang điện. Các tấm pin này được lắp đặt trong lưới điện phân phối và không được National Grid ESO phát hiện. Tác dụng của chúng là giảm nhu cầu điện trong thời kỳ bức xạ mạnh. Công suất thực tế của các máy phát điện này chưa được biết rõ, do đó, ước tính được đưa ra dựa trên mô hình tốt nhất của National Grid ESO MW
embedded_solar_capacity dành cho các đơn vị không được bao gồm trong định nghĩa máy phát điện ND. Điều này có thể ở dạng giảm phát điện hoặc giảm nhu cầu MW
non_bm_stor nhu cầu do bơm tại các đơn vị lưu trữ bơm thủy điện; -ve biểu thị tải bơm MW
pump_storage_pumping nhu cầu do bơm tại các đơn vị lưu trữ bơm thủy điện; -ve biểu thị tải bơm MW
ifa_flow dòng chảy trên liên kết tương ứng, -ve biểu thị công suất xuất ra từ GB; +ve biểu thị công suất nhập vào GB MW
ifa2_flow lưu lượng trên liên kết tương ứng. -ve biểu thị công suất xuất ra từ Vương quốc Anh; +ve biểu thị công suất nhập vào Vương quốc Anh MW
britned_flow lưu lượng trên liên kết tương ứng. -ve biểu thị công suất nhập vào Vương quốc Anh; +ve biểu thị công suất xuất ra từ Vương quốc Anh MW
moyle_flow dòng chảy trên liên kết tương ứng. -ve biểu thị công suất xuất ra từ GB; +ve biểu thị công suất nhập vào GB MW
east_west_flow lưu lượng trên liên kết tương ứng. -ve biểu thị công suất xuất ra từ Vương quốc Anh; +ve biểu thị công suất nhập vào Vương quốc Anh MW
nemo_flow lưu lượng trên liên kết tương ứng. -ve biểu thị công suất xuất ra từ Vương quốc Anh; +ve biểu thị công suất nhập vào Vương quốc Anh MW
is_holiday biến nhị phân (1 = Ngày lễ, 0 = Ngày thường) Binary (0/1)

Trên đây là bảng mô tả chi tiết các biến trong bộ dữ liệu, bao gồm tên biến, ý nghĩa và đơn vị tính của các biến.

2. Xử lý dữ liệu thô, mã hóa dữ liệu (10 thao tác)

Thao tác 1: Xử lý dữ liệu

processed_data <- dataUK %>%
  mutate(
    settlement_date = dmy_hm(settlement_date), 
    year = year(settlement_date),
    month = month(settlement_date, label = TRUE, abbr = FALSE),
    weekday = wday(settlement_date, label = TRUE, abbr = FALSE),
    hour = as.numeric(substr(period_hour, 1, 2))
  )

Thao tác 2: Xóa các biến số không cần thiết

processed_data$non_bm_stor <- NULL # gán giá trị NULL cho biến "non_bm_stor", loại bỏ chúng khỏi tệp dữ liệu.
processed_data$pump_storage_pumping <- NULL # gán giá trị NULL cho biến "pump_storage_pumping", loại bỏ chúng khỏi tệp dữ liệu.

Hai biến “non_bm_stor” và “pump_storage_pumping” đã được xóa.

Thao tác 3: Tạo 2 biến mới

processed_data <- processed_data %>% 
  mutate(
    total_flow = ifa_flow + ifa2_flow + britned_flow + moyle_flow + east_west_flow + nemo_flow,
    embedded_ratio = (embedded_wind_generation + embedded_solar_generation)/nd
)
# dùng cú pháp tidyverse (%>% và mutate()) để tạo một cột mới tên là "total_flow" bằng cách cộng giá trị của năm cột luồng điện khác nhau.

Thao tác 4: Phân tổ dữ liệu theo mùa

processed_data <- processed_data %>%
  mutate(
    season = case_when(
      month %in% c("December", "January", "February") ~ "Winter",
      month %in% c("March", "April", "May") ~ "Spring",
      month %in% c("June", "July", "August") ~ "Summer",
      month %in% c("September", "October", "November") ~ "Autumn"
    )
  )

Thao tác 5: Phân tổ dữ liệu theo buổi trong ngày

processed_data <- processed_data %>%
  mutate(
    time_of_day = case_when(
      hour >= 5 & hour < 12 ~ "Morning",
      hour >= 12 & hour < 17 ~ "Afternoon",
      hour >= 17 & hour < 22 ~ "Evening",
      TRUE ~ "Night"
    )
  )

Thao tác 6: Phân tổ dữ liệu loại ngày

processed_data <- processed_data %>%
  mutate(
    day_group = case_when(
      is_holiday == 1 ~ "Ngày lễ",
      is_holiday == 0 ~ "Ngày thường"
    )
  )

Thao tác 7: Phân tổ dữ liệu theo Nhu cầu Quốc gia

processed_data <- processed_data %>%
  mutate(
    nd_group = case_when(
      nd <= 20000 ~ "Nhu cầu thấp",
      nd > 20000 & nd <= 40000 ~ "Nhu cầu trung bình",
      nd > 40000 ~ "Nhu cầu cao"
    )
  )

Thao tác 8: Phân tổ dữ liệu theo năm ghi nhận

processed_data <- processed_data %>%
  mutate(
    year_group = case_when(
      year <= 2012 ~ "Early Period",
      year > 2012 & year <= 2016 ~ "Mid Period",
      year > 2016 & year <= 2020 ~ "Later Period",
      TRUE ~ "Recent Period"
    )
  )

Thao tác 9: Phân tổ dữ liệu theo mức độ dòng chảy kết nối (interconnector flow)

processed_data <- processed_data %>%
  mutate(
    flow_group = case_when(
      total_flow < -2000 ~ "Large Net Export",
      total_flow >= -2000 & total_flow < -500 ~ "Moderate Net Export",
      total_flow >= -500 & total_flow <= 500 ~ "Near Balance",
      total_flow > 500 & total_flow <= 2000 ~ "Moderate Net Import",
      total_flow > 2000 ~ "Large Net Import"
    )
  )

Thao tác 10: Phân tổ dữ liệu theo chỉ số “embedded_ratio”

processed_data <- processed_data %>%
  mutate(
    em_ra_group = case_when(
      embedded_ratio <= 0.05 ~ "Very Low Renewable Impact",
    embedded_ratio > 0.05 & embedded_ratio <= 0.15 ~ "Low Renewable Impact",
    embedded_ratio > 0.15 & embedded_ratio <= 0.3 ~ "Medium Renewable Impact",
    TRUE ~ "High Renewable Impact"
    )
  )

3. Thống kê cơ bản (10 thao tác)

Thao tác 1: Tính toán và hiển thị các thống kê mô tả cơ bản cho biến định lượng nd

describe(processed_data$nd) # Tính toán và hiển thị các thống kê mô tả cho cột nd
##    vars      n     mean      sd median  trimmed    mad   min   max range skew
## X1    1 278512 31187.04 7831.31  30491 30826.31 8814.8 13367 59095 45728 0.38
##    kurtosis    se
## X1    -0.49 14.84

Kết quả:

  • Mean = 31187.04: giá trị trung bình của nd là 31187.04 MW.

  • sd = 7831.31: độ lệch chuẩn hay độ phân tán trung bình của dữ liệu quanh giá trị là 7831.31 (mức biến động lớn).

  • median = 30491: giá trị trung vị hay giá trị nằm chính giữa tập dữ liệu là 30491 MW.

  • trimmed = 30826.31: trung bình hiệu chỉnh sau khi loại 10% dữ liệu ở hai đầu (giúp giảm ảnh hưởng của ngoại lai).

  • mad = 8814.8: độ lệch tuyệt đối trung vị.

  • min = 13367: giá trị thấp nhất của nd là 13367 MW.

  • max = 59095: giá trị cao nhất của nd là 59095 MW.

  • range = 45728: khoảng biến thiên của nd.

  • skew = 0.38: độ xiên dương (>0), phân phối xiên phải, phần đuôi của đồ thị phân phối biến nd kéo dài về phía bên phải. Điều này có nghĩa là có một số lượng nhỏ các giá trị cực đoan cao (ngoại lai dương) kéo giá trị trung bình lên cao hơn so với trung vị.

  • kurtosis = -0.49: độ nhọn âm (<0), cho thấy phân phối dẹt hơn so với phân phối chuẩn (platykurtic), tức là ít ngoại lai cực đoan hơn.

  • se = 14.84: sai số chuẩn của trung bình, ước tính độ chính xác của giá trị trung bình mẫu, chứng tỏ rằng nếu bạn lặp lại quá trình lấy mẫu và tính toán giá trị trung bình nhiều lần, trung bình mẫu của bạn sẽ dao động xung quanh trung bình thực của tổng thể với độ biến thiên xấp xỉ \(14.84\) đơn vị.

Thao tác 2: tính toán tần suất (số lượng) và tỷ lệ phần trăm của các quan sát trong tập dữ liệu theo từng mùa (season)

season_counts <- table(processed_data$season) # Đếm số lượng quan sát cho mỗi mùa
season_props <- prop.table(season_counts)*100 # Tính tỷ lệ phần trăm của mỗi mùa
season_summary <- data.frame( # Tạo dataframe tóm tắt kết quả
  Mùa = names(season_counts), # Lấy tên các mùa (hàng)
  Số_lượng = as.numeric(season_counts), # Chuyển số lượng sang dạng số
  Tỷ_lệ_phần_trăm = round(as.numeric(season_props), 2) # Chuyển tỷ lệ phần trăm sang dạng số, làm tròn 2 chữ số thập phân
)
kable( # Hàm dùng để hiển thị bảng đẹp mắt
  season_summary, # Bảng kết quả được hiển thị
  caption = "**Tần suất theo mùa**", # Đặt tiêu đề cho bảng
  align = c('l', 'c', 'c') # Căn lề cho các cột
)
Tần suất theo mùa
Mùa Số_lượng Tỷ_lệ_phần_trăm
Autumn 69840 25.08
Spring 70480 25.31
Summer 70128 25.18
Winter 68064 24.44

Kết quả:

  • Spring: có 70480 quan sát, chiếm 25.31%.

  • Summer: có 70128 quan sát, chiếm 25.18%.

  • Autumn: có 69840 quan sát, chiếm 25.08%.

  • Winter: có 68064 quan sát, chiếm 24.44%.

Thao tác 3: Tính toán tần suất (số lượng quan sát) và tỷ lệ phần trăm của các nhóm luồng điện tổng thể (flow_group) và sắp xếp kết quả theo thứ tự giảm dần

flow_distribution <- processed_data %>% # Bắt đầu với dataframe processed_data
  group_by(flow_group) %>% # Nhóm dữ liệu theo cột flow_group
  tally(name = "So_luong_quan_sat") %>% # Đếm số lượng quan sát trong mỗi nhóm và đặt tên cột là So_luong_quan_sat
  mutate(Ty_le_phan_tram = round(So_luong_quan_sat / sum(So_luong_quan_sat) * 100, 2)) %>% # Tính tỷ lệ phần trăm của mỗi nhóm, làm tròn 2 chữ số
  arrange(desc(So_luong_quan_sat)) # Sắp xếp kết quả theo số lượng quan sát giảm dần
kable( # Hàm dùng để hiển thị bảng đẹp mắt
  flow_distribution, # Bảng kết quả được hiển thị
  caption = "**Phân phối Tổng dòng chảy kết nối (Total Flow)**", # Đặt tiêu đề cho bảng
  align = 'c' # Căn giữa nội dung các cột
)
Phân phối Tổng dòng chảy kết nối (Total Flow)
flow_group So_luong_quan_sat Ty_le_phan_tram
Large Net Import 124235 44.61
Moderate Net Import 86025 30.89
Near Balance 29309 10.52
Moderate Net Export 26605 9.55
Large Net Export 12338 4.43

Kết quả:

  • Nhóm Large Net Import có số quan sát nhiều nhất là 124235, chiếm tỉ lệ cao nhất là 44.61%.

  • Nhóm Large Net Export có số quan sát ít nhất là 12338, chiếm tỉ lệ thấp nhất là 4.43%.

Thao tác 4: Tính toán Ma trận Hệ số Tương quan tuyến tính Pearson

selected_vars <- processed_data %>% # Bắt đầu với dataframe processed_data
  select(nd, tsd, embedded_wind_generation, embedded_solar_generation, total_flow) # Chọn các cột cần phân tích tương quan
correlation_matrix <- cor(selected_vars, use = "complete.obs") # Tính ma trận tương quan (bỏ qua các hàng có giá trị NA)
rounded_matrix <- round(correlation_matrix, 4) # Làm tròn các hệ số tương quan đến 4 chữ số thập phân
kable( # Hàm dùng để hiển thị bảng đẹp mắt
  rounded_matrix, # Ma trận tương quan đã làm tròn được hiển thị
  caption = "**Ma trận Hệ số Tương quan**", # Đặt tiêu đề cho bảng
  align = 'c' # Căn giữa nội dung các cột
)
Ma trận Hệ số Tương quan
nd tsd embedded_wind_generation embedded_solar_generation total_flow
nd 1.0000 0.9920 -0.1577 -0.1543 -0.1081
tsd 0.9920 1.0000 -0.1500 -0.1720 -0.1985
embedded_wind_generation -0.1577 -0.1500 1.0000 0.1619 0.0393
embedded_solar_generation -0.1543 -0.1720 0.1619 1.0000 0.1436
total_flow -0.1081 -0.1985 0.0393 0.1436 1.0000

Kết quả:

  • \(\mathbf{r}(\text{nd}, \text{tsd}) = 0.9920\): tương quan dương cực kỳ mạnh, gần như giống hệt nhau về mặt tuyến tính.

  • \(\mathbf{r}(\text{nd}, \text{embedded\_wind\_generation}) = -0.1577\): tương quan âm rất yếu, cho thấy mối liên hệ nghịch biến.

  • \(\mathbf{r}(\text{nd}, \text{embedded\_solar\_generation}) = -0.1543\): tương quan âm rất yếu, cho thấy mối liên hệ nghịch biến.

  • \(\mathbf{r}(\text{total\_flow}, \text{nd}) = -0.1081\): tương quan âm rất yếu, cho thấy mối liên hệ nghịch biến.

Thao tác 5: Phân tích Phương sai Một chiều (One-Way ANOVA) để kiểm tra xem có sự khác biệt đáng kể về mặt thống kê về mức nhu cầu (nd) giữa các nhóm năm (year_group) hay không.

processed_data$year_group <- as.factor(processed_data$year_group)
anova_model <- aov(nd ~ year_group, data = processed_data)
anova_summary <- summary(anova_model)
print(anova_summary)
##                 Df    Sum Sq   Mean Sq F value Pr(>F)    
## year_group       3 3.242e+12 1.081e+12   21747 <2e-16 ***
## Residuals   278508 1.384e+13 4.969e+07                   
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1

Kết quả:

  • Giá trị P (Pr(>F)) < 2e-16, giá trị cực kỳ nhỏ, gần như bằng 0, suy ra bác bỏ giả thuyết \(H_0\): Giá trị trung bình của nd là như nhau giữa tất cả các nhóm năm.

  • F value = 21747: Giá trị thống kê F lớn chứng tỏ rằng sự khác biệt quan sát được giữa các nhóm năm là rất lớn so với sự biến thiên bên trong các nhóm đó.

–> Kết luận: Yếu tố Thời gian (năm) có ảnh hưởng đáng kể đến mức nhu cầu (nd). Điều này phản ánh xu hướng nhu cầu thay đổi theo thời gian, có thể do tăng trưởng dân số, hiệu suất năng lượng, thay đổi khí hậu hoặc xu hướng kinh tế.

Thao tác 6: Tính toán Trung bình Động 24 kỳ (24-period Moving Average - MA) cho biến nd

ma_nd <- stats::filter( # Tính toán trung bình động bằng hàm filter
  processed_data$nd, # Dữ liệu đầu vào là cột nd
  filter = rep(1/24, 24), # Tạo vector trọng số 1/24 cho 24 kỳ
  method = "convolution", # Phương pháp tính toán
  sides = 1, # Tính trung bình động trượt về phía sau (sử dụng 24 giá trị quá khứ/hiện tại)
  circular = FALSE # Không coi dữ liệu là tuần hoàn
)
processed_data$nd_MA24 <- c(rep(NA, 23), ma_nd[!is.na(ma_nd)]) # Gán kết quả vào cột mới, điền NA cho 23 kỳ đầu
tail_ma_nd <- tail(processed_data[, c("nd", "nd_MA24")], 10) # Chọn 10 dòng cuối cùng của nd và nd_MA24
kable( # Hàm dùng để hiển thị bảng đẹp mắt
  tail_ma_nd, # Bảng kết quả được hiển thị
  caption = "**Ví dụ về Trung bình động 24 kỳ của ND**", # Đặt tiêu đề cho bảng
  align = 'c' # Căn giữa nội dung các cột
)
Ví dụ về Trung bình động 24 kỳ của ND
nd nd_MA24
278503 36248 36157.04
278504 34942 36254.33
278505 33594 36228.62
278506 32220 36132.50
278507 30535 35923.62
278508 29114 35660.50
278509 27204 35298.00
278510 26006 34884.58
278511 23908 34381.67
278512 23217 33851.67

Kết quả:

Thao tác 7: Tính toán giá trị trung bình (mean) và trung vị (median) của tỷ lệ sử dụng năng lượng nhúng (embedded_ratio) riêng biệt cho từng nhóm ngày (day_group)

ratio_by_day_group <- processed_data %>% # Bắt đầu với dataframe processed_data
  group_by(day_group) %>% # Nhóm dữ liệu theo cột day_group
  summarise( # Tính toán các giá trị tổng hợp cho mỗi nhóm
    Mean_Embedded_Ratio = mean(embedded_ratio, na.rm = TRUE), # Tính trung bình (bỏ qua NA)
    Median_Embedded_Ratio = median(embedded_ratio, na.rm = TRUE) # Tính trung vị (bỏ qua NA)
  )
kable( # Hàm dùng để hiển thị bảng đẹp mắt
  ratio_by_day_group, # Bảng kết quả tính toán được hiển thị
  caption = "**Tỷ lệ sử dụng Năng lượng Nhúng trung bình theo Loại ngày**", # Đặt tiêu đề cho bảng
  align = 'c' # Căn giữa nội dung các cột
)
Tỷ lệ sử dụng Năng lượng Nhúng trung bình theo Loại ngày
day_group Mean_Embedded_Ratio Median_Embedded_Ratio
Ngày lễ 0.0836409 0.0482291
Ngày thường 0.0764484 0.0456548

Kết quả:

  • Ngày lễ: Mean = 0.0836409, Median = 0.0482291.

  • Ngày thường: Mean = 0.0764484, Median = 0.0456548.

  • Sự khác biệt giữa các nhóm ngày: Giá trị trung bình và trung vị của embedded_ratio ở nhóm Ngày lễ đều cao hơn so với nhóm Ngày thường, tức là tỷ lệ nhu cầu được đáp ứng bằng năng lượng nhúng cao hơn vào ngày lễ so với ngày thường. Minh chứng cho điều này là do nhu cầu tổng thể thấp hơn vào ngày nghỉ (do công nghiệp giảm), khiến cùng một lượng sản lượng nhúng chiếm tỷ lệ lớn hơn.

Thao tác 8: Tạo bảng tần số chéo (cross-tabulation) giữa hai biến phân loại (day_group và nd_group)

cross_tab_nd_day <- table(processed_data$day_group, processed_data$nd_group) # Tạo bảng tần số chéo (số lần đếm)
prop_table_nd_day <- prop.table(cross_tab_nd_day) * 100 # Tính tỷ lệ phần trăm chung của mỗi ô
kable( # Hàm dùng để hiển thị bảng đẹp mắt
  cross_tab_nd_day, # Bảng tần số chéo được hiển thị
  caption = "**Phân tích chéo giữa loại ngày và nhóm nhu cầu**", # Đặt tiêu đề cho bảng
  align = c('c', 'c', 'c') # Căn giữa nội dung các cột
)
Phân tích chéo giữa loại ngày và nhóm nhu cầu
Nhu cầu cao Nhu cầu thấp Nhu cầu trung bình
Ngày lễ 177 606 5457
Ngày thường 40230 15038 217004

Kết quả:

  • Ngày lễ: tập trung Nhu cầu trung bình cao nhất với 5457, theo sau là Nhu cầu thấp với 606 và Nhu cầu cao là thấp nhất với 177.

  • Ngày thường: tập trung Nhu cầu trung bình cao nhất với 217004, theo sau là Nhu cầu cao với 40230 và Nhu cầu thấp là thấp nhất với 15038.

Thao tác 9: Tính toán hệ số tương quan tuyến tính Pearson giữa hai biến định lượng: nd và embedded_ratio.

cor_nd_emratio <- cor(processed_data$nd, processed_data$embedded_ratio) # Tính hệ số tương quan giữa nd và embedded_ratio
print(paste("Hệ số tương quan giữa nd và embedded_ratio:", cor_nd_emratio)) # In kết quả ra màn hình
## [1] "Hệ số tương quan giữa nd và embedded_ratio: -0.354116168299656"

Kết quả: Hệ số tương quan giữa nd và embedded_ratio là -0.354116168299656 (<0), tương quan âm, nghịch biến.

Thao tác 10: Tính toán giá trị trung bình của biến nd (nhu cầu/demand) dựa trên sự kết hợp của hai yếu tố phân loại: thời điểm trong ngày (time_of_day) và nhóm ngày (day_group).

mean_nd_by_time_day <- aggregate(nd ~ time_of_day + day_group, data = processed_data, FUN = mean) # Tính trung bình nd theo time_of_day và day_group
print("Giá trị trung bình của nd theo time_of_day và day_group:") # In ra một tiêu đề
## [1] "Giá trị trung bình của nd theo time_of_day và day_group:"
print(mean_nd_by_time_day) # Hiển thị kết quả tính toán
##   time_of_day   day_group       nd
## 1   Afternoon     Ngày lễ 30250.14
## 2     Evening     Ngày lễ 32393.14
## 3     Morning     Ngày lễ 26426.76
## 4       Night     Ngày lễ 24010.99
## 5   Afternoon Ngày thường 34498.82
## 6     Evening Ngày thường 36246.69
## 7     Morning Ngày thường 31359.27
## 8       Night Ngày thường 25301.97

Kết quả:

  • Ngày lễ: nhu cầu vào buổi sáng là 26426.76 MW, vào buổi chiều là 30250.14 MW, vào buổi tối là 32393.14 và vào buổi khuya là 24010.99 MW.

  • Ngày thường: nhu cầu vào buổi sáng là 31359.27 MW, vào buổi chiều là 34498.82 MW, vào buổi tối là 36246.69 và vào buổi khuya là 25301.97 MW.

Thao tác 11: Tính toán giá trị trung bình của sản lượng điện mặt trời nhúng (embedded_solar_generation) theo từng tháng (month)

mean_solar_by_month <- aggregate(embedded_solar_generation ~ month, data = processed_data, FUN = mean)
print("Giá trị trung bình sản lượng mặt trời nhúng theo tháng:")
## [1] "Giá trị trung bình sản lượng mặt trời nhúng theo tháng:"
print(mean_solar_by_month)
##        month embedded_solar_generation
## 1    January                  273.6083
## 2   February                  495.4155
## 3      March                  798.1228
## 4      April                 1238.7887
## 5        May                 1431.1196
## 6       June                 1482.9145
## 7       July                 1407.6153
## 8     August                 1237.1067
## 9  September                  986.1375
## 10   October                  620.0771
## 11  November                  346.4325
## 12  December                  207.8900

Kết quả: cho ra sản lượng điện mặt trời nhúng trung bình của từng tháng như sau:

  • Tháng 1: 273.6083 MW

  • Tháng 2: 495.4155 MW

  • Tháng 3: 798.1228 MW

  • Tháng 4: 1238.7887 MW

  • Tháng 5: 1431.1196 MW

  • Tháng 6: 1482.9145 MW

  • Tháng 7: 1407.6153 MW

  • Tháng 8: 1237.1067 MW

  • Tháng 9: 986.1375 MW

  • Tháng 10: 620.0771 MW

  • Tháng 11: 346.4325 MW

  • Tháng 12: 207.8900 MW

Thao tác 12: Tính toán giá trị trung bình của sản lượng điện gió nhúng (embedded_wind_generation) theo từng tháng (month)

mean_wind_by_month <- aggregate(embedded_wind_generation ~ month, data = processed_data, FUN = mean)
print("Giá trị trung bình sản lượng gió nhúng theo tháng:")
## [1] "Giá trị trung bình sản lượng gió nhúng theo tháng:"
print(mean_wind_by_month)
##        month embedded_wind_generation
## 1    January                1533.3996
## 2   February                1645.8491
## 3      March                1396.9221
## 4      April                1162.6461
## 5        May                1036.6392
## 6       June                 975.8777
## 7       July                 935.5192
## 8     August                1055.0263
## 9  September                1130.2600
## 10   October                1386.8316
## 11  November                1436.0914
## 12  December                1600.3519

Kết quả: cho ra sản lượng điện gió nhúng trung bình của từng tháng như sau:

  • Tháng 1: 1533.3996 MW

  • Tháng 2: 1645.8491 MW

  • Tháng 3: 1396.9221 MW

  • Tháng 4: 1162.6461 MW

  • Tháng 5: 1036.6392 MW

  • Tháng 6: 975.8777 MW

  • Tháng 7: 935.5192 MW

  • Tháng 8: 1055.0263 MW

  • Tháng 9: 1130.2600 MW

  • Tháng 10: 1386.8316 MW

  • Tháng 11: 1436.0914 MW

  • Tháng 12: 1600.3519 MW

Thao tác 13: Tìm giá trị Mode (giá trị xuất hiện nhiều nhất) cho biến phân loại nd_group

mode_nd_group <- names(sort(table(processed_data$nd_group), decreasing = TRUE)[1])
print(paste("Mode (giá trị xuất hiện nhiều nhất) của nd_group là:", mode_nd_group))
## [1] "Mode (giá trị xuất hiện nhiều nhất) của nd_group là: Nhu cầu trung bình"

Kết quả: Nhóm nhu cầu trung bình xuất hiện nhiều nhất.

Thao tác 14: Tính toán Hệ số Biến thiên (Coefficient of Variation - CV) cho biến tsd

cv_tsd <- sd(processed_data$tsd) / mean(processed_data$tsd) # Tính Hệ số biến thiên (độ lệch chuẩn chia trung bình)
cv_tsd * 100 # Tính và hiển thị Hệ số biến thiên dưới dạng phần trăm.
## [1] 23.24795

Kết quả:: Hệ số biến thiên CV có giá trị là 23.24795 tức là xấp xỉ 23.25%, độ lệch chuẩn của biến “tsd” bằng khoảng \(23.25\%\) của giá trị trung bình của nó. Đồng thời, chỉ ra rằng biến “tsd” có mức độ biến động tương đối khoảng \(23.25\%\), khẳng định rằng tsd không phải là một biến cố định; giá trị của nó thay đổi đáng kể so với mức trung bình của nó. Mức độ biến động này cần được xem xét khi xây dựng mô hình dự báo hoặc phân tích rủi ro liên quan đến “tsd”.

Thao tác 15: Tính toán phạm vi (range) và khoảng biến thiên (range difference) của biến total_flow.

range(processed_data$total_flow) # Trả về vector chứa giá trị tối thiểu và tối đa.
## [1] -5118  5963
diff(range(processed_data$total_flow)) # Tính khoảng cách từ min đến max.
## [1] 11081

Kết quả: Với biến “total_flow”, giá trị nhỏ nhất là -5118, giá trị lớn nhất là 5963 và khoảng cách từ min đến max là 11081.

Thao tác 16: Tính toán giá trị trung bình của các cột đại diện cho luồng điện qua cáp kết nối (interconnector flows) cho hai nhóm dữ liệu: ngày nghỉ (is_holiday = TRUE) và ngày thường (is_holiday = FALSE).

flow_cols <- c("ifa_flow", "ifa2_flow", "britned_flow", "moyle_flow", "east_west_flow", "nemo_flow") # Định nghĩa vector chứa tên các cột lưu lượng (flow)
processed_data %>% # Bắt đầu với dataframe processed_data
  group_by(is_holiday) %>% # Nhóm dữ liệu theo cột is_holiday (TRUE/FALSE)
  summarise(across(all_of(flow_cols), mean)) # Tính giá trị trung bình (mean) cho tất cả các cột trong flow_cols
## # A tibble: 2 × 7
##   is_holiday ifa_flow ifa2_flow britned_flow moyle_flow east_west_flow nemo_flow
##        <int>    <dbl>     <dbl>        <dbl>      <dbl>          <dbl>     <dbl>
## 1          0     922.      53.8         506.      -125.          -50.9      176.
## 2          1    1098.      61.2         439.      -143.          -60.1      170.

Kết quả: Có sự khác biệt về mức độ luồng điện trung bình của hầu hết các cáp kết nối khi so sánh Ngày Nghỉ với Ngày Thường.

  • Giá trị Trung bình Dương (\(\text{ifa\_flow}\), \(\text{ifa2\_flow}\), \(\text{britned\_flow}\), \(\text{nemo\_flow}\)): Cho thấy xu hướng trung bình là xuất khẩu điện (tức là luồng điện ra khỏi hệ thống mà dữ liệu này đại diện, thường là Vương quốc Anh) thông qua các kết nối này.

  • Giá trị Trung bình Âm (\(\text{moyle\_flow}\), \(\text{east\_west\_flow}\)): Cho thấy xu hướng trung bình là nhập khẩu điện (tức là luồng điện đi vào hệ thống) thông qua các kết nối này.

  • Sự khác biệt này cho thấy luồng điện qua cáp kết nối chịu ảnh hưởng bởi mô hình nhu cầu/sản xuất khác nhau xảy ra vào các ngày nghỉ lễ so với các ngày làm việc điển hình. Ví dụ: nhu cầu công nghiệp giảm vào ngày nghỉ có thể làm thay đổi sự cân bằng cung cầu, từ đó ảnh hưởng đến luồng điện qua các đường truyền quốc tế.

Thao tác 17: Tính ma trận hiệp phương sai giữa các biến “nd”, “tsd” và “england_wales_demand”

cov(processed_data[, c("nd", "tsd", "england_wales_demand")]) # Tính ma trận hiệp phương sai.
##                            nd      tsd england_wales_demand
## nd                   61329362 59034588             55440348
## tsd                  59034588 57741477             53396795
## england_wales_demand 55440348 53396795             50283885

Kết quả: Ta có được ma trận hiệp phương sai giữa các biến “nd”, “tsd” và “england_wales_demand”.

  • Các giá trị trên đường chéo chính là phương sai của từng biến số, đo lường mức độ biến động (phân tán) của mỗi biến quanh giá trị trung bình của nó. \(\text{Var}(nd) = 61,329,362\): Cho thấy nd có độ biến động rất lớn. * \(\text{Var}(tsd) = 57,741,477\): tsd có độ biến động cao, xếp sau nd. * \(\text{Var}(\text{england\_wales\_demand}) = 50,283,885\): độ biến động thấp hơn nhiều so với ndtsd.

  • Các Phần Tử Ngoài Đường Chéo (Hiệp phương sai - Covariance) là hiệp phương sai giữa hai biến số. Giá trị dương lớn cho thấy hai biến có xu hướng cùng tăng hoặc cùng giảm.

Thao tác 18: Kiểm định ANOVA

anova_two_way <- aov(nd ~ season * day_group, data = processed_data) # Thiết lập mô hình Two-Way ANOVA
summary(anova_two_way) # Hiển thị bảng tóm tắt kết quả kiểm định ANOVA
##                      Df    Sum Sq   Mean Sq  F value Pr(>F)    
## season                3 2.668e+12 8.892e+11 17335.79 <2e-16 ***
## day_group             1 1.171e+11 1.171e+11  2282.90 <2e-16 ***
## season:day_group      3 1.113e+10 3.710e+09    72.32 <2e-16 ***
## Residuals        278504 1.429e+13 5.129e+07                    
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1

Kết quả: Tất cả các kiểm định trong ANOVA (ảnh hưởng chính của season, ảnh hưởng chính của day_group, và tương tác \(\text{season}:\text{day\_group}\)) đều có \(\text{P-value}\) nhỏ hơn \(0.05\). Điều này cho thấy cả mùa, nhóm ngày và sự tương tác giữa chúng đều là những yếu tố dự báo đáng tin cậy cho sự biến đổi của nd.

Thao tác 19: Kiểm định Wilcoxon

wilcox.test(nd ~ is_holiday, data = processed_data) # Kiểm định phi tham số cho 2 mẫu độc lập.
## 
##  Wilcoxon rank sum test with continuity correction
## 
## data:  nd by is_holiday
## W = 1063640543, p-value < 2.2e-16
## alternative hypothesis: true location shift is not equal to 0

Kết quả:

  • Wilcoxon rank sum test with continuity correction: Kiểm định tổng hạng Wilcoxon có hiệu chỉnh liên tục

  • \(W = 1063640543\)

  • \(p\text{-value} < 2.2e-16\), bác bỏ giả thuyết \(H_0\). *Kết luận: Có bằng chứng thống kê mạnh mẽ để kết luận rằng vị trí phân phối (hay trung vị/trung bình) của biến nd khác nhau đáng kể giữa ngày nghỉ và ngày thường. Nói cách khác, giá trị của nd chịu ảnh hưởng bởi việc ngày đó có phải là ngày nghỉ hay không.

Thao tác 20: Tính toán công suất tối đa của gió và mặt trời, sau đó tính tổng công suất nhúng tối đa cho từng nhóm năm

processed_data %>% # Bắt đầu với dataframe processed_data và chuyển nó qua bước tiếp theo
  group_by(year_group) %>% # Nhóm dữ liệu theo cột year_group
  summarise( # Tính toán các giá trị tổng hợp cho mỗi nhóm
    Max_Wind_Capacity = max(embedded_wind_capacity), # Tính công suất gió tối đa trong nhóm
    Max_Solar_Capacity = max(embedded_solar_capacity), # Tính công suất mặt trời tối đa trong nhóm
    Total_Embedded_Capacity = Max_Wind_Capacity + Max_Solar_Capacity # Tính tổng công suất nhúng tối đa
  )
## # A tibble: 4 × 4
##   year_group    Max_Wind_Capacity Max_Solar_Capacity Total_Embedded_Capacity
##   <fct>                     <int>              <int>                   <int>
## 1 Early Period               2236               2035                    4271
## 2 Later Period               6559              13080                   19639
## 3 Mid Period                 5113              11503                   16616
## 4 Recent Period              6622              17197                   23819

Kết quả:

  • Trong giai đoạn Early Period (2009 - 2012): công suất gió nhúng tối đa là 2236 MW, công suất năng lượng mặt trời nhúng là 2035 MW và tổng công suất nhúng là 4271 MW.

  • Trong giai đoạn Mid Period (2013 - 2016): công suất gió nhúng tối đa là 5113 MW, công suất năng lượng mặt trời nhúng là 11503 MW và tổng công suất nhúng là 16616 MW.

  • Trong giai đoạn Later Period (2017 - 2020): công suất gió nhúng tối đa là 6559 MW, công suất năng lượng mặt trời nhúng là 13080 MW và tổng công suất nhúng là 19639 MW.

  • Trong giai đoạn Recent Period (2021 - 2024): công suất gió nhúng tối đa là 6622 MW, công suất năng lượng mặt trời nhúng là 17197 MW và tổng công suất nhúng là 23819 MW.

4. Trực quan hóa dữ liệu: (20 biểu đồ)

Biểu đồ 1: Biểu đồ Mật độ Phân phối Nhu cầu Điện năng Quốc gia

# Biểu đồ Mật độ Phân phối Nhu cầu Điện năng Quốc gia
processed_data %>%
  ggplot(aes(x = nd)) +                                                 # Khởi tạo biểu đồ, trục x là Nhu cầu Điện (nd)
  geom_density(fill = "#0072B2", alpha = 0.7, color = "darkblue", linewidth = 0.8) + # Vẽ đường mật độ, tô màu xanh, độ trong suốt 70%, viền xanh đậm
  geom_vline(aes(xintercept = mean(nd, na.rm = TRUE)),                  # Thêm đường thẳng đứng tại giá trị trung bình của nd
             color = "red", linetype = "dashed", linewidth = 1) +       # Đường màu đỏ, nét đứt, độ dày 1
  labs(title = "Phân phối Nhu cầu Điện năng Quốc gia",                  # Thiết lập tiêu đề và nhãn
       x = "Nhu cầu Điện năng (MW)",
       y = "Mật độ") +
  xlim(min(processed_data$nd, na.rm = TRUE), max(processed_data$nd, na.rm = TRUE)) + # Thiết lập giới hạn trục x từ min đến max của dữ liệu
  annotate("text", x = mean(processed_data$nd, na.rm = TRUE)*1.05, y = 0.00005, # Thêm nhãn văn bản cho giá trị trung bình
           label = paste("Trung bình:", round(mean(processed_data$nd, na.rm = TRUE), 0), "MW"),
           color = "red") +
  scale_x_continuous(labels = comma) +                                  # Định dạng nhãn trục x sử dụng dấu phân cách hàng nghìn
  theme_minimal() +                                                     # Áp dụng theme tối giản
  theme(plot.title = element_text(hjust = 0.5, face = "bold", size = 16)) # Căn giữa, in đậm và tăng cỡ chữ tiêu đề chính

–> Nhận xét:

  • Phân phối Chuẩn và Lệch: Phân phối của Nhu cầu Điện (\(nd\)) có hình dạng tương đối giống phân phối chuẩn (Normal Distribution), tập trung ở mức trung bình. Tuy nhiên, nó có vẻ hơi lệch trái (negatively skewed), tức là có một cái đuôi dài hơn về phía nhu cầu thấp hơn, và đỉnh phân phối nằm ở bên phải của giá trị trung bình.

  • Khoảng Tập trung: Đại đa số các quan sát Nhu cầu Điện tập trung mạnh trong khoảng từ \(24,000\ MW\) đến \(32,000\ MW\).

  • Giá trị Trung bình và Độ biến động: Giá trị trung bình được xác định là \(31,187\ MW\) (đường đứt quãng màu đỏ). Tuy nhiên, đỉnh của mật độ phân phối (mode) dường như nằm ở mức nhu cầu thấp hơn một chút so với giá trị trung bình, khoảng \(28,000\ MW\). Sự phân tán khá rộng, cho thấy nhu cầu điện có độ biến động cao, phản ánh sự thay đổi lớn giữa nhu cầu thấp điểm mùa hè/cuối tuần và nhu cầu cao điểm mùa đông/ngày thường.

Biểu đồ 2: Biểu đồ Cột Nhu cầu Điện năng Quốc gia Trung bình Hàng tháng

# Biểu đồ Cột Nhu cầu Điện năng Quốc gia Trung bình Hàng tháng
dothi2 <- processed_data %>%                                            # Bắt đầu chuỗi xử lý dữ liệu với processed_data
  group_by(month) %>%                                                   # Nhóm dữ liệu theo Tháng
  summarise(avg_nd = mean(nd, na.rm = TRUE)) %>%                        # Tính Nhu cầu Điện năng Trung bình (avg_nd) theo từng Tháng
  ungroup()                                                             # Bỏ nhóm
dothi2 %>%
  ggplot(aes(x = month, y = avg_nd, fill = avg_nd)) +                   # Khởi tạo biểu đồ, trục x là Tháng, trục y là Nhu cầu Trung bình, màu tô theo Nhu cầu
  geom_col(color = "black", linewidth = 0.5) +                          # Vẽ biểu đồ cột, viền đen, độ dày 0.5
  geom_text(aes(label = round(avg_nd, 0)), vjust = -0.5, color = "black", size = 3) + # Thêm nhãn giá trị Nhu cầu (làm tròn) phía trên cột
  labs(title = "Nhu cầu Điện năng Quốc gia Trung bình theo Tháng",      # Thiết lập tiêu đề và nhãn
       x = "Tháng",
       y = "Nhu cầu Điện năng Trung bình (MW)",
       fill = "Nhu cầu (MW)") +
  scale_fill_gradient(low = "lightblue", high = "red", label = comma) + # Dải màu chuyển tiếp (gradient) từ xanh nhạt đến đỏ, định dạng nhãn theo dấu phẩy
  scale_y_continuous(labels = comma, expand = expansion(mult = c(0, 0.1))) + # Định dạng nhãn trục y, mở rộng trục y thêm 10% ở phía trên
  geom_segment(aes(x = as.numeric(month) - 0.45, xend = as.numeric(month) + 0.45, y = avg_nd, yend = avg_nd), # Vẽ thêm đoạn thẳng màu đen trên đỉnh mỗi cột
               color = "black", linewidth = 1.5) +
  theme_light() +                                                       # Áp dụng theme sáng
  theme(plot.title = element_text(hjust = 0.5, face = "bold"),          # Căn giữa và in đậm tiêu đề chính
        legend.position = "right")                                     # Đặt chú thích màu ở phía bên phải

–> Nhận xét:

  • Tính Mùa vụ Đỉnh-Đáy: Nhu cầu điện thể hiện một chu kỳ rõ rệt, đạt đỉnh cao nhất vào các tháng Mùa Xuân (Tháng 12, Tháng 1, Tháng 2) và thấp nhất vào các tháng Mùa Hè (Tháng 7, Tháng 8). Đỉnh: Nhu cầu trung bình cao nhất là vào Tháng 1 (khoảng \(27,325\ MW\)), Tháng 12 (khoảng \(35,160\ MW\)) và Tháng 2 (khoảng \(35,882\ MW\)). Đáy: Nhu cầu trung bình thấp nhất là vào Tháng 7 (khoảng \(34,942\ MW\)) và Tháng 8 (khoảng \(27,019\ MW\)).

  • Sự Chuyển tiếp Dần dần: Sự thay đổi nhu cầu không đột ngột mà là một quá trình chuyển tiếp mượt mà: nhu cầu giảm dần từ đỉnh Đông sang đáy Hè, và tăng dần trở lại từ đáy Hè sang đỉnh Đông. Các tháng chuyển tiếp như Tháng 4 và Tháng 10 có nhu cầu ở mức trung bình.

  • Sự Phụ thuộc vào Nhiệt độ: Sự phân bố này cho thấy nhu cầu điện chịu ảnh hưởng mạnh mẽ bởi yếu tố nhiệt độ, với nhu cầu sưởi ấm chiếm phần lớn trong tổng nhu cầu vào mùa đông, trong khi nhu cầu làm mát vào mùa hè không đủ lớn để đẩy nhu cầu lên mức tương đương.

Biểu đồ 3:Biểu đồ Đường Chu kỳ Nhu cầu Điện Trung bình trong Ngày, Chia theo Mùa

# Biểu đồ Đường Chu kỳ Nhu cầu Điện Trung bình trong Ngày, Chia theo Mùa
processed_data %>%
  ggplot(aes(x = hour, y = nd, color = season)) +                       # Khởi tạo biểu đồ, trục x là Giờ, trục y là Nhu cầu, màu theo Mùa
  stat_summary(fun = "mean", geom = "line", size = 1.2) +               # Vẽ đường bằng cách tóm tắt (stat_summary), hàm tính trung bình, kiểu đường, độ dày 1.2
  facet_wrap(~season) +                                                 # Chia biểu đồ thành các ô nhỏ (facet) theo Mùa
  scale_y_continuous(labels = comma) +                                  # Định dạng nhãn trục y sử dụng dấu phân cách hàng nghìn
  labs(                                                                 # Thiết lập tiêu đề và nhãn
    title = "Chu kỳ Nhu cầu điện trung bình trong ngày theo từng Mùa",
    x = "Giờ trong ngày",
    y = "Nhu cầu điện trung bình (MW)",
    color = "Mùa"
  ) +
  theme_bw() +                                                          # Áp dụng theme đen trắng
  theme(legend.position = "none") +                                     # Ẩn chú thích màu
  theme(
    plot.title = element_text(hjust = 0.5),                             # Căn giữa tiêu đề chính
    plot.subtitle = element_text(hjust = 0.5)                           # Căn giữa tiêu đề phụ
  )

=> Nhận xét:

  • Nhu cầu điện trong ngày thường có 2 đỉnh: một đỉnh nhỏ vào buổi sáng (khoảng 8-9h) và một đỉnh lớn hơn vào buổi tối (khoảng 17-19h).

  • Mùa đông có nhu cầu cao nhất ở mọi thời điểm trong ngày, đặc biệt là vào buổi tối.

  • Mùa hè có nhu cầu thấp nhất và đường cong nhu cầu cũng “phẳng” hơn so với các mùa khác. ### Biểu đồ 4:Heatmap Nhu cầu Điện năng Trung bình Phân bố theo Giờ trong Ngày và Ngày trong Tuần

# Heatmap Nhu cầu Điện năng Trung bình Phân bố theo Giờ trong Ngày và Ngày trong Tuần
dothi4 <- processed_data %>%                                            # Bắt đầu chuỗi xử lý dữ liệu với processed_data
  group_by(weekday, hour) %>%                                           # Nhóm dữ liệu theo Ngày trong Tuần và Giờ
  summarise(avg_nd = mean(nd, na.rm = TRUE)) %>%                        # Tính Nhu cầu Điện năng Trung bình (avg_nd) cho mỗi ô giờ-ngày
  ungroup()                                                             # Bỏ nhóm
dothi4 %>%
  ggplot(aes(x = weekday, y = factor(hour), fill = avg_nd)) +           # Khởi tạo biểu đồ, trục x là Ngày, trục y là Giờ, màu tô theo Nhu cầu Trung bình
  geom_tile(color = "red", linewidth = 0.5) +                           # Vẽ ô (tile) cho heatmap, viền đỏ, độ dày 0.5
  labs(title = "Heatmap Nhu cầu Điện năng (theo Giờ & Ngày trong Tuần)", # Thiết lập tiêu đề và nhãn
       x = "Ngày trong Tuần",
       y = "Giờ trong Ngày",
       fill = "Nhu cầu (MW)") +
  scale_fill_viridis_c(option = "magma", labels = comma) +              # Sử dụng bảng màu Viridis "magma", định dạng nhãn bằng dấu phân cách hàng nghìn
  geom_rect(aes(xmin = as.numeric(weekday) - 0.5, xmax = as.numeric(weekday) + 0.5, # Vẽ thêm khung viền mỏng (rect) cho mỗi ô
                ymin = as.numeric(factor(hour)) - 0.5, ymax = as.numeric(factor(hour)) + 0.5),
            fill = NA, color = "grey", linewidth = 0.1) +               # Khung màu xám, không tô màu bên trong
  scale_y_discrete(limits = rev) +                                      # Đảo ngược thứ tự trục y (Giờ) để 0h ở trên cùng
  geom_text(data = filter(dothi4, avg_nd == max(avg_nd, na.rm = TRUE)), # Thêm nhãn văn bản cho ô có nhu cầu cao nhất
            aes(label = round(avg_nd/1000, 1)), color = "red", size = 3, fontface = "bold") + # Nhãn là giá trị nhu cầu (chia 1000), màu đỏ, chữ đậm
  theme_minimal() +                                                     # Áp dụng theme tối giản
  theme(plot.title = element_text(hjust = 0.5, face = "bold"),          # Căn giữa và in đậm tiêu đề chính
        axis.title.x = element_text(angle = 0, hjust = 0.5))            # Điều chỉnh nhãn trục x

–> Nhận xét:

1. Tính chu kỳ và Cấu trúc Cao điểm/Thấp điểm: Biểu đồ thể hiện rõ ràng hai cấu trúc tiêu thụ chính:

  • Cao điểm (Màu sáng/trắng): Tập trung mạnh vào các ngày trong tuần (Thứ Hai đến Thứ Sáu), với hai giai đoạn cao điểm chính là: Sáng sớm (Khoảng 7h-9h): Phản ánh nhu cầu khởi động các hoạt động kinh doanh và cá nhân. Chiều tối (Khoảng 17h-20h): Đây là giai đoạn cao điểm nhất, nơi ô màu trắng/vàng đậm nhất xuất hiện, do sự trùng lặp của nhu cầu dân dụng (nấu ăn, sưởi ấm) và các hoạt động công nghiệp/thương mại cuối ngày.

  • Thấp điểm (Màu tối/tím): Thấp điểm xảy ra vào ban đêm (từ 0h đến 5h) ở tất cả các ngày và cuối tuần (Thứ Bảy, Chủ Nhật). Nhu cầu cuối tuần giảm đáng kể, đặc biệt là vào ban ngày, cho thấy sự ngắt quãng của các hoạt động công nghiệp lớn.

2. Sự Giảm Sút Cuối Tuần (Weekend Effect): Nhu cầu điện trong Thứ Bảy và Chủ Nhật là thấp hơn đáng kể so với các ngày trong tuần (màu sắc tối hơn). Cấu trúc hai đỉnh cao điểm cũng mờ nhạt hoặc biến mất vào cuối tuần.

3. Đỉnh Nhu cầu Tuyệt đối: Giá trị Nhu cầu trung bình cao nhất (được đánh dấu) tập trung ở khung giờ 18h - 19h của các ngày giữa tuần (Thứ Ba, Thứ Tư, Thứ Năm).

Biểu đồ 5: Biểu đồ Violin và Boxplot So sánh Phân phối Nhu cầu Điện giữa Ngày Thường và Ngày Lễ

# Biểu đồ Violin và Boxplot So sánh Phân phối Nhu cầu Điện giữa Ngày Thường và Ngày Lễ
dothi5 <- processed_data %>%
  mutate(is_holiday_label = factor(is_holiday, levels = c(0, 1), labels = c("Ngày thường", "Ngày lễ"))) # Tạo biến phân loại Ngày Thường (0) và Ngày Lễ (1)
dothi5 %>%
  ggplot(aes(x = is_holiday_label, y = nd, fill = is_holiday_label)) +  # Khởi tạo biểu đồ, trục x là loại ngày, trục y là Nhu cầu, màu tô theo loại ngày
  geom_violin(trim = TRUE, alpha = 0.6) +                               # Vẽ biểu đồ violin (mật độ phân phối), cắt bớt đuôi, độ trong suốt 60%
  geom_boxplot(width = 0.1, color = "black", alpha = 0.8) +             # Vẽ boxplot (hộp và râu) chồng lên, chiều rộng 10% của violin
  labs(title = "Phân phối Nhu cầu Điện năng: Ngày Thường và Ngày Lễ",    # Thiết lập tiêu đề và nhãn
       x = "Loại ngày",
       y = "Nhu cầu Điện năng (MW)",
       fill = "Loại ngày") +
  scale_fill_manual(values = c("Ngày thường" = "#007302", "Ngày lễ" = "#0072B2")) + # Đặt màu thủ công
  scale_y_continuous(labels = comma) +                                  # Định dạng nhãn trục y sử dụng dấu phân cách hàng nghìn
  geom_jitter(data = . %>% sample_frac(0.005), alpha = 0.1, size = 0.5, color = "black") + # Thêm các điểm dữ liệu ngẫu nhiên (chỉ 0.5% mẫu) để hiển thị sự phân tán
  stat_summary(fun = median, geom = "point", shape = 20, size = 5, color = "white") + # Thêm điểm trung vị (màu trắng, kích thước lớn)
  theme_minimal() +                                                     # Áp dụng theme tối giản
  theme(plot.title = element_text(hjust = 0.5, face = "bold"),          # Căn giữa và in đậm tiêu đề chính
        legend.position = "none")                                       # Loại bỏ chú thích màu (legend)

–> Nhận xét:

  • Nhu cầu Ngày Lễ Thấp hơn Đáng kể: Phân phối Nhu cầu trong Ngày Lễ (màu xanh dương) nằm thấp hơn rõ rệt so với Ngày Thường (màu xanh lá). Điểm trung vị (dấu chấm trắng) và hộp (boxplot) của Ngày Lễ nằm thấp hơn, cho thấy cả mức nhu cầu điện điển hình lẫn mức nhu cầu trung bình đều giảm đáng kể vào các ngày nghỉ.

  • Độ Biến động Thấp hơn (Ngày Lễ): Biểu đồ violin của Ngày Lễ có vẻ hẹp hơn và ngắn hơn so với Ngày Thường (đặc biệt là ở phía trên), cho thấy nhu cầu không chỉ thấp hơn mà còn ít biến động hơn hoặc ít đạt đến các mức nhu cầu cực đại như Ngày Thường. Điều này phản ánh sự dừng lại hoặc giảm cường độ của các hoạt động thương mại và công nghiệp.

  • Phân phối Ngày Thường: Phân phối Ngày Thường trải rộng hơn và có đuôi dài hơn về phía nhu cầu cao (skewness), cho thấy sự tồn tại của các thời điểm nhu cầu rất cao (cao điểm).

Biểu đồ 6: Biểu đồ Cột Xếp chồng Tổng Nhu cầu Điện Phân tách theo Mùa và Năm

# Biểu đồ Cột Xếp chồng Tổng Nhu cầu Điện Phân tách theo Mùa và Năm
dothi6 <- processed_data %>%                                            # Bắt đầu chuỗi xử lý dữ liệu với processed_data
  group_by(year, season) %>%                                            # Nhóm dữ liệu theo Năm và Mùa
  summarise(total_nd = sum(nd, na.rm = TRUE)) %>%                       # Tính tổng Nhu cầu Điện (nd) cho mỗi tổ hợp Năm-Mùa
  ungroup()                                                             # Bỏ nhóm
dothi6 %>%
  ggplot(aes(x = factor(year), y = total_nd, fill = season)) +          # Khởi tạo biểu đồ, trục x là Năm (dạng factor), trục y là Tổng Nhu cầu, màu tô theo Mùa
  geom_col(position = position_stack(reverse = TRUE), color = "black", linewidth = 0.3) + # Vẽ biểu đồ cột xếp chồng, đảo ngược thứ tự xếp chồng, viền đen mảnh
  labs(title = "Tổng Nhu cầu Điện năng theo Mùa và Năm (Chọn lọc)",     # Thiết lập tiêu đề và nhãn
       x = "Năm",
       y = "Tổng Nhu cầu Điện năng (MW)",
       fill = "Mùa") +
  scale_fill_manual(values = c("Đông" = "#0072B2", "Thu" = "#D55E00", "Hè" = "#009E73", "Xuân" = "#F0E442")) + # Đặt màu thủ công cho từng Mùa
  scale_y_continuous(labels = unit_format(unit = "GWh", scale = 1e-6)) + # Định dạng trục y, giả định chuyển MW thành GWh
  geom_text(aes(label = round(total_nd / sum(total_nd, na.rm = TRUE) * 100, 1), group = year), # Thêm nhãn là % đóng góp của mỗi mùa trong năm
            position = position_stack(vjust = 0.5, reverse = TRUE), size = 3, color = "black") + # Vị trí nhãn ở giữa cột, màu đen, cỡ 3
  geom_hline(yintercept = 0, color = "black", linewidth = 1) +          # Thêm đường tham chiếu ngang tại y=0
  theme_classic() +                                                     # Áp dụng theme cổ điển
  theme(plot.title = element_text(hjust = 0.5, face = "bold"),          # Căn giữa và in đậm tiêu đề chính
        axis.text.x = element_text(angle = 0))                          # Giữ nhãn trục x nằm ngang

–> Nhận xét:

  • Xu hướng Giảm Tổng Nhu cầu: Xu hướng rõ rệt nhất là chiều cao tổng thể của các cột giảm dần qua các năm, đặc biệt từ năm 2010 đến 2023. Điều này tái khẳng định nhận xét trước đó: tổng nhu cầu điện năng quốc gia đang giảm dần trong dài hạn.

  • Sự Chiếm ưu thế Ổn định của Mùa Đông: Trong cơ cấu nhu cầu hàng năm, Mùa Đông (Winter - màu xanh đậm) luôn chiếm tỷ trọng lớn nhất (thường từ \(29\%\) đến \(30\%\)) và là mùa có tổng nhu cầu cao nhất. Điều này cho thấy vai trò chủ đạo của nhu cầu sưởi ấm trong tổng tiêu thụ điện.

  • Sự Ổn định Tỷ lệ Mùa vụ: Mặc dù tổng nhu cầu giảm, cơ cấu tỷ lệ phần trăm đóng góp của các mùa lại tương đối ổn định qua các năm: Mùa Đông (tối đa) \(\approx 29\% - 30\%\). Mùa Hè (Summer - màu xanh lá) chiếm tỷ trọng thấp nhất (thường \(\approx 20\% - 21\%\)). Mùa Xuân (Spring - màu vàng) và Mùa Thu (Autumn - màu cam) duy trì tỷ trọng ở mức trung bình (khoảng \(23\% - 24\%\) mỗi mùa).

Biểu đồ 7: Biểu đồ Histogram Phân phối Nhu cầu Điện Anh & xứ Wales theo Mùa

# Biểu đồ Histogram Phân phối Nhu cầu Điện Anh & xứ Wales theo Mùa
processed_data %>%
  ggplot(aes(x = england_wales_demand, fill = season)) +                 # Khởi tạo biểu đồ, trục x là Nhu cầu Anh & xứ Wales, màu tô theo Mùa
  # Layer 1: Histogram (Biểu đồ tần suất)
  geom_histogram(bins = 50, color = "white", alpha = 0.8) +             # Vẽ histogram với 50 bins, viền trắng, độ trong suốt 80%
  # Layer 2: Tiêu đề
  labs(title = "Phân phối Nhu cầu Điện năng ở Anh và xứ Wales theo Mùa", # Thiết lập tiêu đề và nhãn
       x = "Nhu cầu Điện năng (MW)",
       y = "Số lượng Quan sát") +
  # Layer 3: Small Multiples theo Mùa
  facet_wrap(~ season, scales = "free_y", ncol = 2) +                   # Chia biểu đồ thành các ô nhỏ theo Mùa, trục y tự do, sắp xếp 2 cột
  # Layer 4: Phối màu
  scale_fill_manual(values = c("Đông" = "#56B4E9", "Xuân" = "#009E73", "Hè" = "#F0E442", "Thu" = "#E69F00")) + # Đặt màu thủ công cho từng Mùa
  # Layer 5: Điều chỉnh tỷ lệ trục X
  scale_x_continuous(labels = comma) +                                  # Định dạng nhãn trục x sử dụng dấu phân cách hàng nghìn
  # Layer 6: Theme
  theme_bw() +                                                          # Áp dụng theme đen trắng
  # Layer 7: Xóa chú thích
  theme(legend.position = "none",                                       # Loại bỏ chú thích màu (legend)
        plot.title = element_text(hjust = 0.5, face = "bold")) +        # Căn giữa và in đậm tiêu đề chính
  # Layer 8: Đường trung bình trong mỗi facet (tính toán lại)
  geom_vline(data = . %>% group_by(season) %>% summarise(avg_demand = mean(england_wales_demand, na.rm = TRUE)), # Tính giá trị trung bình cho mỗi mùa
             aes(xintercept = avg_demand), color = "red", linetype = "dashed", linewidth = 1) # Vẽ đường thẳng đứng tại giá trị trung bình, màu đỏ, nét đứt

–> Nhận xét:

  • Nhu cầu Trung bình Biến động theo Mùa: Giá trị trung bình (đường đứt quãng màu đỏ) cho thấy nhu cầu điện có xu hướng cao nhất vào Mùa Đông (lớn nhất) và thấp nhất vào Mùa Hè (nhỏ nhất). Mùa Thu và Mùa Xuân có mức nhu cầu trung bình nằm giữa, với Mùa Thu có nhu cầu trung bình cao hơn Mùa Xuân. Điều này phản ánh rõ ràng nhu cầu sưởi ấm và chiếu sáng tăng cao trong những tháng lạnh.

  • Hình dạng Phân phối: Mùa Hè (Hè) thì Phân phối nhu cầu là hẹp nhất và tập trung nhất xung quanh mức trung bình thấp, cho thấy nhu cầu ổn định hơn. Mùa Đông (Đông) thì Phân phối nhu cầu là rộng nhất và có phần lệch phải, cho thấy sự biến động lớn nhất (có cả những thời điểm nhu cầu cực kỳ cao) và một dải nhu cầu rộng hơn so với các mùa khác. Mùa Xuân (Xuân)Mùa Thu (Thu) thì Các phân phối này có độ rộng và vị trí nằm giữa hai thái cực Hè và Đông.

Biểu đồ 8: Biểu đồ Tán xạ Quan hệ Nhu cầu Điện và Phát điện Gió Nhúng

# Biểu đồ Tán xạ Quan hệ Nhu cầu Điện và Phát điện Gió Nhúng
processed_data %>%
  sample_frac(0.01) %>%                                                 # Lấy mẫu ngẫu nhiên 1% dữ liệu để biểu diễn (giúp biểu đồ nhẹ hơn)
  ggplot(aes(x = nd, y = embedded_wind_generation)) +                   # Khởi tạo biểu đồ, trục x là Nhu cầu Điện, trục y là Phát điện Gió
  # Layer 1: Điểm tán xạ
  geom_point(alpha = 0.5, color = "#0072B2") +                          # Vẽ các điểm dữ liệu với độ trong suốt 50%, màu xanh
  # Layer 2: Đường hồi quy tuyến tính (Linear Regression Line)
  geom_smooth(method = "lm", color = "red", se = TRUE, linewidth = 1.2) + # Thêm đường hồi quy tuyến tính (lm), màu đỏ, hiển thị dải sai số (se=TRUE)
  # Layer 3: Tiêu đề
  labs(title = "Mối quan hệ giữa Nhu cầu Điện năng và Phát điện Gió",    # Thiết lập tiêu đề và nhãn
       x = "Nhu cầu Điện năng (MW)",
       y = "Phát điện Gió (MW)") +
  # Layer 4: Điều chỉnh tỷ lệ trục X và Y
  scale_x_continuous(labels = comma) +                                  # Định dạng nhãn trục x sử dụng dấu phân cách hàng nghìn
  scale_y_continuous(labels = comma) +                                  # Định dạng nhãn trục y sử dụng dấu phân cách hàng nghìn
  # Layer 5: Thêm đường tham chiếu (tạm thời)
  geom_hline(yintercept = mean(processed_data$nd, na.rm = TRUE),         # Thêm đường ngang tại giá trị trung bình của Nhu cầu Điện (chú ý: đây là cách dùng không chuẩn, nhưng theo code gốc)
             linetype = "dotted", color = "grey50") +
  # Layer 6: Text annotation (tạm thời)
  annotate("text", x = max(processed_data$nd, na.rm = TRUE) * 0.9, y = 0, # Thêm chú thích văn bản (R-squared) ở góc dưới bên phải
           label = paste("R-squared:", round(cor(processed_data$nd, processed_data$embedded_wind_generation, use = "complete.obs")^2, 3)),
           color = "red", size = 4) +
  # Layer 7: Chủ đề
  theme_classic() +                                                     # Áp dụng theme cổ điển
  # Layer 8: Điều chỉnh tiêu đề
  theme(plot.title = element_text(hjust = 0.5, face = "bold"))          # Căn giữa và in đậm tiêu đề chính

–> Nhận xét:

  • Không có Mối Quan hệ Tuyến tính Mạnh mẽ: Các điểm dữ liệu phân tán rộng khắp biểu đồ, tạo thành một hình chữ nhật lớn thay vì một đường thẳng rõ ràng. Đường hồi quy tuyến tính (màu đỏ) gần như nằm ngang với độ dốc rất nhỏ (gần như bằng 0). Điều này được xác nhận bởi giá trị \(R^2\) (Hệ số xác định) rất thấp, gần bằng 0.

  • Ý nghĩa Thống kê: Giá trị \(R^2\) thấp chỉ ra rằng Nhu cầu Điện năng (\(nd\)) giải thích rất ít (hoặc gần như không giải thích) sự thay đổi của Phát điện Gió (\(embedded\_wind\_generation\)). Nói cách khác, lượng điện gió được tạo ra không phụ thuộc một cách có ý nghĩa vào mức nhu cầu điện năng tại thời điểm đó.

  • Độ Biến động: Phát điện gió (\(y\)) thể hiện độ biến động rất lớn ở hầu hết mọi mức nhu cầu (\(x\)), từ 0 MW đến hơn 6000 MW, cho thấy nguồn điện gió chủ yếu bị chi phối bởi các yếu tố thời tiết (tốc độ gió), không liên quan đến nhu cầu tiêu thụ.

  • Phân bố Nhu cầu: Nhu cầu điện (\(x\)) tập trung chủ yếu trong khoảng từ \(20,000\ MW\) đến \(45,000\ MW\).

Biểu đồ 9: Biểu đồ Treemap Tổng Nhu cầu Điện Phân cấp theo Năm và Buổi

# Biểu đồ Treemap Tổng Nhu cầu Điện Phân cấp theo Năm và Buổi
dothi9 <- processed_data %>%                                            # Bắt đầu chuỗi xử lý dữ liệu với processed_data
  group_by(year, time_of_day) %>%                                       # Nhóm dữ liệu theo Năm và Buổi (Sáng, Trưa, Chiều, Tối)
  summarise(total_nd = sum(nd, na.rm = TRUE), .groups = 'drop')         # Tính Tổng Nhu cầu Điện (total_nd) cho mỗi tổ hợp Năm-Buổi

ggplot(dothi9, aes(area = total_nd, fill = year, label = time_of_day, subgroup = year)) + # Khởi tạo biểu đồ, diện tích ô theo total_nd, màu tô theo năm, nhãn theo buổi, nhóm theo năm
  # Layer 1: Vẽ các ô treemap
  geom_treemap() +                                                      # Vẽ các ô treemap, kích thước tỉ lệ với total_nd
  # Layer 2: Tạo nhóm cho các giai đoạn
  geom_treemap_subgroup_border(color = "white", size = 5) +             # Vẽ đường viền trắng dày cho các nhóm (Năm)
  # Layer 3: Thêm nhãn cho các buổi
  geom_treemap_text(color = "white", place = "centre", grow = TRUE, fontface = "italic") + # Thêm nhãn (Buổi) ở trung tâm ô, màu trắng, cỡ chữ tự điều chỉnh
  # Layer 4: Thêm nhãn cho nhóm giai đoạn
  geom_treemap_subgroup_text(place = "bottom", alpha = 0.5, color = "black", fontface = "bold") + # Thêm nhãn nhóm (Năm) ở dưới cùng, màu đen, độ trong suốt 50%
  # Layer 5: Tiêu đề
  labs(title = "Cấu trúc Phân cấp Tổng Nhu cầu Điện theo Giai đoạn và Buổi") + # Thiết lập tiêu đề
  # Layer 6: Tùy chỉnh chú thích
  theme(legend.position = "none") +                                     # Loại bỏ chú thích màu (legend)
  theme(plot.title = element_text(hjust = 0.5, face = "bold"))          # Căn giữa và in đậm tiêu đề

–> Nhận xét:

  • Xu hướng Giảm Nhu cầu Tổng thể: Quan sát tổng thể, diện tích của các nhóm Năm có xu hướng giảm dần từ các năm đầu (ví dụ: 2010, 2011) sang các năm cuối chuỗi dữ liệu (ví dụ: 2023). Điều này củng cố nhận xét trước đó về sự giảm sút trong tổng nhu cầu điện năng quốc gia trong dài hạn.

  • Nhu cầu Tập trung theo Buổi: Trong hầu hết các năm, hai nhóm buổi là Tối (Evening) và Chiều (Afternoon) chiếm phần lớn diện tích của treemap, cho thấy đây là hai khoảng thời gian có tổng nhu cầu điện lớn nhất. Điều này là hợp lý do sự trùng lặp của các hoạt động dân dụng, thương mại và công nghiệp vào các buổi này (ví dụ: nấu ăn, giải trí, kết thúc giờ làm việc).

  • Thay đổi Mức độ Chiếm ưu thế: Mặc dù Tối và Chiều là hai buổi lớn nhất, có thể thấy trong các năm gần đây, nhu cầu của buổi Sáng (Morning) và Trưa (Day) (các ô nhỏ hơn) có vẻ ổn định hơn hoặc giảm chậm hơn, trong khi buổi Tối (ô lớn nhất) giảm đáng kể nhất, dẫn đến sự thu hẹp khoảng cách tỷ lệ giữa các buổi. Sự thay đổi này có thể phản ánh sự thay đổi trong mô hình sử dụng điện hoặc sự ảnh hưởng của nguồn năng lượng phân tán (ví dụ: điện mặt trời nhúng hoạt động mạnh vào Buổi Trưa/Chiều, làm giảm nhu cầu ròng từ lưới điện).

Biểu đồ 10: Biểu đồ Histogram và Mật độ Phân phối Nhu cầu Điện theo Mùa

# Biểu đồ Histogram và Mật độ Phân phối Nhu cầu Điện theo Mùa
ggplot(processed_data, aes(x = nd, fill = season)) +                     # Khởi tạo biểu đồ, trục x là Nhu cầu (nd), màu tô theo Mùa
  geom_histogram(aes(y = ..density..), alpha = 0.6, bins = 50, position = 'identity') + # Vẽ histogram, trục y là mật độ, độ trong suốt 60%, 50 bins, chồng lấp
  geom_density(alpha = 0.4, color = "black", linewidth = 0.5) +          # Vẽ đường mật độ ước tính, độ trong suốt 40%, đường viền đen
  labs(                                                                 # Thiết lập tiêu đề và nhãn
    title = "Phân phối Nhu cầu Điện Quốc gia (nd) theo Mùa",
    subtitle = "Nhu cầu cao nhất vào Mùa Đông và thấp nhất vào Mùa Hè",
    x = "Nhu cầu Quốc gia (MW)",
    y = "Mật độ",
    fill = "Mùa"
  ) +
  scale_x_continuous(labels = comma) +                                  # Định dạng nhãn trục x sử dụng dấu phân cách hàng nghìn (comma)
  theme_minimal() +                                                     # Áp dụng theme tối giản
  theme(
    plot.title = element_text(hjust = 0.5),                             # Căn giữa tiêu đề chính
    plot.subtitle = element_text(hjust = 0.5)                           # Căn giữa tiêu đề phụ
  )

–> Nhận xét:

  • Sự Dịch chuyển theo Mùa: Phân phối Nhu cầu (\(nd\)) dịch chuyển rõ rệt dọc theo trục X (trục Nhu cầu): Mùa Đông (Winter) có phân phối tập trung ở mức Nhu cầu cao nhất, với đường mật độ (màu đỏ) nằm xa nhất về phía bên phải. Mùa Hè (Summer) có phân phối tập trung ở mức Nhu cầu thấp nhất, với đường mật độ (màu xanh lá) nằm xa nhất về phía bên trái. Mùa Thu (Autumn)Mùa Xuân (Spring) có phân phối nằm ở giữa, với Mùa Thu (màu tím) hơi cao hơn Mùa Xuân (màu xanh dương).

  • Độ Biến thiên: Phân phối Nhu cầu trong Mùa Đông có vẻ rộng hơn và trải dài hơn (độ lệch chuẩn lớn hơn), cho thấy độ biến động cao hơn trong nhu cầu điện so với các mùa khác. Ngược lại, Mùa Hè có phân phối hẹp hơn, chỉ ra rằng nhu cầu điện ổn định hơn ở mức thấp trong mùa này.

  • Ý nghĩa: Sự khác biệt này phản ánh tác động mạnh mẽ của yếu tố nhiệt độ và ánh sáng đến nhu cầu điện, nơi sưởi ấm và chiếu sáng trong Mùa Đông đẩy nhu cầu lên mức cao hơn và biến động hơn. Điều này có ý nghĩa quan trọng trong việc lập kế hoạch vận hành và dự báo, đặc biệt là đối với việc cân bằng cung cầu trong những tháng lạnh.

Biểu đồ 11: Biểu đồ Đường Tỷ lệ Năng lượng Tái tạo Nhúng Trung bình Hàng tháng trên Tổng Nhu cầu Quốc gia

# Biểu đồ Đường Tỷ lệ Năng lượng Tái tạo Nhúng Trung bình Hàng tháng trên Tổng Nhu cầu Quốc gia
dothi11 <- processed_data %>%                                            # Bắt đầu chuỗi xử lý dữ liệu với processed_data
  group_by(year, month) %>%                                             # Nhóm dữ liệu theo Năm và Tháng
  summarise(avg_ratio = mean(embedded_ratio, na.rm = TRUE), .groups = 'drop') %>% # Tính tỷ lệ trung bình hàng tháng (embedded_ratio)
  mutate(date = make_date(year, month))                                 # Tạo cột ngày (date) từ năm và tháng
dothi11 %>%
  ggplot(aes(x = date, y = avg_ratio)) +                                # Khởi tạo biểu đồ, trục x là ngày, trục y là tỷ lệ trung bình
  geom_line(color = "#0072B2", linewidth = 1) +                         # Vẽ đường nối các điểm, màu xanh đậm, độ dày 1
  # Layer 2: Thêm các điểm dữ liệu hàng tháng
  geom_point(color = "#D55E00", size = 1.5) +                           # Vẽ các điểm dữ liệu hàng tháng, màu cam, kích thước 1.5
  # Layer 3: Thêm đường xu hướng dài hạn (LOESS)
  geom_smooth(method = "loess", se = FALSE, color = "darkgreen", span = 0.3) + # Thêm đường xu hướng làm mịn LOESS, bỏ qua dải sai số, màu xanh lá cây đậm
  # Layer 4: Tiêu đề và nhãn, định dạng trục Y theo phần trăm
  labs(                                                                 # Thiết lập tiêu đề và nhãn
    title = "Tỷ lệ Năng lượng Tái tạo trong Tổng Nhu cầu Quốc gia",
    subtitle = "Xu hướng tăng trưởng rõ rệt từ năm 2009 đến nay",
    x = "Năm",
    y = "Tỷ lệ trung bình hàng tháng"
  ) +
  # Layer 5: Định dạng trục Y
  scale_y_continuous(labels = percent_format(accuracy = 1)) +           # Định dạng nhãn trục y theo tỷ lệ phần trăm (percent_format)
  theme_classic() +                                                     # Áp dụng theme cổ điển
  theme(
    plot.title = element_text(hjust = 0.5),                             # Căn giữa tiêu đề chính
    plot.subtitle = element_text(hjust = 0.5)                           # Căn giữa tiêu đề phụ
  )

–> Nhận xét: - Xu hướng Tăng Trưởng Mạnh mẽ: Có một xu hướng tăng trưởng lũy tiến (tăng tốc) rõ rệt về tỷ lệ đóng góp của năng lượng tái tạo nhúng (đường màu xanh đậm). Bắt đầu từ mức rất thấp (gần 0%) vào năm 2009, tỷ lệ này đã tăng lên đáng kể, vượt qua mốc 10% vào khoảng năm 2017 và tiếp tục tăng trưởng mạnh mẽ, đạt gần 20% vào cuối chuỗi dữ liệu. Điều này phản ánh thành công của việc triển khai các nguồn năng lượng tái tạo phân tán (như điện gió và mặt trời nhúng).

  • Tính Mùa vụ Rõ rệt: Mặc dù xu hướng dài hạn là tăng, biểu đồ cho thấy sự biến động mùa vụ cao. Các điểm dữ liệu dao động lớn xung quanh đường xu hướng làm mịn (màu xanh lá cây đậm). Các đỉnh (tỷ lệ cao) thường xảy ra vào mùa hè, do sản lượng điện mặt trời nhúng đạt mức tối đa. Các đáy (tỷ lệ thấp) thường xảy ra vào mùa đông, khi sản lượng mặt trời giảm và mặc dù sản lượng gió tăng, nó không đủ để bù đắp sự sụt giảm tổng thể, đặc biệt khi nhu cầu điện cũng tăng cao vào mùa đông.

  • Ý nghĩa: Xu hướng tăng trưởng này là chỉ báo mạnh mẽ cho thấy năng lượng tái tạo đang ngày càng đóng vai trò quan trọng trong việc đáp ứng nhu cầu điện quốc gia. Tuy nhiên, tính biến động cao theo mùa của tỷ lệ này (do đặc tính nguồn gió/mặt trời) tạo ra những thách thức lớn về sự ổn định và cân bằng lưới điện.

Biểu đồ 12: Biểu đồ Donut Phân bố Tỷ lệ Trạng thái Dòng chảy Liên kết theo Mùa

# Biểu đồ Donut Phân bố Tỷ lệ Trạng thái Dòng chảy Liên kết theo Mùa
dothi12 <- processed_data %>%                                            # Bắt đầu chuỗi xử lý dữ liệu với processed_data
  count(season, flow_group) %>%                                         # Đếm số lượng quan sát cho mỗi tổ hợp Mùa và Nhóm Dòng chảy
  group_by(season) %>%                                                  # Nhóm dữ liệu theo Mùa
  mutate(percentage = n / sum(n))                                       # Tính tỷ lệ phần trăm (percentage) của mỗi nhóm dòng chảy trong từng mùa
ggplot(dothi12, aes(x = 2, y = percentage, fill = flow_group)) +        # Khởi tạo biểu đồ, xác định vị trí x, trục y là tỷ lệ, màu tô theo nhóm dòng chảy
  # Layer 1 & 2: Vẽ biểu đồ cột và chuyển sang tọa độ cực
  geom_col(color = "white") +                                           # Vẽ biểu đồ cột (column chart) với viền trắng
  coord_polar("y", start = 0) +                                         # Chuyển đổi tọa độ thành tọa độ cực (polar), trục y (tỷ lệ) xác định góc
  # Layer 3: Tạo lỗ hổng donut
  xlim(c(0.2, 2.5)) +                                                   # Giới hạn trục x để tạo khoảng trống ở giữa, biến biểu đồ tròn thành donut
  # Layer 4: Chia biểu đồ theo Mùa
  facet_wrap(~ season, ncol = 4) +                                      # Chia biểu đồ thành các ô nhỏ theo Mùa, sắp xếp 4 cột
  # Layer 5: Tiêu đề và chú thích
  labs(                                                                 # Thiết lập tiêu đề và nhãn
    title = "So sánh Cấu trúc Dòng chảy Liên kết qua các Mùa",
    subtitle = "Sự khác biệt nhỏ trong tỷ lệ nhập/xuất khẩu điện",
    fill = "Trạng thái Dòng chảy"
  ) +
  # Layer 6: Tùy chỉnh theme
  theme_void() +                                                        # Áp dụng theme rỗng (theme_void) để loại bỏ các yếu tố không cần thiết
  theme(
    legend.position = "right",                                         # Đặt chú thích ở phía dưới
    strip.text = element_text(face = "bold", size = 12)                  # Định dạng văn bản tiêu đề của các ô nhỏ (Mùa)
  ) +
  theme(
    plot.title = element_text(hjust = 0.5),                             # Căn giữa tiêu đề chính
    plot.subtitle = element_text(hjust = 0.5)                           # Căn giữa tiêu đề phụ
  ) +
  # Layer 7: Bảng màu
  scale_fill_brewer(palette = "Spectral")                               # Sử dụng bảng màu "Spectral"

–> Nhận xét: - Trạng thái Thống trị: Ở tất cả các mùa, trạng thái Nhập khẩu ròng (Net Import) (màu đỏ/cam) chiếm tỷ trọng lớn nhất và nổi bật nhất trong cấu trúc dòng chảy. Điều này chỉ ra rằng, phần lớn thời gian, hệ thống điện quốc gia là một người tiêu dùng ròng điện năng từ các liên kết quốc tế.

  • Sự Đồng nhất giữa các Mùa: Cấu trúc tỷ lệ phần trăm cho thấy sự đồng nhất đáng kể giữa bốn mùa. Không có sự khác biệt lớn về tỷ lệ giữa Nhập khẩu ròng và Xuất khẩu ròng/Cân bằng ròng. Điều này gợi ý rằng, mô hình sử dụng các liên kết quốc tế để cân bằng lưới điện là ổn định và ít bị ảnh hưởng bởi tính mùa vụ hơn so với các yếu tố khác (như nhu cầu cao điểm/thấp điểm hoặc sản lượng NLTT).

  • Trạng thái Cân bằng và Xuất khẩu: Tỷ lệ Xuất khẩu ròng (Net Export) (màu xanh lá) và Cân bằng ròng (Net Zero/Balanced) (màu xanh dương) đều chiếm tỷ lệ nhỏ, cho thấy hệ thống hiếm khi là nhà cung cấp ròng hoặc đạt trạng thái cân bằng hoàn hảo trên các liên kết.

  • Khác biệt Nhỏ theo Mùa: Mặc dù sự khác biệt nhỏ, có thể quan sát thấy Mùa Hè dường như có tỷ lệ Nhập khẩu ròng thấp nhất và tỷ lệ Xuất khẩu ròng/Cân bằng ròng cao nhất (màu đỏ/cam nhỏ hơn một chút so với các mùa khác). Điều này có thể liên quan đến nhu cầu nội địa thấp hơn và/hoặc sản lượng điện mặt trời nhúng cao vào mùa hè, làm giảm nhu cầu nhập khẩu để cân bằng lưới.

Biểu đồ 13: Biểu đồ Vùng Xếp chồng Tỷ trọng Sản lượng Điện Gió và Điện Mặt trời Nhúng theo Thời gian

# Biểu đồ Vùng Xếp chồng Tỷ trọng Sản lượng Điện Gió và Điện Mặt trời Nhúng theo Thời gian
dothi13 <- processed_data %>%                                            # Bắt đầu chuỗi xử lý dữ liệu với processed_data
  group_by(year, month) %>%                                             # Nhóm dữ liệu theo Năm và Tháng
  summarise(
    total_wind = sum(embedded_wind_generation, na.rm = TRUE),           # Tính tổng sản lượng Điện Gió hàng tháng
    total_solar = sum(embedded_solar_generation, na.rm = TRUE),         # Tính tổng sản lượng Điện Mặt trời hàng tháng
    .groups = 'drop'                                                    # Bỏ nhóm sau khi tính toán
  ) %>%
  mutate(date = make_date(year, month)) %>%                              # Tạo cột ngày (date) từ năm và tháng
  pivot_longer(cols = c(total_wind, total_solar), names_to = "source", values_to = "generation") # Chuyển đổi từ cột rộng sang cột dài (long format)

ggplot(dothi13, aes(x = date, y = generation, fill = source)) +         # Khởi tạo biểu đồ, trục x là ngày, trục y là sản lượng, màu tô theo nguồn
  # Layer 1: Vẽ biểu đồ vùng xếp chồng 100%
  geom_area(position = "fill", color = "white") +                       # Vẽ biểu đồ vùng với position="fill" để hiển thị tỷ lệ 100%, viền trắng
  # Layer 2: Tiêu đề và nhãn
  labs(                                                                 # Thiết lập tiêu đề và nhãn
    title = "Sự trỗi dậy của Năng lượng Mặt trời trong Cơ cấu Tái tạo",
    subtitle = "Tỷ trọng của Điện Gió và Mặt trời trong tổng sản lượng NLTT nhúng",
    x = "Năm",
    y = "Tỷ lệ Đóng góp",
    fill = "Nguồn Năng lượng"
  ) +
  # Layer 3: Tùy chỉnh nhãn chú thích
  scale_fill_manual(values = c("total_wind" = "#2171B5", "total_solar" = "#FDB813"), # Đặt màu thủ công cho Gió và Mặt trời
                    labels = c("Điện Gió", "Điện Mặt trời")) +           # Đặt nhãn cho chú thích
  # Layer 4: Định dạng trục Y theo phần trăm
  scale_y_continuous(labels = scales::percent) +                        # Định dạng nhãn trục y theo tỷ lệ phần trăm
  # Layer 5: Thêm đường tham chiếu 50%
  geom_hline(yintercept = 0.5, linetype = "dotted", color = "black") +  # Thêm đường ngang nét chấm màu đen tại y = 0.5 (50%)
  # Layer 6: Chú thích cho đường tham chiếu
  annotate("text", x = as.Date("2010-01-01"), y = 0.55, label = "Mức cân bằng", color = "black") + # Thêm chữ "Mức cân bằng" gần đường 50%
  # Layer 7: Thêm đường làm mịn cho một nguồn (ví dụ: Gió)
  stat_smooth(                                                          # Thêm đường làm mịn (xu hướng)
    data = filter(dothi13, source == "total_wind"),                     # Chỉ áp dụng cho dữ liệu Gió
    aes(group = source),
    method = "loess", se = FALSE, color = "white",                      # Sử dụng phương pháp loess, không vẽ dải sai số, màu trắng
    position = "fill", linetype = "dashed"                              # Vị trí fill để hiển thị tỷ lệ, nét đứt
  ) +
  # Layer 8: Theme
  theme_classic()                                                       # Áp dụng theme cổ điển

–> Nhận xét:

  • Sự Trỗi dậy Đáng kể của Điện Mặt trời: Biểu đồ thể hiện sự gia tăng nhanh chóng và vượt bậc của tỷ trọng Điện Mặt trời (màu vàng/cam) trong cơ cấu năng lượng tái tạo nhúng. Vào những năm đầu (2009-2012), Điện Gió gần như chiếm toàn bộ tỷ trọng.

  • Điểm Cân Bằng (50%): Khoảng từ năm 2014 đến 2016, tỷ trọng Điện Mặt trời đã vượt qua mốc 50% (đường nét chấm), đánh dấu một bước ngoặt quan trọng khi Điện Mặt trời trở thành nguồn năng lượng tái tạo nhúng chiếm ưu thế về mặt sản lượng so với Điện Gió.

  • Tính Mùa vụ Rõ rệt: Cả hai nguồn đều thể hiện tính mùa vụ rõ rệt: Điện Mặt trời có tỷ trọng đóng góp cao hơn rõ rệt vào mùa hè (các đỉnh màu vàng/cam) và giảm mạnh vào mùa đông, phản ánh chu kỳ ánh sáng mặt trời. Ngược lại, Điện Gió có xu hướng chiếm tỷ trọng cao hơn vào mùa đông (các đỉnh màu xanh) khi tốc độ gió thường mạnh hơn.

  • Xu hướng Dài hạn: Bất chấp sự biến động theo mùa, đường xu hướng làm mịn (nét đứt) cho thấy tỷ trọng của Điện Gió đang có xu hướng giảm dần (hoặc tỷ trọng Mặt trời đang tăng dần) trong dài hạn, củng cố vị thế dẫn đầu của Điện Mặt trời trong tổng sản lượng tái tạo nhúng. ### Biểu đồ 14: Biểu đồ Mật độ Phân phối Nhu cầu Điện (nd) theo Năm và Giai đoạn

# Biểu đồ Mật độ Phân phối Nhu cầu Điện (nd) theo Năm và Giai đoạn
ggplot(processed_data, aes(x = nd, fill = year)) +                      # Khởi tạo biểu đồ, xác định trục x (Nhu cầu), và màu tô theo Năm
  # Layer 1: Vẽ biểu đồ mật độ
  geom_density(alpha = 0.8, color = "white") +                         # Vẽ biểu đồ mật độ với độ trong suốt 80%, đường viền màu trắng
  # Layer 2: Chia thành các biểu đồ nhỏ theo giai đoạn
  facet_wrap(~ year_group, ncol = 2) +                                 # Chia biểu đồ thành các ô nhỏ theo nhóm "year_group", sắp xếp 2 cột
  # Layer 3: Thêm đường trung vị cho mỗi giai đoạn
  geom_vline(                                                          # Thêm đường thẳng đứng
    data = . %>% group_by(year) %>% summarise(median_nd = median(nd)),  # Tính toán giá trị trung vị của nd cho từng năm (year)
    aes(xintercept = median_nd),                                       # Vị trí đường tại giá trị trung vị
    color = "red", linetype = "dashed", linewidth = 1                  # Định dạng đường: màu đỏ, nét đứt, độ dày 1
  ) +
  # Layer 4: Tiêu đề và nhãn
  labs(                                                                # Thiết lập tiêu đề và nhãn
    title = "Sự thay đổi Phân phối Nhu cầu Điện qua các Giai đoạn",
    x = "Nhu cầu Quốc gia (MW)",
    y = "Mật độ"
  ) +
  # Layer 5: Tùy chỉnh bảng màu
  scale_fill_brewer(palette = "YlGnBu") +                              # Sử dụng bảng màu "YlGnBu" cho màu tô
  # Layer 6: Định dạng trục X
  scale_x_continuous(labels = comma) +                                 # Định dạng nhãn trục x sử dụng dấu phân cách hàng nghìn (comma)
  # Layer 7: Theme và loại bỏ chú thích
  theme_bw() + theme(legend.position = "none")                         # Áp dụng giao diện (theme) đen trắng và loại bỏ chú thích màu (legend)

–> Nhận xét: Có hai xu hướng quan trọng và liên quan đến nhau

  • Quan hệ Nhu cầu và Dòng chảy Liên kết: Biểu đồ tán xạ chỉ ra một mối quan hệ nghịch biến cơ bản giữa Nhu cầu Quốc gia (\(nd\)) và Tổng Dòng chảy (\(total\_flow\), tức là nhập/xuất khẩu ròng). Khi nhu cầu điện nội địa tăng, hệ thống có xu hướng giảm nhập khẩu ròng hoặc tăng xuất khẩu ròng. Tuy nhiên, mối quan hệ này trở nên yếu đi trong những giai đoạn có Tác động Cao của Năng lượng Tái tạo (NLTT). Điều này ngụ ý rằng, sự đóng góp của NLTT (như gió và mặt trời) đang làm giảm sự phụ thuộc của lưới điện vào việc điều chỉnh dòng chảy qua các liên kết để cân bằng nhu cầu, đặc biệt trong các mùa có NLTT dồi dào.

  • Sự thay đổi Phân phối Nhu cầu theo Giai đoạn: Biểu đồ mật độ minh họa rằng Nhu cầu Quốc gia trung bình có xu hướng giảm dần qua các giai đoạn, thể hiện qua sự dịch chuyển sang trái của đường trung vị từ 2009-2012 đến 2021-2024. Đồng thời, hình dạng phân phối trở nên tập trung và hẹp hơn trong các giai đoạn gần đây, cho thấy tính ổn định cao hơn và ít biến động hơn của nhu cầu điện quanh mức trung bình thấp hơn. Xu hướng này có thể là kết quả của các yếu tố như tăng hiệu suất năng lượng, hoặc sự phân tán của sản xuất điện nhờ NLTT nhúng (embedded generation), khiến nhu cầu ròng mà lưới điện trung tâm phải đối ứng giảm đi.

Biểu đồ 15: Biểu đồ Tán xạ Quan hệ Nhu cầu và Tổng Dòng chảy Liên kết theo Mùa và Tác động của NLTT

# Biểu đồ Tán xạ Quan hệ Nhu cầu và Tổng Dòng chảy Liên kết theo Mùa và Tác động của NLTT
ggplot(processed_data, aes(x = nd, y = total_flow, color = season)) + # Khởi tạo biểu đồ, xác định trục x (Nhu cầu), trục y (Tổng dòng chảy) và màu sắc theo Mùa
  # Layer 1: Vẽ các điểm dữ liệu
  geom_point(alpha = 0.4, size = 1.5) +                                # Vẽ các điểm dữ liệu với độ trong suốt 40% và kích thước 1.5
  # Layer 2: Thêm đường xu hướng cho mỗi mùa
  geom_smooth(method = "lm", se = FALSE, linewidth = 0.8) +             # Thêm đường hồi quy tuyến tính (lm) cho xu hướng, bỏ qua dải sai số (se=FALSE)
  # Layer 3: Chia biểu đồ theo mức độ tác động của NLTT
  facet_wrap(~ em_ra_group, scales = "free_y") +                       # Chia biểu đồ thành các ô nhỏ theo nhóm "em_ra_group", trục y tự do cho mỗi ô
  # Layer 4: Thêm đường tham chiếu tại điểm cân bằng dòng chảy (0)
  geom_hline(yintercept = 0, linetype = "dashed", color = "black") +   # Thêm đường ngang nét đứt màu đen tại y = 0
  # Layer 5: Tiêu đề và nhãn
  labs(                                                                # Thiết lập tiêu đề và nhãn
    title = "Quan hệ Nhu cầu - Dòng chảy dưới Tác động của Năng lượng Tái tạo",
    x = "Nhu cầu Quốc gia (MW)",
    y = "Tổng Dòng chảy (MW)",
    color = "Mùa"
  ) +
  # Layer 6: Tùy chỉnh bảng màu
  scale_color_brewer(palette = "Dark2") +                              # Sử dụng bảng màu "Dark2" cho màu sắc theo Mùa
  # Layer 7: Định dạng trục số
  scale_x_continuous(labels = comma) +                                 # Định dạng nhãn trục x sử dụng dấu phân cách hàng nghìn (comma)
  scale_y_continuous(labels = comma) +                                 # Định dạng nhãn trục y sử dụng dấu phân cách hàng nghìn (comma)
  # Layer 8: Theme
  theme_light()                                                        # Áp dụng giao diện (theme) sáng cho biểu đồ

–> Nhận xét: Biểu đồ thể hiện mối quan hệ giữa Nhu cầu Quốc gia (nd) và Tổng Dòng chảy (total_flow) qua các liên kết, được phân tích theo Mùa và Mức độ Tác động của NLTT (em_ra_group). Tổng dòng chảy là lượng điện nhập/xuất khẩu ròng qua các liên kết với nước ngoài, với giá trị dương (+) là nhập khẩu ròng và giá trị âm (-) là xuất khẩu ròng. Đường tham chiếu \(\mathbf{y = 0}\) đại diện cho trạng thái cân bằng dòng chảy ròng (nhập bằng xuất).

  • Mối quan hệ Tổng quát: Nhìn chung, ở hầu hết các nhóm tác động của NLTT, có một mối quan hệ nghịch biến rõ rệt giữa Nhu cầu Quốc gia (\(nd\)) và Tổng Dòng chảy (\(total\_flow\)). Khi nhu cầu tăng, tổng dòng chảy có xu hướng giảm (tức là chuyển từ nhập khẩu ròng sang xuất khẩu ròng hoặc ít nhập khẩu hơn). Điều này cho thấy khi nhu cầu nội địa cao, hệ thống có xu hướng giảm phụ thuộc vào nhập khẩu hoặc thậm chí tăng xuất khẩu để đáp ứng.

  • Tác động của NLTT (Facet Wrap): Ở nhóm Tác động Thấp và Trung bình, mối quan hệ nghịch biến giữa nhu cầu và dòng chảy là mạnh và rõ ràng nhất, thể hiện qua độ dốc âm lớn của đường xu hướng. Ở nhóm Tác động Cao, đường xu hướng có vẻ ít dốc hơn hoặc thậm chí gần như nằm ngang (đặc biệt trong Mùa Thu và Mùa Xuân), cho thấy khi NLTT đóng góp lớn, mối liên hệ giữa nhu cầu và dòng chảy liên kết trở nên lỏng lẻo hơn hoặc bị che mờ bởi vai trò của NLTT.

  • Tác động của Mùa: Các mùa có Nhu cầu cao hơn (Đông - màu xanh đậm) thường nằm ở phía phải của biểu đồ và có xu hướng cắt đường \(\mathbf{y = 0}\) ở mức nhu cầu cao hơn so với các mùa khác. Mùa Hè (màu đỏ) thường có Tổng Dòng chảy ròng ít dương nhất (gần \(0\) hoặc âm hơn), cho thấy ít nhập khẩu ròng nhất so với các mùa khác, đặc biệt khi nhu cầu ở mức trung bình. Mùa Đông và Mùa Thu (màu tím/xanh lá) có vẻ là những mùa có xu hướng nhập khẩu ròng nhiều hơn (điểm nằm phía trên \(\mathbf{y = 0}\)) ở mức nhu cầu thấp và trung bình.

Biểu đồ 16: Bản đồ Trực quan hóa Nhu cầu Điện (Dot Map)

world <- ne_countries(scale = "medium", returnclass = "sf") # Tải dữ liệu ranh giới quốc gia (dạng sf)
uk_map <- world[world$sovereignt == "United Kingdom", ] # Lọc chỉ giữ lại ranh giới của Vương quốc Anh

# Tính toán nhu cầu trung bình
avg_ewdemand <- mean(processed_data$england_wales_demand, na.rm = TRUE) # Tính nhu cầu trung bình Anh & Wales (bỏ qua NA)
# Tạo điểm dữ liệu trung tâm cho Anh & Wales (tọa độ gần đúng)
center_point <- st_sfc(st_point(c(-1.5, 52.5)), crs = 4326) # Tạo một đối tượng điểm hình học (sfc) tại tọa độ trung tâm

ggplot(data = uk_map) + # Khởi tạo đồ thị với dữ liệu bản đồ UK
  # Layer 1: Vẽ nền bản đồ Vương quốc Anh
  geom_sf(fill = "antiquewhite") + # Vẽ đa giác (polygon) ranh giới UK với màu nền
  # Layer 2: Thêm điểm dữ liệu đại diện cho Anh & Wales
  geom_sf(data = center_point, aes(color = avg_ewdemand, size = avg_ewdemand), alpha = 0.6) + # Vẽ điểm tại trung tâm, màu sắc và kích thước phụ thuộc vào nhu cầu trung bình
  # Layer 3: Tiêu đề và chú thích
  labs(
    title = "Nhu cầu Điện Trung bình tại Anh & Wales", # Tiêu đề chính
    subtitle = paste0("Giá trị trung bình giai đoạn 2009-2024: ", round(avg_ewdemand, 0), " MW"), # Tiêu đề phụ (hiển thị giá trị)
    caption = "Vị trí điểm là tượng trưng" # Chú thích cuối
  ) +
  # Layer 4: Tùy chỉnh thang màu
  scale_color_gradient(low = "yellow", high = "red", name = "Nhu cầu TB (MW)") + # Thiết lập thang màu cho màu sắc của điểm
  # Layer 5: Tắt chú thích kích thước
  guides(size = "none") + # Ẩn chú thích (legend) cho kích thước vì nó trùng lặp với màu sắc
  # Layer 6: Giới hạn tọa độ để zoom vào UK
  coord_sf(xlim = c(-8, 2), ylim = c(49, 59), expand = FALSE) + # Giới hạn bản đồ để tập trung vào UK
  # Layer 7: Theme cho bản đồ
  theme(
    panel.background = element_rect(fill = "aliceblue"), # Màu nền panel (biển)
    axis.text = element_blank(), # Ẩn nhãn trục tọa độ
    axis.ticks = element_blank(), # Ẩn các dấu gạch trên trục
    panel.grid.major = element_line(color = "white", linetype = "dashed") # Thêm đường lưới mờ
  )

–> Nhận xét: Biểu đồ xác định rằng Nhu cầu Điện Trung bình cho khu vực Anh & Wales trong giai đoạn 15 năm này là khoảng 28,390 MW. Điểm dữ liệu tượng trưng được tô màu đỏ cam đậm và có kích thước lớn, theo thang màu được thiết lập, cho thấy nhu cầu này là một giá trị cao so với phạm vi dữ liệu tổng thể (nếu không có so sánh tương đối, ta chỉ biết giá trị tuyệt đối).

Biểu đồ 17: “Bảng điều khiển Hiệu suất Năng lượng” (Energy Performance Dashboard).

dothi17 <- processed_data %>%
  # Lọc dữ liệu: Chỉ giữ lại các hàng thuộc nhóm "Recent Period" (Giả định 2021-2024)
  filter(year_group == "Recent Period") %>%
  # Tính toán các chỉ số trung bình trong giai đoạn này
  summarise(
    avg_nd = mean(nd),        # Nhu cầu quốc gia trung bình (MW)
    avg_flow = mean(total_flow), # Dòng chảy ròng trung bình (MW)
    avg_ratio = mean(embedded_ratio) # Tỷ lệ NLTT trung bình
  )

# Card 1: Nhu cầu
p1 <- ggplot() + # Khởi tạo đồ thị
  geom_rect(aes(xmin=0,xmax=1,ymin=0,ymax=1), fill="#E6F5FF") + # Vẽ hình chữ nhật nền (màu xanh nhạt)
  annotate("text", x=0.5, y=0.6, label=paste0(round(dothi17$avg_nd/1000,1)," GW"), size=10) + # Hiển thị giá trị nhu cầu (làm tròn 1 chữ số, đơn vị GW)
  annotate("text", x=0.5, y=0.85, label="Nhu cầu TB", size=5) + # Hiển thị nhãn tiêu đề "Nhu cầu TB"
  theme_void() # Loại bỏ tất cả các thành phần trục và nền

# Card 2: Dòng chảy
p2 <- ggplot() + # Khởi tạo đồ thị
  geom_rect(aes(xmin=0,xmax=1,ymin=0,ymax=1), fill="#E6FFF5") + # Vẽ hình chữ nhật nền (màu xanh lá nhạt)
  annotate("text", x=0.5, y=0.6, label=paste0(round(dothi17$avg_flow)," MW"), size=10, color="darkgreen") + # Hiển thị giá trị dòng chảy (làm tròn số nguyên, đơn vị MW)
  annotate("text", x=0.5, y=0.85, label="Dòng chảy Nhập ròng TB", size=5) + # Hiển thị nhãn tiêu đề "Dòng chảy Nhập ròng TB"
  theme_void() # Loại bỏ tất cả các thành phần trục và nền

# Card 3: Tỷ lệ NLTT
p3 <- ggplot() + # Khởi tạo đồ thị
  geom_rect(aes(xmin=0,xmax=1,ymin=0,ymax=1), fill="#FFF5E6") + # Vẽ hình chữ nhật nền (màu cam/vàng nhạt)
  annotate("text", x=0.5, y=0.6, label=scales::percent(dothi17$avg_ratio, 0.1), size=10, color="orange") + # Hiển thị giá trị tỷ lệ (định dạng phần trăm 1 chữ số thập phân)
  annotate("text", x=0.5, y=0.85, label="Tỷ lệ NLTT TB", size=5) + # Hiển thị nhãn tiêu đề "Tỷ lệ NLTT TB"
  theme_void() # Loại bỏ tất cả các thành phần trục và nền

# Ghép 3 card lại
# Ghép các đối tượng đồ thị p1, p2, p3 lại với nhau
(p1 + p2 + p3) +
  # Layer 4, 5, 6: Cấu trúc layout và tiêu đề
  plot_layout(ncol = 3) + # Sắp xếp 3 đồ thị thành 3 cột
  plot_annotation(
    title = 'Bảng điều khiển Hiệu suất Năng lượng (Giai đoạn 2021-2024)', # Đặt tiêu đề chung cho bảng điều khiển
    theme = theme(plot.title = element_text(size = 18, face = "bold", hjust = 0.5)) # Tùy chỉnh định dạng tiêu đề (cỡ chữ, đậm, căn giữa)
  )

–> Nhận xét: Bảng điều khiển xác nhận rằng trong giai đoạn 2021-2024, hệ thống điện Anh đang ở trạng thái chuyển đổi mạnh mẽ, với \(12.4\%\) nhu cầu được đáp ứng bởi các nguồn năng lượng tái tạo phân tán. Tuy nhiên, bất chấp sự tăng trưởng đó, quốc gia này vẫn duy trì tình trạng nhập khẩu ròng đáng kể (\(\approx 1300 \text{ MW}\)) để đáp ứng tổng nhu cầu trung bình \(\approx 26.8 \text{ GW}\), cho thấy sự phụ thuộc vào nguồn cung nước ngoài để cân bằng lưới điện vẫn còn cao trong quá trình giảm dần nhiên liệu hóa thạch.

Biểu đồ 18:

cor_data <- processed_data %>%
  # Chọn các cột dữ liệu quan trọng là các dòng chảy liên kết
  select(ifa_flow, ifa2_flow, britned_flow, moyle_flow, east_west_flow, nemo_flow) %>%
  # Tính ma trận tương quan giữa các cột đã chọn
  cor() %>%
  # Chuyển ma trận tương quan thành một dataframe
  as.data.frame() %>%
  # Chuyển tên hàng (biến 'from') thành một cột riêng biệt
  rownames_to_column("from") %>%
  # Chuyển dữ liệu từ dạng rộng sang dạng dài (cột 'to' và 'correlation')
  pivot_longer(-from, names_to = "to", values_to = "correlation") %>%
  # Lọc bỏ các giá trị trùng lặp (ví dụ: A-B và B-A) và tương quan với chính nó (A-A)
  filter(from < to)

# Tạo đối tượng đồ thị
# Tạo đối tượng đồ thị mạng từ dataframe `cor_data`, không định hướng (directed = FALSE)
graph_cor <- graph_from_data_frame(cor_data, directed = FALSE)

# Khởi tạo đồ thị với layout tuyến tính (linear)
ggraph(graph_cor, layout = 'linear') +
  # Layer 1: Vẽ các cung, màu sắc và độ dày theo tương quan
  # Vẽ các cung dạng cung tròn (arc edge)
  geom_edge_arc(aes(label = round(correlation, 2), # Gắn nhãn là giá trị tương quan (làm tròn 2 chữ số)
                    color = correlation,             # Màu sắc cung theo giá trị tương quan
                    width = abs(correlation)),       # Độ dày cung theo giá trị tuyệt đối của tương quan
                arrow = arrow(length = unit(2, 'mm')), # Thêm mũi tên nhỏ để chỉ hướng
                end_cap = circle(3, 'mm')) +           # Tạo khoảng trống tại các nút (node)
  # Layer 2 & 3: Vẽ các điểm nút và nhãn
  # Vẽ các điểm nút (node)
  geom_node_point(size = 5, color = "skyblue") +
  # Thêm nhãn cho các nút (tên biến), tránh trùng lặp nhãn
  geom_node_text(aes(label = name), repel = TRUE, size = 4) +
  # Layer 4: Tùy chỉnh thang màu
  # Thiết lập thang màu phân kỳ (diverging) cho cung: Đỏ (Âm) -> Xám (Gần 0) -> Xanh Lá (Dương)
  scale_edge_color_gradient2(low = "red", mid = "grey", high = "green") +
  # Layer 5: Tùy chỉnh độ dày cung
  # Thiết lập phạm vi độ dày cho cung (càng mạnh càng dày)
  scale_edge_width(range = c(0.5, 2)) +
  # Layer 6: Tiêu đề
  # Đặt tiêu đề cho biểu đồ
  labs(title = "Mức độ Tương quan giữa các Dòng chảy Liên kết") +
  # Layer 7: Theme
  # Áp dụng theme tối giản cho đồ thị mạng
  theme_graph()

–> Nhận xét: Biểu đồ cho thấy sự phân cực rõ rệt trong mối quan hệ giữa các dòng chảy liên kết: hầu hết các kết nối liên lục địa (IFA, IFA2, BritNed, NEMO) có mối tương quan Dương Mạnh với nhau, trong khi các kết nối với Ireland (Moyle, East-West) thể hiện mối tương quan Âm Yếu hoặc gần như bằng không với nhóm liên lục địa.

  • Tương quan Dương Mạnh (Màu Xanh Lá Dày): Các dòng chảy IFA, IFA2, BritNed và NEMO có tương quan dương mạnh (hệ số \(\approx 0.5\) đến \(0.8\)). Điều này có nghĩa là khi nhu cầu điện ở Anh tăng cao, hệ thống sẽ đồng thời nhập khẩu điện từ cả Pháp, Bỉ, Hà Lan, Na Uy và các nước khác qua các tuyến liên kết này. Đây là bằng chứng cho thấy các thị trường điện ở Châu Âu hoạt động đồng pha, cùng chịu tác động từ các yếu tố vĩ mô như giá khí đốt và điều kiện thời tiết.

  • Tương quan Âm Yếu/Gần 0 (Màu Đỏ/Xám Mỏng): Mối quan hệ giữa Moyle Flow và East-West Flow (kết nối với Ireland) với nhóm liên lục địa là rất yếu hoặc âm nhẹ. Điều này chỉ ra rằng thị trường điện Ireland hoạt động độc lập hơn so với thị trường lục địa Châu Âu, chịu ảnh hưởng chủ yếu bởi các yếu tố nội tại của hệ thống Anh và Ireland, không bị chi phối nhiều bởi nhu cầu và giá cả xuyên lục địa.

  • Độ dày Cung (Cường độ): Độ dày của các cung (edges) minh họa cho cường độ tương quan (giá trị tuyệt đối của R). Sự chênh lệch rõ rệt về độ dày củng cố nhận xét trên: các kết nối lục địa là các mối quan hệ quan trọng và có tính ràng buộc nhất trong hệ thống liên kết của Anh.

Biểu đồ 19:

# Bắt đầu chuỗi xử lý dữ liệu với dataframe `processed_data`
solar_utilization <- processed_data %>%
  filter(year_group == "Later Period" & embedded_solar_capacity > 0) %>% # Lọc dữ liệu: Chỉ giữ lại các hàng thuộc nhóm "Later Period", (Giả định nhóm này là 2017-2020) VÀ công suất điện mặt trời lớn hơn 0(để tránh lỗi chia cho 0).
  summarise(util_rate = mean(embedded_solar_generation / embedded_solar_capacity, na.rm = TRUE)) %>% # Tạo một bảng tóm tắt, Tính `util_rate` (tỷ lệ tận dụng trung bình) bằng công thức (Sản lượng điện mặt trời / Công suất lắp đặt) trung bình, `na.rm = TRUE` loại bỏ các giá trị NA khỏi phép tính trung bình
  pull(util_rate) # Trích xuất giá trị tính toán (`util_rate`) ra khỏi dataframe để sử dụng tiếp

gauge_data_solar <- data.frame(value = c(solar_utilization, 1 - solar_utilization), category = c("Used", "Unused")) # Tạo dataframe mới với 2 hàng để vẽ biểu đồ dạng nửa cột tròn (Gauge), Hàng 1: Giá trị Tận dụng được (đã tính ở trên), Hàng 2: Giá trị Chưa tận dụng (1 - Tỷ lệ đã tận dụng), Nhãn tương ứng cho 2 hàng

ggplot(gauge_data_solar, aes(x = 1.2, y = value, fill = category)) + # Khởi tạo ggplot với dữ liệu `gauge_data_solar`, x=1.2 (hằng số) để tạo một cột duy nhất, y=value (chiều cao cột), fill=category (màu sắc)
  # Layer 1 & 2: Vẽ cột và chuyển sang tọa độ cực
  geom_col(width = 0.8, color = "black") + # Vẽ biểu đồ cột (`geom_col`) với độ rộng `0.8` và đường viền màu đen
  coord_polar("y", start = -pi / 2) + # Chuyển biểu đồ cột sang hệ tọa độ cực (`coord_polar`) theo trục Y, tạo hình dạng hình tròn (Gauge), `start = -pi / 2` xoay biểu đồ để điểm bắt đầu (0%) nằm ở vị trí 9 giờ
  # Layer 3: Đặt giới hạn trục
  ylim(c(-0.5, 1.5)) + # Thiết lập giới hạn trục Y, đặt giới hạn này (-0.5 đến 1.5) là kỹ thuật để tạo ra **khoảng trống** ở dưới cùng của hình tròn, biến nó thành một hình nửa tròn (Gauge)
  # Layer 4 & 5: Hiển thị giá trị và nhãn
  annotate("text", x = 0, y = 0, label = scales::percent(solar_utilization, 0.1), size = 15, color = "#e6550d") + # Thêm một nhãn văn bản cố định (`annotate`) để hiển thị giá trị phần trăm đã tính, x=0, y=0 đặt nhãn ở trung tâm biểu đồ, `scales::percent(..., 0.1)` định dạng giá trị thành phần trăm với một chữ số thập phân
  annotate("text", x = 1.2, y = 1.05, label = "Max", size = 4) + # Thêm nhãn "Max" (100%) tại đỉnh của nửa hình tròn
  # Layer 6: Tùy chỉnh màu sắc và theme
  scale_fill_manual(values = c("Used" = "#fdae6b", "Unused" = "grey80")) + # Gán màu thủ công cho hai danh mục "Used" và "Unused"
  theme_void() + theme(legend.position = "none") + # Áp dụng theme tối giản (trống rỗng), loại bỏ tất cả các thành phần không cần thiết, Ẩn phần chú giải (legend) vì thông tin đã được hiển thị trực quan
  # Layer 7: Tiêu đề
  labs(title = "Tỷ lệ Tận dụng Công suất Điện Mặt trời Trung bình (2017-2020)") # Đặt tiêu đề cho biểu đồ.

–> Nhận xét: Tỷ lệ Tận dụng Công suất Điện Mặt trời trung bình (Capacity Factor) trong giai đoạn 2017-2020 đạt mức 10.2%, một con số thấp nhưng mang tính thống kê hợp lý đối với công nghệ quang điện ở Vương quốc Anh. Tỷ lệ này xác nhận rằng, trung bình các hệ thống điện mặt trời chỉ hoạt động ở 10.2% công suất tối đa theo thiết kế do đặc tính gián đoạn (chỉ hoạt động vào ban ngày) và điều kiện khí hậu. Con số thấp này cho thấy điện mặt trời không thể là nguồn cung ứng nền ổn định (baseload power) và buộc hệ thống điện phải dựa vào các nguồn dự phòng (như nhiệt điện) để bù đắp cho khoảng 89.8% công suất còn lại. Đây là thách thức chính, nhấn mạnh tầm quan trọng của việc đầu tư vào công nghệ lưu trữ để tích trữ năng lượng từ ban ngày.

Biểu đồ 20:

seasonal_loop_ratio <- processed_data %>% # Bắt đầu một chuỗi xử lý dữ liệu với dataframe `processed_data`
  filter(year == 2023) %>% # Lọc và chỉ giữ lại các hàng có giá trị `year` bằng 2023.
  group_by(month, season) %>% # Nhóm các hàng dữ liệu lại với nhau dựa trên cột `month` và `season`.
  summarise( # Tạo một bảng tóm tắt mới từ các nhóm đã tạo.
    avg_nd = mean(nd, na.rm = TRUE), # Tạo cột mới `avg_nd`, tính giá trị trung bình của cột `nd` cho mỗi nhóm, `na.rm = TRUE` đảm bảo các giá trị NA (nếu có) sẽ được bỏ qua.
    avg_ratio = mean(embedded_ratio, na.rm = TRUE) # tạo cột `avg_ratio`, tính giá trị trung bình của `embedded_ratio`, `na.rm = TRUE` đảm bảo các giá trị NA (nếu có) sẽ được bỏ qua.
  )
ggplot(seasonal_loop_ratio, aes(x = avg_nd, y = avg_ratio)) + # Khởi tạo một đối tượng biểu đồ ggplot với dữ liệu `seasonal_loop_ratio`, `aes()` thiết lập: trục X sẽ là `avg_nd`, trục Y là `avg_ratio`.
  # Layer 1 & 2: Vẽ đường nối và điểm
  geom_path(arrow = arrow(length = unit(0.2, "cm"))) + # Thêm một lớp (layer) đường thẳng (`geom_path`) để nối các điểm dữ liệu theo thứ tự chúng xuất hiện trong dataframe, `arrow` thêm một mũi tên vào cuối đường thẳng để chỉ rõ hướng của chuỗi thời gian.
  geom_point(aes(color = season), size = 6) + # Thêm một lớp điểm (`geom_point`) tại mỗi cặp tọa độ (x, y), `aes(color = season)` chỉ định rằng màu của mỗi điểm sẽ được xác định bởi giá trị trong cột `season`, `size = 6` làm cho các điểm lớn hơn để dễ nhìn.
  # Layer 3: Thêm nhãn tháng
  geom_text(aes(label = month), size = 3, color = "black") + # Thêm một lớp văn bản (`geom_text`) để hiển thị nhãn tại mỗi điểm, `aes(label = month)` chỉ định rằng nội dung văn bản sẽ là giá trị từ cột `month`, `size = 3` và `color = "black"` điều chỉnh kích thước và màu sắc của văn bản.
  # Layer 4: Tiêu đề và nhãn
  labs( # Sử dụng hàm `labs()` để tùy chỉnh tất cả các nhãn của biểu đồ.
    title = "Vòng lặp Nghịch đảo giữa Nhu cầu và Tỷ lệ NLTT (Năm 2023)", # Tiêu đề chính
    x = "Nhu cầu Quốc gia Trung bình (MW)", # Nhãn cho trục X
    y = "Tỷ lệ NLTT Trung bình", # Nhãn cho trục Y
    color = "Mùa" # Tiêu đề cho phần chú giải (legend) màu sắc
  ) +
  # Layer 5 & 6: Tùy chỉnh màu và định dạng
  scale_color_brewer(palette = "Set1") + # Áp dụng một bảng màu (`palette`) có sẵn tên là "Set1" từ `RColorBrewer` cho các điểm
  scale_y_continuous(labels = percent) + # Định dạng lại các nhãn trên trục Y để hiển thị dưới dạng phần trăm (%)
  # Layer 7: Theme
  theme_light() # Áp dụng một giao diện (theme) có sẵn là `theme_light()`, với nền trắng và các đường lưới màu xám nhạt

–> Nhận xét: Phân tích biểu đồ “Vòng lặp theo mùa” cho thấy một mối quan hệ nghịch đảo và mang tính chu kỳ rõ rệt giữa nhu cầu điện và tỷ lệ năng lượng tái tạo (NLTT) trong năm 2023. Cụ thể, vào Mùa Hè, nhu cầu tiêu thụ ở mức thấp nhất nhưng sản lượng điện mặt trời lại đạt đỉnh, đẩy tỷ lệ NLTT lên cao nhất. Ngược lại, Mùa Đông chứng kiến nhu cầu sưởi ấm và chiếu sáng tăng vọt, trong khi sản lượng mặt trời gần như bằng không, khiến tỷ lệ NLTT giảm mạnh. Kết quả này không chỉ minh họa một quy luật tự nhiên mà còn chỉ ra thách thức chiến lược cốt lõi của ngành năng lượng Anh: sự lệch pha giữa thời điểm sản xuất năng lượng sạch dồi dào và thời điểm nhu cầu tiêu thụ ở mức cao nhất, qua đó nhấn mạnh tầm quan trọng của các giải pháp lưu trữ năng lượng.

PHẦN 2: PHÂN TÍCH CTCP CHỨNG KHOÁN SSI QUA BÁO CÁO TÀI CHÍNH: GIAI ĐOẠN 2015 - 2024

Ở phần 2, nhóm chúng em đã sử dụng bộ dữ liệu về các chỉ tiêu trong Bảng Kết quả Hoạt động Kinh doanh của CTCP Chứng khoán SSI từ năm 2015 - 2024 (10 năm).