1 Tuần 7

# Gọi các package cần thiết
  library(rvest)
  library(ggplot2)
  library(ggthemes)
  library(tidyverse)
  library(DT)
  library(scales)
  library(dplyr)
  library(cowplot)

1.1 Srcap dữ liệu từ internet

Có nhiều gói trong R dùng để scrape dữ liệu. Ta có thể sử dụng gói tùy theo ta muốn. Ở đây vì đã được học trên lớp nên em sẽ sử dụng gói rvest trong R để scrape dữ liệu từ trang web. Đầu tiên, cài đặt gói rvest bằng cách chạy lệnh sau: install.packages("rvest") nếu đã cài đặt rồi thì chỉ cần chạy lệnh ‘library(“rvest”)’. Sau đó, bạn có thể sử dụng hàm read_html để đọc trang web và hàm html_table để lấy bảng dữ liệu từ trang web.

1.1.1 Cào dữ liệu từ web: cophieu68.vn

Cophieu68.vn là một trang web chuyên về cung cấp dữ liệu và thông tin về thị trường chứng khoán Việt Nam. Trang web này cung cấp thông tin về các mã chứng khoán, bảng giá, biểu đồ, tin tức và các công cụ phân tích dữ liệu phục vụ cho các nhà đầu tư và người quan tâm đến thị trường chứng khoán Việt Nam.

library(rvest)

url <- "https://www.cophieu68.vn/historyprice.php?id=vcb"
webpage <- read_html(url)

# Lấy bảng dữ liệu từ trang web
data <- html_table(webpage, fill = TRUE)[[2]]

print(data)
## # A tibble: 101 × 13
##    X1    X2    X3    X4    X5    X6    X7    X8    X9    X10   X11   X12   X13  
##    <chr> <chr> <chr> <chr> <chr> <chr> <chr> <chr> <chr> <chr> <chr> <chr> <chr>
##  1 STT   Ngày  Giá … +/- … % (*) Đóng… Khối… Mở C… Cao … Thấp… Giao… Nước… Nước…
##  2 #1    18-0… 104.… -0.50 -0.4… 104.… 590,… 104.… 105   104.… 0     571,… 447,…
##  3 #2    17-0… 105   -0.20 -0.1… 104.… 791,… 105   105   104.… 1     503,… 567,…
##  4 #3    14-0… 104.… 0.10  0.10% 105   797,… 104.… 105   104   511,… 263,… 494,…
##  5 #4    13-0… 104   0.90  0.87% 104.… 928,… 105   105   103.… 755,… 1,11… 551,…
##  6 #5    12-0… 103   1     0.97% 103.… 684,… 102.… 104.… 102.… 0     330,… 392,…
##  7 #6    11-0… 102.… 0.30  0.29% 103.… 843,… 101.… 105   101.… 0     237,… 1,34…
##  8 #7    10-0… 105   -2.30 -2.1… 102.… 915,… 104.… 104.… 102.… 828,… 805,… 489,…
##  9 #8    07-0… 100.… 4.30  4.27% 105   1,06… 100.… 105   100.… 1,00… 1,86… 367,…
## 10 #9    06-0… 102   -1.30 -1.2… 100.… 1,02… 102.… 102.… 100.… 828,… 495,… 1,26…
## # ℹ 91 more rows

Dữ liệu vừa cào bao gồm các thông tin về giá chứng khoán, khối lượng giao dịch và các chỉ số chứng khoán của mã chứng khoán VCB (Vietcombank).

Ngày (Ngay): Thông tin về ngày giao dịch. (Ở đây em lấy từ tháng 2/2023 đến nay)

Giá tham chiếu (G.TC): giá đóng cửa của ngày giao dịch gần nhất trước đó.

Giá mở phiên giao dịch (G.M): Giá của mã chứng khoán VCB tại thời điểm mở phiên giao dịch.

Giá cao nhất (G.CN): Giá cao nhất mã chứng khoán VCB trong ngày.

Giá thấp nhất (G.TN): Giá thấp nhất mã chứng khoán VCB trong ngày.

Giá đóng cửa phiên giao dịch (G.DC): Giá của mã chứng khoán VCB tại thời điểm đóng cửa phiên giao dịch.

Khối lượng giao dịch (KL.GD): Khối lượng giao dịch (số lượng mã chứng khoán VCB được mua và bán) trong ngày.

+/- ( T/G.G): là mức thay đổi giá sao với Giá tham chiếu

% (*) (%T/G.G): là phần trăm mức thay đổi giá sao với Giá tham chiếu

Giao dịch thõa thuận (GD.TT): Khối lượng giao dịch (số lượng mã chứng khoán VCB được mua và bán) thõa thuận trong ngày.

Nước ngoài mua (NN.M): Số lượng cổ phiếu Nhà đầu tư nước ngoài đặt mua.

Nước ngoài bán (NN.B): Số lượng cổ phiếu Nhà đầu tư nước ngoài đặt bán.

1.1.2 Xử lý dữ liệu

Thông thường thì dữ liệu từ các trang web sẽ cần phải xem xét xử lý trước khi bước vào giai đoạn phân tích. Dữ liệu thu thập được từ trang web này có một số vấn đề cần xử lý, bao gồm:

Loại bỏ dòng đầu tiên và cột đầu tiên vì nó không phải là dữ liệu

Đặt lại tên cho các biến số (để tiện cho việc thao tác)

Tiếp theo là xóa dấu chấm và dấu phẩy trong dữ liệu để chuyển đổi kiểu dữ liệu sang số

Chuyển đổi cột ngày thành kiểu dữ liệu ngày

#Loại bỏ dòng đầu tiên của dữ liệu 
data <- data[-1,]

#Đổi tên cho các biến 
names(data) <- c("STT","Ngay","G.TC","T/G.G","%T/G.G","G.DC","KL.GD","G.M","G.CN","G.TN","GD.TT","NN.M","NN.B")
#Chuyển đổi kiểu dữ liệu thành số 
data <- data %>% mutate_at(.vars = c("G.TC","T/G.G","G.DC","G.M","G.CN","G.TN"),
 .funs = as.numeric)
#Chuyển đổi kiểu dữ liệu thành ngày
data <- data %>% mutate_at(.var = "Ngay",
                           .fun = as.ts)

Sau khi xử lý xong các vấn đề trên ta sẽ xem lại dữ liệu đã sửa, có đúng như ý ta cần

#Xem cấu trúc dữ liệu 
str(data)
## tibble [100 × 13] (S3: tbl_df/tbl/data.frame)
##  $ STT   : chr [1:100] "#1" "#2" "#3" "#4" ...
##  $ Ngay  : Time-Series [1:100] from 1 to 100: 18-07-2023 17-07-2023 14-07-2023 13-07-2023 ...
##  $ G.TC  : num [1:100] 105 105 105 104 103 ...
##  $ T/G.G : num [1:100] -0.5 -0.2 0.1 0.9 1 0.3 -2.3 4.3 -1.3 2 ...
##  $ %T/G.G: chr [1:100] "-0.48%" "-0.19%" "0.10%" "0.87%" ...
##  $ G.DC  : num [1:100] 104 105 105 105 104 ...
##  $ KL.GD : chr [1:100] "590,000" "791,600" "797,700" "928,300" ...
##  $ G.M   : num [1:100] 105 105 105 105 103 ...
##  $ G.CN  : num [1:100] 105 105 105 105 104 ...
##  $ G.TN  : num [1:100] 104 104 104 104 103 ...
##  $ GD.TT : chr [1:100] "0" "1" "511,000" "755,000" ...
##  $ NN.M  : chr [1:100] "571,878" "503,120" "263,500" "1,112,700" ...
##  $ NN.B  : chr [1:100] "447,418" "567,387" "494,900" "551,427" ...
# Hiển thị 6 dòng đầu 
head(data)
## # A tibble: 6 × 13
##   STT   Ngay     G.TC `T/G.G` `%T/G.G`  G.DC KL.GD   G.M  G.CN  G.TN GD.TT NN.M 
##   <chr> <chr>   <dbl>   <dbl> <chr>    <dbl> <chr> <dbl> <dbl> <dbl> <chr> <chr>
## 1 #1    18-07-…  105.    -0.5 -0.48%    104. 590,…  105.  105   104. 0     571,…
## 2 #2    17-07-…  105     -0.2 -0.19%    105. 791,…  105   105   104. 1     503,…
## 3 #3    14-07-…  105.     0.1 0.10%     105  797,…  105.  105   104  511,… 263,…
## 4 #4    13-07-…  104      0.9 0.87%     105. 928,…  105   105   104. 755,… 1,11…
## 5 #5    12-07-…  103      1   0.97%     104. 684,…  103.  104.  103. 0     330,…
## 6 #6    11-07-…  103.     0.3 0.29%     103. 843,…  102.  105   102. 0     237,…
## # ℹ 1 more variable: NN.B <chr>
#Hiển thị 6 dòng cuối 
tail(data)
## # A tibble: 6 × 13
##   STT   Ngay     G.TC `T/G.G` `%T/G.G`  G.DC KL.GD   G.M  G.CN  G.TN GD.TT NN.M 
##   <chr> <chr>   <dbl>   <dbl> <chr>    <dbl> <chr> <dbl> <dbl> <dbl> <chr> <chr>
## 1 #95   03-03-…  93.2    -2.3 -2.47%    90.9 798,…  93.2  93.2  90.9 66,0… 161,…
## 2 #96   02-03-…  93       0.2 0.22%     93.2 984,…  93    93.8  91.8 0     474,…
## 3 #97   01-03-…  93.5    -0.5 -0.53%    93   729,…  93.5  93.5  92.2 46,0… 255,…
## 4 #98   28-02-…  92.8     0.7 0.75%     93.5 565,…  92.8  93.7  92.6 60,0… 445,…
## 5 #99   27-02-…  93.5    -0.7 -0.75%    92.8 501,…  93.5  93.5  91.7 20,0… 33,5…
## 6 #100  24-02-…  93.3     0.2 0.21%     93.5 631,…  93.3  94    90   86,0… 484,…
## # ℹ 1 more variable: NN.B <chr>

1.1.3 Trích xuất dữ liệu

1.1.3.1 Trích xuất theo cột

Trong nhiều tình huống các bạn chỉ quan tâm đến một số biến chứ không phải toàn bộ biến số ở một data frame sẵn có. Chẳng hạn, với dữ liệu data ở trên chúng ta chỉ quan tâm đến hai biến là giá mở cửa (G.M) và giá đóng cửa (G.DC) và muốn tách (lọc) hai biến này thành một data frame khác có tên gọi P

P <- data[, c(6,8 )]
head(P) # Xem 6 quan sát đầu tiên của P
## # A tibble: 6 × 2
##    G.DC   G.M
##   <dbl> <dbl>
## 1  104.  105.
## 2  105.  105 
## 3  105   105.
## 4  105.  105 
## 5  104.  103.
## 6  103.  102.
tail(P) # Xem 6 quan sát cuối của P
## # A tibble: 6 × 2
##    G.DC   G.M
##   <dbl> <dbl>
## 1  90.9  93.2
## 2  93.2  93  
## 3  93    93.5
## 4  93.5  92.8
## 5  92.8  93.5
## 6  93.5  93.3

1.1.3.2 Trích xuất theo hàng

Có thể trích xuất ra một data frame con bằng cách chỉ định cụ thể quan sát nào muốn lấy theo vị trí của hàng

p1 <- data[c(1, 20, 99), ] # lấy quan sát ở dòng 1, 20 và 99

p2 <- data[c(1:3, 50, 100 ), ] # lấy quan sát từ 1 đến 3, 50 và 100

1.1.3.3 Trích xuất theo hàng và cột

Để trích xuất dữ liệu đồng thời theo hàng và cột:

p3 <- data[c(1:3, 50, 100), c(6,8)]

Tùy theo sự quán sát của bạn mà có thể trích xuất các dòng các cột theo ý của mình.

1.1.4 Lọc dữ liệu

Trong một giá trình quan tích dữ liệu không phải lúc nào ta cũng sử dụng hết toàn bộ bộ dữ liệu của mình. Mà ta có thể chỉ quan tâm đến những số liệu nhất định. Chẳng hạn ở đây sau khi lấy bộ dữ liệu về lịch sử giá của VCB từ tháng 2/2023 đến nay thì em chỉ quan tâm đến một số ván đề như sau:

Những lần giá mở cửa và giá đông cửa bằng nhau

#Giá mở cửa và giá đóng cửa bằng nhau  
p50.50 <- data[data$G.M == data$G.DC,]
p50.50
## # A tibble: 4 × 13
##   STT   Ngay     G.TC `T/G.G` `%T/G.G`  G.DC KL.GD   G.M  G.CN  G.TN GD.TT NN.M 
##   <chr> <chr>   <dbl>   <dbl> <chr>    <dbl> <chr> <dbl> <dbl> <dbl> <chr> <chr>
## 1 #12   03-07-… 100       0   0%       100   490,… 100   101.   99.8 0     322,…
## 2 #14   29-06-… 101.      0.8 0.79%    102.  619,… 102.  103   101.  0     236,…
## 3 #16   27-06-… 100       0   0%       100   685,… 100   101    99.7 0     301,…
## 4 #64   17-04-…  88.4     0   0%        88.4 488,…  88.4  88.5  87.8 76,0… 319,…
## # ℹ 1 more variable: NN.B <chr>

Kết quả cho biết trong những dữ liệu thu được từ internet về lịch sử giá của mã chứng khoán VCB thì có 4 lần giá mở cưuar và giá đóng cửa bằng nhau

Những lần giá đóng cửa bằng với giá cao nhất và lớn hơn 90 ngàn đồng

p50.50.90 <- data[(data$G.CN == data$G.DC) & data$G.CN >90,]
p50.50.90
## # A tibble: 7 × 13
##   STT   Ngay     G.TC `T/G.G` `%T/G.G`  G.DC KL.GD   G.M  G.CN  G.TN GD.TT NN.M 
##   <chr> <chr>   <dbl>   <dbl> <chr>    <dbl> <chr> <dbl> <dbl> <dbl> <chr> <chr>
## 1 #3    14-07-… 105.      0.1 0.10%    105   797,… 105.  105   104   511,… 263,…
## 2 #8    07-07-… 101.      4.3 4.27%    105   1,06… 100.  105   100.  1,00… 1,86…
## 3 #31   06-06-…  98       1   1.02%     99   759,…  98    99    96.5 20,0… 533,…
## 4 #48   12-05-…  91       1.8 1.98%     92.8 710,…  91    92.8  90.8 183,… 462,…
## 5 #79   27-03-…  89       2   2.25%     91   730,…  89    91    88   96,0… 493,…
## 6 #81   23-03-…  89       1.7 1.91%     90.7 849,…  89    90.7  87.3 1,09… 616,…
## 7 #92   08-03-…  91.9     0.3 0.33%     92.2 871,…  91.9  92.2  90.7 0     294,…
## # ℹ 1 more variable: NN.B <chr>

Kết quả cho biết trong những dữ liệu thu được từ internet về lịch sử giá của mã chứng khoán VCB thì có 8 ần giá đóng cửa bằng với giá cao nhất và lớn hơn 90 ngàn đồng

Ở trên chỉ là một vài ví dụ nhỏ, bạn có thể thực hiện lọc theo tiêu chí của riêng bạn.

1.2 Phân rã chuỗi

1.2.0.1 Đồ thị chuỗi

plot.ts(data$G.DC,frequency=12)

1.2.0.2 Chuỗi không có yếu tố mùa vụ

Một chuỗi thời gian không có yếu tố mùa vụ (non-seasonal time series) mùa bao gồm một thành phần xu hướng và một thành phần bất thường.

Phân tách chuỗi thời gian liên quan đến việc cố gắng tách chuỗi thời gian thành các các thành phần, nghĩa là ước tính thành phần xu hướng và thành phần bất thường. Để ước tính thành phần xu hướng của chuỗi thời gian không có yếu tố mùa vụ dạng cộng tính, người ta thường sử dụng phương pháp làm mịn (smoothing method), chẳng hạn như tính toán trung bình động đơn giản (simple moving average) của chuỗi.

Hàm SMA() trong gói TTR có thể được sử dụng để làm mượt chuỗi bằng cách sử dụng kỹ thuật trung bình trượt giản đơn. Để sử dụng hàm này, đầu tiên bạn cần cài đặt gói TTR vào máy và gọi thư viện TTR.

library("TTR")

Sau đó, bạn có thể sử dụng hàm SMA() để làm mịn dữ liệu chuỗi thời gian. Đầu tiên là chỉ định thứ tự (span) của đường trung bình động đơn giản, sử dụng tham số “n”. Ví dụ, để tính một đường trung bình động đơn giản bậc 5, chúng ta đặt n = 5 trong hàm SMA().

Trở lại ví dụ về lịch sử giao dịch giá mã chứng khoán VCB là chuỗi không có yếu tố mùa vụ, được mô tả bằng một mô hình cộng, vì các dao động ngẫu nhiên trong dữ liệu có độ lớn gần như không đổi theo thời gian. Vì vậy, chúng ta có thể ước tính thành phần xu hướng của chuỗi bằng phương pháp làm mịn chuỗi với kỹ thuật trung bình trượt giản đơn. Thiết lập n = 3 để tính toán trung bình 3 kỳ và hiển thị chuỗi đã được làm mịn như sau:

plot.KMV3 <- SMA(data$G.DC, n = 3)
plot.ts(plot.KMV3) 

Dường như vẫn còn khá nhiều biến động ngẫu nhiên trong chuỗi thời gian được làm mịn với SMA = 3. Do đó, để ước tính thành phần xu hướng chính xác hơn, tôi sẽ thử làm mịn dữ liệu bằng một đường trung bình động đơn giản có bậc cao hơn. Tôi sẽ sai thử vài lần để tìm ra mức độ làm mịn phù hợp. Ví dụ bên dưới là chuỗi bên dưới đã được làm mịn với bậc bằng 8.

plot.KMV8 <- SMA(data$G.DC, n = 8)
plot.ts(plot.KMV8) 

Dữ liệu được làm mịn với đường trung bình động đơn giản bậc 8 cho một bức tranh rõ ràng hơn về thành phần xu hướng. Chúng ta có thể thấy rằng giá đóng cửa của mã chứng khoán VCB dường như đã giảm từ hơn 100 VND xuống còn dưới 90 VND trong trong , và sau đó tăng lên gần 95 VND trong cuối chuỗi thười gian.

1.2.1 Dự báo bằng phương pháp mũ đơn giản

Nếu bạn có một chuỗi thời gian có thể được mô tả bằng mô hình cộng với hằng số và không có tính thời vụ, bạn có thể sử dụng phương pháp làm trơn hàm mũ đơn giản (simple exponential smoothing) để thực hiện các dự báo ngắn hạn.

Phương pháp làm mịn hàm mũ đơn giản cung cấp một cách ước tính mức ở thời điểm hiện tại. Việc làm mịn được điều khiển bởi tham số alpha; để ước tính mức độ tại thời điểm hiện tại. Giá trị của alpha nằm giữa 0 và 1, cho biết tầm quan trọng của các quan sát gần nhất đến giá trị dự báo trong tương lai. Alpha gần bằng 0 có nghĩa là các quan sát gần đây nhất có trọng số nhỏ lên giá trị dự báo.

Ví dụ sử dụng dữ liệu về lịch sử giao dịch giá mã chứng khoán VCB , giai thời gian từ tháng 2/2023 đến tháng 7/2023

Để đưa ra dự báo bằng cách sử dụng phương pháp làm mịn hàm mũ đơn giản trong R, sử dụng hàm HoltWinters(). Để sử dụng hàm HoltWinters() để làm mịn hàm mũ đơn giản, chúng ta cần đặt tham số beta = FALSE và gamma = FALSE trong hàm. Hàm HoltWinters() trả về một biến danh sách.

rainseriesforecasts <- HoltWinters(data$G.DC, beta = FALSE, gamma = FALSE)
rainseriesforecasts
## Holt-Winters exponential smoothing without trend and without seasonal component.
## 
## Call:
## HoltWinters(x = data$G.DC, beta = FALSE, gamma = FALSE)
## 
## Smoothing parameters:
##  alpha: 0.8856876
##  beta : FALSE
##  gamma: FALSE
## 
## Coefficients:
##       [,1]
## a 93.42837

Kết quả của hàm HoltWinters() cho chúng ta biết rằng giá trị ước tính của tham số alpha là khoảng 0,8846. Giá trị này gần bằng 1. Điều này cho chúng tôi biết rằng các dự báo dựa trên cả những quan sát gần đây.

Theo mặc định, hàm HoltWinters() chỉ đưa ra dự báo cho cùng khoảng thời gian xem xét. Trong trường hợp này, chuỗi thời gian ban đầu của chúng ta là lịch sử giao dịch giá mã chứng khoán VCB, thời gian từ tháng 2/2023 đến tháng 7/2023 . Vì vậy các dự báo cũng dành cho thời gian từ tháng 2/2023 đến tháng 7/2023.

Trong ví dụ trên, chúng ta đã lưu kết quả của hàm HoltWinters() trong biến danh sách tên là rainseriesforecasts. Các dự báo từ HoltWinters() được lưu trữ là một phần tử có tên fitted trong biến danh sách rainseriesforecasts. Vì vậy chúng ta có thể lấy các giá trị của chúng bằng cách nhập:

head(rainseriesforecasts$fitted, 5)
##          xhat    level
## [1,] 104.3000 104.3000
## [2,] 104.7428 104.7428
## [3,] 104.9706 104.9706
## [4,] 104.9081 104.9081
## [5,] 103.6610 103.6610

Chúng ta có thể vẽ chuỗi thời gian ban đầu được dự báo:

plot(rainseriesforecasts)

Biểu đồ cho thấy chuỗi dự báo (đường màu đỏ) mượt mà hơn nhiều so với chuỗi thời gian gốc (đường màu đen). Để đo độ chính xác của các dự báo, chúng ta có thể tính tổng sai số bình phương (sum of squared errors) cho các sai số dự báo trong mẫu. Nghĩa là các sai số dự báo cho khoảng thời gian được xem xét ở chuỗi thời gian ban đầu của chúng ta. Tổng bình phương các sai số được lưu trữ trong một phần tử được đặt tên SSE của biến danh sách rainseriesforecasts. Chúng ta có thể nhận được giá trị này bằng cách:

rainseriesforecasts$SSE
## [1] 173.872

Tức là, ở đây tổng bình phương sai số là 173.6154. Việc làm trơn hàm mũ giản đơn thường sử dụng giá trị đầu tiên trong chuỗi thời gian làm giá trị khởi tạo. Ví dụ, trong chuỗi thời gian lịch sử giao dịch giá đóng cửa mã chứng khoán VCB, giá trị đầu tiên là 104.8000 (VND) cho giá đóng của tháng 2/2023. Bạn có thể chỉ định giá trị ban đầu cho hàm HoltWinters() bằng cách sử dụng tham số l.start. Ví dụ, để đưa ra dự báo với giá trị ban đầu là 104.8000, chúng ta gõ:

HoltWinters(data$G.DC, beta = FALSE, gamma = FALSE, l.start = 104.8000)
## Holt-Winters exponential smoothing without trend and without seasonal component.
## 
## Call:
## HoltWinters(x = data$G.DC, beta = FALSE, gamma = FALSE, l.start = 104.8)
## 
## Smoothing parameters:
##  alpha: 0.8850601
##  beta : FALSE
##  gamma: FALSE
## 
## Coefficients:
##       [,1]
## a 93.42802

Như đã giải thích ở trên, theo mặc định, hàm HoltWinters() chỉ đưa ra dự báo cho khoảng thời gian được bao quát của dữ liệu gốc. Đó là thời gian từ tháng 2/2023 đến tháng 7/2023 cho chuỗi thời về lịch sử giá đóng cửa mã chứng khoán VCB. Chúng ta có thể đưa ra dự báo cho các mốc thời gian tiếp theo bằng cách sử dụng hàm forecast.HoltWinters() trong gói forecast trên R.

Đối số đầu tiên (đầu vào) của hàm forecast.HoltWinters() là kết quả dự báo từ hàm HoltWinters().

