#Phần I. Lập trình R căn bản
#Bài 1
#1. Vectơ (1, 2, 3, ..., 19, 20)
vec1 <- seq(1, 20)
vec1
##  [1]  1  2  3  4  5  6  7  8  9 10 11 12 13 14 15 16 17 18 19 20
#2 Vectơ (20, 19, ..., 2, 1)
vec2 <- seq(20, 1)
vec2
##  [1] 20 19 18 17 16 15 14 13 12 11 10  9  8  7  6  5  4  3  2  1
#3 Vectơ (1, 2, 3, ..., 19, 20, 19, 18, ..., 2, 1)
vec3 <- c(seq(1, 20), seq(19, 2))
vec3
##  [1]  1  2  3  4  5  6  7  8  9 10 11 12 13 14 15 16 17 18 19 20 19 18 17 16 15
## [26] 14 13 12 11 10  9  8  7  6  5  4  3  2
#4 
#Để tạo ra véc tơ e, có thể sử dụng hàm rep() của R để lặp lại tmp trong e:
tmp <- c(4, 6, 3)
e <- rep(tmp, times = 10)
e
##  [1] 4 6 3 4 6 3 4 6 3 4 6 3 4 6 3 4 6 3 4 6 3 4 6 3 4 6 3 4 6 3
#Để tạo ra véc tơ f, có thể sử dụng hàm rep() kết hợp với c() để thêm số 4 vào cuối véc tơ e:
f <- c(e, 4)
f
##  [1] 4 6 3 4 6 3 4 6 3 4 6 3 4 6 3 4 6 3 4 6 3 4 6 3 4 6 3 4 6 3 4
#Bài 2
set.seed(50)
xVec <- sample(0:999, 250, replace = T)
yVec <- sample(0:999, 250, replace = T)