Ví dụ: trong trường hợp chuỗi thời gian lượng mưa, chúng ta đã lưu trữ mô hình dự báo bằng hàm HoltWinters() ở biến rainseriesforecasts. Bạn chỉ định số lượng điểm thời gian tiếp theo mà bạn muốn đưa ra dự báo bằng cách sử dụng tham số h trong hàm forecast.HoltWinters(). Bên dưới là phần dự báo lượng mưa cho các tháng 8 - 12 (5 tháng tiếp theo) bằng cách sử dụng forecast.HoltWinters():

library("forecast")
## Registered S3 method overwritten by 'quantmod':
##   method            from
##   as.zoo.data.frame zoo
rainseriesforecasts2 <- forecast:::forecast.HoltWinters(rainseriesforecasts, h = 5) 
rainseriesforecasts2
##     Point Forecast    Lo 80    Hi 80    Lo 95    Hi 95
## 101       93.42837 91.72884 95.12790 90.82916 96.02758
## 102       93.42837 91.15809 95.69865 89.95627 96.90047
## 103       93.42837 90.70441 96.15233 89.26243 97.59431
## 104       93.42837 90.31618 96.54057 88.66868 98.18806
## 105       93.42837 89.97127 96.88547 88.14119 98.71555

Hàm forecast.HoltWinters() cung cấp cho bạn dự báo cho một tháng với khoảng dự báo 80% và 95%. Ví dụ, lượng mưa dự báo cho tháng 8/2023 là khoảng 93.31 VND, với khoảng dự báo 95% là (88.04, 98.59).

Để vẽ các dự báo được đưa ra bởi forecast.HoltWinters(), chúng ta có thể sử dụng hàm plot.forecast():

forecast:::plot.forecast(rainseriesforecasts2) 

Ở đây, các dự báo cho tháng 2/2023 đến tháng 7/2023 được vẽ dưới dạng một đường màu xanh lam, khoảng dự báo 80% dưới dạng vùng được tô bóng màu cam và khoảng dự báo 95% là vùng được tô bóng màu vàng. Các sai số dự báo được tính bằng giá trị quan sát được trừ đi giá trị dự báo cho mỗi thời điểm.

1.3 Tạo function

Trong quá trình phân tích dữ liệu em thấy việc đọc dữ liệu từ internet và thực hiện các đi tính lại các hàm trong thống kê và vẽ biểu đồ cho từng bộ dữ liệu lấy về gây mất thời gian nên em sẽ tạo ra một function cho riêng việc em muốn làm.

Để tạo 3 function kết hợp việc đọc dữ liệu từ internet, tính toán thống kê và vẽ biểu đồ trong R, ta cần sử dụng các package phù hợp như tidyverse, rvestggplot2 và nhiều gói khác.

docTinhVaVeDoThiHtml <- function(url, x, y,css_selector, type = "scatter"){
  # Gọi các gói packages 
library(rvest)
library(ggplot2)
library(tidyverse)
library(DT)
library(scales)
library(dplyr)
library(cowplot)
  # Đọc dữ liệu HTML từ internet
web <- read_html(url)

  # Gửi yêu cầu GET đến trang web
page_web <- web %>% html_table(header = NA,
  trim = TRUE,
  fill = FALSE ,
  dec = ".",
  na.strings = "NA")

 # Xác định các phần tử HTML chứa thông tin cần scrape
p = page_web[[1]]
  
# Loại bỏ dữ liệu chứa giá trị missing
p <- p [colSums(!is.na(p)) > 0]

 # Loại bỏ hàng đầu tiên (tiêu đề)
  p  <- p[-1, ]
  
  # Chuyển đổi kiểu dữ liệu
  df <- df %>% mutate_at(vars(-one_of(x, y)), as.numeric)
  
  # Tính các giá trị thống kê
  mean_value <- mean(df)
  median_value <- median(df)
  sd_value <- sd(df)
  min_value <- min(df)
  max_value <- max(df)
  
  # Tạo summary statistics
  summary_stats <- summary(df)
  
  # Tạo quantiles
  quantiles <- quantile(df, probs = c(0.25, 0.5, 0.75))
  
  # Hiển thị kết quả
  cat("Mean:", mean_value, "\n")
  cat("Median:", median_value, "\n")
  cat("Standard Deviation:", sd_value, "\n")
  cat("Min:", min_value, "\n")
  cat("Max:", max_value, "\n")
  
  cat("\nSummary Statistics:\n")
  print(summary_stats)
  
  cat("\nQuantiles:\n")
  print(quantiles)
  
  # Trực quan hóa dữ liệu
  if (type == "scatter") {
    # Biểu đồ scatter plot
    ggplot(data, aes_string(x = x, y = y)) + 
      geom_point() +
      labs(x = x, y = y) +
      theme_minimal()
  } else if (type == "bar") {
    # Biểu đồ bar chart
    ggplot(data, aes_string(x = x, y = y)) + 
      geom_col() +
      labs(x = x, y = y) +
      theme_minimal()
  } else if (type == "line") {
    # Biểu đồ line chart
    ggplot(data, aes_string(x = x, y = y, group = 1)) + 
      geom_line() +
      labs(x = x, y = y) +
      theme_minimal()
  } else {
    cat("Invalid type. Please choose 'scatter', 'bar', or 'line'.")
  }
  
}

Function docTinhVaVeDoThiHtml nhận bốn đối số là url (đường dẫn trang web), css_selector (chọn các phần tử HTML), x (tên cột để làm trục x) và y (tên cột để làm trục y). Function này sử dụng read_html trong package rvest để đọc dữ liệu HTML từ đường dẫn trang web. Sau đó, function sử dụng html_nodeshtml_table để trích xuất dữ liệu từ các phần tử HTML đã chọn với CSS selector và lưu vào dataframe df.

Tiếp theo, function đặt tên cho các cột trong dataframe bằng cách sử dụng hàng đầu tiên của dataframe df làm tiêu đề. Sau đó, function loại bỏ hàng đầu tiên (tiêu đề) và chuyển đổi kiểu dữ liệu của các cột không phải là xy sang kiểu numeric.

Function tiếp tục, function thongKeMoTa nhận một vector dữ liệu làm đối số (data). Function sử dụng các hàm tính toán thống kê như mean, median, sd, minmax để tính giá trị trung bình, trung vị, độ lệch chuẩn, giá trị nhỏ nhất và giá trị lớn nhất của dữ liệu.

Function cũng sử dụng hàm summary để tạo summary statistics (thống kê tóm tắt) và hàm quantile để tính quantiles (ngạch định), mặc định là 1st quartile (Q1), median (Q2) và 3rd quartile (Q3).

Cuối cùng, function xuất kết quả bằng cách sử dụng hàm cat để in các giá trị thống kê và sử dụng hàm print để in summary statistics và quantiles.

Function cuối cùng, function trucQuanHoaDuLieu nhận ba đối số là data (dữ liệu), x (tên cột để làm trục x) và y (tên cột để làm trục y). Function này cũng có một đối số tùy chọn type, mặc định là “scatter” (scatter plot) nhưng bạn có thể chọn “bar” (bar chart) hoặc “line” (line chart).

Function sử dụng các hàm trong package ggplot2 để tạo biểu đồ dựa trên dữ liệu đã cho. Sử dụng aes_string để liên kết cột x và y với trục x và trục y trên biểu đồ. Function sử dụng geom_point cho scatter plot, geom_col cho bar chart và geom_line cho line chart.

Cuối cùng, function đặt tên cho trục x và trục y thông qua labs và sử dụng theme_minimal để chỉnh thiết kế biểu đồ.

1.4 Tìm hiểu 10 indecators của World bank

Package WDI trong R đề cập đến một gói phần mềm R được sử dụng để truy cập và sử dụng dữ liệu World Development Indicators (WDI) từ Ngân hàng Thế giới.

Gói WDI trong R chứa các chức năng cho phép người dùng tải xuống và truy vấn các chỉ số WDI một cách dễ dàng từ dữ liệu WDI đã được thu thập và tổ chức sẵn. Điều này cho phép người dùng thực hiện phân tích và trực quan hóa dữ liệu WDI một cách thuận tiện trực tiếp trong môi trường R.

Để sử dụng gói WDI trong R, bạn cần cài đặt gói này bằng cách chạy lệnh install.packages("WDI"). Sau đó, bạn có thể gọi gói WDI vào phiên làm việc R bằng cách sử dụng lệnh library(WDI).

Gói WDI trong R cung cấp các hàm như WDIsearch() để tìm kiếm thông tin về chỉ số WDI, WDIconc() để tải dữ liệu WDI và WDI() để truy vấn dữ liệu từ WDI. Bạn có thể tìm hiểu thêm về các hàm và cách sử dụng chúng trong tài liệu và ví dụ được cung cấp bởi gói WDI.

library(WDI)

Chúng ta cần tìm hiểu các chỉ số (kí hiệu cũng như miêu tả) có thể lấy bằng lệnh WDIcache():

w <- WDIcache()
w1 <- data.frame(w$series) 
w2 <- data.frame(w$country) 

Ở đây w1 là danh sách (mà thực chất là một data frame – một khái niệm mà chúng ta sẽ biết rõ hơn ở các mục sau) các chỉ số có thể lấy và có hai cột chúng ta cần chú ý. Cột thứ nhất là kí hiệu các chỉ số (cột indicator). Cột thứ hai là miêu tả ngắn về chỉ số đó (cột name). Chúng ta có thể thấy điều này bằng xem 6 quan sát đầu tiên trong danh sách (trích một phần):

head(w1)
##              indicator                                    name
## 1   1.0.HCount.1.90usd         Poverty Headcount ($1.90 a day)
## 2    1.0.HCount.2.5usd         Poverty Headcount ($2.50 a day)
## 3 1.0.HCount.Mid10to50   Middle Class ($10-50 a day) Headcount
## 4      1.0.HCount.Ofcl Official Moderate Poverty Rate-National
## 5  1.0.HCount.Poor4uds            Poverty Headcount ($4 a day)
## 6  1.0.HCount.Vul4to10      Vulnerable ($4-10 a day) Headcount
##                                                                                                                                                     description
## 1                      The poverty headcount index measures the proportion of the population with daily per capita income (in 2011 PPP) below the poverty line.
## 2                      The poverty headcount index measures the proportion of the population with daily per capita income (in 2005 PPP) below the poverty line.
## 3                      The poverty headcount index measures the proportion of the population with daily per capita income (in 2005 PPP) below the poverty line.
## 4 The poverty headcount index measures the proportion of the population with daily per capita income below the official poverty line developed by each country.
## 5                      The poverty headcount index measures the proportion of the population with daily per capita income (in 2005 PPP) below the poverty line.
## 6                      The poverty headcount index measures the proportion of the population with daily per capita income (in 2005 PPP) below the poverty line.
##   sourceDatabase
## 1 LAC Equity Lab
## 2 LAC Equity Lab
## 3 LAC Equity Lab
## 4 LAC Equity Lab
## 5 LAC Equity Lab
## 6 LAC Equity Lab
##                                                      sourceOrganization
## 1     LAC Equity Lab tabulations of SEDLAC (CEDLAS and the World Bank).
## 2     LAC Equity Lab tabulations of SEDLAC (CEDLAS and the World Bank).
## 3     LAC Equity Lab tabulations of SEDLAC (CEDLAS and the World Bank).
## 4 LAC Equity Lab tabulations of data from National Statistical Offices.
## 5     LAC Equity Lab tabulations of SEDLAC (CEDLAS and the World Bank).
## 6     LAC Equity Lab tabulations of SEDLAC (CEDLAS and the World Bank).

Ví dụ, chỉ số có kí hiệu 1.0.HCount.1.90usd được miêu tả là “Poverty Headcount ($1.90 a day)” và do đó chúng ta hiểu chỉ số này là chi tiêu để đo lường tỷ lệ dân số sống dưới mức nghèo đói, với ngưỡng nghèo đói là 1,90 đô la Mỹ một ngày.

Có thể xem chi tiết hơn (và cũng thuận lợi hơn) danh sách này bằng lệnh View(), dim()và nrow():

View(w1)
dim(w1)
## [1] 20939     5
nrow(w1)
## [1] 20939

Số lượng các chỉ số có thể lấy từ WB là hơn 20900

Danh sách w2 là các thông tin về những quốc gia mà chúng ta có thể lấy số liệu cho nó. Có ba cột thông tin đáng quan tâm là: (1) country - tên của quốc gia, (2) iso2c - mã quốc gia, và (3) income - nhóm thu nhập của quốc gia theo cách phân loại của WB:

# Số lượng các quốc gia có trong kho dữ liệu của ngân hàng thế giới: 
dim(w2) 
## [1] 297   9
# Xem 6 quan sát đầu: 
head(w2)
##   iso3c iso2c                     country                    region    capital
## 1   ABW    AW                       Aruba Latin America & Caribbean Oranjestad
## 2   AFE    ZH Africa Eastern and Southern                Aggregates           
## 3   AFG    AF                 Afghanistan                South Asia      Kabul
## 4   AFR    A9                      Africa                Aggregates           
## 5   AFW    ZI  Africa Western and Central                Aggregates           
## 6   AGO    AO                      Angola        Sub-Saharan Africa     Luanda
##   longitude latitude              income        lending
## 1  -70.0167  12.5167         High income Not classified
## 2                             Aggregates     Aggregates
## 3   69.1761  34.5228          Low income            IDA
## 4                             Aggregates     Aggregates
## 5                             Aggregates     Aggregates
## 6    13.242 -8.81155 Lower middle income           IBRD

Chúng ta có thể xem qua phân bố các quốc gia theo nhóm thu nhập:

table(w2$income)
## 
##          Aggregates         High income          Low income Lower middle income 
##                  79                  83                  26                  54 
##      Not classified Upper middle income 
##                   1                  54

Với 297 quốc gia và vùng lãnh thổ thì tìm mã iso2c cho, chẳng hạn, cho Việt Nam là một công việc khá chán nếu dò từng dòng bằng mắt. Chúng ta nên sử dụng lệnh filter() của gói dplyr thuộc hệ sinh thái tidyverse để tìm:

library(tidyverse)
filter(w2, country == "Vietnam")
##   iso3c iso2c country              region capital longitude latitude
## 1   VNM    VN Vietnam East Asia & Pacific   Hanoi   105.825  21.0069
##                income lending
## 1 Lower middle income    IBRD

Mã quốc gia của Việt Nam là VN thuộc khu vực Đông Á - Thái Bình Dương với thủ đô là Hà Nội có kinh độ 105.825 và vĩ độ là 21.0069 và nằm trong nhóm thu nhập Lower middle income.

Với hơn 20900 chỉ số tì tìm kiếm một chỉ số nào đó trong kho là một việc rất mất thời gian nếu chúng ta cứ tra từng dòng một. Dưới đây là cách tìm kiếm một chỉ số nhanh chóng hơn với lệnh WDIsearch(). Chẳng hạn chúng ta cần tìm các chỉ số có chữ GDP (chú ý không phân biệt chữ hoa – chữ thường) trong phần miêu tả về chỉ số đó ở cột name:

# Các chỉ số có chữ gdp: 
wf1 <- WDIsearch("gdp", cache = w)
dim(wf1) # Có 540 chỉ số có chữ gdp
## [1] 540   2
head(wf1) # Xem 6 chỉ số đầu.
##                 indicator                                                 name
## 689       6.0.GDP_current                                      GDP (current $)
## 690        6.0.GDP_growth                                GDP growth (annual %)
## 691           6.0.GDP_usd                                GDP (constant 2005 $)
## 692    6.0.GDPpc_constant GDP per capita, PPP (constant 2011 international $) 
## 1534    BG.GSR.NFSV.GD.ZS                         Trade in services (% of GDP)
## 1535 BG.KAC.FNEI.GD.PP.ZS          Gross private capital flows (% of GDP, PPP)

Chúng ta có thể thu hẹp phạm vi tìm kiếm hơn nữa với điều kiện là chỉ số đó có: (1) có cụm gdp, (2) capita, và (3) current:

# Các chỉ số có ba nhóm chữ gdp, capita và current: 
wf2 <- WDIsearch("gdp.*capita.*current", cache = w)
dim(wf2)
## [1] 4 2
wf2
##                  indicator
## 11679 NE.GDI.FTOT.SNA08.CR
## 11976       NY.GDP.PCAP.CD
## 11977       NY.GDP.PCAP.CN
## 11981    NY.GDP.PCAP.PP.CD
##                                                                                             name
## 11679 GDP expenditure on gross fixed capital formation (in IDR Million), SNA 2008, Current Price
## 11976                                                               GDP per capita (current US$)
## 11977                                                               GDP per capita (current LCU)
## 11981                                              GDP per capita, PPP (current international $)

Như vậy có 4 chỉ số thỏa mãn các điều kiện tìm kiếm ở trên.

1.4.1 Indicator: BG.GSR.NFSV.GD.ZS

Địch nghĩa: GDP per capita, PPP (constant 2011 international $) là một chỉ số đo lường giá trị GDP trên mỗi người dân của một quốc gia, được tính toán bằng cách sử dụng quy ước mua sắm sức mạnh mua hàng (PPP) và giá trị tiền tệ được điều chỉnh theo năm 2011.

Chỉ số này cho phép so sánh mức sống và mức độ phát triển kinh tế giữa các quốc gia một cách công bằng hơn. Bằng cách sử dụng quy ước PPP, GDP per capita đưa ra một ước lượng về khả năng mua hàng và mức độ phát triển kinh tế của mỗi người dân trong một quốc gia.

GDP per capita, PPP (constant 2011 international $) cho phép so sánh mức sống và mức độ phát triển kinh tế ở các quốc gia khác nhau không chỉ dựa trên giá trị tiền tệ hiện tại, mà còn xem xét đến sức mạnh mua sắm tương đối của mỗi quốc gia trong năm 2011.

d1 <- WDI(indicator = c('BG.GSR.NFSV.GD.ZS'),
          country = c('TH'),
          start = 1980, end = 2020)

Chú ý rằng không phải quốc gia nào cũng có số liệu từ năm 1980. Thái Lan có lẽ cũng không ngoại lệ. Có thể tìm số lượng những năm không có số liệu về chỉ số này như sau:

sum(is.na(d1$BG.GSR.NFSV.GD.ZS))
## [1] 0

Như vậy có 0 năm trong khoảng thời gian trên Thái Lan không có số liệu.

1.4.1.1 Tính toán cơ bản cho bộ dữ liệu

#Thống kê cơ bản cho giá trị GDP trên mỗi người dân của một quốc gia 
summary(d1$BG.GSR.NFSV.GD.ZS)
##    Min. 1st Qu.  Median    Mean 3rd Qu.    Max. 
##   9.223  14.914  22.185  19.515  24.316  27.162
#Tính trung bình giá trị GDP trên mỗi người dân của một quốc gia
mean(d1$BG.GSR.NFSV.GD.ZS)
## [1] 19.51484
#Tính trung bình giá trị GDP trên mỗi người dân của một quốc gia theo năm
aggregate(d1$BG.GSR.NFSV.GD.ZS, list(d1$year), FUN = "mean") 
##    Group.1         x
## 1     1980  9.686564
## 2     1981  9.846377
## 3     1982  9.222892
## 4     1983  9.376225
## 5     1984  9.267167
## 6     1985  9.912086
## 7     1986  9.638179
## 8     1987 10.836352
## 9     1988 13.324485
## 10    1989 13.788435
## 11    1990 14.914142
## 12    1991 15.587083
## 13    1992 17.636398
## 14    1993 18.254341
## 15    1994 18.431353
## 16    1995 19.894362
## 17    1996 19.992070
## 18    1997 22.051983
## 19    1998 22.127836
## 20    1999 22.276879
## 21    2000 23.204361
## 22    2001 22.972168
## 23    2002 23.909776
## 24    2003 22.305624
## 25    2004 24.359919
## 26    2005 24.679919
## 27    2006 25.805290
## 28    2007 25.931570
## 29    2008 27.162204
## 30    2009 22.943358
## 31    2010 22.184707
## 32    2011 23.634727
## 33    2012 23.189745
## 34    2013 24.315648
## 35    2014 23.859108
## 36    2015 25.068876
## 37    2016 25.957086
## 38    2017 25.776426
## 39    2018 26.129578
## 40    2019 25.374640
## 41    2020 15.278689
#Tính trung vị cho giá trị GDP trên mỗi người dân của một quốc gia
median(d1$BG.GSR.NFSV.GD.ZS)
## [1] 22.18471
#Tính độ lệch chuẩn cho giá trị GDP trên mỗi người dân của một quốc gia
sd(d1$BG.GSR.NFSV.GD.ZS)
## [1] 6.010553
#Tính phương sai cho giá trị GDP trên mỗi người dân của một quốc gia
var(d1$BG.GSR.NFSV.GD.ZS)
## [1] 36.12674
#Tính tổng giá trị GDP trên mỗi người dân của một quốc gia
sum(d1$BG.GSR.NFSV.GD.ZS)
## [1] 800.1086

1.4.1.2 Trực quan hóa dữ liệu

Có thể hình ảnh hóa dữ liệu (Data Visualization) nhằm mô tả tăng trưởng GDP đầu người của Thái Lan bằng hình ảnh sau:

k1 <- ggplot(d1, aes(year, BG.GSR.NFSV.GD.ZS)) +
 geom_line() +
 geom_point(col = "red") +
 labs(x = NULL, 
 y = NULL, 
 title = "Thái Lan's Economic Growth: 1980 - 2020", 
 subtitle = "Unit: Percentage", 
 caption = "Data Source: The World Bank") +
 theme_economist()
k1

Chúng ta cũng có thể lấy nhiều chỉ số cùng một lúc cho nhiều quốc gia. Dưới đây là minh họa việc lấy cả BG.GSR.NFSV.GD.ZS và SP.DYN.LE00.IN (tuổi thọ bình quân) cho 6 nước là Lào, Campuchia, Việt Nam, Thái Lan, Philippine và Indonesia:

d1.1 <- WDI(country = c("LA","KH","VN","TH","PH","ID"),
 indicator = c("BG.GSR.NFSV.GD.ZS","SP.DYN.LE00.IN"),
 start = 1986, 
 end = 2020, 
 extra = TRUE, 
 cache = NULL)

Giả sử chúng ta chỉ quan tâm đến xu hướng về tuổi thọ của các quốc gia mà thôi thì chúng ta có thể tách từ ra biến SP.DYN.LE00.IN và year mà thôi:

d1.2 <- select(d1.1, country, year, SP.DYN.LE00.IN)

Sau đó đổi tên biến cho dễ hiểu hơn:

d1.2 <-rename(d1.2, Country = country, 
 Year = year, 
 Longevity = SP.DYN.LE00.IN)

Rồi hình ảnh hóa dữ liệu:

k1.1 <- ggplot(d1.2, aes(Year, Longevity, color = Country)) +
 geom_line(size=0.7) +
 geom_point() + 
labs(x = NULL, y = NULL, 
 title = "Tuổi thọ trung bình ở một số quốc gia: 1980 - 2020", 
 subtitle = "Unit: Năm", 
 caption = "Data Source: The World Bank") 
## Warning: Using `size` aesthetic for lines was deprecated in ggplot2 3.4.0.
## ℹ Please use `linewidth` instead.
## This warning is displayed once every 8 hours.
## Call `lifecycle::last_lifecycle_warnings()` to see where this warning was
## generated.
k1.1

1.4.2 Indicator: BI.WAG.TOTL.GD.ZS

Định nghĩa: Chỉ số Gross Foreign Direct Investment (FDI) (% of GDP) được sử dụng để đo lường lượng vốn đầu tư trực tiếp nước ngoài vào một quốc gia so với tổng sản phẩm quốc nội (GDP) của quốc gia đó. Chỉ số này cho thấy mức độ hấp dẫn của một quốc gia đối với các nhà đầu tư nước ngoài.

Nếu chỉ số FDI (% of GDP) cao, điều này cho thấy quốc gia có môi trường kinh doanh thu hút nhà đầu tư nước ngoài, và đầu tư trực tiếp từ các quốc gia khác đóng vai trò quan trọng trong kinh tế xã hội của quốc gia đó.

Tuy nhiên, nếu chỉ số này thấp, có thể cho thấy quốc gia không thu hút được nhiều vốn đầu tư trực tiếp từ nước ngoài hoặc không có môi trường kinh doanh thuận lợi cho các nhà đầu tư nước ngoài.

Chỉ số FDI (% of GDP) là một trong những chỉ số quan trọng được sử dụng để đánh giá tình trạng đầu tư nước ngoài trong một quốc gia và đánh giá mức độ hạnh phúc kinh tế của quốc gia đó.

d2 <- WDI(country = c("VN","TH","KH"), 
 indicator=c("BI.WAG.TOTL.GD.ZS"), 
 start = 2000, 
 end = 2020, 
 extra = TRUE, 
 cache = NULL)
d2 <- na.omit(d2)

Ở đây, VN, TH, KH lần lượt là kí hiệu của Việt Nam, Thái Lan, Campuchia và BI.WAG.TOTL.GD.ZS là kí hiệu bộ dữ liệu về dòng vốn đầu tư ở 3 nước. Dữ liệu thu thập được gồm nhiều biến số nhưng chúng ta chỉ quan tâm đến FDI ròng và thời gian cho nên chúng ta chỉ cần giữ lại hai biến số đó.

1.4.2.1 Tính toán cơ bản

Ta sử dụng các thông kê cơ bản cho các biến có trong bộ dữ liệu BX.KLT.DINV.CD.WD

#Thông kê cơ bản vốn đầu tư trực tiếp nước ngoài vào một quốc gia so với tổng sản phẩm quốc nội (GDP) của quốc gia đó
summary(d2$BI.WAG.TOTL.GD.ZS)
##    Min. 1st Qu.  Median    Mean 3rd Qu.    Max. 
##   3.020   5.176   6.250   5.924   6.828   8.900
#Tính trung bình vốn đầu tư trực tiếp nước ngoài vào một quốc gia so với tổng sản phẩm quốc nội (GDP) của quốc gia đó theo từng nước 
aggregate(d2$BI.WAG.TOTL.GD.ZS, list(d2$country), FUN = "mean")
##    Group.1        x
## 1 Cambodia 5.040315
## 2 Thailand 6.358527
## 3  Vietnam 6.929732
#Tính trung vị cho vốn đầu tư trực tiếp nước ngoài vào một quốc gia so với tổng sản phẩm quốc nội (GDP) của quốc gia đó theo từng nước 
aggregate(d2$BI.WAG.TOTL.GD.ZS, list(d2$country), FUN = "median")
##    Group.1        x
## 1 Cambodia 4.330187
## 2 Thailand 6.327697
## 3  Vietnam 7.060598
#Tính độ lệch chuẩn cho vốn đầu tư trực tiếp nước ngoài vào một quốc gia so với tổng sản phẩm quốc nội (GDP) của quốc gia đó theo từng nước
aggregate(d2$BI.WAG.TOTL.GD.ZS, list(d2$country), FUN = "var")
##    Group.1         x
## 1 Cambodia 3.0432939
## 2 Thailand 0.2774051
## 3  Vietnam 2.1784930
#Tính phương sai cho vốn đầu tư trực tiếp nước ngoài vào một quốc gia so với tổng sản phẩm quốc nội (GDP) của quốc gia đó theo từng nước
aggregate(d2$BI.WAG.TOTL.GD.ZS, list(d2$country), FUN = "sd")
##    Group.1         x
## 1 Cambodia 1.7445039
## 2 Thailand 0.5266926
## 3  Vietnam 1.4759719
#Tính tổng vốn đầu tư trực tiếp nước ngoài vào một quốc gia so với tổng sản phẩm quốc nội (GDP) của quốc gia đó theo từng nước
aggregate(d2$BI.WAG.TOTL.GD.ZS, list(d2$country), FUN = "sum")
##    Group.1         x
## 1 Cambodia  80.64504
## 2 Thailand 133.52908
## 3  Vietnam  34.64866

Ngoài ra để dễ hiểu chúng ta có thể đổi tên cho biến số đồng thời tạo ra một biến mới là FDI_b với ngụ ý đơn vị của FDI ròng là tỉ Dollar:

d2 <- rename(d2, Year = year, FDI2 = BI.WAG.TOTL.GD.ZS, Country = country)
d2 <- select(d2, Year, FDI2, Country)
d2 <- mutate(d2, FDI_b2  = FDI2 / 1000000000)

1.4.2.2 Trực quan hóa dữ liệu

Kế tiếp chúng ta sử dụng gói ggplot2 (không cần phải gọi gói này vì hệ sinh thái tidyverse khi được gọi thì gói ggplot2 cũng được gọi cùng) để hình ảnh hóa dòng FDI ròng trong khoảng thời gian trên với nền (themes) theo phong cách của tạp chí The Economists:

ggplot(d2, aes(x = Year, y = FDI_b2)) +
 geom_bar(stat="identity", position="identity", 
 show.legend = F, fill = c("#1874CD")) +
 labs(x = NULL, 
 y = NULL, 
 title = " net FDI flows: 1987 - 2015", 
 subtitle = "Unit: Billion", 
 caption = "Source: The World Bank") +
 theme_economist()+
  facet_grid(. ~ Country)

1.4.3 Indicator: NY.GDP.PCAP.KD

Định nghĩa: GDP per capita (constant 2000 US) là một chỉ số kinh tế được tính bằng cách chia tổng sản phẩm quốc nội (GDP) của một quốc gia theo giá trị không đổi vào một năm cụ thể (năm 2000 trong trường hợp này) cho số dân của quốc gia đó.

Đơn vị tiền tệ sử dụng trong chỉ số này là đô la Mỹ (US$) và giá trị không đổi ở năm 2000 được sử dụng để điều chỉnh dữ liệu theo thời gian để có được một số liệu so sánh chính xác hơn giữa các quốc gia.

GDP per capita (constant 2000 US$) được sử dụng để đo lường mức độ phát triển kinh tế trung bình cho mỗi cá nhân trong một quốc gia. Nó cho phép so sánh sự giàu có và mức độ phát triển giữa các quốc gia khác nhau mà không bị ảnh hưởng bởi sự biến động của tỷ giá hoặc giá cả trong thời gian.

Tóm lại, GDP per capita (constant 2000 US$) là một chỉ số quan trọng trong việc đo lường mức độ phát triển kinh tế trung bình cho mỗi người dân theo giá trị không đổi vào năm 2000 và được sử dụng để so sánh mức độ giàu có và phát triển giữa các quốc gia khác nhau.

d3 <- WDI(country = c("TH","VN"),
 indicator=c("NY.GDP.PCAP.KD"), 
 start = 1980,
 end = 2020, 
 extra = TRUE, 
 cache = NULL)
d3 <- na.omit(d3)

Ở đây, VN, TH lần lượt là kí hiệu của Việt Nam, Thái Lan và NY.GDP.PCAP.KD là kí hiệu bộ dữ liệu về mức độ phát triển kinh tế trung bình cho mỗi cá nhân trong một quốc gia ở 2 nước.

1.4.3.1 Tính toán cơ bản

#Thông kê cơ bản mức độ phát triển kinh tế trung bình cho mỗi cá nhân trong một quốc gia ở 2 nước.
summary(d3$NY.GDP.PCAP.KD)
##    Min. 1st Qu.  Median    Mean 3rd Qu.    Max. 
##   588.3  1407.8  2356.6  2734.0  3711.3  6453.9
#Tính trung bình vmức độ phát triển kinh tế trung bình cho mỗi cá nhân trong một quốc gia theo từng nước 
aggregate(d3$NY.GDP.PCAP.KD, list(d3$country), FUN = "mean")
##    Group.1        x
## 1 Thailand 3809.769
## 2  Vietnam 1541.929
#Tính trung vị mức độ phát triển kinh tế trung bình cho mỗi cá nhân trong một quốc gia theo từng nước 
aggregate(d3$NY.GDP.PCAP.KD, list(d3$country), FUN = "median")
##    Group.1        x
## 1 Thailand 3599.096
## 2  Vietnam 1309.430
#Tính độ lệch chuẩn mức độ phát triển kinh tế trung bình cho mỗi cá nhân trong một quốc gia theo từng nước
aggregate(d3$NY.GDP.PCAP.KD, list(d3$country), FUN = "var")
##    Group.1         x
## 1 Thailand 2330090.7
## 2  Vietnam  721248.5
#Tính phương sai mức độ phát triển kinh tế trung bình cho mỗi cá nhân trong một quốc giatheo từng nước
aggregate(d3$NY.GDP.PCAP.KD, list(d3$country), FUN = "sd")
##    Group.1         x
## 1 Thailand 1526.4635
## 2  Vietnam  849.2635
#Tính tổng mức độ phát triển kinh tế trung bình cho mỗi cá nhân trong một quốc giatheo từng nước
aggregate(d3$NY.GDP.PCAP.KD, list(d3$country), FUN = "sum")
##    Group.1         x
## 1 Thailand 156200.54
## 2  Vietnam  57051.37

1.4.3.2 Trực quan hóa dữ liệu

ggplot(d3, aes(x = year, y = NY.GDP.PCAP.KD)) +
 geom_bar(stat="identity", position="identity", 
 show.legend = F, fill = c("#1874CD")) +
 labs(x = NULL, 
 y = NULL, 
 title = "Mức độ phát triển kinh tế trung bình cho mỗi cá nhân trong một quốc gia: 1980 - 2020", 
 subtitle = "Unit: đô la Mỹ (US$)", 
 caption = "Source: The World Bank") +
 theme_economist()+
  facet_grid(. ~ country)

1.4.4 Indicator: NY.GDP.MKTP.PP.KD

Định nghĩa: GDP per capita, PPP (constant 2005 international) là một chỉ số kinh tế dùng để đo mức độ giàu có trung bình cho mỗi người dân trong một quốc gia.

Trong trường hợp này, GDP được tình toán bằng cách sử dụng phương pháp Parity Purchasing Power (PPP) để điều chỉnh giá cả giữa các nền kinh tế khác nhau. Giá trị không đổi vào năm 2005 được sử dụng để đặt cơ sở cho việc so sánh giữa các quốc gia.

Đơn vị tiền tệ được sử dụng là đô la Mỹ (US$) với giá trị không đổi trong năm 2005. Phương pháp PPP được áp dụng để đo lường sức mua cùng một lượng hàng hóa và dịch vụ ở các quốc gia khác nhau, dựa trên tỉ lệ giữa giá cả và mức độ tiêu dùng của mỗi quốc gia.

GDP per capita, PPP (constant 2005 international $) cho phép so sánh mức độ giàu có và mức độ phát triển kinh tế giữa các quốc gia khác nhau, bỏ qua ảnh hưởng của giá cả và tỷ giá hoán đổi tiền tệ. Giá trị không đổi trong năm 2005 cung cấp một cơ sở chuẩn để so sánh trong thời gian dài.

d4 <-  WDI(country = c("TH","VN"),
 indicator=c("NY.GDP.MKTP.PP.KD"), 
 start = 1980,
 end = 2020, 
 extra = TRUE, 
 cache = NULL)
d4 <- na.omit(d4)

1.4.4.1 Tính toán cơ bản

#Thôngs kê cơ bản mức độ giàu có trung bình cho mỗi người dân trong một quốc gia
summary(d4$NY.GDP.MKTP.PP.KD)
##      Min.   1st Qu.    Median      Mean   3rd Qu.      Max. 
## 1.405e+11 4.030e+11 6.148e+11 6.443e+11 8.977e+11 1.283e+12
#Tính trung bình mức độ giàu có trung bình cho mỗi người dân trong một quốc gia
d4 %>% group_by(d4$country) %>%  summarise(mean_gdp = mean(d4$NY.GDP.MKTP.PP.KD))
## # A tibble: 2 × 2
##   `d4$country`      mean_gdp
##   <chr>                <dbl>
## 1 Thailand     644345182079.
## 2 Vietnam      644345182079.
#Tính trung vị mức độ giàu có trung bình cho mỗi người dân trong một quốc gia 
d4 %>% group_by(d4$country) %>% summarise(median_gdp = median(d4$NY.GDP.MKTP.PP.KD)) 
## # A tibble: 2 × 2
##   `d4$country`    median_gdp
##   <chr>                <dbl>
## 1 Thailand     614810185928.
## 2 Vietnam      614810185928.
#Tính tổng mức độ giàu có trung bình cho mỗi người dân trong một quốc gia
d4 %>% group_by(d4$country) %>% summarise(total_gdp = sum(d4$NY.GDP.MKTP.PP.KD))
## # A tibble: 2 × 2
##   `d4$country` total_gdp
##   <chr>            <dbl>
## 1 Thailand       3.99e13
## 2 Vietnam        3.99e13

1.4.4.2 Trực quan hóa dữ liệu

ggplot(d4, aes(year, NY.GDP.MKTP.PP.KD, color = country)) +
 geom_line() +
 geom_point(col = "red") +
 labs(x = NULL, 
 y = NULL, 
 title = "Mức độ giàu có trung bình cho mỗi người dân trong một quốc gia: 1980 - 2020", 
 subtitle = "Unit: Đô la Mỹ (US$)", 
 caption = "Data Source: The World Bank") 

1.4.5 Indicator: NY.GDP.PCAP.CN

Định nghĩa: NGDP per capita (current LCU) là một phép đo kinh tế dùng để tính toán giá trị GDP trung bình cho mỗi người dân trong một quốc gia. Nó được tính bằng cách chia tổng giá trị GDP cho dân số của quốc gia.

GDP per capita (current LCU) cho ta cái nhìn về mức độ phát triển kinh tế của mỗi công dân trong một nền kinh tế cụ thể. Đơn vị của nó thường được tính bằng tiền tệ hiện tại của quốc gia đó, ví dụ như việt Nam đồng (đơn vị tiền tệ của Việt Nam) hoặc baht (đơn vị tiền tệ của Thái Lan).

GDP per capita (current LCU) cung cấp thông tin về mức sống trung bình, khả năng mua sắm và tiêu dùng của dân số trong một quốc gia. Nó cũng là một trong những chỉ số mà các chính phủ sử dụng để đánh giá và so sánh sự phát triển kinh tế giữa các quốc gia.

d5 <- WDI(country = c("VN"),
 indicator=c("NY.GDP.PCAP.CN"), 
 start = 1980,
 end = 2020, 
 extra = TRUE, 
 cache = NULL)
d5 <- na.omit(d5)

1.4.5.1 Tính toán cơ bản

#Thôngs kê cơ bản mức sống trung bình, khả năng mua sắm và tiêu dùng của dân số trong một quốc gia
summary(d5$NY.GDP.PCAP.CN)
##     Min.  1st Qu.   Median     Mean  3rd Qu.     Max. 
##     1956  2339518  7086413 21773084 41454763 83233269
#Tính trung bình mức sống trung bình, khả năng mua sắm và tiêu dùng của dân số trong một quốc gia
d5 %>% summarise(mean5 = mean(d5$NY.GDP.PCAP.CN))
##      mean5
## 1 21773084
#Tính trung vị mức sống trung bình, khả năng mua sắm và tiêu dùng của dân số trong một quốc gia
d5 %>% summarise(median_gdp5 = median(d5$NY.GDP.PCAP.CN)) 
##   median_gdp5
## 1     7086413
#Tính tổng mức sống trung bình, khả năng mua sắm và tiêu dùng của dân số trong một quốc gia
d5 %>% summarise(total_gdp5 = sum(d5$NY.GDP.PCAP.CN))
##   total_gdp5
## 1  783831040

1.4.5.2 Trực quan hóa dữ liệu

#Biểu đồ cột 
ggplot(d5, aes(x = year, y = NY.GDP.PCAP.CN)) +
 geom_bar(stat="identity", position="identity", 
 show.legend = F, fill = c("#1874CD")) +
 labs(x = NULL, 
 y = NULL, 
 title = "Mức sống trung bình, khả năng mua sắm và tiêu dùng của dân số trong một quốc gia: 1980 - 2020", 
 subtitle = "Unit: Việt Nam đồng", 
 caption = "Source: The World Bank") +
 theme_economist()

#Biểu đồ đường 
ggplot(d5, aes(year, NY.GDP.PCAP.CN)) +
 geom_line() +
 geom_point(col = "red") +
 labs(x = NULL, 
 y = NULL, 
 title = "Mức sống trung bình, khả năng mua sắm và tiêu dùng của dân số trong một quốc gia: 1980 - 2020", 
 subtitle = "Unit: Việt Nam đồng", 
 caption = "Data Source: The World Bank")

1.4.6 Ìndicator: SP.DYN.LE00.IN

Định nghĩa: Tuổi thọ trung bình khi mới sinh (life expectancy at birth) là một chỉ số thống kê quan trọng để đo lường tuổi thọ trung bình của một đối tượng khi họ sinh ra. Chỉ số này thường được tính bằng cách lấy tổng số năm mà một nhóm người (thường là một quốc gia) sống được chia cho tổng số người trong nhóm đó.

Tuổi thọ trung bình khi mới sinh được xem là một chỉ số quan trọng để đánh giá chất lượng cuộc sống và trình độ phát triển của một quốc gia. Nó phản ánh sự cải thiện trong y tế, giáo dục, môi trường sống và các chính sách xã hội khác.

Tuy chỉ số này rất hữu ích trong việc so sánh giữa các quốc gia và đánh giá tiến bộ trong việc nâng cao chất lượng cuộc sống, nhưng nó không phản ánh được sự phân bố tuổi thọ trên toàn quần thế giới. Có thể có sự khác biệt đáng kể giữa các nhóm dân số và khu vực trong một quốc gia, vì vậy việc xem xét các yếu tố khác nhau như giới tính, tài chính, địa điểm và điều kiện sống cũng rất quan trọng khi đánh giá tuổi thọ trung bình.

d6 <- WDI(country = c("LA","KH","VN","TH","PH","ID"),
          indicator = c("SP.DYN.LE00.IN"))
d6 <- na.omit(d6)

1.4.6.1 Trực quan hóa dữ liệu

 ggplot(d6, aes(year, SP.DYN.LE00.IN, color = country)) +
 geom_line(size= 0.7) +
 geom_point() +
 labs(x = NULL, 
 y = NULL, 
 title = "Tuổi thọ trung bình của một đối tượng khi họ sinh ra: 1980 - 2020", 
 subtitle = "Unit: Tuổi", 
 caption = "Data Source: The World Bank") +
 theme_economist()

1.4.7 Indicator: DP.DOD.DECT.CR.FC.Z1

Định nghĩa: Gross PSD, Financial Public Corp., All maturities, All instruments, Nominal Value, % of GDP là một chỉ số đo lường giá trị tổng cộng của các công cụ tài chính (chứng khoán, trái phiếu, v.v.) mà các Công ty tài chính công cộng (Financial Public Corp.) của một quốc gia nắm giữ. Chỉ số này được tính dựa trên tổng cộng giá trị danh nghĩa của các công cụ tài chính nhất định (bất kể kỳ hạn và loại công cụ) mà các Công ty tài chính công cộng đã mua hoặc nắm giữ. Chỉ số này được tính dưới dạng phần trăm của GDP (tổng sản phẩm quốc nội).

Chỉ số này có thể cho thấy mức độ nợ công của các Công ty tài chính công cộng trong một quốc gia so với GDP. Nếu giá trị PSD tăng cao và gần với GDP, điều đó có thể chỉ ra rằng các Công ty tài chính công cộng đang gặp khó khăn trong việc quản lý nợ và có thể tác động tiêu cực đến tình hình tài chính của quốc gia. Điều này có thể đòi hỏi sự can thiệp hoặc điều chỉnh từ phía Chính phủ để đảm bảo sự ổn định kinh tế và tài chính.

d7 <-WDI(country = c("TH","PH","ID"),
          indicator = c("DP.DOD.DECT.CR.FC.Z1"))
d7 <- na.omit(d7)

1.4.7.1 Tính toán cơ bản

#Thông kê cơ bản mức độ nợ công của các Công ty tài chính
summary(d7$DP.DOD.DECT.CR.FC.Z1)
##    Min. 1st Qu.  Median    Mean 3rd Qu.    Max. 
##  0.2386  1.0838  1.8421  8.5487 12.0961 31.9376
#Tính trung bình mức độ nợ công của các Công ty tài chính theo từng nước 
aggregate(d7$DP.DOD.DECT.CR.FC.Z1, list(d7$country), FUN = "mean")
##       Group.1          x
## 1   Indonesia 19.5614485
## 2 Philippines  1.5437965
## 3    Thailand  0.3320801
#Tính trung vị mức độ nợ công của các Công ty tài chính theo từng nước 
aggregate(d7$DP.DOD.DECT.CR.FC.Z1, list(d7$country), FUN = "median")
##       Group.1          x
## 1   Indonesia 25.3089781
## 2 Philippines  1.4223770
## 3    Thailand  0.3400045
#Tính độ lệch chuẩn mức độ nợ công của các Công ty tài chính theo từng nước
aggregate(d7$DP.DOD.DECT.CR.FC.Z1, list(d7$country), FUN = "var")
##       Group.1            x
## 1   Indonesia 99.365924974
## 2 Philippines  0.230827297
## 3    Thailand  0.002330275
#Tính phương sai mức độ nợ công của các Công ty tài chính theo từng nước
aggregate(d7$DP.DOD.DECT.CR.FC.Z1, list(d7$country), FUN = "sd")
##       Group.1          x
## 1   Indonesia 9.96824583
## 2 Philippines 0.48044489
## 3    Thailand 0.04827292
#Tính tổng mức độ nợ công của các Công ty tài chính theo từng nước
aggregate(d7$DP.DOD.DECT.CR.FC.Z1, list(d7$country), FUN = "sum")
##       Group.1           x
## 1   Indonesia 1036.756772
## 2 Philippines   83.365013
## 3    Thailand    8.302002

1.4.7.2 Trực qun hóa dữ liệu

ggplot(d7, aes(x = year, y = DP.DOD.DECT.CR.FC.Z1)) +
 geom_bar(stat="identity", position="identity", 
 show.legend = F, fill = c("#1874CD")) +
 labs(x = NULL, 
 y = NULL, 
 title = "Tình hình nợ công tổng hợp của chính phủ trung ương", 
 subtitle = "Unit: Phần trăm GDP", 
 caption = "Source: The World Bank") +
 theme_economist()+
  facet_grid(. ~ country)

1.4.8 Indicator: DP.DOD.DECT.CR.CG.Z1

Địng nghĩa:

Gross PSD là viết tắt của Gross Public Sector Debt (Nợ công cộng tổng hợp), là tổng số tiền mà các cơ quan và tổ chức thuộc ngành công cộng nợ lại.

Central Gov. (Chính phủ trung ương) chỉ đến nợ công của chính phủ trung ương, bao gồm các khoản nợ và nợ hoá đơn vị trung ương đã cấp phát.

“All maturities” đề cập đến tất cả các khoản nợ từ ngắn hạn đến dài hạn.

“All instruments” được sử dụng để chỉ tất cả các công cụ tài chính được sử dụng trong việc gây nợ, bao gồm trái phiếu, vay nợ và các hình thức khác.

“Nominal Value” (Giá trị danh nghĩa) thể hiện số tiền gốc của các khoản nợ, tức là số tiền ban đầu mà người vay đã nhận.

“% of GDP” (Phần trăm GDP) biểu thị tỷ lệ của nợ công so với tổng sản phẩm quốc nội (GDP). Thông thường, con số này sẽ giúp đánh giá mức độ của nợ công đối với nền kinh tế.

Vậy tổng hợp lại, Gross PSD, Central Gov., All maturities, All instruments, Nominal Value, % of GDP là các yếu tố liên quan đến việc đo lường và mô tả tình hình nợ công tổng hợp của chính phủ trung ương, bao gồm tất cả các khoản nợ, tất cả các công cụ tài chính và giá trị danh nghĩa của các khoản nợ, được so sánh với tổng sản phẩm quốc nội để đánh giá mức độ tác động của nợ lại đến nền kinh tế.

d8 <-  WDI(country = c("TH","PH","ID"),
          indicator = c("DP.DOD.DECT.CR.CG.Z1"))
d8 <- na.omit(d8)

1.4.8.1 Tính toán cơ bản