#(a)
vector_a = yVec[-1] -  xVec[-length(xVec)]
vector_a
##   [1] -359  692 -724   40 -626 -719 -809  527  -89 -829  248  144 -749 -352 -220
##  [16] -249  387 -492   85 -106  303  -97 -436  146  282 -206 -385  -96 -567 -757
##  [31]  287  277 -562  292  -89  -93 -847 -822 -203  679  309 -199 -273    4  -47
##  [46]  142  122  414 -602 -304 -674   -8 -662 -168 -349  -63 -221  115    1 -600
##  [61] -382 -487    2  375   19 -113 -634  107   60   47  214 -325  -49 -290  169
##  [76]  290 -624  457 -408  581 -189  204  -80  409  209 -410  461   37 -127  185
##  [91]  382 -446   44  -56 -270 -598 -378 -155  134 -187  109  316 -139  158  305
## [106]  -39 -119  182  441 -403 -107  615  614 -378 -464   31 -385  665  674 -217
## [121] -279 -406  -45 -489 -350 -451  -18  660  504   -6   60 -130 -379 -302 -219
## [136]  -21  438  129 -201 -275  131  694  -96 -176  117 -113  887 -439 -126 -148
## [151]  392 -158  444 -291  232  -12 -274  477 -510  336 -759 -363 -195 -220  160
## [166] -308 -333  302 -183  227  -12  428  665 -301   -8  222  -50 -444 -425 -650
## [181] -424  318  154  238 -727   71  472  908  265  654 -644 -754  657 -382 -313
## [196]  910 -381  394 -596  602  397 -572  378 -274 -271  601 -791 -378 -461   39
## [211]  163 -118 -332 -170  -94  262 -474  566 -273 -366 -400  374   42  100  135
## [226]  609 -527  580 -219  128 -524  620 -206  410 -280  -66  -50  252  279   48
## [241] -595  -59 -623  247  514   62 -102  475  287
#(b)
vector_b = sin(yVec[-1])/cos(xVec[-length(xVec)])
vector_b
##   [1]   -1.17240581    1.17912119   -1.18405690    0.91383388   -1.03466431
##   [6]   -4.54995011    0.96744602   -0.60165877   -1.45069126    4.77314012
##  [11]   -0.87493498    2.55269394   -1.09592154    0.52599111   -0.58209835
##  [16]    1.00173656   -0.30068981   -1.24434675   -0.87814679   -0.01297143
##  [21]    0.74708907   -0.70304510  -20.16375764    1.01149224   -2.44831431
##  [26]    8.21654493   -0.18713516   -1.28175667   -1.04007889    2.32511346
##  [31]    0.30936979   -0.03142845    0.13852990    1.12311909   -0.35660630
##  [36]    1.05612441    0.61851802    0.99257387   -1.24624168   -3.27973512
##  [41]    0.73776169    0.53909056    0.59126157   -0.24567710   -2.51185638
##  [46]   -5.77079655    1.07157635   -1.08948381    0.99057131   -0.75603199
##  [51]   -0.66765815   -1.18413772   -2.04581314    0.58751132   -3.44748597
##  [56]   -0.83156650    0.79089273    1.21448060   -0.87285882   -2.08273830
##  [61]    0.59939389    0.00000000    0.46058752   -0.93104100   -1.33148856
##  [66]   -0.08985446    1.90152477    9.03582187    0.23197843    0.75447547
##  [71]   -1.72102029    1.30261307    1.26111791   -0.52918358   -0.80400191
##  [76]    3.61432300   -1.28257757   -1.01957014   -0.14326352   -0.13984157
##  [81]    0.93489723   44.45266049    0.84879241    1.03599894    1.06215150
##  [86]   -0.99538657   -0.92525910   -1.85905156   -1.13523700    2.26022833
##  [91]   -1.39414741   -1.08726749    1.28458050  -14.27631579    0.35215314
##  [96]   -0.96324077   -2.12823293    0.62640479    3.85631482   -2.38983690
## [101]    2.49092447   -0.24709327   -0.40883224   13.23192970    1.30040049
## [106]   -1.13666480    1.93685969    0.36331935    1.65634429   -2.27093778
## [111]    7.43403244   -7.83206398   -1.02923436   -1.49722581    1.85128150
## [116]    0.29847442   -0.89926413    0.47955111    1.54938327   73.38987154
## [121]   -4.15756270  -23.34750989   -0.18523880    1.13142145    0.30891204
## [126]    1.31397148    1.36891757   -0.81562375    1.19542291    3.52600513
## [131]    7.07508558    0.76396099  -11.56612997   -2.26901456    0.28463076
## [136]   -1.28088838   -1.15650611   -1.66374145    0.17724777    1.11947959
## [141]   -0.94299568    0.86166639   -0.25703697   -1.68635919   -1.83967514
## [146]    0.33970529    0.18618231    0.48191908    0.49269232 -213.74554174
## [151]   -0.85073887   -3.43286395   -1.77467428   -1.56762066   -0.76146774
## [156]    2.67368530    0.09646823    5.78220626    0.05725002   -0.63768319
## [161]    0.34047746   -0.73599637    0.58628813  -44.97227747   17.14918285
## [166]   -9.83279992   -0.33073449   16.34713189    0.45723708    0.41501918
## [171]    0.89164296    0.63114475   -0.61879787    1.10698992   -2.11758798
## [176]    0.71053046    0.65835495    1.54289030    0.07877718    0.00000000
## [181]    0.73547993   -0.78049129    0.45497512   -3.49933520    0.85415348
## [186]    0.43002471    3.49991856    0.05346361    0.20966456    2.92825394
## [191]    1.59249748    0.09785974    1.87023492    1.59486678   -0.69404053
## [196]   -1.16521258    4.67695014   -3.57474788    1.99444312   -0.84927490
## [201]    1.33276064   -0.59765860    0.18336188    0.26188648   -0.87979353
## [206]   -0.76044135    0.78305929   -0.07755715   -1.27397613    0.70532666
## [211]   -0.47127381    1.41535669    0.55206430   -0.48032852    1.03152656
## [216]   -1.17042534   -1.81759372    0.97200315   -1.65764774   -1.00250214
## [221]    0.35934231   -0.81613658   -1.05241135    0.31508672   -0.40536967
## [226]   -1.36393769    1.10638927    0.66811992    0.58843372    0.81980761
## [231]    0.09380321    0.04082033    0.90521120    1.01526009  -11.85003825
## [236]   -1.31166711    2.70642672    0.52562918   -4.71623127   -0.71718964
## [241]    1.50574675   -0.81741731   -1.72650328    0.83179237   -1.02614926
## [246]   -1.74828942   -1.19748013   -1.03957071   -1.32464191
#(c)
n = length(xVec)
vector_c = xVec[-c(n,(n-1))] + 2*xVec[c(1,n)] - xVec[-c(1,2)]
vector_c
##   [1]  282 1506  691  803  783 2097  841 1061 1169 2476   19  843 1444 1880  671
##  [16] 1303  243 1912 1144 1548  188 1276 1076 1397  885 1801  639 1410 1143 2535
##  [31]  284 1386 1182  992  -31 1499 1298 2245  578  988  659 1607 1241 2100  142
##  [46] 1460  639 1049  572 2406  694 1511  916 1193  778 2187 1434  652  143 2100
##  [61] 1103 1612  607 1097  377 2113  990 1303  898 1534  154 1868 1555 1875   23
##  [76] 1566  729 1725  789 1639  621 1412 1477 1242  418 1839  918 1854  948  996
##  [91]  663 1399  408 1774  195 1448 1328 1636  649 1829  613 1882  660 1479  600
## [106] 1325 1312 1554  564 1983  864 1203  130 1667 1122 2023 1005 1332  436  990
## [121]  769 1723  451 1558 1036 2437 1023  925  576 1949  442 1158  576 2094  962
## [136] 1197  989 1565  860 2204  289 1358 1316  951  670 1644  459 2141  498 1373
## [151]  822 1374  993 1882  199 1706  944 1352  532 1278  861 1744  887 1392  271
## [166] 2341  918 1771  876 1420 1045 1404  312 1207 1222 1475  344 1825  657 1800
## [181] 1227 1758   42 1063 1220 2364  796 1397  445  812 1152 1878   21 2220  932
## [196] 1566  898 1541 1105  868  343 2073  460 1867  787  725  611 1642  939 2119
## [211]  970 1629  981 1850  297 1499  844  858  885 2102  370 1172 1469 2267  247
## [226] 1620  317 1707 1014 1547 1120 1379  528 1667  417 1368  894 1480  460 1175
## [241] 1001 2256  972 1453  383 1777 1395 1006
# (d)
vector_d = sum(exp(-xVec[-1])/xVec[-n]+10)
vector_d
## [1] 2490
#bài 3
#chúng ta có thể sử dụng tính chất của hàm cumprod và hàm seq trong R để tính giá trị của biểu thức đã cho.
#Đầu tiên, ta tạo ra một vector chứa các giá trị từ 2 đến 39 như sau:
x <- seq(2, 39)
#Tiếp theo, ta tạo ra một vector chứa các phân số tương ứng với mỗi phần tử trong vector đó:
fractions <- x / seq(3, 40)
#Sau đó, ta sử dụng hàm cumprod để tính tích phân trên từng phần tử của vector fractions:
y <- cumprod(fractions)
#Cuối cùng, ta thêm 1 và giá trị đầu tiên của vector y và tính tổng của các phần tử trong vector đó:
result <- sum(c(1, y))
result
## [1] 6.557086