#Thông kê cơ bản tình hình nợ công tổng hợp của chính phủ trung ương
summary(d8$DP.DOD.DECT.CR.CG.Z1)
##    Min. 1st Qu.  Median    Mean 3rd Qu.    Max. 
##   9.359  13.854  23.432  24.856  35.053  56.648
#Tính trung bình tình hình nợ công tổng hợp của chính phủ trung ương theo từng nước 
aggregate(d8$DP.DOD.DECT.CR.CG.Z1, list(d8$country), FUN = "mean")
##       Group.1        x
## 1   Indonesia 28.39820
## 2 Philippines 12.73102
## 3    Thailand 43.53637
#Tính trung vị tình hình nợ công tổng hợp của chính phủ trung ương theo từng nước 
aggregate(d8$DP.DOD.DECT.CR.CG.Z1, list(d8$country), FUN = "median")
##       Group.1        x
## 1   Indonesia 27.43744
## 2 Philippines 11.97414
## 3    Thailand 36.59790
#Tính độ lệch chuẩn tình hình nợ công tổng hợp của chính phủ trung ương theo từng nước
aggregate(d8$DP.DOD.DECT.CR.CG.Z1, list(d8$country), FUN = "var")
##       Group.1         x
## 1   Indonesia 35.135819
## 2 Philippines  7.772691
## 3    Thailand 83.709871
#Tính phương sai tình hình nợ công tổng hợp của chính phủ trung ương theo từng nước
aggregate(d8$DP.DOD.DECT.CR.CG.Z1, list(d8$country), FUN = "sd")
##       Group.1        x
## 1   Indonesia 5.927547
## 2 Philippines 2.787955
## 3    Thailand 9.149310
#Tính tổng tình hình nợ công tổng hợp của chính phủ trung ương theo từng nước
aggregate(d8$DP.DOD.DECT.CR.CG.Z1, list(d8$country), FUN = "sum")
##       Group.1         x
## 1   Indonesia 1505.1049
## 2 Philippines  687.4752
## 3    Thailand 1088.4092

1.4.8.2 Trực quan hóa dữ liệu

ggplot(d8, aes(x = year, y = DP.DOD.DECT.CR.CG.Z1)) +
 geom_bar(stat="identity", position="identity", 
 show.legend = F, fill = c("#1874CD")) +
 labs(x = NULL, 
 y = NULL, 
 title = "Tình hình nợ công tổng hợp của chính phủ trung ương", 
 subtitle = "Unit: Phần trăm GDP", 
 caption = "Source: The World Bank") +
 theme_economist()+
  facet_grid(. ~ country)

1.4.9 Indicator: BX.KLT.DINV.CD.WD

Định nghĩa: Foreign direct investment, net inflows (BoP, current US$) là một chỉ số mô tả số tiền đầu tư trực tiếp của các nhà đầu tư nước ngoài vào một quốc gia cụ thể trong một năm nhất định. Chỉ số này đo lường số tiền thu được từ việc đầu tư trực tiếp của các doanh nghiệp nước ngoài vào quốc gia đó sau khi đã trừ đi số tiền rút về của các doanh nghiệp đó.

Chỉ số FDI net inflows (BoP, current US$) mang ý nghĩa quan trọng trong việc đánh giá mức độ hấp dẫn của một quốc gia đối với các nhà đầu tư và sự tăng trưởng kinh tế. Một số yếu tố có thể ảnh hưởng đến chỉ số này bao gồm chính sách đầu tư của quốc gia, môi trường kinh doanh, ổn định chính trị, tiềm năng thị trường và các yếu tố khác.

Một mức đầu tư trực tiếp nước ngoài tăng cao có thể cho thấy sự tin tưởng và quan tâm của các nhà đầu tư đối với tiềm năng kinh tế của quốc gia, đồng thời cũng có thể góp phần vào việc tăng trưởng kinh tế, cải thiện công nghệ và tạo ra cơ hội việc làm.

d9 <- WDI(country = c("VN"), 
 indicator=c("BX.KLT.DINV.CD.WD"), 
 start = 2000, 
 end = 2020, 
 extra = TRUE, 
 cache = NULL)

d9 <- na.omit(d9)

Ở đây, VN là kí hiệu của Việt Nam và BX.KLT.DINV.CD.WD là kí hiệu bộ dữ liệu về dòng vốn đầu tư ở Việt Nam. Dữ liệu thu thập được gồm nhiều biến số nhưng chúng ta chỉ quan tâm đến FDI ròng và thời gian cho nên chúng ta chỉ cần giữ lại hai biến số đó.

1.4.9.1 Tính toán cơ bản

Ta sử dụng các thông kê cơ bản cho các biến có trong bộ dữ liệu BX.KLT.DINV.CD.WD

summary(d9)
##    country             iso2c              iso3c                year     
##  Length:21          Length:21          Length:21          Min.   :2000  
##  Class :character   Class :character   Class :character   1st Qu.:2005  
##  Mode  :character   Mode  :character   Mode  :character   Median :2010  
##                                                           Mean   :2010  
##                                                           3rd Qu.:2015  
##                                                           Max.   :2020  
##  BX.KLT.DINV.CD.WD      status          lastupdated           region         
##  Min.   :1.298e+09   Length:21          Length:21          Length:21         
##  1st Qu.:1.954e+09   Class :character   Class :character   Class :character  
##  Median :8.000e+09   Mode  :character   Mode  :character   Mode  :character  
##  Mean   :7.767e+09                                                           
##  3rd Qu.:1.180e+10                                                           
##  Max.   :1.612e+10                                                           
##    capital           longitude           latitude            income         
##  Length:21          Length:21          Length:21          Length:21         
##  Class :character   Class :character   Class :character   Class :character  
##  Mode  :character   Mode  :character   Mode  :character   Mode  :character  
##                                                                             
##                                                                             
##                                                                             
##    lending         
##  Length:21         
##  Class :character  
##  Mode  :character  
##                    
##                    
## 

Ngoài ra để dễ hiểu chúng ta có thể đổi tên cho biến số đồng thời tạo ra một biến mới là FDI_b với ngụ ý đơn vị của FDI ròng là tỉ Dollar:

d9 <- rename(d9, Year = year, FDI = BX.KLT.DINV.CD.WD)
d9 <- select(d9, Year, FDI)
d9 <- mutate(d9, FDI_b = FDI / 1000000000)

1.4.9.2 Trực quan hóa dữ liệu

Kế tiếp chúng ta sử dụng gói ggplot2 (không cần phải gọi gói này vì hệ sinh thái tidyverse khi được gọi thì gói ggplot2 cũng được gọi cùng) để hình ảnh hóa dòng FDI ròng trong khoảng thời gian trên với nền (themes) theo phong cách của tạp chí The Economists:

library(ggthemes)
ggplot(d9, aes(x = Year, y = FDI_b)) +
 geom_bar(stat="identity", position="identity", 
 show.legend = F, fill = c("#1874CD")) +
 labs(x = NULL, 
 y = NULL, 
 title = "Vietnam's net FDI flows: 1987 - 2015", 
 subtitle = "Unit: Billion", 
 caption = "Source: The World Bank") +
 theme_economist()

Hoăc có thể sử dụng toán tử pipe mà chúng ta đã biết thì tất cả các dòng lệnh (mỗi dòng lệnh đại diện cho một công đoạn xử lí dữ liệu – data manipulation) dài dòng trên có thể thu gọn về chỉ còn một dòng lệnh (không tính các dòng lệnh gọi các gói) như sau mà vẫn thu được kết quả cuối cùng:

1.4.10 Indicator: BN.KLT.DINV.CD.ZS

Định nghĩa: Foreign direct investment (% of GDP) là một thước đo mà đo lường số tiền mà các công ty nước ngoài đầu tư vào một quốc gia cụ thể so với tổng sản phẩm quốc nội của quốc gia đó. Nó là một chỉ số quan trọng để đánh giá mức độ thu hút đầu tư trong một quốc gia và thường được coi là một dấu hiệu của sự mở cửa và sự phát triển kinh tế. Mức độ FDI (% GDP) càng cao có thể cho thấy quốc gia đó có môi trường kinh doanh thuận lợi, hấp dẫn đối với các nhà đầu tư nước ngoài và có tiềm năng tăng trưởng mạnh trong tương lai.

d10 <- WDI(indicator = 'BN.GSR.FCTY.CD.ZS')
d10 <- na.omit(d10)

2 Dữ liệu

Package: Ecdat - Datasets: FriendFoe(Data from the Television Game Show Friend Or Foe ?)

“Dữ liệu quan sát về một game show Bạn hay thù? là một chương trình trò chơi của Mỹ dựa trên kiến thức và sự tin tưởng được phát sóng trên Game Show Network”.

Ta có thể tìm hiểu kỹ hơn về dữ liệu thông qua trang web được gắn link ở đây: Friend_or_Foe

Mô tả dữ liệu

Số quan sát : 227

Quan sát : Cá nhân

Quốc gia : Mỹ

Ý nghĩa các biến thuộc dữ liệu FriendFoe

Biến Giải thích
sex Giới tính thí sinh
white Thí sinh có phải là người da trắng không?
age Tuổi của thí sinh
play Lựa chọn của thí sinh: một yếu tố có cấp độ “kẻ thù” và “bạn bè”
round Vòng chơi thí sinh bị loại, theo từng cấp độ 1,2,3
season Mùa chương trình ( mùa 1,2)
cash Số tiền trong hộp ủy thác
sex1 Giới tính của đối thủ
white1 Đối thủ có phải là người da trắng hay không?
age1 Tuổi của đối thủ
play1 Sự lựa chọn của đối tác : một yếu tố có cấp độ “kẻ thù” và “bạn bè”
win Số tiền thí sinh giành được (tính theo đôla $)
win1 Số tiền đối thủ giành được (tính theo đôla $)

3 Tuần 5

3.1 Thực hành trên lớp

Gọi các packages liên quan và bộ dữ liệu

library(ggplot2)
library(tidyverse)
library(DT)
library(scales)
library(dplyr)
library(cowplot)
#Bộ dữ liệu chương trình game show "Bạn hay thù" trong packages Ecdat 
library(Ecdat)
data(FriendFoe)
ffoe <- na.omit(FriendFoe)
#Xem 6 dòng đầu của data frame 
head(ffoe)
##      sex white age   play round season cash   sex1 white1 age1  play1 win win1
## 1   male   yes  20    foe     1      1  1.2   male    yes   32 friend 1.2  0.0
## 2   male   yes  40    foe     3      1  7.7 female    yes   31    foe 0.0  0.0
## 3 female    no  35    foe     2      1  3.2 female     no   24    foe 0.0  0.0
## 4   male   yes  26 friend     1      1  1.2   male    yes   40 friend 0.6  0.6
## 5 female   yes  40 friend     3      1  5.7   male    yes   26    foe 0.0  5.7
## 6 female   yes  28    foe     2      1  3.7 female    yes   23 friend 3.7  0.0
#Xem 6  dòng cuối của data frame 
tail(ffoe)
##        sex white age   play round season cash   sex1 white1 age1  play1 win
## 222 female   yes  22 friend     1      2  0.2 female    yes   21 friend 0.1
## 223   male   yes  25 friend     3      2  2.5   male    yes   28    foe 0.0
## 224   male    no  25    foe     2      2  4.0 female     no   24    foe 0.0
## 225   male   yes  43 friend     1      2  1.5 female    yes   26    foe 0.0
## 226   male   yes  26    foe     3      2  5.0   male    yes   37    foe 0.0
## 227 female   yes  34    foe     1      2  1.0 female    yes   31    foe 0.0
##     win1
## 222  0.1
## 223  2.5
## 224  0.0
## 225  1.5
## 226  0.0
## 227  0.0
#Xem cấu trúc data frame 
str(ffoe)
## 'data.frame':    227 obs. of  13 variables:
##  $ sex   : Factor w/ 2 levels "female","male": 2 2 1 2 1 1 1 2 1 1 ...
##  $ white : Factor w/ 2 levels "no","yes": 2 2 1 2 2 2 2 1 2 2 ...
##  $ age   : int  20 40 35 26 40 28 26 30 30 25 ...
##  $ play  : Factor w/ 2 levels "friend","foe": 2 2 2 1 1 2 1 2 1 1 ...
##  $ round : Factor w/ 3 levels "1","2","3": 1 3 2 1 3 2 1 3 2 1 ...
##  $ season: Factor w/ 2 levels "1","2": 1 1 1 1 1 1 1 1 1 1 ...
##  $ cash  : num  1.2 7.7 3.2 1.2 5.7 3.7 1.2 7.2 3.7 0.7 ...
##  $ sex1  : Factor w/ 2 levels "female","male": 2 1 1 2 2 1 1 2 2 2 ...
##  $ white1: Factor w/ 2 levels "no","yes": 2 2 1 2 2 2 2 1 2 2 ...
##  $ age1  : int  32 31 24 40 26 23 48 27 22 61 ...
##  $ play1 : Factor w/ 2 levels "friend","foe": 1 2 2 1 2 1 1 1 2 1 ...
##  $ win   : num  1.2 0 0 0.6 0 3.7 0.6 7.2 0 0.35 ...
##  $ win1  : num  0 0 0 0.6 5.7 0 0.6 0 3.7 0.35 ...
#Tạo bảng cho data frame 
datatable(ffoe)

3.2 Phân tích bộ dữ liệu

3.2.1 Phân tích biến giới tính sex với các biến liên quan khác

1. sex - white

Ta muốn xem xét trong các thí sinh tham gia thì có bao nhiêu người là da trắng và bao nhiêu người không phải da trắng theo từng giới tính

#Tạo bảng tần số và tính toán bảng tần số đó 
table(ffoe$white,ffoe$sex)
##      
##       female male
##   no      17   20
##   yes    102   88
prop.table(table(ffoe$white,ffoe$sex))
##      
##           female       male
##   no  0.07488987 0.08810573
##   yes 0.44933921 0.38766520
#Trực quan hóa dữ liệu 
w1 <- ggplot(ffoe, aes(x = sex,
                y = after_stat(count))) +
  geom_bar(fill = "cornflowerblue", 
           color="black") +
  geom_text(aes(label = (after_stat(count))), stat = 'count', color = 'black', vjust = - .25) +
  theme_classic() +
  labs(x = "Giới tính",
       y = "Số người",
       title = "Giới tính và màu da") +
facet_grid(. ~ white) 
 
w2 <- ggplot(ffoe, aes(x = sex,
                y = after_stat(count))) +
  geom_bar( fill = "indianred3", 
           color = "black") +
  geom_text(aes(label = scales::percent(after_stat(count/sum(count)))), 
            stat = 'count', color = 'black', vjust = - .25) +
  theme_classic() +
  labs(x = "Giới tính",
       y = "Phần trăm",
       title = "Phần trăm thí sinh tham gia theo màu da") +
  facet_grid(. ~ white)

plot_grid(w1,w2)

Nhìn vào kết quả sau khi trực quan hóa dữ liệu ta có thể thấy được số thí sinh tham gia là giới tính nữ màu da trắng có 102 người (44.9%) và không phải da trắng có 17 người (7.5%). Thí sinh tham gia là giới tính nam có 88 người (38.8%) da trắng và 20 người (8.8%) người không phải da trắng.

2. sex - age

Xem xét theo từng giới tính tham gia thì họ có độ tuổi bao nhiêu

#Bảng tần suất và tính toán trên bảng tần suất 
table(ffoe$sex, ffoe$age)
##         
##          18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 39 40 41
##   female  6  2  5  1  6  8 11  8  4  5  6  7  5  7  8  4  3  2  1  0  2  4  3
##   male    2  2  5  5  8  7  4  8  5  6  4  7  5  5  4  2  5  1  3  4  3  2  1
##         
##          42 43 44 46 47 48 49 51 55 57
##   female  3  2  1  1  1  0  0  2  1  0
##   male    2  2  2  0  1  1  1  0  0  1
nam <-  filter(ffoe, sex == 'male' )
nữ <- filter(ffoe, sex == 'female' )
#Trực quan hóa dữ liệu 
n1 <- ggplot(nam, aes(x = age)) +
  geom_histogram(fill = "cornflowerblue",
                 color = "white",
                 binwidth = 3)  +
  labs(x = "Tuổi",
       y = " ",
       title = "Tuổi thí sinh nam")

n2 <- ggplot(nữ, aes(x = age))+
  geom_histogram(fill = "cornflowerblue",
                 color = "white",
                 binwidth = 3)  +
  labs(x = "Tuổi",
       y = " ",
       title = "Tuổi thí sinh nữ")
plot_grid(n1,n2)

Theo như sự phân phối của biểu đồ histogram cho cae 2 giới tính thì ta thấy độ tuổi thí sinh tham gia game show của nữ đa dạng và liên tục hơn của nam. Hình chung độ tuổi của 2 giới tính tập trung từ 20 tuổi đến gần 40 tuổi là chủ yếu.

Thay vì vẽ buổi đồ histogram để so sánh độ tuổi của 2 giới tính ta có thể vẽ biểu đồ cột theo sự phân chia về độ tuổi mà ta cần quan sát

Ta sẽ chia độ tuổi thành 3 khoảng Thanh niên, Trung niên, Lão

f_age <- ffoe %>% 
  mutate(d = cut(ffoe$age, 
               breaks=c(17,39,50,60),
                  labels= c ("Thanh niên","Trung niên","Lão")))
#Biểu đồ cột đôi 
f_age <- f_age  %>% count(d,sex) %>% mutate(pc=prop.table(n))
ggplot(f_age, aes(x = d, y = n, fill = factor(sex))) +
  geom_col(position = "dodge") +
  geom_text(aes(label=percent(pc, accuracy = .01)), position = position_dodge(1), vjust = -.5, size = 3)+
  labs(title = "Biểu đồ cột đôi",
       x = "Nhóm tuổi",
       y = "Số lượng",
       fill = "Giới tính") +
  theme_minimal()

Nhìn vào biểu đồ cột đôi có thể nhận xét được người tham gia là nữ nhiều hơn nam. Và biểu đồ cho ta biết trong độ tuổi thanh niên có 44.49% người là giới tính nữ và 41.85% người là giới tính nam. Độ tuổi trung niên thì có 6.61% là nữ và 5.29% là nam. Còn lại ở độ tuổi số người là nữ chiếm 1.32% và 0.44% là nam.

3. sex - win - age

#Bảng tần suất 
table(ffoe$sex,ffoe$win)
##         
##           0 0.1 0.2 0.25 0.35 0.5 0.6 0.7  1 1.1 1.2 1.5 1.7 1.75 1.85  2 2.1
##   female 60   4   2    2    2   6   4   1  1   2   2   3   1    1    1  4   1
##   male   72   1   0    4    0   0   2   1  3   0   1   4   1    1    0  1   0
##         
##          2.5 2.6 2.7 2.75  3 3.1 3.2 3.25 3.5 3.7 3.85  4 4.1 4.25 4.35 5.2 5.5
##   female   1   1   1    1  2   1   1    1   2   3    2  0   1    1    0   1   0
##   male     1   1   1    0  1   1   0    0   0   0    1  1   1    0    1   0   1
##         
##          5.7  6 6.7 7.2 7.5 7.7 15
##   female   1  0   0   0   1   0  1
##   male     1  2   1   1   1   1  0
#Tổng số tiền thưởng thắng được theo giới tính 
aggregate(ffoe$win,list(ffoe$sex),FUN ='sum')
##   Group.1      x
## 1  female 127.25
## 2    male 101.15
#Biểu đồ cột 
sum_win <- ffoe %>%
  group_by(sex) %>%
  summarize(sum_win = sum(win))
            
ggplot(sum_win, 
       aes(x = factor(sex,
                      labels = c("Nam","Nữ")), 
                      y = sum_win)) +
  geom_bar(stat = "identity", 
           fill = "cornflowerblue") +
  geom_text(aes(label = dollar(sum_win)), 
            vjust = -0.25) +
  scale_y_continuous(label = dollar) +
  labs(title = "Tổng số tiền thưởng thắng được", 
       subtitle = "Theo giới tính",
       x = "",
       y = "")

Mặc dù, nữ giới tham gia nhiều hơn so với nam giới nhưng số tiền thưởng thắng được của nam lại nhiều hơn nữ.

#Biểu đồ phân tán 
ggplot(ffoe,aes(x = age, 
                     y = win,
                     color = sex)) +
  geom_point(alpha = .8, 
             size = 3) +
  scale_y_continuous(label = scales::dollar, 
                     breaks = seq(0,15,2),
                     limits = c(0, 15)) +
  scale_x_continuous(breaks = seq(17, 60, 10), 
                     limits=c(17, 60)) + 
  labs(x = "Tuổi",
       y = " ",
       title = "Biểu đồ phân tán tiền thưởng theo tuổi và giới tính") +
  geom_smooth(formula = y ~ x, method = "lm", 
              se = FALSE, 
              size = 1.5)

cả nam và nữ có xu hướng nghịch biến giữa độ tuổi với tiền thưởng.

4. sex - round - age

#Tạo bảng
table(ffoe$round,ffoe$sex)
##    
##     female male
##   1     53   38
##   2     33   29
##   3     33   41
#Biểu đồ 
ggplot(ffoe,aes(x = age, 
                     y = win,
                     color = sex)) +
  geom_point(alpha = .8, 
             size = 3) +
  scale_y_continuous(label = scales::dollar, 
                     breaks = seq(0,15,2),
                     limits = c(0, 15)) +
  scale_x_continuous(breaks = seq(17, 60, 10), 
                     limits=c(17, 60)) + 
  labs(x = "Tuổi",
       y = " ",
       title = "Biểu đồ phân tán",
       subtitle = " Chia theo cấp độ vòng chơi") +
  geom_smooth(formula = y ~ x, method = "lm", 
              se = FALSE, 
              size = 1.5) +
facet_grid(.~ round)

Nhìn chung người bị loại theo từng vòng thì nữ bị loại nhiều hơn.

Vòng 1, số tiền thưởng của cả nam và nữ gần bằng nhau không có sự chênh lệch quá rõ rệt.

Vòng 2, số tiền thưởng giới nữ nhận được cao hơn nam.

Vòng cuối cùng, có sự chênh lệch rõ rệt giữa nam và nữ giới trong số tiền thưởng họ nhận được. Nhưng đặc biệt trong đó chỉ có phụ nữ nhận được mức tiền thưởng cao ngất ngưỡng.

3.2.2 Phân tích biến giới tính ageage1 với các biến liên quan khác

Ta chỉ phân tích theo độ tuổi của người tham gia không cần phải tách biệt giữa tuổi thí sinh và tuổi đối thủ nên ta sẽ gộp chúng lại thành một với lệnh pivot_longer.

df_long <- ffoe %>% 
  pivot_longer(
    cols = c(`age`,`age1`),
    names_to = 'n_age', 
    values_to = 'long_age' )
#Tính toán thống kê cho biến tuổi 
summary(df_long$long_age)
##    Min. 1st Qu.  Median    Mean 3rd Qu.    Max. 
##   18.00   23.00   27.00   29.05   33.00   65.00
#Biểu đồ phân bố tuổi 
ggplot(df_long, aes(x = long_age)) +
  geom_histogram(fill = "cornflowerblue", 
                 color = "white",
                   bins = 40) + 
  labs(title = "Tuổi của người tham gia game show Bạn hay thù",
       x = "Tuổi")

Thí sinh nhỏ tuổi nhất tham gia game show nằm ở tuổi 18 và thí sinh lớn tuổi nhất tham gia game show nằm ỏ tuổi 65 Độ tuổi trung bình của người tham gia game show là khoảng 29 tuổi

Tứ phân vị thứ nhất cho biết có khoản 25% thí sinh ở độ tuổi 23 đã tham gia game show

Tứ phân vị thứ ba cho biết có khoản 75% thí sinh ở độ tuổi 33 đã tham gia game show

Median = 28 cho biết số thí sinh tham gia game show ở độ tuổi nằm ở giữa các độ tuổi đã tham gia game show.

Kết luận: Hầu hết những người tham gia dường như ở độ tuổi đầu độ tuổi 20 và cuối độ tuổi 30 với một nhóm khác ở độ tuổi 40 và một nhóm nhỏ hơn ở độ tuổi đầu 50 và gần 70

3.2.3 Phân tích biến winwin1 với các biến liên quan khác

Trước tiên ta sẽ xem tổng quát về số tiền thắng được của người tham gia game show “Friend or Foe” sau đó mới phân tích từng biến

df_longwin <- ffoe %>% 
  pivot_longer(
    cols = c(`win`,`win1`),
    names_to = 'n_win', 
    values_to = 'long_win' )
#Tính toán thống kê cho biến long_win
summary(df_longwin$long_win)
##    Min. 1st Qu.  Median    Mean 3rd Qu.    Max. 
##   0.000   0.000   0.000   1.154   1.500  16.400
#Biểu đồ histogram 
ggplot(df_longwin, aes(x = long_win)) +
  geom_histogram(fill = "cornflowerblue", 
                 color = "white",
                   bins = 40) + 
  scale_x_continuous(label = scales::dollar) +
  labs(title = "Số tiền thắg được của người tham gia game show",
       y = "",
       x = "")

Số tiền thưởng thắng được của người tham gia game show đi từ 0$ đến 16.4$

Trung bình mỗi người tham gia thắng được 1.154$

Tứ phân vị thứ nhất cho biết có 25% người tham gia thắng được số tiền là 0$

Tứ phân vị thứ ba cho biết có 75% người tham gia thắng được số tiền là 1.5$

Trung vị (median = 0$) cho biết số tiền ở giữa các số tiền thắng được sắp xếp tăng dần hoặc giảm dần.

1.Phân tích số tiền thắng được theo mùa

#Tính tổng số tiền thắng được 
sum(df_longwin$long_win)
## [1] 523.7

Con số 523.7$ biểu thị cho tổng số tiền thưởng mà người chơi game show đã đem về ở cả 2 mùa.

Xem xét số tiền thắng được theo mùa (mùa 1 và mùa 2)

#Tổng số tiền thắng được trong mùa 1 và mùa 2  
df_longwin %>% group_by(season) %>% summarise_at(c('long_win'),list(n=sum))
## # A tibble: 2 × 2
##   season     n
##   <fct>  <dbl>
## 1 1       257.
## 2 2       267
#Đồ thị 
sum_wins <- df_longwin %>%
  group_by(season) %>%
  summarize(sum_wins = sum(long_win))
ggplot(sum_wins, 
       aes(x = factor(season,
                      labels = c("Mùa 1","Mùa 2")), 
                      y = sum_wins)) +
  geom_bar(stat = "identity", 
           fill = "cornflowerblue") +
  geom_text(aes(label = dollar(sum_wins)), 
            vjust = -0.25) +
  scale_y_continuous(label = dollar) +
  labs(title = "Tổng số tiền thưởng thắng được", 
       subtitle = "Theo mùa",
       x = "",
       y = "")

Mùa 2 số tiền cao hơn so với mùa 1.

2.Phân tích số tiền thắng được theo vòng

#Tính tổng tiền theo vòng 
df_longwin %>% group_by(round) %>% summarise_at(c('long_win'),list(n=sum))
## # A tibble: 3 × 2
##   round     n
##   <fct> <dbl>
## 1 1      70.5
## 2 2     139. 
## 3 3     314
#Biểu đồ
sum_winr <- df_longwin %>%
  group_by(round) %>%
  summarize(sum_winr = sum(long_win))
ggplot(sum_winr, 
       aes(x = factor(round,
                      labels = c("Vòng 1","Vòng 2","Vòng 3")), 
                      y = sum_winr)) +
  geom_bar(stat = "identity", 
           fill = "cornflowerblue") +
  geom_text(aes(label = dollar(sum_winr)), 
            vjust = -0.25) +
  scale_y_continuous(label = dollar) +
  labs(title = "Tổng số tiền thưởng thắng được", 
       subtitle = "Theo vòng chơi",
       x = "",
       y = "")

Ta thấy có chênh lệch về số tiền thưởng thắng được theo từng vòng. Số tiền thưởng có xu hướng tăng theo từng vòng chơi. Cụ thể, số tiền thưởng thắng được ở vòng 3 gấp 2.26 lần vòng 2 và gấp 4.45 lần so với vòng 1.

4 Tuần 4

4.1 Giới thiệu về ggplot2

4.1.1 Gọi packages ggplot2 và các packages bổ trợ

library(ggplot2)
library(tidyverse)
library(DT)
library(scales)
library(dplyr)
library(cowplot)

4.1.2 Tổng quan về ggplot2

Các hàm trong gói ggplot2 xây dựng biểu đồ theo lớp. Chúng ta có thể xây dựng một biếu đồ phức tạp bằng cách bắt đầu với một biểu đồ đơn giản và thêm các phần tử bổ sung, mỗi lần một phần tử.

Ví dụ sử dụng dữ liệu từ khảo sát từ một game show Bạn hay thù (FriendFoe) để phám khá mối quan hệ giữa độ tuổi thí sinh (age) và số tiền thắng được (win)

library(Ecdat)
data(FriendFoe)
ffoe <- na.omit(FriendFoe)
datatable(ffoe)

Khi xây dựng biếu đồ ggplot2, chỉ cần có 2 hàm đầu tiên được mô tả bên dưới. Các chức năng khác là tùy chọn và có thể xuất hiện theo bất cứ lúc nào.

4.1.2.1 ggplot

Hàm đầu tiên trong xây dựng đồ thị là hàm số ggplot. Nó chỉ định các

  • Khung dữ liệu chứa các dữ liệu được vẽ

  • Ánh xạ của các biến đến các thuộc tính trực quan của biểu đồ. Các ánh xạ được đặt trong hàm aes (aes: viết tắt là thẩm mỹ)

Một số hàm bắt đầu bằng aes_

  • shape = Hiển thị một điểm với hàm geom_point() dưới dạng dấu chấm, ngôi sao, hình tam giác hoặc hình vuông…

  • fill = Màu sắc bên trong (vd: của cột hoặc boxplot)

  • color = Đường bên ngoài của cột, boxplot, v.v., hoặc màu của điểm nếu sử dụng hàm geom_point()

  • size = Kích thước (vd: độ dày của đường, kích thước của điểm)

  • alpha = Độ trong suốt (1 = bình thường, 0 = vô hình)

  • binwidth = Độ rộng các bins trong biểu đồ histogram

  • width = Độ rộng của các cột trong “biểu đồ cột”

  • linetype = Kiểu của đường (vd: liền, nét đứt, chấm chấm)

#Chỉ định biến với biểu đồ 
ggplot(data = ffoe,
       mapping = aes(x = age, y = win))

Biểu đồ trống ở đây có nghĩa ta đã chỉ định rằng biến age phải được ánh xạ tới trục x và biến win phải được ánh xạ tới trục y, nhưng chưa chỉ định những gì ta muốn đặt trên biểu đồ.

4.1.2.2 geoms

Geoms là các đối tượng hình học (points(điểm), lines(đường thẳng), bars(thanh), etc) có thể được đặt trên biểu đồ. Chúng được thêm vào bằng các hàm bắt đầu bằng goem_.

Một số goem_ phổ biến

  • Histograms - geom_histogram()

  • Biểu đồ cột - geom_bar() hoặc geom_col()

  • Box plots - geom_boxplot()

  • Điểm (vd: biểu đồ phân tán) - geom_point()

  • Biểu đồ đường - geom_line() hoặc geom_path()

  • Đường xu hướng - geom_smooth()

Trong ví dụ này, chúng ta sẽ thêm điểm bằng cách sử dụng chức năng goem_points, tạo biểu đồ phân tán.

Trong gói vẽ đồ thị ggplot2 thì các chức năng được nối với nhau bằng cách sử dụng dấu + để xây dựng một biểu đồ cuối cùng.

#Thêm điểm 
ggplot(data = ffoe,
       mapping = aes(x = age, y = win)) +
  geom_point()

Biểu đồ chỉ ra rằng có một ngoại lệ. Một cá nhân có số tiền thưởng cao hơn nhiều so với những người còn lại. Ta sẽ loại bỏ trường hợp này sau đó tiếp tục các thao tác tiếp theo.

#Loại bỏ giá trị ngoại lệ 
cleardata <-  filter(ffoe, win < 15 )
g1 <-  ggplot(data = cleardata,
       mapping = aes(x = age, y = win)) +
  geom_point()

Một số tham số (tùy chọn) có thể được chỉ định trong một hàm geom_. Các tùy chọn cho chức năng geom_point bao gồm color, size, và alpha. Chúng kiểm soát màu sắc, kích thước và độ trong suốt của điểm tương ứng. Độ trong suốt nằm trong khoảng từ 0 (hoàn toàn trong suốt) đến 1 (hoàn toàn mờ đục). Thêm một mức độ minh bạch có thể giúp hình dung các điểm chồng chéo.

#Sửa đổi màu sắc, độ trong suốt và kích thước của điểm 
g2 <- ggplot(data = cleardata,
       mapping = aes(x = age, y = win)) +
  geom_point(color = "cornflowerblue",
             alpha = .7,
             size = 3)
plot_grid(g1,g2)

Tiếp theo, vẽ thêm một đường hồi quy (tuyến tính). Chúng ta có thể làm điều này với chức năng geom_smooth. Các tùy chọn kiểm soát loại đường (tuyến tính, bậc hai, không tham số), độ dày của đường, màu của đường và sự hiện diện hay vắng mặt của khoảng tin cậy. Ở đây ta yêu cầu một dòng hồi quy tuyến tính method = lm(trong đó lm là viết tắt của mô hình tuyến tính).

#Thêm đường hồi quy 
ggplot(data = cleardata,
       mapping = aes(x = age, y = win)) +
  geom_point(color = "cornflowerblue",
             alpha = .7,
             size = 3) +
  geom_smooth(formula = 'y ~ x',method = "lm")

Số tiền thưởng có mối quan hệ nghịch biến với độ tuổi

4.1.2.3 grouping

Ngoài việc ánh xạ các biến tới trục x và y , các biến có thể được ánh xạ tới màu sắc, hình dạng, kích thước, độ trong suốt và các đặc điểm trực quan khác của các đối tượng hình học. Điều này cho phép các nhóm quan sát được xếp chồng lên nhau trong một biểu đồ.

Ta thêm biến giới tính thí sinh (sex) vào biểu đồ và thể hiện nó bằng màu sắc.

#Thêm biến giới tính và ánh xạ nó bởi màu sắc 
ggplot(data = cleardata,
       mapping = aes(x = age, 
                     y = win,
                     color = sex)) +
  geom_point(alpha = .7,
             size = 3) +
  geom_smooth(formula = 'y ~ x',
              method = "lm", 
              se = FALSE, 
              size = 1.5)

Tùy chọn color = sex được đặt trong hàm aes, bởi vì tôi đang ánh xạ một biến thành một thẩm mỹ. Tùy chọn geom_smooth (se = FALSE) được thêm vào để triệt tiêu khoảng tin cậy.

Có vẻ như phụ nữ có xu hướng nhận được số tiền thưởng cao hơn đàn ông. Ngoài ra, có thể có mối quan hệ mạnh mẽ hơn giữa age và tiền thưởng thắng được đối với nam giới so với nữ giới.

4.1.2.4 scales

Tỷ lệ kiểm soát cách các biến được ánh xạ tới các đặc điểm hình ảnh của biểu đồ. Các hàm tỷ lệ (bắt đầu bằng scale_) cho phép bạn sửa đổi ánh xạ này. Trong biểu đồ tiếp theo, ta sẽ thay đổi tỷ lệ trục x và y cũng như các màu được sử dụng.

#Thay đổi màu sắc và nhãn trục 
ggplot(data = cleardata,
       mapping = aes(x = age, 
                     y = win,
                     color = sex)) +
  geom_point(alpha = .7,
             size = 3) +
  geom_smooth(formula = 'y ~ x',
              method = "lm", 
              se = FALSE, 
              size = 1.5) +
  scale_x_continuous(breaks = seq(20, 60, 10)) +
  scale_y_continuous(breaks = seq(0, 8, 2),
                     label = scales::dollar) +
  scale_color_manual(values = c("indianred3", 
                                "cornflowerblue"))

Ở biểu đồ này tôi chỉ định khoảng cách các trục x và y theo cách mà tôi muốn để dễ quan sát hơn, thêm ký hiệu đô la cho biến win để dễ phân biệt và thay đổi màu sắc để hấp dẫn hơn.

4.1.2.5 facets

Chia nhỏ biểu đồ được sử dụng để chia một biểu đồ thành nhiều phần nhỏ, với một biểu đồ cho mỗi cấp độ cho một biến nhất định. Mỗi biểu đồ được tạo bắng các hàm bắt đầu bằng facet_. Theo như ví dụ đưa ra ở trên, ở đây mỗi biểu đồ được chia nhỏ ra sẽ được xác định theo (round)

#Chia nhỏ biểu đồ theo biến vòng chơi (round)
ggplot(data = cleardata,
       mapping = aes(x = age, 
                     y = win,
                     color = sex)) +
  geom_point(alpha = .7,
             size = 3)  +
  geom_smooth(formula = 'y ~ x',
              method = "lm", 
              se = FALSE, 
              size = 1.5) +
  scale_x_continuous(breaks = seq(20, 60, 10)) +
  scale_y_continuous(breaks = seq(0, 8, 2),
                     label = scales::dollar) +
  scale_color_manual(values = c("indianred3", 
                                "cornflowerblue")) +
                                  
  facet_wrap(~round)  

Ở đây ta thấy sự khác biệt giữa số tiền nhận được và độ tuổi đã phụ thuộc vào cấp độ vòng chơi

  • Ở vòng 1 số người bị loại có cả nam và nữ,số tiền thưởng trãi dài ở đủ mọi lứa tuổi nhưng ta thấy đa số số tiền thưởng họ nhận được không quá 2$ chỉ duy một đối tượg duy nhất nhận được số tiền trên 2$

  • Ở vòng 2 số người bị loại có cả nam và nữ, ở vòng này độ tuổi bị rút lại một chút chỉ có thí sinh dưới 50 tuổi (do đã bị loại ở vòng 1). Và số tiền họ nhận được cũng khác hơn so với vòng 1, vòng này họ thắng được số tiền thưởng từ 4$ trở xuống và có chỉ duy nhất một đối tượng ngoại lệ nhận được số tiền thưởng ở mức gần 6$.

  • Ở vòng cuối cùng số tiền thưởng thắng được của họ lên mức gần 8$ cao gấp 4 lần so với vòng 1, gấp 2 lần so với vòng 2.

Tóm lại: Theo như ba biểu đồ thì đa số tiền thưởng nhận được nghịch biến với số tuổi. Số tiền thắng được sẽ tăng theo mỗi vòng theo (vòng 3 tăng gấp 2 lần so với 2 và tăng gấp 4 lần). Và đa số người nhận được số tiền thưởng cao tập trung vào nam giới hơn so với nữ giới. Độ tuổi nhận được tiền thưởng tập trung vào nhóm tuổi dưới 40 tuổi.

#Chia nhỏ biểu đồ theo mùa chương trình
ggplot(data = cleardata,
       mapping = aes(x = age, 
                     y = win,
                     color = sex)) +
  geom_point(alpha = .7,
             size = 3)  +
  geom_smooth(formula = 'y ~ x',
              method = "lm", 
              se = FALSE, 
              size = 1.5) +
  scale_x_continuous(breaks = seq(20, 60, 10)) +
  scale_y_continuous(breaks = seq(0, 8, 2),
                     label = scales::dollar) +
  scale_color_manual(values = c("indianred3", 
                                "cornflowerblue")) +
                                  
  facet_wrap(~season)

Sau khi chia biểu đồ theo từng mùa game show ta thấy được số tiền có mối quan hệ nghịch biến với số tuổi. Đa số người nhận được số tiền thưởng cao thiên về nam giới hơn nữ giới. Nhưng khi so về mặt bằng chung thì phụ nữ vẫn nhận được số tiền thưởng cao hơn 0$ nhiều hơn.

4.1.2.6 labs

Đồ thị để dễ hiểu thì nhãn thông tin là yếu tố chính. Hàm labs này cung cấp các nhãn tùy chỉnh cho các trục và chú giải. Ngoài ra, ta có thể thêm tiêu đề, phụ đề và chú thích tùy chỉnh.

#Thêm tiêu đề và nhãn thông tin
ggplot(data = cleardata,
       mapping = aes(x = age, 
                     y = win,
                     color = sex)) +
  geom_point(alpha = .7,
             size = 3)  +
  geom_smooth(formula = 'y ~ x',
              method = "lm", 
              se = FALSE, 
              size = 1.5) +
  scale_x_continuous(breaks = seq(20, 60, 10)) +
  scale_y_continuous(breaks = seq(0, 8, 2),
                     label = scales::dollar) +
  scale_color_manual(values = c("indianred3", 
                                "cornflowerblue")) +
                                  
  facet_wrap(~round) +
  labs(title = "Cấp độ trò chơi",
       subtitle = "Số tiền thưởng thắng được theo cấp độ trò chơi",
       x = "Tuổi thí sinh",
       y = "Tiền thưởng",
       color = "Giới tính")

4.1.2.7 Theme

Cuối cùng, chúng ta có thể tùy chỉnh giao diện của biểu đồ bằng các chủ đề. Các hàm chủ đề (bắt đầu bằng theme_) kiểm soát màu nền, phông chữ, đường lưới, vị trí chú thích và các tính năng không liên quan đến dữ liệu khác của biểu đồ.

#Tùy chỉnh chủ đề 
ggplot(data = cleardata,
       mapping = aes(x = age, 
                     y = win,
                     color = sex)) +
  geom_point(alpha = .8,
             size = 3)  +
  geom_smooth(method = "lm", 
              se = FALSE, 
              size = 1.5) +
  scale_x_continuous(breaks = seq(20, 60, 10)) +
  scale_y_continuous(breaks = seq(0, 8, 2),
                     label = scales::dollar) +
  scale_color_manual(values = c("indianred3", 
                                "cornflowerblue")) +
                                  
  facet_wrap(~round) +
  labs(title = "Cấp độ trò chơi",
       subtitle = "Số tiền thưởng thắng được theo cấp độ trò chơi",
       x = "Tuổi thí sinh",
       y = "Tiền thưởng",
       color = "Giới tính") + 
theme_minimal()
## `geom_smooth()` using formula = 'y ~ x'

4.2 Đồ thị dạng scatter

Khi giới thiệu tổng quan về gói ggplot tôi đã có lấy ví dụ về đồ thị dạng scatter để chạy thử. Giờ tôi sẽ thực hành trực qan hóa dữ liệu các biến định lượng: số tiền thắng được win, win1 và số tiền có trong hộp ủy thác cash với các biến định tính khác liên quan khác.

4.2.1 Trực quan hóa dữ liệu biến age1 - win1

Tôi sẽ phân tích biến age1 với win1 với các biến khác xem nó có mối quan hệ như thế nào.

Trong đó:

  • age1 : độ tuổi của đối thủ

  • win1 : tiền thưởng đối thủ thắng được

#Biểu đồ cơ bản 
ggplot(data = ffoe,
       mapping = aes(x = age1, y = win1)) +
  geom_point()

#Nối các điểm trên đồ thị bằng đường thẳng 
ggplot(ffoe,
       aes(x = age1, y = win1)) +
  geom_point(color = 'cornflowerblue') +
  geom_line(color = 'red')

#Biểu đồ phân tán với màu sắc, độ trong suốt, tỷ lệ trục và nhãn trục
ggplot(ffoe, 
       aes(x = age1, 
           y = win1)) +
  geom_point(color="cornflowerblue", 
             size = 3, 
             alpha=.8) +
  scale_y_continuous(label = scales::dollar) +
  labs(x = "Tuổi đối thủ",
       y = " ",
       title = "Số tiền thưởng đối thủ thắng được")

Biểu đồ biểu thị một cách rõ ràng về sự phân tán số tiền và độ tuổi của đối thủ, độ tuổi của đối thủ tham gia game show nhiều nhất từ 18 đến dưới 40 tuổi, một nhóm nhỏ trên 40 tuổi và rãi rác một số người ở độ tuổi trên 50 dưới 68 tuổi. Số tiền thưởng họ nhận được cũng phân tán không đều theo từng mức số tiền, đa số họ nhận được số tiền thưởng dưới 5$, một số ít nhận được số tiền trên 5$ dưới 10$ và chỉ duy nhất một đối tượng nhận được số tiền trên 15$.

Mối quan hệ tuyến tính của độ tuổi và số tiền thưởng thắng được của đối thủ.

#Biểu đồ phân tán với đường tuyến tính
ggplot(ffoe, 
       aes(x = age1, 
           y = win1)) +
  geom_point(color="cornflowerblue", 
             size = 3, 
             alpha=.8) +
  scale_y_continuous(label = scales::dollar) +
  labs(x = "Tuổi đối thủ",
       y = " ",
       title = "Số tiền thưởng đối thủ thắng được") +
  geom_smooth(formula = y ~ x, method = "lm",
              se = FALSE,
              size = 1.5)

Số tiền thưởng thắng được của người tham gia với vai trò là đối thủ với tuổi của họ có mối quan hệ nghịch biến.

Các biểu đồ trên tôi sử dụng để quan sát tổng quan về dữ liệu của biến age1win1. Giờ tôi sẽ biểu thị biểu đồ theo số liệu tôi muốn quan sát bằng cách tách dữ liệu theo ý mình và thêm các ánh xạ để biểu thị mối quan hệ giữa 2 biến trên với các biến khác.

#Biểu đồ phân tán ánh xạ màu sắc với biến giới tính đối thủ (sex1)  
ggplot(data = ffoe,
       mapping = aes(x = age1, 
                     y = win1,
                     color = sex1)) +
  geom_point(alpha = .8, 
             size = 3) +
  scale_y_continuous(label = scales::dollar, 
                     breaks = seq(0,10,2),
                     limits = c(0, 10)) +
  scale_x_continuous(breaks = seq(18, 48, 10), 
                     limits=c(18, 48)) + 
  labs(x = "Tuổi đối thủ",
       y = " ",
       title = "Số tiền thưởng đối thủ thắng được") +
  geom_smooth(formula = y ~ x, method = "lm", 
              se = FALSE, 
              size = 1.5)

Biểu đồ ánh xạ màu sắc với biến giới tính đối thủ sex1 để ta có thể thấy mối tương quan giữa giới tính, độ tuổi và số tiền thưởng mà họ thắng được qua màu sắc.

Có vẻ như đàn ông có xu hướng nhận được số tiền thưởng cao hơn phụ nữ. Ngoài ra, có thể có mối quan hệ mạnh mẽ hơn giữa tuổi đối thủ và tiền thưởng thắng được đối với nam giới so với nữ giới.Ở đây, ta thấy được dù là giới tính nào thì họ số tiền thưởng mà họ thắng được có mối quan hệ nghịch biến với độ tuổi.

Sau khi ánh xạ biến giới tính cho biểu đồ thì tôi muốn xem xét về mối liên hệ của giới tính, số tiền thưởng, tuổi với biến vòng trò chơi bằng cách ánh xạ biến vòng trò chơi round bằng hình dạng.

#Biểu đồ phân tán với ánh xạ màu sắc và hình dạng 
ggplot(data = ffoe,
       mapping = aes(x = age1, 
                     y = win1,
                     color = sex1,
                     shape = round)) +
  geom_point(alpha = .8, 
             size = 3) +
  scale_y_continuous(label = scales::dollar, 
                     breaks = seq(0,10,2),
                     limits = c(0, 10)) +
  scale_x_continuous(breaks = seq(18, 48, 10), 
                     limits=c(18, 48)) + 
  labs(x = "Tuổi đối thủ",
       y = " ",
       title = "Số tiền thưởng đối thủ thắng được") 
## Warning: Removed 9 rows containing missing values (`geom_point()`).

Biểu đồ ánh xạ màu sắc biến giới tính đối thủ và ánh xạ hình dạng là biến số vòng đối thủ bị loại. Cho ta biết, với từng giới tính thì họ bao nhiêu tuổi bị loại ở vòng nào và nhận được số tiền thưởng là bao nhiêu.

Mỗi hình dạng cho ta biết về một vòng của trò chơi, nó đại diện cho số người bị loại ở vòng đó. Ta thấy theo từng vòng (cấp độ 1,2,3) số tiền thưởng cũng dần tăng lên, đa số người chơi đi đến được vòng 3 thì khả năng họ nhận được số tiền thưởng cao hơn.

Người chơi là nam và nữ nhận được số tiền thưởng ở từng vòng cũng khác nhau. Nhìn vào biểu đồ ta thấy đa số người nam đi đến vòng 2 và vòng 3 nhiều hơn là nữ. Số tiền thưởng họ nhận được cũng có chút ít cao hơn so với giới nữ.

Ta cũng có thể ánh xạ kích thước theo giá trị số tiền.

ggplot(ffoe, aes(x = age1, 
               y = win1, 
               size= cash)) + 
  geom_point(color = "cornflowerblue",
             alpha = .4) +
  scale_x_continuous(label = scales::comma) +
  scale_y_continuous(label = scales::dollar ) +
  scale_size(range = c(1,10), # point size range
             label = scales::dollar)