#Phần 2 Lập trình hàm trong R #bài 1

myvector <- c(1, 2, 3, 4, 5,6)

#1 .Hàm tính tổng, giá trị trung bình các phần tử của myvector
tong = function(x){
  sum  = 0
  for(i in 1:length(x)) {
    sum  = sum + x[i]
  }
  return(sum)
}

trung_binh = function(x){
  mean  = tong(x)/length(x)
  return(mean)
}


#2 Hàm tính giá trị nhỏ nhất và lớn nhất của myvector:
MIN =function(x){
  min = x[1]
  for(i in 1:length(x)){
    if(min > x[i]){
      min = x[i]
    }
  }
  return(min)
}

MAX  = function(x){
  max = x[1]
  for(i in  1:length(x)){
    if(max < x[i]){
      max = x[i]
    }
  }
  return(max)
}

#3 Hàm tính giá trị phương sai và độ lệch chuẩn của myvector:
phuong_sai = function(x){
  a = (x - trung_binh(x))^2
  sum = 0
  for (i in 1:length(x)) {
    sum  = sum + a[i]
  }
  return(sum/(length(x)-1))
}

tong(x)
## [1] 779
trung_binh(x)
## [1] 20.5
MIN(x)
## [1] 2
MAX(x)
## [1] 39
phuong_sai(x)
## [1] 123.5

#Phần 3 Tính hiệp phương sai #Bài1

#Viết hàm tính hiệp phương sai:
#Viết hàm tính hiệp phương sai:
covariance = function(x,y){
  a  = (x-mean(x))*(y-mean(y))
  sum = 0
  if(length(x)==length(y)){
    for(i in 1:length(x)){
      sum  = sum + a[i]
    }
  }
  return(sum/(length(x)-1))
}
x = c(1,2,3,7,4,6,9,-5)
y = c(2,3,6,7,1,-6,6,2)
covariance(x,y)
## [1] 2.303571
# Tạo dãy các phân số cần tính
frac <- as.numeric(sprintf("2/3%s", paste0(sprintf("%d/%d", seq(4, 39, by = 2), seq(5, 39, by = 2)), collapse = "+")))
## Warning: NAs introduced by coercion
# Tính tổng của dãy phân số
result <- sum(c(1, frac))

# In kết quả
result
## [1] NA