Biểu đồ ánh xạ kích thước với số tiền có trong hộp ủy thác cash. Cho ta biết, trong hộp ủy thác có số tiền là bao nhiêu, đối thủ đã thắng được số tiền bao nhiêu trong hộp ủy thác đó và họ ở độ tuổi bao nhiêu.

Sau khi ánh xạ bằng nhìn dạng theo từng vòng trò chơi thì tôi muốn xem xét về số tiền có trong hộp ủy thác nằm ở mức bao nhiêu theo từng vòng. Vì vậy tôi sẽ thay đổi ánh xạ màu sắc thành biến round và ánh xạ kích thước với biến cash để xem sự khác biệt.

#Biểu đồ phân tán với ánh xạ màu sắc và kích thước
ggplot(data = ffoe,
       mapping = aes(x = age1, 
                     y = win1,
                     color = round,
                     size = cash)) +
  geom_point(alpha = .8) +
  scale_y_continuous(label = scales::dollar, 
                     breaks = seq(0,10,2),
                     limits = c(0, 10)) +
  scale_x_continuous(breaks = seq(18, 48, 10), 
                     limits=c(18, 48)) + 
  labs(x = "Tuổi đối thủ",
       y = " ",
       title = "Số tiền thưởng đối thủ thắng được") 
## Warning: Removed 9 rows containing missing values (`geom_point()`).

Biểu đồ ánh xạ màu sắc là vòng đối thủ bị loại roud và ánh xạ kích thước với biến số tiền có trong hộp ủy thác cash. Cho ta biết, ở mỗi vòng trong hộp ủy thác có bao nhiêu, người chơi bị loại ở vòng nào với độ tuổi bao nhiêu và nhận được số tiền thưởng bao nhiêu.

Từng vòng chơi (cấp độ 1,2,3) số tiền có trong hộp ủy thác đều mang những giá trị gia tăng. Người chơi cũng theo đó mà nhận được số tiền có giá trị gia tăng theo từng vòng.

4.2.2 Trực quan hóa dữ liệu biến win - win1

Tôi sẽ phân tích biến win với win1 với các biến khác xem nó có mối quan hệ như thế nào.

Trong đó:

  • win : Tiền thưởng thí sinh thắng được

  • win1 : tiền thưởng đối thủ thắng được

Trước tiên ta sẽ biểu diễn hai biến trên biểu đồ histograms để xem chúng phân phối như thế nào

#Biểu đồ histograms biến win 
h1 <- ggplot(ffoe, aes(x = win)) +
  geom_histogram(fill = "cornflowerblue",
                 color = "white",
                 binwidth = 3)  +
  scale_x_continuous(label = scales::dollar) +
  labs(x = "Số người",
       y = "Tiền thưởng thí sinh thắng được",
       title = "Biểu đồ histograms win")

#Biểu đồ histograms biến win1 
h2 <- ggplot(ffoe, aes(x = win1)) +
  geom_histogram(fill = "cornflowerblue",
                 color = "white",
                 binwidth = 3)  +
  scale_x_continuous(label = scales::dollar) +
  labs(x = "Số người",
       y = "Tiền thưởng đối thủ thắng được",
       title = "Biểu đồ histograms win1")
plot_grid(h1,h2)

Nhìn chung, tiền thưởng thắng được của cả thí sinh và đối thủ đều không cao.

#Đường tuyến tính 
ggplot(ffoe, 
       aes(x = win, 
           y = win1)) +
  geom_point(color="cornflowerblue", 
             size = 3, 
             alpha=.8,) +
  scale_y_continuous(label = scales::dollar) +
  scale_x_continuous(label = scales::dollar) +
  labs(x = "Số tiền thưởng thí sinh thắng được",
       y = "Số tiền thưởng đối thủ thắng được",
       title = "Số tiền thưởng người tham gia game show thắng được") +
   geom_smooth(formula = y ~ x, method = "lm",
              se = FALSE,
              size = 1.5)

Số tiền thưởng của thí sinh và đối thủ có mối quan hệ nghịch biến.

#Biểu đồ phân với ánh xạ vòng chơi 
ggplot(data = ffoe,
       mapping = aes(x = win, 
                     y = win1,
                     color = round)) +
  geom_point(alpha = .8, 
             size = 3) +
  scale_y_continuous(label = scales::dollar, 
                     breaks = seq(0,10,2),
                     limits = c(0, 10)) +
  scale_x_continuous(label = scales::dollar, 
                     breaks = seq(0, 10, 2), 
                     limits=c(0, 10 )) + 
  labs(x = "Số tiền thưởng thí sinh thắng được",
       y = "Số tiền thưởng đối thủ thắng được",
       title = "Số tiền thưởng người tham gia game show thắng được") +
  geom_smooth(formula = y ~ x, method = "lm", 
              se = FALSE, 
              size = 1.5) 

Ta ánh xạ màu sắc cho biến vòng chơi round để quan sát số tiền thưởng thắng được của cả thí sinh và đối thủ có mối quan hệ ra sau qua từng vòng.

Để dễ cho việc quan sát ta sẽ tách biểu đồ chung cho cả ba cấp độ chơi trên thành từng biến riêng.

#Tách biểu đồ 
ggplot(data = ffoe,
       mapping = aes(x = win, 
                     y = win1,
                     color = round)) +
  geom_point(alpha = .8, 
             size = 3) +
  scale_y_continuous(label = scales::dollar, 
                     breaks = seq(0,10,2),
                     limits = c(0, 10)) +
  scale_x_continuous(label = scales::dollar, 
                     breaks = seq(0, 10, 2), 
                     limits=c(0, 10 )) + 
  labs(x = "Số tiền thưởng thí sinh thắng được",
       y = "Số tiền thưởng đối thủ thắng được",
       title = "Số tiền thưởng người tham gia game show thắng được") +
  geom_smooth(formula = y ~ x, method = "lm", 
              se = FALSE, 
              size = 1.5) +
facet_wrap(~round)  

Sau khi tách các biểu đồ theo từng vòng chơi (cấp độ 1,2,3) ta dễ quan sát hơn hẳn

  • Vòng 1 mối quan hệ giữa số tiền thưởng của cả thí sinh và đối thủ không mấy cách biệt nhưng ta vẫn thấy được đối thủ nhận được số tiền khả quan hơn.

  • Vòng 2 ta thấy mối quan hệ này rõ rệt hơn hẳn ở vòng 1, đối thủ nhận được số tiền thưởng cao hơn và nhiều người có thưởng hơn so với thí sinh

  • Vòng 3 thể hiện mối quan hệ mạnh mẽ giữa số tiền thưởng thí sinh nhận được và đối thủ nhận được. Đường tuyến tính dốc xuống trong thấy rõ hơn rất nhiều so với vòng 1 và vòng 2. Một mối quan hệ nghịch biến mạnh mẽ.

4.3 Đồ thị cột

4.3.1 Đồ thị cột dạng đơn biến

4.3.1.1 Biến định tính

Ta sẽ vẽ biểu đồ với biến số lượng người bị loại ở mỗi vòng chơi round(cấp độ 1,2,3) và liên hệ nó với những biến khác. Với các biến liên quan khác như play, play1ta chỉ cần quan sát 1 biến vì chúng có tính chất tương tự nhau

#Biểu đồ cột đơn giản 
ggplot(ffoe, aes(x = round)) + 
  geom_bar()

Phần lớn người bị loại ở vòng 1, tiếp theo là vòng 3, và cuối cùng là vòng 2.

#Biểu đồ với màu sắc, nhãn và tiêu đề đã được thay đổi 
g3 <- ggplot(ffoe, aes(x = round)) + 
  geom_bar(fill = "cornflowerblue", 
           color="black") +
  labs(x = "Cấp độ trò chơi", 
       y = "Số người bị loại", 
       title = "Số người bị loại theo từng cấp độ")

#Biểu đồ cột ghi nhãn số 
g4 <- ggplot(ffoe, aes(x = round,
                y = after_stat(count))) +
  geom_bar(fill = "cornflowerblue", 
           color="black") +
  geom_text(aes(label = (after_stat(count))), stat = 'count', color = 'black', vjust = - .25) +
  theme_classic() +
  labs(x = "Cấp độ trò chơi",
       y = "Số người",
       title = "Số người bị loại theo từng cấp độ")
plot_grid(g3,g4)

Các đồ thị cột có thể đại diện cho phần trăm chứ không phải số đếm. Đối với biểu đồ cột, mã aes(x=round) nó là một lối tắt cho aes(x= round, y = after_stat(count)), trong đó count là một biến đặc biệt biểu thị tần suất trong mỗi danh mục.

Biểu đồ cho ta biết tuần suất về số người bị loại theo từng cấp độ trò chơi.

  • Vòng 1 có 91 người bị loại

  • Vòng 2 có 62 người bị

  • Vòng 3 còn lại 74 người

#Biểu đồ với tỷ lệ phần trăm 
g5 <-  ggplot(ffoe, 
       aes(x = round, 
           y = after_stat(count/sum(count)))) + 
  geom_bar(fill = "indianred3", 
           color = "black") +
  labs(x = "Cấp độ trò chơi", 
       y = "Phần trăm người bị loại", 
       title  = "Phần trăm người bị loại theo từng cấp độ") +
scale_y_continuous(labels = scales::percent)

#Biểu đồ với nhãn tỷ lệ phần trăm 
g6 <- ggplot(ffoe, aes(x = round,
                y = after_stat(count/sum(count)))) +
  geom_bar( fill = "indianred3", 
           color = "black") +
  geom_text(aes(label = scales::percent(after_stat(count/sum(count)))), 
            stat = 'count', color = 'black', vjust = - .25) +
  theme_classic() +
  labs(x = "Cấp độ trò chơi",
       y = "Số người",
       title = "Phần trăm số người bị loại theo từng cấp độ") +
  scale_y_continuous(labels = scales::percent)
plot_grid(g5,g6)

Trong dòng lệnh ở trên, gói scales được sử dụng để thêm ký hiệu % vào nhãn trục y.

Hiểu thị phần trăm của biểu đồ cho ta biết ở mỗi cấp độ trò chơi có bao nhiêu phần trăm người bị loại

  • Vòng 1 có 40.1% người bị loại

  • Vòng 2 có 27.3% người bị loại

  • Vòng 3 còn lại 32.6% người chơi

Ngoài việc tính tỷ lệ % và đếm số người bị loại theo từng vòng thì ta có thể phân chia đồ thị theo một số tiêu chí(biến) khác để phân tích

Ta chia biểu đồ với biến giới tính thí sinh

#Chia đồ thị giá trị số theo biến sex (giới tính)
g7 <- ggplot(ffoe, aes(x = round,
                y = after_stat(count))) +
  geom_bar(fill = "cornflowerblue", 
           color="black") +
  geom_text(aes(label = (after_stat(count))), stat = 'count', color = 'black', vjust = - .25) +
  theme_classic() +
  labs(x = "Cấp độ trò chơi",
       y = "Số người",
       title = "Số người và cấp độ bị loại của từng giới tính thí sinh") +
facet_grid(. ~ sex)

# Chia đồ thị theo tỷ lệ phần trăm giới tính đối thủ
g8  <- ggplot(ffoe, aes(x = round,
                y = after_stat(count/sum(count)))) +
  geom_bar( fill = "indianred3", 
           color = "black") +
  geom_text(aes(label = scales::percent(after_stat(count/sum(count)))), 
            stat = 'count', color = 'black', vjust = - .1) +
  theme_classic() +
  labs(x = "Cấp độ trò chơi",
       y = "Số người",
       title = "Phần trăm số người và cấp độ bị loại của từng giới tính thí sinh") +
  scale_y_continuous(labels = scales::percent) +
  facet_grid(.~ sex)
plot_grid(g7,g8)

Biểu đồ biểu thị số lượng người chơi bị loại ở từng vòng (cấp độ 1,2,3) theo giới tính thí sinh

  • Với người chơi là nữ có 53 (22.9%) người bị loại ở vòng 1 và 33 (14.5%) bị loại lần lượt ở vòng 2 và vòng 3.

  • Với người chơi là nam có 38 (16.7%) người bị loại ở vòng 1, 29 (12.8%) người bị loại ở vòng 2 và 41 (18.1%) người bị loại ở vòng 3.

Ta chia biểu đồ với giới tính đối thủ

#Chia đồ thị giá trị số theo biến sex1 (giới tính của đối thủ)
g9 <- ggplot(ffoe, aes(x = round,
                y = after_stat(count))) +
  geom_bar(fill = "cornflowerblue", 
           color="black") +
  geom_text(aes(label = (after_stat(count))), stat = 'count', color = 'black', vjust = - .1) +
  theme_classic() +
  labs(x = "Cấp độ trò chơi",
       y = "Số người",
       title = "Số người và cấp độ bị loại của từng giới tính đối thủ") +
facet_grid(. ~ sex1)

#Chia đồ thị theo tỷ lệ phần trăm giới tính thí sinh  
g10 <- ggplot(ffoe, aes(x = round,
                y = after_stat(count/sum(count)))) +
  geom_bar( fill = "indianred3", 
           color = "black") +
  geom_text(aes(label = scales::percent(after_stat(count/sum(count)))), 
            stat = 'count', color = 'black', vjust = - .1) +
  theme_classic() +
  labs(x = "Cấp độ trò chơi",
       y = "Số người",
       title = "Phần trăm và cấp độ bị loại của từng giới tính đối thủ") +
  scale_y_continuous(labels = scales::percent) +
  facet_grid(.~ sex1)
plot_grid(g9,g10)

Biểu đồ biểu thị số lượng người chơi với vai trò là đối thủ bị loại ở từng vòng (cấp độ 1,2,3) theo giới tính đối thủ

  • Với người chơi là nữ có 52 (22.9%) người bị loại ở vòng 1, 34 (15%) người bị loại ở vòng 2 và 25 (11%) người bị loại ở vòng 3.

  • Với người chơi là nam có 39 (17.2%) người bị loại ở vòng 1, 28 (12.3%) người bị loại ở vòng 2 và 49 (21.6%) người bị loại ở vòng 3.

Chia biểu đồ theo lựa chọn cấp độ chơi của thí sinh

#Chia đồ thị theo giá trị số biến play(lựa chọn cấp độ chơi của thí sinh)
g11 <- ggplot(ffoe, aes(x = round,
                y = after_stat(count))) +
  geom_bar(fill = "cornflowerblue", 
           color="black") +
  geom_text(aes(label = (after_stat(count))), stat = 'count', color = 'black', vjust = - .25) +
  theme_classic() +
  labs(x = "Cấp độ trò chơi",
       y = "Số người",
       title = "Số người và cấp độ của lối chơi của thí sinh") +
facet_grid(. ~ play) 

# Chia đồ thị theo tỷ lệ phần trăm biến play(lựa chọn cấp độ chơi của thí sinh)
g12 <- ggplot(ffoe, aes(x = round,
                y = after_stat(count/sum(count)))) +
  geom_bar( fill = "indianred3", 
           color = "black") +
  geom_text(aes(label = scales::percent(after_stat(count/sum(count)))), 
            stat = 'count', color = 'black', vjust = - .25) +
  theme_classic() +
  labs(x = "Cấp độ trò chơi",
       y = "Số người",
       title = "Phần trăm Số người bị loại theo từng cấp độ") +
  scale_y_continuous(labels = scales::percent) +
  facet_grid(.~ play)
plot_grid(g11,g12)