#Phần 4 Trực quan dữ liệu Trực quan hóa dữ liệu Visualization in R Sự cần thiết của trực quan dữ liệu Một số khái niệm về trực quan Có một vấn đề được đặt ra là: Với hàng triệu mẫu DNA và con số ngày nay cùng với hàng triệu ca nhiễm COVID-19 trên toàn thế giới ngày càng gia tăng thì chúng ta cần làm gì để có thể biết được xu hướng, ý nghĩa và cách phân phối của dữ liệu (ứng với từng quốc gia cho các ca nhiễm COVID-19 chẳng hạn). Việc phân tích mối tương quan hoặc xu hướng phân bố của dữ liệu đóng vai trò cực kỳ quan trọng trong nghiên cứu khoa học và đánh giá thống kê.

Người Trung Hoa hay có câu một hình ảnh có giá trị tương đương với một vạn chữ. Quả đúng như vậy, với một “đại dương” số liệu thì việc khai thác hiệu quả “đại dương” này là một vấn đề nan giải. Chúng ta cần phải hiểu rằng, khi có dữ liệu thì việc truyền tải thông tin tới người khác là vô cùng khó khăn. Phải làm thế nào để họ hiểu, họ nắm được xem bộ dữ liệu đó nói về cái gì, miêu tả cái gì và rút ra điều gì từ bộ dữ liệu đó. Chữ viết hoàn toàn có thể sử dụng cho những bộ dữ liệu đơn giản nhưng không thể thực hiện được việc truyền tải nội dung về xu hướng và dao dộng của dữ liệu

Một số biểu đồ trực quan

Hiển thị dữ liệu, mô phỏng dữ liệu hay trực quan dữ liệu (Visualization) nói chung là một bước quan trọng trong tổng thể phân tích dữ liệu. Trước khi phân tích bất kỳ một mô hình nào, việc đầu tiên là chúng ta cần “cảm thụ” được bộ dữ liệu đó, tức là có một cái nhìn khái quát nhất về bộ dữ liệu mà chúng ta đang có. Hiện nay, trong phân tích nghiên cứu khoa học, một số biểu đồ thường được sử dụng, đó là:

1.Biểu đồ tương quan (scatterplot) 2.Biểu đồ phân phối (histogram) 3.Biểu đồ thanh (barchat) 4.Biểu đồ hộp (box plot) Lịch sử hiển thị dữ liệu Biểu đồ có một lịch sử rất thú vị. Trước thể kỷ 18, dữ liệu khoa học thường được trình bày dạng bảng (tables) và đôi khi biểu đồ được coi là vô dụng vì không phản ánh bất kỳ điều gì. Quan điểm này khá là sai lầm, năm 1786, William Playfair (một nhà kinh tế chính trị học) sáng tạo ra biểu đồ tròn (pie chart), biểu đồ thanh (bar chart) và biểu đồ dây (line chart), những cái mà chúng ta vẫn sử dụng cho tới ngày nay. Mãi đến năm 1832, nhà thiên văn học người Anh là Alexander S. Herche sáng chế ra biểu đồ tương quan (scatter plot) và trở thành rất phổ biến trong khoa học thực nghiệm.

Nguyên tắc thiết kế biểu đồ Hãy làm quen với Edward Tufte, vì ông là một guru - bậc thầy về biểu đồ. Ông là giáo sư thống kê học của Đại học Yale, giáo sư chính trị học và giáo sư về khoa học máy tính của đại học Yale, ông là người có ảnh hưởng rất lớn tới lĩnh vực trực quan dữ liệu. Ông là người đã dám thế chấp căn nhà của mình để vay tiền ngân hàng nghiên cứu và cho ra công trình data visualization mà sau này ông không bao giờ phải hối hận. Tờ báo New York Times gọi ông là Leonardo Da Vinci of Data Edward Tufte đặt ra 4 triết lý và nguyên tắc chính trong trình bày dữ liệu bằng biểu đồ. Có thể tóm gọn như sau “Graphical excellence is that which gives to the viewer the greatest number of ideas in the shortest time with the least ink in the smallest space”. Như vậy, khi trình bày dữ liệu bằng biểu đồ phải để ý tới thông tin của 4 khía cạnh: Lượng thông tin, thời gian, lượng mực in và không gian. Từ đó có thể hiểu 4 nguyên tắc chính khi trình bày dữ liệu chính là: Phản ảnh dữ liệu một cách đầy đủ, tối ưu hóa dữ liệu trên mực in, tối ưu hóa mật độ dữ liệu và trình bày dữ liệu chứ không phải trang trí biểu đồ.

Thư viện GGPLOT2 Giới thiệu về ggplot2 Chương trình ggplot2 do tác giả Hadley Wickham phát triển và phổ biến là một thư viện rất có ích cho việc biên soạn biểu đồ với chất lượng cao. Cú pháp của ggplot2 được mô phỏng theo việc chồng lấp các lớp (layers); mỗi lớp sẽ có một chức năng riêng. Tuy nhiên có 3 layers chính, đó là:

Lớp xác định biến số cần trực quan dữ liệu Lớp hình thức thể hiện Lớp trang trí, gán nhãn cho biểu đồ..

Lớp biến số Về định nghĩa biến số, thông thường một biểu đồ thường có 2 biến số chính là x và y . Nếu chúng ta muốn thể hiện mối liên quan giữa giới tính và thu nhập thì thông thường x sẽ là biến giới tính và y là biến thu nhập. Ví dụ dưới đây chỉ ra mối liên hệ giữa thu nhập và tuổi thọ trung bình giữa các quốc gia trong thư viện ggplot2.

Cú pháp của lớp này như sau: p=ggplot(data=gapminder,aes(x=gdpPercap,y=lifeExp))

library(ggplot2)
library(gapminder)
p=ggplot(data=gapminder,aes(x=gdpPercap,y=lifeExp))
p + geom_point(aes(color = continent))

Hình thức thể hiện: Hình thức thể hiện của biến x và y thể hiện qua argument có tên là geom(), trong đó có một số loại phổ biến sau:

geom_point(): Biểu đồ tương quan geom_box(): Biểu đồ hộp geom_histogram(): Biểu đồ phân bố geom_line(): Biểu đồ dây geom_text(): Biểu đồ chữ viết geom_smooth(): Chọn đường biểu diễn làm mịn dữ liệu geom_jitter(): Tạo sàng rung, hiển thị dữ liệu, fix lỗi overplotting geom_hline(): Đường biểu diễn nằm ngang geom_vline(): Đường biểu diễn thẳng đứng Trang trí biểu đồ Tiêu đề của biểu đồ

ggtitle(“tên biểu đồ”) + theme(plot.title = element_text(line.height = 0.8, face = “bold”, hjust = 0.5))

Nhãn và trục tung, trục hoành

labs(x=“Tiêu đề trục x”, y = “Tiêu đề trục y”)

Màu và kích thước của nhãn trục tung và hoành

theme(axis.title.x = element_text(color = “blue, size = 14, face =”bold“), axis.title.y = element_text(color =”blue, size = 14, face =“bold”))

Khoảng cách giá trị của trục tung và trục hoành

scale_x_continuous(name=“…”, limits =c(min, max)) + scale_y_continuous(name=“…”, limits = c(min,max)) Một trong những lợi thế của ggplot2 là cho phép người sử dụng hoán chuyển dữ liệu ngày trong phần arguments của hàm ggplot. Chúng ta có thể hoán chuyển đơn vị của trục tung (thu nhập) sang đơn vị log:

library(ggplot2)
library(gapminder)
p1 = ggplot(data=gapminder,aes(x=gdpPercap,y=lifeExp)) + geom_point(aes(color = continent)) 
p1 <- p1 + scale_x_log10() + geom_smooth(method="loess")
p1
## `geom_smooth()` using formula = 'y ~ x'

geom_smooth() using formula ‘y ~ x’

Thực hành ggplot2 Để áp dụng cách sử dụng thư viện ggplot2, chúng ta sử dụng bộ dữ liệu có tên là gapminder, vẽ biểu đồ tương quan giữa 2 biến là tuổi thọ trung bình và thu nhập bình quân. Xem qua về dữ liệu

mydata <- gapminder
head(gapminder)
## # A tibble: 6 × 6
##   country     continent  year lifeExp      pop gdpPercap
##   <fct>       <fct>     <int>   <dbl>    <int>     <dbl>
## 1 Afghanistan Asia       1952    28.8  8425333      779.
## 2 Afghanistan Asia       1957    30.3  9240934      821.
## 3 Afghanistan Asia       1962    32.0 10267083      853.
## 4 Afghanistan Asia       1967    34.0 11537966      836.
## 5 Afghanistan Asia       1972    36.1 13079460      740.
## 6 Afghanistan Asia       1977    38.4 14880372      786.
str(gapminder)
## tibble [1,704 × 6] (S3: tbl_df/tbl/data.frame)
##  $ country  : Factor w/ 142 levels "Afghanistan",..: 1 1 1 1 1 1 1 1 1 1 ...
##  $ continent: Factor w/ 5 levels "Africa","Americas",..: 3 3 3 3 3 3 3 3 3 3 ...
##  $ year     : int [1:1704] 1952 1957 1962 1967 1972 1977 1982 1987 1992 1997 ...
##  $ lifeExp  : num [1:1704] 28.8 30.3 32 34 36.1 ...
##  $ pop      : int [1:1704] 8425333 9240934 10267083 11537966 13079460 14880372 12881816 13867957 16317921 22227415 ...
##  $ gdpPercap: num [1:1704] 779 821 853 836 740 ...