Mặc dù biểu đồ này chỉ biểu diễn sự lựa chọn cấp độ của thí sinh nhưng ta cũng có thể xác định lối chơi của đối thủ thí sinh vì biến play và play1` có tính đối lập.

Đồ thị biểu thị số lượng người bị loại lựa chọn cấp độ chơi (cấp độ friend or foe) của từng vòng (cấp độ 1,2,3)

  • Với sự lựa chọn cấp độ chơi là friend có 47 (20.07%) người bị loại ở vòng 1, 29 (12.78%) người bị loại ở vòng 2 và 36 (15.86%) người bị loại ở vòng 3.

  • Với sự lựa chọn cấp độ chơi là foe có 44 (19.38%) người bị loại ở vòng 1, 33 (14.54%) ngườ bị loại ở vòng 2 và 38 (16.74%) người bị loại ở vòng 3.

Tiếp theo đây, ta sẽ quan sát số lượng người tham gia game show theo biến màu da của thí sinh white và biến màu da của đối thủ white1

#Biểu đồ biểu hiện số lượng người theo biến white (màu da của thí sinh)
g13 <- ggplot(ffoe, aes(x = white,
                y = after_stat(count))) +
  geom_bar(fill = "white", 
           color="black") +
  geom_text(aes(label = (after_stat(count))), stat = 'count', color = 'black', vjust = - .25) +
  theme_classic() +
  labs(x = "Màu da",
       y = "Số người",
       title = "Số người và cấp độ theo màu da ") 

#Biểu đồ biểu hiện số lượng người theo biến white (màu da của thí sinh)
g14 <- ggplot(ffoe, aes(x = white,
                y = after_stat(count/sum(count)))) +
  geom_bar( fill = "white", 
           color = "black") +
  geom_text(aes(label = scales::percent(after_stat(count/sum(count)))), 
            stat = 'count', color = 'black', vjust = - .25) +
  theme_classic() +
  labs(x = "Màu da",
       y = "Số người",
       title = "Phần trăm số người bị loại theo màu da") +
  scale_y_continuous(labels = scales::percent) 
plot_grid(g13,g14)

Các con số biểu thị trong biểu đồ đã nói lên số người tham gia game show với màu da là trắng có 190 người chiếm 84% rất cao so với số người không phải da trắng chỉ có 37 người (16%).

4.3.1.2 Biến định lượng

Do có 2 biến ageage1 nó đại diện cho số tuổi thí sinh tham gia và đối thủ của họ nên tôi sẽ dùng lệnh pivot_longer đã học ở tuần 3 để gộp 2 biến lại thành 1 để dễ dàng biểu thị lên biểu đồ vì tôi chỉ quan tâm đến tuổi mà không cần biết họ là thí sinh hay đối thủ của thí sinh.

df_long <- ffoe %>% 
  pivot_longer(
    cols = c(`age`,`age1`),
    names_to = 'n_age', 
    values_to = 'long_age' )

Trước tiên tôi sẽ vẽ biểu đồ histogram để quan sát số người tham gia game show nằm ở độ tuổi nào nhiều hơn sau đó chia dữ liệu theo cách tôi quan sát.

#Biểu đồ cơ bản 
ggplot(df_long, aes(x = long_age)) +
  geom_histogram() + 
  labs(title = "Tuổi của người tham gia game show Bạn hay thù",
       x = "Tuổi")
## `stat_bin()` using `bins = 30`. Pick better value with `binwidth`.

Hầu hết những người tham gia dường như ở độ tuổi đầu độ tuổi 20 và cuối độ tuổi 30 với một nhóm khác ở độ tuổi 40 và một nhóm nhỏ hơn ở độ tuổi đầu 50 và gần 70

#Biểu đồ với màu nền, đường viền và số ngăn đã chỉnh sửa
ggplot(df_long, aes(x = long_age)) +
  geom_histogram(fill = "cornflowerblue", 
                 color = "white",
                   bins = 40) + 
  labs(title = "Tuổi của người tham gia game show Bạn hay thù",
       x = "Tuổi")

Sau khi có được sựu quan sát về khoảng tuổi xuất hiện nhất ta có thể chia theo từng khoảng độ tuổi mà ta muốn quan sát sau đó vè biểu đồ để thể hiện nó bằng trực quan hóa dữ liệu. Tôi sẽ chia độ tuổi làm 3 nhóm với Thanh niên, Trung niên, Lão

na.omit(df_long)
## # A tibble: 454 × 13
##    sex    white play   round season  cash sex1   white1 play1    win  win1 n_age
##    <fct>  <fct> <fct>  <fct> <fct>  <dbl> <fct>  <fct>  <fct>  <dbl> <dbl> <chr>
##  1 male   yes   foe    1     1        1.2 male   yes    friend   1.2   0   age  
##  2 male   yes   foe    1     1        1.2 male   yes    friend   1.2   0   age1 
##  3 male   yes   foe    3     1        7.7 female yes    foe      0     0   age  
##  4 male   yes   foe    3     1        7.7 female yes    foe      0     0   age1 
##  5 female no    foe    2     1        3.2 female no     foe      0     0   age  
##  6 female no    foe    2     1        3.2 female no     foe      0     0   age1 
##  7 male   yes   friend 1     1        1.2 male   yes    friend   0.6   0.6 age  
##  8 male   yes   friend 1     1        1.2 male   yes    friend   0.6   0.6 age1 
##  9 female yes   friend 3     1        5.7 male   yes    foe      0     5.7 age  
## 10 female yes   friend 3     1        5.7 male   yes    foe      0     5.7 age1 
## # ℹ 444 more rows
## # ℹ 1 more variable: long_age <int>
df_long <- df_long %>% 
  mutate(d = cut(df_long$long_age, 
               breaks=c(18,39,50,65),
                  labels= c ("Thanh niên","Trung niên","Lão")))

#Biểu đồ biểu thị giá trị 
g15 <- ggplot(df_long, aes(x = d ,
                y = after_stat(count))) +
  geom_bar(fill = "cornflowerblue", 
           color="black") +
  geom_text(aes(label = (after_stat(count))), stat = 'count', color = 'black', vjust = - .25) +
  theme_classic() +
  labs(title = "Số người theo nhóm tuổi") 

#Biểu đồ biểu hiện phần trăm
g16 <- ggplot(df_long, aes(x = d,
                y = after_stat(count/sum(count)))) +
  geom_bar( fill = "indianred3", 
           color = "black") +
  geom_text(aes(label = scales::percent(after_stat(count/sum(count)))), 
            stat = 'count', color = 'black', vjust = - .25) +
  theme_classic() +
  labs(title = "Phần trăm theo nhóm tuổi") +
  scale_y_continuous(labels = scales::percent) 
plot_grid(g15,g16)

Phần lớn thí sinh tham gia game show rơi vào nhóm tuổi thanh niên là chủ yếu tiếp đến là độ tuổi trung niên và ít nhất là độ tuổi lão

4.3.2 Đồ thị cột dạng hai biến

Đồ thị hai biến biểu thị mối quan hệ giữa hai biến. Loại biểu đồ này sẽ phụ thuộc vào mức độ đo lường của các biến (định tính hoặc định lượng).

4.3.2.1 Đồ thị cột xếp chồng

Tôi sẽ vẽ một biểu đồ thể hiện mối quan hệ giữa số người bị loại ở từng vòng (cấp độ 1,2,3) roundvới biến mùa chương trình game Bạn hay thù season.

#Biểu đồ cột chồng đơn giản 
ggplot(ffoe, 
       aes(x = season,
           fill = round)) + 
  labs(title = "Số người bị loại theo từng vòng của từng mùa",
       y = "Mùa chương trình") +
  geom_bar() +
 coord_flip()

#Biểu đồ cột chồng hiển thị nhãn giá trị
g17 <- ggplot(ffoe, aes(x = season,
                 y = after_stat(count),
                 fill = round)) +
  geom_bar() +
  geom_text(aes(label = (after_stat(count))), stat = 'count', color = 'white',
            position = position_stack(vjust = 0.5)) +
  theme_classic() +
  labs(x = "Mùa game show",
       y = "Số người",
       title = "Số người bị loại theo từng vòng của từng mùa")

#Biểu đồ cột chồng hiển thị phần trăm 
g18 <- ggplot(ffoe, aes(x = season,
                 y = after_stat(count),
                 fill = round)) +
  geom_bar() +
  geom_text(aes(label = scales::percent(after_stat(count/sum(count)))),
            stat = 'count', color = 'white',
            position = position_stack(vjust = 0.5)) +
  theme_classic() +
  labs(x = "Mùa game show",
       y = "Số người",
       title = "Phần trắm số người bị loại theo từng vòng của từng mùa")
plot_grid(g17,g18)

4.3.2.2 Đồ thị cột phân đoạn

Biểu đồ thanh xếp phân đoạn cũng giống như biểu đồ cột xếp chồng nhưng ở đây mỗi cột đại diện cho 100%.

#Biểu đồ phân đoạn cơ bản 
ggplot(ffoe,
       aes(x = play,
           fill = round)) +
  geom_bar(position = "fill") +
  labs(y = "Phân đoạn")

plotdata <- ffoe %>%
  group_by(play,round) %>%
  summarize(n = n()) %>% 
  mutate(pct = n/sum(n),
         lbl = scales::percent(pct)) 
## `summarise()` has grouped output by 'play'. You can override using the
## `.groups` argument.
plotdata 
## # A tibble: 6 × 5
## # Groups:   play [2]
##   play   round     n   pct lbl  
##   <fct>  <fct> <int> <dbl> <chr>
## 1 friend 1        47 0.420 42.0%
## 2 friend 2        29 0.259 25.9%
## 3 friend 3        36 0.321 32.1%
## 4 foe    1        44 0.383 38.3%
## 5 foe    2        33 0.287 28.7%
## 6 foe    3        38 0.330 33.0%
ggplot(plotdata, 
       aes(x = factor(play,
                      levels = c("friend", "foe")),
           y = pct,
           fill = factor(round, 
                         levels = c("1", "2", "3"),
                         labels = c("Vòng 1", 
                                    "Vòng 2", 
                                    "Vòng 3")))) + 
  geom_bar(stat = "identity",
           position = "fill") +
  scale_y_continuous(breaks = seq(0, 1, .2), 
                     label = percent) +
  geom_text(aes(label = lbl), 
            size = 3, 
            position = position_stack(vjust = 0.5)) +
  scale_fill_brewer(palette = "Set2") +
  labs(y = "Percent", 
       fill = "Vòng trò chơi",
       x = "Cấp độ trò chơi",
       title = "Biểu đồ phân đoạn vòng trò chơi với cấp độ trò chơi") +
  theme_minimal()

4.4 Đồ thị tròn

5 Tuần 3

5.1 Xoay trục dữ liệu

Để xoay trực dữ liệu ta cần gọi gói packages tidyverse, datasets và packages có chứa bộ dữ liệu đó

library(tidyverse)
library(ggplot2)
library(Ecdat)
data(FriendFoe)
ffoe <- FriendFoe

5.1.1 Từ ngang sang dọc (pivot_longer)

Chúng ta muốn sử dụng hàm pivot_longer() trong package tidyverse để chuyển đổi dữ liệu từ “ngang” sang định dạng “dọc”. Cụ thể, để chuyển đổi bốn cột dạng số có dữ liệu về giới tinh và cấp độ chơi thành hai cột mới: một cột chứa tên các biến được gộp và một cột chứa các ước số tương ứng.

Trong quá trình này, kết quả trả về hai cột “mới” - một cột có các danh mục (tên cột cũ) và một cột chứa các ước số tương ứng (ví dụ: Giới tính và cấp độ chơi). Ta có thể chấp nhận tên mặc định của cột mới hoặc có thể tùy chỉnh bằng names_to =values_to = tương ứng.

df_long <- ffoe %>% 
  pivot_longer(
    cols = c(`sex`,`sex1`, `play`,`play1`),
    names_to = 'new', 
    values_to = 'fac_new' )
df_long
## # A tibble: 908 × 11
##    white   age round season  cash white1  age1   win  win1 new   fac_new
##    <fct> <int> <fct> <fct>  <dbl> <fct>  <int> <dbl> <dbl> <chr> <fct>  
##  1 yes      20 1     1        1.2 yes       32   1.2     0 sex   male   
##  2 yes      20 1     1        1.2 yes       32   1.2     0 sex1  male   
##  3 yes      20 1     1        1.2 yes       32   1.2     0 play  foe    
##  4 yes      20 1     1        1.2 yes       32   1.2     0 play1 friend 
##  5 yes      40 3     1        7.7 yes       31   0       0 sex   male   
##  6 yes      40 3     1        7.7 yes       31   0       0 sex1  female 
##  7 yes      40 3     1        7.7 yes       31   0       0 play  foe    
##  8 yes      40 3     1        7.7 yes       31   0       0 play1 foe    
##  9 no       35 2     1        3.2 no        24   0       0 sex   female 
## 10 no       35 2     1        3.2 no        24   0       0 sex1  female 
## # ℹ 898 more rows

Lưu ý rằng bộ dữ liệu mới được tạo (df_long) có nhiều hàng hơn (908 so với 227); bộ dữ liệu đã trở nên “dài hơn”. Trên thực tế, bộ dữ liệu đã dài hơn gấp bốn lần, bởi vì mỗi hàng trong tập dữ liệu ban đầu hiện đại diện cho bốn hàng trong df_long, một hàng cho mỗi quan sát giới tính của người tham gia game show và lựa chọn cấp độ chơi của “Bạn hay thù”

Ngoài việc dài hơn, bộ dữ liệu mới có ít cột hơn (11 so với 13), vì dữ liệu trước đây được lưu trữ trong bốn cột (sex, sex1, play, play1), hiện được lưu trữ chỉ trong hai cột (new, fac_new).

Bây giờ chúng ta có thể chuyển tiếp bộ dữ liệu mới này tới ggplot2, và định vị cột mới fac_new với trục y và cột mới new tới độ số fill = (màu bên trong cột). Việc này giúp hiển thị số tiền thưởng trong một biểu đồ cột chồng, theo ước số của biến tương ứng:

ggplot(data = df_long) +
  geom_col(
    mapping = aes(x = new , y = fac_new , fill = fac_new),
    width = 1
  )

Nhận xét:

  • Từ đồ thị mặc dù không thể thấy được số liệu một cách chính xác để nói nhưng ta có thể quan sát và thấy được sự chênh lệch về giới tính nam và nữ của người chơi khi tham gia chương trình này. Ở đây ta thấy người tham gia là nam nhiều hơn người tham gia là nữ nó được thể hiện rõ qua 2 màu sắc đỏxanh lá bên trong đồ thị.

  • Cũng tương tự như giới tính thì sự lựa chọn về cấp độ trò chơi cũng có sự cách biệt rõ rệt mà không cần đến số liệu khi nhìn vào biểu đồ. Đa số người chơi thiên về hướng chọn cấp độ là Foe nhiều hơn so với cấp độ là Friend. Lượng màu sắc tím chiếm hơn phân nửa biểu đồ đã thể hiện được sự phong cách chọn cấp độ của người chơi.

Sau khi sử dụng pivot_longer cho các biến mang dữ liệu là ước số factor thì ta chuyển sang làm pivot_longer cho các biến mang dữ liệu giá trị để tạo ra một data frame mới với tên là df_long1

df_long1 <- ffoe %>% 
  pivot_longer(
    cols = c(`win`,`win`,`cash`),
    names_to = 'new1', 
    values_to = 'num_new1' )
df_long1 
## # A tibble: 454 × 13
##    sex    white   age play   round season sex1   white1  age1 play1   win1 new1 
##    <fct>  <fct> <int> <fct>  <fct> <fct>  <fct>  <fct>  <int> <fct>  <dbl> <chr>
##  1 male   yes      20 foe    1     1      male   yes       32 friend   0   win  
##  2 male   yes      20 foe    1     1      male   yes       32 friend   0   cash 
##  3 male   yes      40 foe    3     1      female yes       31 foe      0   win  
##  4 male   yes      40 foe    3     1      female yes       31 foe      0   cash 
##  5 female no       35 foe    2     1      female no        24 foe      0   win  
##  6 female no       35 foe    2     1      female no        24 foe      0   cash 
##  7 male   yes      26 friend 1     1      male   yes       40 friend   0.6 win  
##  8 male   yes      26 friend 1     1      male   yes       40 friend   0.6 cash 
##  9 female yes      40 friend 3     1      male   yes       26 foe      5.7 win  
## 10 female yes      40 friend 3     1      male   yes       26 foe      5.7 cash 
## # ℹ 444 more rows
## # ℹ 1 more variable: num_new1 <dbl>

Giống như dòng lệnh ở trên thì dữ liệu mới được tạo (df_long1) có nhiều hàng hơn (454 so với 227); bộ dữ liệu đã trở nên “dài hơn”. Và bộ dữ liệu đã dài hơn gấp ba lần, bởi vì mỗi hàng trong tập dữ liệu ban đầu hiện đại diện cho ba hàng trong ffoe, một hàng cho mỗi quan sát số tiền thắng được của người tham gia game show và số tiền có trong hộp ủy thác của trò chơi “Bạn hay thù” này.

Ngoài việc dài hơn, bộ dữ liệu mới có ít cột hơn (12 so với 13), vì dữ liệu trước đây được lưu trữ trong ba cột (win, win1, cash), hiện được lưu trữ chỉ trong hai cột (new1, num_new).

Để có thể giải thích một cách rõ ràng hơn về biểu đồ ta sẽ tính thông kê mô tả của các biến này để xem giá trị max min của từng biến.

#Số tiền có trong hộp ủy thác($)
summary(ffoe$cash)
##    Min. 1st Qu.  Median    Mean 3rd Qu.    Max. 
##   0.200   1.000   2.500   3.335   5.350  16.400
#Số tiền thưởng thí sinh thắng được($)
summary(ffoe$win)
##    Min. 1st Qu.  Median    Mean 3rd Qu.    Max. 
##   0.000   0.000   0.000   1.006   1.350  15.000
#Số tiền thưởng người tham gia với vai trò là đối thủ thắng được($)
summary(ffoe$win1)
##    Min. 1st Qu.  Median    Mean 3rd Qu.    Max. 
##   0.000   0.000   0.000   1.301   1.800  16.400

Chúng ta sẽ vẽ đồ thị cho data frame mới này để có thể quan sát và so sánh

df_long1 %>% ggplot(aes(x = num_new1 )) +
  geom_bar( fill = 'black', )

Nhận xét:

  • Ta thấy được số tiền có trong hộp ủy thác ở mức cao nhất là 16.4$ và chỉ có một người trong số người tham gia thắng được và đem về số tiền này

  • Phần lớn người tham gia đều nhận về khoản tiền từ 0$ đến dưới 10$ là chủ yếu

Ta sử dụng vòng lặp for để tạo ra một biến về việc phân chia số tiền thưởng nhận được để vẽ biểu đồ cho thấy khả năng thắng và nhận được khoảng tiền nằm ở mức bao nhiêu của người chơi.

for_long1 <- ifelse(df_long1$num_new1  ==  0 , "Thua", 
 ifelse(df_long1$num_new1 > 0 & df_long1$num_new1 <= 8, "Thuongtrungbinh", 
 ifelse(df_long1$num_new1 > 8, "Thuongcao","Thua")))
table(for_long1)
## for_long1
##            Thua       Thuongcao Thuongtrungbinh 
##             132              15             307
df_long1 <- mutate(df_long1, for_long1)
df_long1 %>% ggplot(aes(x = round , 
                 y = after_stat(count),
                 fill = for_long1)) +
  geom_bar(position = 'dodge') + 
  labs(x = 'Số người bị loại ở mỗi vòng và số tiền họ thắng được', y = 'Số người')

Nhận xét:

  • Ta thấy số người bị loại ở vòng 1 là nhiều nhất và số tiền họ thắng được nằm ở mức trung bình là nhiều và không có khả năng thắng số tiền thưởng cao nhất.

  • Người bị loại ở vòng 2 tương đối ít và số tiền họ thắng trải ra cả 3 mức trong đó tiền thưởng ở mức trung bình là cao nhất, không nhận được số tiền thưởng nào thấp nhất trong 3 vòng, Số tiền thưởng cao ở đây rất ít.

  • Người đi đến vòng 3 thì khả năng họ nhận được số tiền thưởng cao có thể xảy ra cao. Việc nhận được tiền thưởng trung bình cũng là một điều hiển nhiên. Và ở đay khả năng không nhận được số tiền thưởng nào cũng gần như bằng ở vòng 1.

  • Tóm lại thì số người nhận được số tiền thưởng ở mức trung bình chiếm đa số(307 người), người thắng số tiền thưởng cao chỉ có 15 người. Và số người thua không nhận được số tiền thưởng nào nằm ở giữa 132 người.

5.1.2 Từ dọc sang ngang (pivot_wider)

Trong một số trường hợp, chúng ta có thể muốn chuyển đổi bộ dữ liệu sang định dạng ngang. Đối với điều này, chúng ta có thể sử dụng hàm pivot_wider().

Tình huống phổ biến là khi chúng ta muốn chuyển đổi kết quả phân tích thành một định dạng dễ hiểu hơn cho người đọc. Thông thường, điều này bao gồm việc chuyển đổi một bộ dữ liệu trong đó thông tin chủ thể được trải rộng trên nhiều hàng, sau đó được thống nhất thành một định dạng mà thông tin được lưu trữ trên một hàng duy nhất.

Giả sử chúng ta muốn biết giới tính người chơi theo nhóm tuổi.Ta tạo ra thêm một biến mới để dễ dàng trong việc xoay dữ liệu

age_new <- cut(ffoe$age, breaks = c(18,28,40,57))
table(age_new)
## age_new
## (18,28] (28,40] (40,57] 
##     110      84      25
ffoe <- mutate(ffoe,age_new)
df_wide <- 
  ffoe %>% 
  count(age_new, sex)
df_wide
##   age_new    sex  n
## 1 (18,28] female 56
## 2 (18,28]   male 54
## 3 (28,40] female 43
## 4 (28,40]   male 41
## 5 (40,57] female 14
## 6 (40,57]   male 11
## 7    <NA> female  6
## 8    <NA>   male  2

Điều này cho chúng ta một bộ dữ liệu dạng dọc, rất tốt để trực quan hóa trong ggplot2, nhưng không lý tưởng để trình bày bảng:

ggplot(df_wide) +
  geom_col(aes(x = age_new  , y =  n   , fill = sex))

Do đó, chúng ta có thể sử dụng hàm pivot_wider() để chuyển đổi dữ liệu sang định dạng tốt hơn để đưa vào các bảng trong báo cáo.

Đối số names_from chỉ định cột mà từ đó tạo ra tên cột mới, trong khi đối số values_from chỉ định cột mà từ đó nhận các giá trị để điền. Đối số id_cols = là tùy chọn, nhưng nó có thể được chứa một vectơ tên các cột không xoay trục và do đó sẽ xác định từng hàng.

table_wide <- 
  df_wide %>% 
  pivot_wider(
    id_cols = age_new,
    names_from = sex ,
    values_from = n
  )

table_wide
## # A tibble: 4 × 3
##   age_new female  male
##   <fct>    <int> <int>
## 1 (18,28]     56    54
## 2 (28,40]     43    41
## 3 (40,57]     14    11
## 4 <NA>         6     2

Hay chúng ta cũng có thể trình bày dữ liệu dưới dạng bảng total trong excel

table_wide %>% 
  janitor::adorn_totals(c("row", "col")) %>% 
  knitr::kable() %>% 
  kableExtra::row_spec(row = 5 , bold = TRUE) %>% 
  kableExtra::column_spec(column = 4, bold = TRUE) 
age_new female male Total
(18,28] 56 54 110
(28,40] 43 41 84
(40,57] 14 11 25
NA 6 2 8
Total 119 108 227

5.1.3 Lắp dữ liệu

Ở đây đã có một số dữ liệu không có giá trị ở trước đó nên đã hiển thị là NA, vì vậy ta có thể lắp đầy chúng bằng lệnh bind

Ví dụ: lấy hai bộ dữ liệu, mỗi bộ dữ liệu có các quan sát về các đại lượng đo lường, cấp độ trò chơi và số tiền thắng được thời điểm đó. Tuy nhiên, bộ dữ liệu thứ hai cũng có biến round(vòng thí sinh bị loại)

df1 <- 
  tibble::tribble(
       ~seanson, ~play    , ~win,
              1,  "Friend", 0.50,
              2,  "Foe   ", 7.50,
              2,  "Friend", 2.00,
              1,  "Foe   ", 0.25,
              2,  "Foe   ", 1.50,
              1,  "Friend", 0.00,
              1,  "Foe   ", 4.00,
              2,  "Friend", 1.75,
              1,  "Friend", 2.00,
       )

df1 
## # A tibble: 9 × 3
##   seanson play       win
##     <dbl> <chr>    <dbl>
## 1       1 "Friend"  0.5 
## 2       2 "Foe   "  7.5 
## 3       2 "Friend"  2   
## 4       1 "Foe   "  0.25
## 5       2 "Foe   "  1.5 
## 6       1 "Friend"  0   
## 7       1 "Foe   "  4   
## 8       2 "Friend"  1.75
## 9       1 "Friend"  2
df2 <- 
  tibble::tribble(
~round, ~seanson, ~play   , ~win,
     1,       1,  "Friend", 2.50,
     3,       2,  "Foe   ", 5.50,
     2,       2,  "Friend", 8.00,
     2,       1,  "Foe   ", 0.25,
     3,       2,  "Foe   ", 7.50,
       )

df2
## # A tibble: 5 × 4
##   round seanson play       win
##   <dbl>   <dbl> <chr>    <dbl>
## 1     1       1 "Friend"  2.5 
## 2     3       2 "Foe   "  5.5 
## 3     2       2 "Friend"  8   
## 4     2       1 "Foe   "  0.25
## 5     3       2 "Foe   "  7.5

Khi chúng ta thực hiện lệnh bind_rows() để nối hai bộ dữ liệu với nhau, biến round được điền NA cho những hàng không có thông tin trước đó (ví dụ là bộ dữ liệu đầu tiên):

df_bind <- 
  bind_rows(df1, df2) %>% 
  arrange(seanson, win)

df_bind
## # A tibble: 14 × 4
##    seanson play       win round
##      <dbl> <chr>    <dbl> <dbl>
##  1       1 "Friend"  0       NA
##  2       1 "Foe   "  0.25    NA
##  3       1 "Foe   "  0.25     2
##  4       1 "Friend"  0.5     NA
##  5       1 "Friend"  2       NA
##  6       1 "Friend"  2.5      1
##  7       1 "Foe   "  4       NA
##  8       2 "Foe   "  1.5     NA
##  9       2 "Friend"  1.75    NA
## 10       2 "Friend"  2       NA
## 11       2 "Foe   "  5.5      3
## 12       2 "Foe   "  7.5     NA
## 13       2 "Foe   "  7.5      3
## 14       2 "Friend"  8        2

Trong trường hợp này, round là một biến hữu ích cần để thêm vào bộ số liệu . Do đó, chúng ta sử dụng hàm fill() để điền vào các ô trống đó, bằng cách chỉ định cột và hướng cần điền (trong trường hợp này là hướng từ dưới lên trên):

df_bind %>% 
  fill(round, .direction = "up")
## # A tibble: 14 × 4
##    seanson play       win round
##      <dbl> <chr>    <dbl> <dbl>
##  1       1 "Friend"  0        2
##  2       1 "Foe   "  0.25     2
##  3       1 "Foe   "  0.25     2
##  4       1 "Friend"  0.5      1
##  5       1 "Friend"  2        1
##  6       1 "Friend"  2.5      1
##  7       1 "Foe   "  4        3
##  8       2 "Foe   "  1.5      3
##  9       2 "Friend"  1.75     3
## 10       2 "Friend"  2        3
## 11       2 "Foe   "  5.5      3
## 12       2 "Foe   "  7.5      3
## 13       2 "Foe   "  7.5      3
## 14       2 "Friend"  8        2

Bây giờ chúng ta có một bộ dữ liệu sạch để vẽ biểu đồ:

ggplot(df_bind) +
  aes(round, win, fill = play) +
  geom_col()
## Warning: Removed 9 rows containing missing values (`position_stack()`).

5.2 Mã hóa

Chúng ta sẽ sử dụng một biến có sẵn, tên là for_long1 (số tiền thưởng nhận được) và tạo một biến mới có tên for_num bằng cách phân loại các giá trị trong mỗi hàng của biến có sẵn đó thành một số nhóm khác nhau. Chúng ta sẽ thực hiện việc này bằng hàm case_when() trong package dplyr, hàm này sẽ giúp áp dụng tuần tự các tiêu chí logic (phía bên phải) cho mỗi giá trị của biễn có sẵn và trả về giá trị bên trái tương ứng ở biến mới for_num.

df_long1  <- df_long1 %>% 
  mutate(for_num = case_when(
    df_long1$for_long1 == 'Thua' ~ "0 usd",
    df_long1$for_long1 == 'Thuongtrungbinh' ~ "< 8 usd",
    df_long1$for_long1 == 'Thuongcao' ~ "> 8 usd" ))
table(df_long1$for_num, useNA = "always")
## 
## < 8 usd > 8 usd   0 usd    <NA> 
##     307      15     132       0

Sau đó tạo biểu đồ cột để quan sát

ggplot(data = df_long1)+
    geom_bar(mapping = aes(x = for_num))

Nhận xét:

  • Thông qua dữ liệu mà tôi đã mã hóa để tạo ra biểu đồ cột để xem xét số tiền của người tham gia thắng được. Ta thấy đa số người tham gia sẽ thắng được số tiền nhỏ hơn 8$ và lớn hơn 0$.

  • Phần ít người trong số họ thắng được số tiền được xem là khá cao lớn hơn 8$

  • Số còn lại họ thua và không nhận được mức tiền thưởng nào ccar (0$).

6 Tuần 2

Tương tự ở tuần 1 để có thể thao tác trên một datasets của một packages nào đó thì chúng ta cần gọi gói và datasets có trong gói đó lên.

library(Ecdat)
data(FriendFoe)
ffoe <- FriendFoe

6.1 Thống kê mô tả

6.1.1 Hàm summary , sum

Hàm summary được dừng để tính toán các thông kê mô tả cơ bản của biến. Thông qua hàm này ta sẽ thấy được:

  • Giá trị nhỏ nhất(min) và lớn nhất(max) của dữ liệu được tính

  • Con số trung bình của bộ dữ liệu(mean)

  • Cho biết được con số có xác suất xuất hiẹn nhiều nhất(median)

  • Cho biết tứ phân vị thứ nhất và tứ phân vị thứ 3 của bộ dữ liệu (quantile)

Hàm sum tính tổng giá trị

Tôi sẽ sử dụng hàm này để tính các thống kê cơ bản cho 3 biến cash, win và win1

#Tính thông kê mô tả cho biến số tiền có trong hộp ủy thác(cash) 
summary(ffoe$cash)
##    Min. 1st Qu.  Median    Mean 3rd Qu.    Max. 
##   0.200   1.000   2.500   3.335   5.350  16.400

Nhận xét:

  • Số tiền nhỏ nhất có trong hộp ủy thác là 0.2$, số tiền lớn nhất có trong hộp ủy thác là 16.4$

  • Trung bình số tiền có trong hộp ủy thác là 3.335$

  • Tứ phân vị thứ nhất cho biết có 25% số hộp ủy thác có số tiền là 1$

  • Tứ phân vị thứ 3 cho biết có 75% số hộp ủy thác có số tiền là 5.35$

  • Median = 2.5 cho biết số tiền trong hộp ủy thác xuất hiện nhiều lần nhất ở mức 2.5$

#Tính thông kê mô tả cho biến số tiền thí sinh tham gia thắng được(win)
summary(ffoe$win)
##    Min. 1st Qu.  Median    Mean 3rd Qu.    Max. 
##   0.000   0.000   0.000   1.006   1.350  15.000

Nhận xét:

  • Số tiền nhỏ nhất thí sinh thắng được là 0$, số tiền lớn nhất thí sinh thắng được là 15$

  • Trung bình số tiền thí sinh thắng được là 1.006$

  • Tứ phân vị thứ nhất cho biết có 25% thí sinh thắng được số tiền thưởng là 0$

  • Tứ phân vị thứ ba cho biết có 75% thí ính thắng được số tiền thưởng là 1.35$

  • Median = 0 cho biết đa số thí sinh thắng được 0$ xuất hiện nhiều lần nhất

#Tính thông kê mô tả cho biến số tiền người chơi với vai trò là đối thủ thắng được(win1)
summary(ffoe$win1)
##    Min. 1st Qu.  Median    Mean 3rd Qu.    Max. 
##   0.000   0.000   0.000   1.301   1.800  16.400

Nhận xét:

  • Số tiền thắng nhỏ nhất mà người tham gia với vai trò là đối thủ là 0$, số tiền lớn nhất người tham gia với vai trò là đối thủ thắng được là 16.4$

  • Trung bình số tiền thưởng của người tham gia với vai trò là đối thủ là 1.301$

  • Tứ phân vị thứ nhất cho biết có 25% người tham gia với vai trò là đối thủ thắng được số tiền thưởng là 0$

  • Tứ phân vị thứ ba cho biết có 75% người tham gia với vai trò là đối thủ thắng được số tiền thưởng là 1.8$

  • Median = 0 cho thấy đa số người tham gia với vai trò là đối thủ nhận được số tiền thưởng là 0$ xuất hiện nhiều

#Sử dụng hàm sum tính tổng tiền cho cash, win và win1 
sum(ffoe$cash)
## [1] 757
sum(ffoe$win)
## [1] 228.4
sum(ffoe$win1)
## [1] 295.3
#Tổng giá trị tiền thắng được của thí sinh và đối thủ 
sum(sum(ffoe$win),sum(ffoe$win1))
## [1] 523.7

Nhận xét:

  • Tổng giá trị tiền có trong hộp ủy thác của cả 2 mùa game show “Bạn hay thù” có giá trị lên đến 757$

  • Tổng số tiền thưởng mà thí sinh thắng được của game show trong 2 mùa có giá trị là 228.4$

  • Tổng số tiền thưởng mà người tham gia với vai trò là đối thủ thắng được trong 2 mùa có giá trị là 295.3 $

Từ thông kê cơ bản cho 3 biến cash, win và win1 ta có rút ra một số điều như sau

  • Ta thấy số tiền có trong hộp ủy thác lên đến 16.4$ nhưng chỉ có người tham gia với vai trò là đối thủ có thể lấy được max số tiền đó còn thí sinh tham gia chỉ có thể lấy được số tiền thưởng chưa đạt max là 15$

  • Dù là thí sinh hay đối thủ họ xác suất thắng tiền thưởng của họ rất thấp vì chỉ yếu các median ở 2 biến win và win1 đều là con số 0$

  • Số tiền trung bình mà người tham gia trò chơi “Bạn hay thù” cũng nằm trong mức 1$ - 2$

  • Có sự chênnh lệch lớn về số tiền thắng được và số tiền có trong hộp ủy thác. Tổng là 757$ nhưng cả thí sinh và đối thủ chỉ thắng được 523.7$ cho thấy độ khó của game show này.

6.1.2 Các hàm mean, var, quantile, sd

Các hàm này cũng giống như hàm summary đều dùng để tính thông kê mô tả cho biến

  • mean dùng để tính trung bình

  • var dùng để tính phương sai

  • quantile dùng để tính tứ phân vị

  • sd dùng để tính độ lệch chuẩn

#Tính mean 
mean(ffoe$age)
## [1] 29.35242
#Tính sd 
sd(ffoe$age)
## [1] 7.808495
#Tính var 
var(ffoe$age)
## [1] 60.97259
#Tính quantile
quantile(ffoe$age,0.5 )
## 50% 
##  28

Nhận xét:

  • Độ tuổi trung bình của thí sinh tham gia game show “Bạn hay thù” là 29 tuổi

  • Độ lệch chuẩn (hay khoảng cách) về độ tuổi của thí sinh tham gia game show gần băng 7.5 tuổi

  • 60.97 đại diện cho giá trị kỳ vọng của bình phương độ lệch chuẩn của độ tuổi thí sinh tham gia với độ tuổi trung bình thí sinh tham gia game show

  • Con số 28 cho biết có đến 50% số thí sinh tham gia có độ tuổi là 28 tuổi

6.2 Phân tổ không đều - Bảng tuần suất

6.2.1 Phân tổ không đều - bảng tuần suất

Xét biến tuổi của thí sinh tham gia game show “Bạn hay thù”(age) chia theo từng khoảng mà ta mong muốn

a  <- cut(ffoe$age, 
               breaks=c(18.95,30,50,60),
                  labels= c ("Thanh nien","Trung nien","Lao"))
table(a)
## a
## Thanh nien Trung nien        Lao 
##        134         81          4
prop.table(table(a))
## a
## Thanh nien Trung nien        Lao 
## 0.61187215 0.36986301 0.01826484

Đồ thị

barplot(table(a), main = "Biếu đồ tuổi", col = c( "gray","white","black" ))

Nhận xét:

  • Với độ tuổi thanh niên thì số lượng thí sinh tham gia game show nhiều hơn độ tuổi trung và lão niên có 134 thanh niên đã tham gia chiếm 61.19%

  • Với độ tuổi trung niên thì số lượng tham gia game show có phần nhỉnh hơn so với tuổi thanh niên có 81 thí sinh tham gia chiếm 36.99%

  • Với độ tuổi lão thì thí sinh tham gia game show không nhiều chỉ có 4 thí sinh chiếm 1.83%

Sau khi có được bảng tần suất của biến tuổi thí sinh và chia thành từng khoảng ta lập thêm một bảng tần suất giữa biến play và biến age này để xem xét việc các thí sinh ở độ tuổi khác nhau thì phong cách lựa chọn lối chơi của họ như thế nào?

table(ffoe$play, a)
##         a
##          Thanh nien Trung nien Lao
##   friend         63         42   3
##   foe            71         39   1
#Ở đây ta không cần tính tỷ lệ cho bảng tần suất này vì ta chỉ xem xét các lựa chọn khác nhau giữa các độ tuổi.

Đồ thị

barplot(table(ffoe$play, a),
        main = "Tuổi và cấp đồ trò chơi Friend or Foe",
        xlab = "Tuổi",
        col = c("White","red"))
legend("topleft",
       c("Friend","Foe"),
       fill = c("White","red")) 

Nhận xét:

  • Với độ tuổi thanh niên thì số lượng thí sinh tham gia game show có sự lựa chọn làm kẻ thù hơn là bạn bè để bắt đầu lượt chơi (71/63)

  • Với độ tuổi trung niên thì tỷ số này lại đảo ngược so với dộ tuổi thanh niên người chơi chọn cấp độ bạn bè( nhiều hơn là cấp độ kẻ thù (42/39)

  • Ở người lão thì việc lựa chọn cấp độ bắt đầu lượt chơi cũng giống như người ở độ tuổi trung niên chủ yếu thiên về hướng cấp độ bạn bè hơn là kẻ thù (3/1)

Ta lập thêm một bảng tần suất giữa biến sex1 và biến white1 để xem xét người tham gia với vai trò là đối thủ ở giới tính và màu da khác nhau thì phong cách lựa chọn lối chơi của họ như thế nào?

table(ffoe$sex1, ffoe$white1, ffoe$play1)
## , ,  = friend
## 
##         
##          no yes
##   female  6  39
##   male    7  43
## 
## , ,  = foe
## 
##         
##          no yes
##   female 15  51
##   male    9  57
#Cũng giống như bảng tần suất trên ở đây ta chỉ xét sự lựa chọn nên không cần tính tỷ lệ 

Nhận xét:

  • Với lối chơi là Friend(Bạn bè) thì có 95 người tham gia với vai trò là đối thủ đã lựa chọn. Trong đó có 45 người là nữ (gồm 39 người da trắng chọn cùng với 6 người không phải người da trắng) và 50 người là nam (gồm 43 người da trắng và 7 người không phải là người da trắng).

  • Với lối chơi là Foe(Đối thủ) thì có 132 người tham gia với vai trò là đối thủ đã lựa chọn. Trong đó có 66 người là nữ (gồm 51 người da trắng và 15 người không phải là người da trắng) và có 66 người tham gia là nam (gồm 57 người da trắng và 9 người không phải người da trắng).

  • Ta thấy lối chơi của đa số người tham gia với vai trò là đối thủ họ có xu hướng chọn là “kẻ thù” đích thực. Đa số họ đều là người da trắng (190 người/227 người quan sát).

6.3 Nối dữ liệu

Để có thể chạy được dữ liệu ta cần gọi các packages liên quan lên

pacman::p_load(tidyverse) 

6.3.1 Gắn các hàng

Để thao tác gắn các hàng vào nhau ta tạo ra một data frame mới từ bộ data frame cũ dùng 3 biến: play , cash và win để tạo data frame

Bộ data frame mới này chứa dữ liệu của cấp độ chơi, tổng lượng tiền có trong hộp ủy thác của mỗi cấp độ và số tiền trung bình thí sinh tham gia game show thắng được

play_summary <- ffoe %>% 
  group_by(play) %>% 
  summarise(
    cash = n(),
    win = mean(ffoe$win, na.rm = TRUE))

Sau đó tạo một data frame với thống kê “tổng” (không bị nhóm theo câp độ). Điều này sẽ trả về chỉ một hàng tính tổng số lượng tiền có trong hộp ủy thác của cả 2 cấp độ và tổng số tiền trung bình thí sinh tham gia game show thắng được.

total <- ffoe  %>% 
  summarise(                                    
    cash = n(),                                 
    win  = mean(win, na.rm=T))

Cuối cùng là ta gắn 2 bộ dữ liệu này vào nhau bằng lệnh bind_rows

GH <- bind_rows(play_summary,total)

6.3.2 Gắn các cột

Ta cũng sử dụng gói packages như trên để thực hiện thao tác gắn cột cho dữ liệu bằng cách tạo ra hai data frame mới sao đó gắn chúng vào nhau hoặc ta có thể sử dụng cách đơn giản cho bộ dữ liệu đang có.

Do data gốc của datasets FriendFoe của packages Ecdat đang lấy ra sử dụng có chứa những lượng thông tin gần như giống nhau về mặt phần tử, chúng chỉ khác nhau về mặt tên biến vì vậy ta có thể thay đổi tên biến cho giống nhau bằng lệnh rename() sau đó nối chúng lại với nhau lập nên một data frame mới.

Ví dụ: biến age và age1 các phần tử và ý nghĩa sử dụng nó giống nhau là đều dùng để thu nhập tuổi của người quan sát. Hay các cắp biến : sex - sex1 , white - white1, play - play1, win - win1

Để tranh trường hợp xảy ra sai sót trong quá trình làm bài ta sẽ tạo ra một bản sao của datasets FriendFoe và thao thác trên đó

6.4 Hàm aggregate - Toán tử %>%

6.4.1 Hàm aggregate

Hàm aggregate trả về tổng gộp trong một danh sách hoặc một cơ sở dữ liệu. Hàm aggregate có thể áp dụng các hàm tổng gộp khác nhau cho một danh sách hoặc cơ sở dữ liệu với tùy chọn bỏ qua hoặc ẩn các hàng hoặc giá trị lỗi

#Tính tổng gộp danh sách cho trung bình độ tuổi trung bình của từng nhóm tuổi 
aggregate(ffoe$age,list(a),FUN  = 'mean')
##      Group.1        x
## 1 Thanh nien 24.86567
## 2 Trung nien 36.70370
## 3        Lao 53.50000

Nhận xét:

  • Điều này cho biết tổng hợp một cách nhanh chóng về độ tuổi trung bình tham gia chương tình game show Friend or Foe sau khi đã phân chia theo 3 cấp bậc (thanh niên, trung niên và lão)

  • Bảng cho thấy lần lượt độ tuổi trung bình của thanh niên, trung niên và lão khi tham gia chương trình game show này là xấp xỉ 24.9 tuổi, 36.7 tuổi và 53.5 tuổi.

#Tính tổng gộp danh sách cho tổng số tiền thắng được theo từng giới tính 
aggregate(ffoe$win, list(ffoe$sex), FUN = 'sum')
##   Group.1      x
## 1  female 127.25
## 2    male 101.15

Nhận xét:

  • Cũng giống như trên dòng lệnh này tinh tổng gộp danh sách cho tổng số tiền thắng được theo từng giới tính

  • Với nam thì tổng số tiền thưởng thắng được là 127.25$ và với nữ thì tổng số tiền thắng được là 101.15$

#Tính tổng gộp danh sách cho khoảng cách về số tiền có trong hộp ủy thác theo từng vòng
aggregate(ffoe$cash, list(ffoe$round), FUN = 'sd')
##   Group.1         x
## 1       1 0.8497547
## 2       2 1.8176728
## 3       3 2.6351833
aggregate(ffoe$cash, list(ffoe$round), FUN = 'var')
##   Group.1        x
## 1       1 0.722083
## 2       2 3.303934
## 3       3 6.944191

6.4.2 Toán tử %>%

7 Tuần 1

7.1 Thao tác trên datasets

7.1.1 Gọi dữ liệu

Gọi gói packages Ecdat và bộ dữ liệu FriendFoe nằm trong gói packages này

library(Ecdat)
data(FriendFoe)

Xem cấu trúc dữ liệu của bộ dữ liệu FriendFoe sau đó gán dữ liệu vào biến mới có tên là ffoe

str(FriendFoe )
## 'data.frame':    227 obs. of  13 variables:
##  $ sex   : Factor w/ 2 levels "female","male": 2 2 1 2 1 1 1 2 1 1 ...
##  $ white : Factor w/ 2 levels "no","yes": 2 2 1 2 2 2 2 1 2 2 ...
##  $ age   : int  20 40 35 26 40 28 26 30 30 25 ...
##  $ play  : Factor w/ 2 levels "friend","foe": 2 2 2 1 1 2 1 2 1 1 ...
##  $ round : Factor w/ 3 levels "1","2","3": 1 3 2 1 3 2 1 3 2 1 ...
##  $ season: Factor w/ 2 levels "1","2": 1 1 1 1 1 1 1 1 1 1 ...
##  $ cash  : num  1.2 7.7 3.2 1.2 5.7 3.7 1.2 7.2 3.7 0.7 ...
##  $ sex1  : Factor w/ 2 levels "female","male": 2 1 1 2 2 1 1 2 2 2 ...
##  $ white1: Factor w/ 2 levels "no","yes": 2 2 1 2 2 2 2 1 2 2 ...
##  $ age1  : int  32 31 24 40 26 23 48 27 22 61 ...
##  $ play1 : Factor w/ 2 levels "friend","foe": 1 2 2 1 2 1 1 1 2 1 ...
##  $ win   : num  1.2 0 0 0.6 0 3.7 0.6 7.2 0 0.35 ...
##  $ win1  : num  0 0 0 0.6 5.7 0 0.6 0 3.7 0.35 ...
ffoe <- FriendFoe 

Lấy ra 6 dòng quan sát đầu tiên và cuối của bộ dữ liệu ffoe

head(ffoe)
##      sex white age   play round season cash   sex1 white1 age1  play1 win win1
## 1   male   yes  20    foe     1      1  1.2   male    yes   32 friend 1.2  0.0
## 2   male   yes  40    foe     3      1  7.7 female    yes   31    foe 0.0  0.0
## 3 female    no  35    foe     2      1  3.2 female     no   24    foe 0.0  0.0
## 4   male   yes  26 friend     1      1  1.2   male    yes   40 friend 0.6  0.6
## 5 female   yes  40 friend     3      1  5.7   male    yes   26    foe 0.0  5.7
## 6 female   yes  28    foe     2      1  3.7 female    yes   23 friend 3.7  0.0
tail(ffoe)
##        sex white age   play round season cash   sex1 white1 age1  play1 win
## 222 female   yes  22 friend     1      2  0.2 female    yes   21 friend 0.1
## 223   male   yes  25 friend     3      2  2.5   male    yes   28    foe 0.0
## 224   male    no  25    foe     2      2  4.0 female     no   24    foe 0.0
## 225   male   yes  43 friend     1      2  1.5 female    yes   26    foe 0.0
## 226   male   yes  26    foe     3      2  5.0   male    yes   37    foe 0.0
## 227 female   yes  34    foe     1      2  1.0 female    yes   31    foe 0.0
##     win1
## 222  0.1
## 223  2.5
## 224  0.0
## 225  1.5
## 226  0.0
## 227  0.0

7.1.2 Lọc dữ liệu

Tùy theo yêu cầu của việc tính toán hoặc xem các quan sát có điều kiện ta có lọc dữ liệu từ dữ liệu gốc.

Ở mục này tôi muốn lấy ra một số dữ liệu mà tôi quan tâm ở bộ dữ liệu này

Dữ liệu này là chương trình game show và có 2 mùa đã được tổng hợp

#Lấy ra những thí sinh ở mùa 1 và mùa 2  
ffoem1 <- ffoe[ffoe$season == 1, ]
dim(ffoem1)
## [1] 83 13
ffoem2 <- ffoe[ffoe$season == 2, ]
dim(ffoem2)
## [1] 144  13

Nhận xét: Câu lệnh cho ta biết có 83 người tham gia ở mùa 1 và 144 người tham gia game show “Bạn hay thù”

#Tôi muốn biết người tham gia ở mùa 1 và tham gia với vai trò là thí có độ tuổi là 27 là bao nhiêu người

ffoem1t27 <- ffoe[ffoe$season == 1 & ffoe$age == 27, ]
dim(ffoem1t27)
## [1]  5 13
#Tôi muốn xem có bao nhiêu tham gia ở mùa 2 bị loại ở vòng 2 

ffoem2l2 <- ffoe[ffoe$season == 2 & ffoe$round == 2, ]
dim(ffoem2l2)
## [1] 39 13

Nhận xét:

  • Dòng lệnh 1 cho ta biết có 5 người ở độ tuổi đã tham gia game show vào mùa 2

  • Dòng lệnh 2 cho biết có 39 người đã tham gia game show và họ đã trải qua vòng loại thứ nhất sau đó bị loại ở vòng loại thứ 2 của trò chơi “Bạn hay thù”

7.2 Xử lý dữ liệu

7.2.1 Tính các thống kê cơ bản và lập bảng cho biến age (tuổi của thí sinh)

summary(ffoe$age)
##    Min. 1st Qu.  Median    Mean 3rd Qu.    Max. 
##   18.00   23.50   28.00   29.35   33.00   57.00
table(cut(ffoe$age, breaks = c(18,30,45,57)))
## 
## (18,30] (30,45] (45,57] 
##     134      76       9
prop.table(table(cut(ffoe$age, breaks = c(18,30,45,57))))
## 
##    (18,30]    (30,45]    (45,57] 
## 0.61187215 0.34703196 0.04109589
#Đồ thị 
barplot(table(cut(ffoe$age, breaks = c(18,30,45,57))),
main="Tuổi của thí sinh",
xlab="Age",
ylab=" ",
border="black",
col="blue",
density= 20 
)

Nhận xét:

  • Thí sinh nhỏ tuổi nhất tham gia game show nằm ở tuổi 18 và thí sinh lơn tuổi nhất tham gia game show nằm ỏ tuổi 57

  • Độ tuổi trung bình của thí sinh tham gia game show là khoảng 29 tuổi

  • Tứ phân vị thứ nhất cho biết có khoản 25% thí sinh ở độ tuổi 24 đã tham gia game show

  • Tứ phân vị thứ ba cho biết có khoản 75% thí sinh ở độ tuổi 33 đã tham gia game show

  • Median= 28 cho biết số thí sinh tham gia game show ở độ tuổi 28 chiếm đa số trong tổng số thí sinh tham gia

  • Độ tuổi thí sinh tham gia nhiều nhất nằm trong khoảng từ (18,30] tuổi có 134 thí sinh (chiếm 61,19%), độ tuổi ít thí sinh tham gia nằm trong khoảng từ (45,57] tuổi chỉ có 9 thí sinh tham gia (chiếm 4,11%) và thí sinh ở độ tuổi (30,45] chiếm số còn lại

7.2.2 Tính các thống kê cơ bản và lập bảng cho biến age1 (tuổi của người tham gia với vai trò là đối thủ)

summary(ffoe$age1)
##    Min. 1st Qu.  Median    Mean 3rd Qu.    Max. 
##   18.00   23.00   27.00   28.75   32.00   65.00
table(cut(ffoe$age1, breaks = c(18,30,50,65)))
## 
## (18,30] (30,50] (50,65] 
##     154      70       2
prop.table(table(cut(ffoe$age1, breaks = c(18,30,50,65))))
## 
##     (18,30]     (30,50]     (50,65] 
## 0.681415929 0.309734513 0.008849558
#Đồ thị 
barplot(table(cut(ffoe$age1, breaks = c(18,30,50,65))),
main="Tuổi của người tham gia với vai trò là đối thủ",
xlab="Age",
ylab=" ",
border="black",
col="blue",
density= 20 
)

Nhận xét:

  • Người tham gia với vai trò là đối thủ nhỏ tuổi nhất nằm ở tuổi 18 và người tham gia với vai trò là đối thủ lơn tuổi nhất nằm ỏ tuổi 65

  • Độ tuổi trung bình của người tham gia với vai trò là đối thủ là khoảng 28 tuổi

  • Tứ phân vị thứ nhất cho biết có khoản 25% người tham gia với vai trò là đối thủ ở độ tuổi 24 đã tham gia game show

  • Tứ phân vị thứ ba cho biết có khoản 75% người tham gia với vai trò là đối thủ ở độ tuổi 32 đã tham gia game show

  • Median= 27 cho biết số thí sinh tham gia game show ở độ tuổi 28 chiếm đa số trong tổng số thí sinh tham gia

  • Độ tuổi người tham gia với vai trò là đối thủ nhiều nhất nằm trong khoảng từ (18,30] tuổi có 154 thí sinh (chiếm 68,14%), độ tuổi ít thí sinh tham gia nằm trong khoảng từ (50,65] tuổi chỉ có 9 thí sinh tham gia (chiếm 4,11%) và thí sinh ở độ tuổi (30,50] chiếm số còn lại

7.2.3 Xem số thí sinh tham gia là giới tính nào và có màu da nào bằng 2 biến sex và white

table(ffoe$sex, ffoe$white)
##         
##           no yes
##   female  17 102
##   male    20  88
#Đồ thị 
barplot(table(ffoe$sex, ffoe$white),
main = "Giới tính và màu da của thí sinh",
xlab = "Màu da",
col = c("White","black")
)
legend("topleft",
c("Nữ","Nam"),
fill = c("White","black")
)

Nhận xét:

  • Thí sinh tham gia là giới tính nữ có 119 người trong đó có 17 người không phải là người da trắng và 102 người là người da trắng

  • Thí sinh tham gia là giới tính nam có 108 người trong đó có 20 người không phải là người da trắng và 88 người là người da trắng

  • Tóm lại thí sinh nữ tham gia nhiều hơn thí sinh nam và đa số họ đều là người da trắng

7.2.4 Xem người tham gia với vai trò là đối thủ là giới tính gì và có màu da nào qua 2 biến sex1 và white1

table(ffoe$sex1, ffoe$white1)
##         
##           no yes
##   female  21  90
##   male    16 100
#Đồ thị 
barplot(table(ffoe$sex1, ffoe$white1),
main = "Giới tính và màu da của người tham gia với vai trò là đối thủ",
xlab = "Màu da",
col = c("White","black")
)
legend("topleft",
c("Nữ","Nam"),
fill = c("White","black")
)

Nhận xét:

  • Người tham gia với vai trò là đối thủ là giới tính nữ có 111 người trong đó có 21 người không phải là người da trắng và 90 người là người da trắng

  • Thí sinh tham gia là giới tính nam có 116 người trong đó có 16 người không phải là người da trắng và 100 người là người da trắng

  • Tóm lại người tham gia với vai trò là đối thủ giới tính nam tham gia nhiều hơn người tham gia với vai trò là đối thủ giới tính nữ và đa số họ đều là người da trắng

==> Từ 2 bảng trên ta thấy đa số người tham gia game show dù ở vai trò nào thì đa số họ đều là người da trắng

7.2.5 Tính các thống kê cơ bản cho dữ liệu cash (số tiền trong hộp ủy thác)

summary(ffoe$cash)
##    Min. 1st Qu.  Median    Mean 3rd Qu.    Max. 
##   0.200   1.000   2.500   3.335   5.350  16.400
#Vẽ biểu đồ Histograms cho biến tiền trong hộp ủy thác (cash)
hist(ffoe$cash,
main= "Đôla hộp ủy thác",
xlab=" ",
col="blue")

Nhận xét:

  • Bảng thống kê cho biết số tiền nhỏ nhất có trong hợp ủy thác là 0.2$ và có tiền lớn nhất có trong hộp ủy thác là 16.4$

  • Trung bình trong mỗi hộp ủy thác có số tiền là 3.335$

  • Tứ phân vị thứ nhất cho biết có 25% số hộp ủy thác có số tiền là 1$

  • Tứ phân vị thứ 3 cho biết có 75% số hộp ủy thác có số tiền là 5.35$

  • Median = 2.5 cho biết số tiền trong hộp ủy thác xuất hiện nhiều lần nhất ở mức 2.5$