Chúng ta bắt đầu trực quan dữ liệu

p2 <- ggplot(data = mydata, mapping = aes(x = gdpPercap, y = lifeExp)) p2 + geom_point() -> p2

Thêm một đường biểu diễn tương quan tuyến tính

p2 + geom_smooth(method = “loess”) -> p2

Tuy nhiên, quá nhiều điểm dữ liệu cùng màu, rất khó phân biệt, trực quan theo biến lục địa

ggplot(data = mydata, mapping = aes(x = gdpPercap, y = lifeExp)) + geom_point(aes(color = continent)) +
  geom_smooth(method = "loess")
## `geom_smooth()` using formula = 'y ~ x'

Chuyển sang đơn vị log() cho dễ nhìn

ggplot(data = mydata, mapping = aes(x = gdpPercap, y = lifeExp)) + geom_point(aes(color = continent)) +
  geom_smooth(method = "loess") +
  scale_x_log10()
## `geom_smooth()` using formula = 'y ~ x'

geom_smooth() using formula ‘y ~ x’

Gán thêm các nhãn cho biểu đồ

ggplot(data = mydata, mapping = aes(x = gdpPercap, y = lifeExp)) + geom_point(aes(color = continent)) +
  geom_smooth(method = "loess") +
  scale_x_log10() +
  labs(x =" Log GDP per Capita", y = "Life Expectancy") +
  ggtitle("Association between GDP Per Capita and Life Expectancy") + theme(plot.title = element_text(lineheight = 0.8, face = "bold", hjust = 0.5))
## `geom_smooth()` using formula = 'y ~ x'

Thay đổi theo phong cách màu của tạp chí “The Economist” như sau:

library(ggthemes)
ggplot(data = mydata, mapping = aes(x = gdpPercap, y = lifeExp)) + geom_point(aes(color = continent)) +
  geom_smooth(method = "loess") +
  scale_x_log10() +
  labs(x =" Log GDP per Capita", y = "Life Expectancy") +
  ggtitle("Association between GDP Per Capita and Life Expectancy") + theme(plot.title = element_text(lineheight = 0.8, face = "bold", hjust = 0.5)) + theme_economist()
## `geom_smooth()` using formula = 'y ~ x'

geom_smooth() using formula ‘y ~ x’

Một số biểu đồ phổ biến khác sử dụng ggplot2 Biểu đồ histogram Đây còn được gọi là biểu đồ phân bố, sử dụng rất hữu ích khi thể hiện sự phân bố của một biến số liên tục nào đó. Trong bộ dữ liệu gapminder, thì biến gdpPercap là một biến số liên tục ngẫu nhiên, chúng ta thử vẽ biểu đồ histogram cho biến số này vào năm 2007. Sử dụng lệnh subset() đã học để bóc tách dữ liệu cho năm 2007

library(ggplot2)
library(gapminder)
year2007 <- subset(mydata, year == 2007)
head(year2007)
## # A tibble: 6 × 6
##   country     continent  year lifeExp      pop gdpPercap
##   <fct>       <fct>     <int>   <dbl>    <int>     <dbl>
## 1 Afghanistan Asia       2007    43.8 31889923      975.
## 2 Albania     Europe     2007    76.4  3600523     5937.
## 3 Algeria     Africa     2007    72.3 33333216     6223.
## 4 Angola      Africa     2007    42.7 12420476     4797.
## 5 Argentina   Americas   2007    75.3 40301927    12779.
## 6 Australia   Oceania    2007    81.2 20434176    34435.
ggplot(data = year2007, mapping = aes(gdpPercap)) +
  geom_histogram(fill = "lightblue", color = "white") +
  labs(title = "Distribution of GDP per Capita in 2007")
## `stat_bin()` using `bins = 30`. Pick better value with `binwidth`.

Nếu chúng ta không muốn trục Oy là count mà muốn là xác suất (tần suất xuất hiện)

ggplot(data = year2007, mapping = aes(gdpPercap)) +
  geom_histogram(aes(y = ..density..), fill = "lightblue", color = "white")
## Warning: The dot-dot notation (`..density..`) was deprecated in ggplot2 3.4.0.
## ℹ Please use `after_stat(density)` instead.
## `stat_bin()` using `bins = 30`. Pick better value with `binwidth`.

## stat_bin() using bins = 30. Pick better value with binwidth.

Nếu chúng ta quan tâm phân phối theo từng lục địa

ggplot(data = year2007, mapping = aes(gdpPercap, fill = continent)) +
  geom_density(alpha = 0.4)

Biểu đồ thanh Barplot Biểu đồ này thường được dùng để biểu thị tần số xuất hiện của 1 hay nhiều hơn 1 biến liên tục. Ví dụ: Chúng ta muốn tìm hiểu số quốc gia trong mỗi lục địa là bao nhiêu, sử dụng dữ liệu gapminder cho năm 2007.

dim(year2007)
## [1] 142   6
ggplot(data = year2007, mapping = aes(x = continent, fill = continent)) +
  geom_bar() + theme(legend.position = "none")

Ngoài ra biểu đồ barplot còn thể hiện được sự liên quan giữa hai biến số thông qua kiểu (stacked bar plot), biểu đồ thanh chồng lên nhau. Ví dụ tuổi của các quốc gia có thể phân thành các nhóm sau đây:

Nhóm 1: Gồm các quốc gia có tuổi thọ dưới 60 Nhóm 2: Gồm các quốc gia có tuổi thọ lớn hơn 60 và nhỏ hơn 80 Nhóm 3: Gồm các quốc gia có tuổi thọ trên 80 Sử dụng toán tử điều kiện [] để tạo ra một biến mới tên là level_age có tính thứ bậc

year2007$level_age[year2007$lifeExp < 60.0] <- "< 60 age"
## Warning: Unknown or uninitialised column: `level_age`.
year2007$level_age[60.0 <= year2007$lifeExp & year2007$lifeExp <= 80.0] <- "60-80 age"
year2007$level_age[year2007$lifeExp > 80.0] <- "> 80 age"
ggplot(data = year2007, aes(x = continent, fill = level_age)) +
  geom_bar()

Biểu đồ Barplot cũng có thể miêu tả một biến liên tục như sau. Ví dụ: Chúng ta muốn thể hiện tuổi thọ trung bình của mỗi quốc gia thuộc Châu Á (Asian). Trước tiên cần lọc các quốc gia có lục địa là Asian:

library(ggplot2)
asia <- subset(mydata, year == 2007 & continent == "Asia")
dim(asia)
## [1] 33  6

Như vậy ở Châu Á có 33 quốc gia. Trực quan dữ liệu

ggplot(data = asia, mapping = aes(x = country, y = lifeExp, fill = country)) + geom_bar(stat = "identity", width = 0.9)

Tuy nhiên giao diện rất khó nhìn và bị chồng lên nhau ở trục Ox, chúng ta đảo ngược

ggplot(data = asia, mapping = aes(x = country, y = lifeExp, fill = country)) + geom_bar(stat = "identity", width = 0.9) + coord_flip()

Biểu đồ này rất khó so sánh, chúng ta nên sắp xếp lại theo trật tự

ggplot(data = asia, mapping = aes(x = reorder(country, lifeExp), y = lifeExp, fill = country)) + geom_bar(stat = "identity", width = 0.9) + coord_flip() + theme(legend.position = "none") + labs(x="", y="Life Expectancy") -> graph1

Ngoài ra chúng ta có thể trình bày nhiều biểu đồ trên cùng một hình, sử dụng gói gridExtra, biểu diễn hai đồ thị thanh cho tuổi thọ và thu nhập bình quân đầu người

library(ggplot2)
library(gridExtra)
ggplot(data = asia, mapping = aes(x = reorder(country, gdpPercap), y = gdpPercap, fill = country)) + geom_bar(stat = "identity", width = 0.9) + coord_flip() + theme(legend.position = "none") + labs(x="", y="GDP Per Capita") -> graph2
grid.arrange(graph1, graph2, ncol = 2)

Biểu đồ hộp (Boxplot) Giới thiệu về biểu đồ hộp Biểu đồ hộp trong tiếng Anh là Box Plot hay Box and Whisker plot, là một loại biểu đồ thể hiện các khuôn hình của dữ liệu định tính (quantitative data). Biểu đồ hộp do John Tukey sáng tạo ra năm 1977. Biểu đồ hộp (Box plot) hay còn gọi là biểu đồ hộp và râu (Box and whisker plot) là biểu đồ diễn tả 5 vị trí phân bố của dữ liệu, đó là: - Giá trị nhỏ nhất (min) - Giá trị tứ phân vị thứ nhất (Q1) - Giá trị trung vị (median) - Giá trị tứ phân vị thứ 3 (Q3) - Giá trị lớn nhất (max)

John Tukey : “Đặt câu hỏi đúng quan trọng hơn ngàn lần tìm câu trả lời đúng cho một câu hỏi sai.”

Đặc trưng của biểu đồ hộp Số phân tử hay còn gọi là tứ phân vị (Quartiles): Tứ phân vị là đại lượng mô tả sự phân bố và sự phân tán của tập dữ liệu. Số phân tử có 3 giá trị, đó là số phân tử thứ nhất (Q1), thứ nhì (Q2) và thứ ba (Q3). Ba giá trị này chia một tập hợp dữ liệu (đã sắp xếp dữ liệu theo trật từ bé đến lớn) thành 4 phần có số lượng quan sát đều nhau.

Tứ phân vị được xác định như sau:

Sắp xếp các số theo thứ tự tăng dần

Cắt dãy số thành 4 phần bằng nhau

Tứ phân vị là các giá trị tại vị trí cắt

Khoảng biến thiên số phân tử (Interquartile Range - IQR) IQR được xác định như sau:

Biểu đồ boxplot còn thể hiện 2 đại lượng phổ biến khi nói về độ rộng của một tập dữ liệu:

Khoảng dữ liệu (range): Nếu bạn quan tâm đến độ rộng của tất cả dữ liệu thì, đó đơn giản là khoảng cách giữa giá trị lớn nhất và giá trị nhỏ nhất trong tập dữ liệu. Còn nếu bạn muốn loại trừ các giá trị ngoại lai, thì đó là khoảng cách giữa 2 đầu ria mép! Khoảng liên phần tư (IQR): là nửa giữa của tập dữ liệu nằm giữa 2 điểm Q3 và Q1. Trong biểu đồ trên, IQR là khoảng 7 – 3 = 4 Và cuối cùng, biểu đồ boxplots còn cung cấp thông tin cho chúng ta về hình dạng của tập dữ liệu:

Đây là 3 hình dạng chủ yếu về độ lệch. Nếu đường trung vị chia chiếc hộp thành 2 nửa đều nhau, thì tập dữ liệu này đối xứng (symmetric). Nếu nửa phải lớn hơn (nửa trái) thì tập dữ liệu bị lệch phải (right-skewed), và ngược lại, nếu nửa trái lớn hơn thì tập dữ liệu bị lệch trái (left-skewed).

Ví dụ Boxplot và cách đọc Dưới đây mô tả sử dụng biểu đồ hộp để phân tích, nhận biết vấn đề. Ví dụ: Với số liệu thu thập được về tỉ lệ làm lại (Rework Ratio) trong quá trình sản xuất, (có xmin = 0,0; Q1 = 14,9; x = 19,0; x = 15,8; Q3 = 20,6; xmax =23,2) ta có biểu đồ hộp với hình dáng biểu đồ như sau:

Trung bình tỉ lệ làm lại là 15,8%, trung vị là 19%. Dữ liệu có xu hướng nghiêng nhiều về phía trên giá trị trung bình:

Khoảng số phân tử = Q3 - Q1 = 20,6 - 14,9 = 5,7

Khoảng cách giữa giá trị lớn nhất và nhỏ nhất là 23,2 - 0 = 23,2. Nhìn chung, tỉ lệ làm lại cao và quá trình có sự dao động lớn, không ổn định, kiểm soát chất lượng kém. Tuy nhiên, biểu đồ hộp giúp nhìn trực quan hơn khi so sánh 3 giai đoạn hoặc khu vực khác nhau như hình dưới đây:

Nhận xét:

 Với ba lần thu thập dữ liệu về tỉ lệ làm lại vào thời điểm tháng 11/2011, tháng 3/2012 và tháng 6/2012, dữ liệu vào thời điểm tháng 11/2011 cho thấy quá trình kiểm soát lỗi kém vì xu hướng tập trung của dữ liệu (trung vị) ở mức cao, độ dao động lớn.

 Kiểm soát chất lượng vào thời điểm tháng 3/2012 là tốt nhất vì dữ liệu về tỉ lệ làm lại tập trung ở mức thấp, dao động ở phạm vi hẹp.
 

Áp dụng vào dữ liệu Giả sử chúng ta muốn tóm tắt thu nhập bình quân năm 2007 của 142 quốc gia bằng biểu đồ hộp

ggplot(data = year2007, aes(x = continent, y = gdpPercap, fill = continent)) + geom_boxplot(alpha = 0.6)

ggplot(data = year2007, aes(x = continent, y = gdpPercap, fill = continent)) + geom_boxplot(alpha = 0.6) + geom_jitter(alpha = 0.3)