Họ và tên: LƯU THỊ KIM HẠNH

MSSV: 2121011603

1 Tuần 7: Scrape dữ liệu, tìm hiểu World bank và xử lý công việc của mình

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

Indicators trong WordBank là các chỉ số hoặc dấu hiệu được sử dụng để đánh giá hoặc đo lường một khía cạnh nào đó. Các indicators của WordBank thường được sử dụng để đánh giá và theo dõi các vấn đề liên quan đến kinh tế, phát triển, giáo dục, sức khỏe, môi trường, và nhiều lĩnh vực khác.

Đầu tiên, ta phải cài các gói dữ liệu “WDI” VÀ “Wbstats” sau:

install.packages(“WDI”)

install.packages(“wbstats”)

library(WDI)
library(wbstats)

Sau đó, sử dụng hàm WDIsearch() để tìm kiếm các chỉ số có sẵn trong cơ sở dữ liệu World Bank.

1.1.1 Indicators về “Economy”

ECO<- WDIsearch("Economy")

CC.EG.INTS.KW là mã số của chỉ số năng lượng tiêu thụ nội địa (kWh) ở Cộng hòa Congo. Nó viết tắt của “Climate Change - Ecosystem Goods and Services - Integrated Natural and Technological Solutions - Knowledge”. Đây là một khái niệm liên quan đến các giải pháp kết hợp giữa các hệ thống tự nhiên và công nghệ để giải quyết vấn đề biến đổi khí hậu.

eco1 <- WDI(indicator = "CC.EG.INTS.KW")
eco1 <- na.omit(eco1)
datatable(eco1)

TX.VAL.MRCH.RS.ZS là chỉ số Merchandise exports (current US$) - Xuất khẩu hàng hoá (USD hiện tại) đo lường giá trị hàng hoá mà một quốc gia xuất khẩu trong một năm. Chỉ số này cho biết mức độ phát triển và hiệu suất của một quốc gia, do đó càng cao thì quốc gia đó càng phát triển và hiệu suất xuất khẩu của nó càng tốt.

eco2 <- WDI(indicator = "TX.VAL.MRCH.RS.ZS")
eco2 <- na.omit(eco2)
datatable(eco2)

1.1.2 Indicators về “Education”

EDU <- WDIsearch("Education")

3.3_PRI.TEACHERS là chỉ số trong lĩnh vực giáo dục, nó thường được sử dụng để chỉ số lượng giáo viên hiện tại trong một quốc gia, khu vực hay tổ chức giáo dục cụ thể. Số liệu này thường được sử dụng để đánh giá khả năng cung cấp giáo dục và chất lượng giáo viên trong hệ thống giáo dục.

edu1 <- WDI(indicator = "3.3_PRI.TEACHERS")
edu1 <- na.omit(edu1)
datatable(edu1)

3.4_PRI.NEW.TEACHERS là chỉ số liên quan đến 3.3_PRI.TEACHERS, nó thường được sử dụng để chỉ số lượng giáo viên mới được tuyển dụng trong một khoảng thời gian cụ thể. Số liệu này thường được sử dụng để đánh giá khả năng nâng cao số lượng giáo viên và đáp ứng nhu cầu giáo dục trong tương lai.

edu2 <- WDI(indicator = "3.4_PRI.NEW.TEACHERS")
edu2 <- na.omit(edu2)
datatable(edu2)

1.1.3 Indicators về “Energy”

ENE <- WDIsearch("Energy")

CC.CO2.EMSE.EN là chỉ số Carbon dioxide emissions (metric tons per capita) - Khí thải carbon dioxide (tấn metan trên một dân số) là một chỉ số quan trọng để đo lường lượng khí thải carbon dioxide mà một quốc gia sản xuất ra trên mỗi người dân trong quốc gia đó. Chỉ số này giúp đánh giá mức độ gây ô nhiễm môi trường của một quốc gia và cung cấp thông tin về mức độ tiêu thụ năng lượng dựa trên nguồn năng lượng hóa thạch.

ene1 <- WDI(indicator ="CC.CO2.EMSE.EN")
ene1 <- na.omit(ene1)
datatable(ene1)

CC.ENTX.ENE.ZS là chỉ số Energy use (kg of oil equivalent per capita) - Tiêu thụ năng lượng (kg tương đương dầu mỗi người dân) đo lường lượng năng lượng mà một quốc gia tiêu thụ trên mỗi người dân trong quốc gia đó. Chỉ số này cho biết mức độ sử dụng năng lượng của một quốc gia và giúp so sánh mức độ tiêu thụ năng lượng giữa các quốc gia khác nhau.

ene2 <- WDI(indicator = "CC.ENTX.ENE.ZS")
ene2 <- na.omit(ene2)
datatable(ene2)

1.1.4 Indicators về “Environment”

ENV <- WDIsearch("Environment")

CC.ENV.GDS.CADV: Đây là viết tắt của “Climate Change - Environmental Goods and Services - Current Account and Domestic Value Added”. Đây là một chỉ số liên quan đến thương mại hàng hóa và dịch vụ môi trường liên quan đến biến đổi khí hậu. Nó đo lường giá trị thương mại hàng hóa và dịch vụ môi trường được sản xuất trong một quốc gia và được xuất khẩu hoặc tiêu thụ trong nước.

env1 <- WDI(indicator = "CC.ENV.GDS.CADV")
env1 <- na.omit(env1)
datatable(env1)

FC.XPD.ENVR.CR: Đây là viết tắt của “Foreign currency expenditure on environmental protection”. Đây là một chỉ số liên quan đến chi tiêu của một quốc gia trong việc bảo vệ môi trường bằng tiền ngoại tệ. Nó đo lường số tiền mà một quốc gia chi tiêu cho các hoạt động bảo vệ môi trường sử dụng tiền ngoại tệ.

env2 <- WDI(indicator = "FC.XPD.ENVR.CR")
env2 <- na.omit(env2)
datatable(env2)

1.1.5 Indicators về “Gender”

GEN <- WDIsearch("Gender")

BI.WAG.PREM.PB.FM.ED là viết tắt của “Business Intelligence (BI) - Wage Premium (WAG) - Premium Pay (PREM) - Payroll and Benefits (PB) - Financial Management (FM) - Employee Development (ED)”. Đây là một khái niệm trong lĩnh vực quản trị doanh nghiệp, liên quan đến việc sử dụng công nghệ thông tin và dữ liệu để tối ưu hóa quản lý nhân sự, tài chính và phát triển nhân viên trong một tổ chức.

gen1 <- WDI(indicator = "BI.WAG.PREM.PB.FM.ED")
gen1 <- na.omit(gen1)
datatable(gen1)

BI.WAG.PRVS.ED.FM là viết tắt của “Business Intelligence (BI) - Wage Premium (WAG) - Payroll and Benefits (PRVS) - Employee Development (ED) - Financial Management (FM)”. Đây cũng là một khái niệm liên quan đến quản trị doanh nghiệp, tập trung vào việc sử dụng thông tin kinh doanh, quản lý tiền lương và phúc lợi, phát triển nhân viên và quản lý tài chính để đạt được hiệu quả cao trong hoạt động kinh doanh của một tổ chức.

gen2 <- WDI(indicator = "BI.WAG.PRVS.ED.FM")
gen2 <- na.omit(gen2)
datatable(gen2)

1.2 Crape dữ liệu

1.2.1 Giới thiệu dữ liệu

Địa chỉ link: https://www.investing.com/indices/hnx-historical-data

Chứng khoán Việt Nam là thị trường tài chính nổi tiếng và phát triển nhanh chóng trong khu vực Đông Nam Á. Trang web Investing.com cung cấp thông tin chi tiết về thị trường chứng khoán Việt Nam, bao gồm các chỉ số chính, danh sách các công ty niêm yết, tin tức và dữ liệu thống kê. Trên trang chứng khoán Việt Nam của Investing.com, tôi có thể tìm hiểu về chỉ số chính như VN-Index, VN30 hay HNX-Index. Và tôi cũng có thể xem thông tin chi tiết về các công ty niêm yết trên sàn HOSE (Sở Giao dịch Chứng khoán TP.HCM) và HNX (Sở Giao dịch Chứng khoán Hà Nội). Ngoài ra, Investing.com cũng cung cấp tin tức thị trường chứng khoán Việt Nam, bao gồm các bài viết phân tích, dự báo về xu hướng thị trường và những sự kiện quan trọng ảnh hưởng đến thị trường chứng khoán Việt Nam.

Trang web cung cấp dữ liệu thống kê về giá cổ phiếu, biểu đồ phân tích kỹ thuật, bảng giá niêm yết và nhiều công cụ hữu ích khác. Trang web còn cung cấp dữ liệu thống kê về giá cổ phiếu để tôi có thể theo dõi và phân tích hiệu quả. Bên cạnh đó, biểu đồ phân tích kỹ thuật giúp tôi đánh giá xu hướng, mức độ biến động và các điểm mua/bán tiềm năng. Bảng giá niêm yết cung cấp thông tin về giá cổ phiếu hiện tại, khối lượng giao dịch và các chỉ số thị trường.

1.2.2 Xử lý dữ liệu

Để crape dữ liệu và tạo báo cáo trong R, tôi phải cài đặt các thư viện sau:

install.package(“rvest”)

library(rvest)
library(tidyverse)
library(dplyr)
library(DT)

Tôi chọn phân tích HNX 30. Trong đó, HNX 30 là chỉ số chứng khoán của sàn giao dịch Hà Nội (HNX) ở Việt Nam. Chỉ số này được tính dựa trên giá trị thị trường và khối lượng giao dịch của 30 công ty có vốn hóa thị trường lớn nhất trên sàn HNX. Nó thường được sử dụng để đo lường sự biến động của thị trường chứng khoán Hà Nội và đưa ra một cái nhìn tổng quan về tình hình kinh tế và tài chính của Việt Nam.

url <- "https://www.investing.com/indices/hnx-historical-data"
html <- read_html(url)
hnx <- html %>% html_table()

Quan sát các biến số của tập dữ liệu cổ phiếu AAPL, dữ liệu này là một tập dữ liệu chuỗi thời gian, gồm 6 biến số mô tả:

  • Open - Giá mở cửa của phiên giao dịch.

  • High - Là giá cao nhất trong một phiên phiên giao dịch hoặc trong một chu kỳ theo dõi biến động giá.

  • Low - Là giá thấp nhất trong một phiên phiên giao dịch hoặc trong một chu kỳ theo dõi biến động giá.

  • Price - Giá đóng cửa là giá thực hiện tại lần khớp lệnh cuối cùng trong ngày giao dịch.

  • Vol. - Khối lượng giao dịch.

  • Change % - Giá đóng cửa hiệu chỉnh

1.2.3 Bài toán kiểm định

1.2.3.1 Kiểm định phân phối chuẩn: Jarque-Bera

Kiểm định phân phối chuẩn Jarque-Bera (Jarque-Bera Normality Test) là một phương pháp thống kê được sử dụng để kiểm tra xem một tập dữ liệu có tuân theo phân phối chuẩn hay không. Phương pháp này dựa trên hai thống kê mô tả, đó là hệ số bất đối xứng (skewness) và hệ số nhọn (kurtosis), để đánh giá tính chuẩn của phân phối dữ liệu.

Kiểm định phân phối chuẩn Jarque-Bera kiểm tra xem giá trị hệ số bất đối xứng và hệ số nhọn của dữ liệu có phù hợp với phân phối chuẩn hay không. Nếu giá trị p-value của kiểm định nhỏ hơn một ngưỡng ý nghĩa (thường là 0.05), chúng ta có căn cứ để bác bỏ giả thuyết rằng dữ liệu không tuân theo phân phối chuẩn.

Bài toán kiểm định:

H0: Chuỗi giá đóng (giá cuối cùng) không phân theo phân phối chuẩn

H1: Chuỗi giá đóng (giá cuối cùng) có phân theo phân phối chuẩn

library(tseries)
Price <- hnx$Price
PPC <- jarque.bera.test(Price)
print (PPC)
## 
##  Jarque Bera Test
## 
## data:  Price
## X-squared = 1.1181, df = 2, p-value = 0.5718

Vì p-value = 0.5718 > α=0.05 nên chưa đủ cơ sổ để bác bỏ H0. vậy chuỗi giá đóng không phân theo phân phối chuẩn.

1.2.3.2 Kiểm định tính dừng: Augmented dickey - fuller

Kiểm định tính dừng Augmented Dickey-Fuller là một phương pháp thống kê được sử dụng để kiểm tra xem một chuỗi dữ liệu có tính dừng hay không. Tính dừng là tính chất mà một chuỗi dữ liệu không thay đổi theo thời gian và có thể được mô hình hóa bằng một quá trình ngẫu nhiên ổn định.

Phương pháp ADF mở rộng kiểm định Dickey-Fuller thông thường bằng cách bổ sung thêm các tham số tự phương sai và sai số cho mô hình autoregressive. Kiểm định Augmented Dickey-Fuller kiểm tra xem có một hệ số tự hồi quy (autoregressive coefficient) trong mô hình autoregressive có giá trị bằng 1 hay không. Nếu giá trị hệ số tự hồi quy bằng 1, đồng nghĩa với việc chuỗi dữ liệu không có tính dừng.

Kết quả của kiểm định Augmented Dickey-Fuller bao gồm giá trị tới hạn (test statistic), giá trị p-value và giả thuyết thay thế (alternative hypothesis).

Bài toán kiểm định:

H0: Chuỗi giá đóng (giá cuối cùng) có tính dừng

H1: Chuỗi giá đóng (giá cuối cùng) có tính dừng

adf.test(Price)
## 
##  Augmented Dickey-Fuller Test
## 
## data:  Price
## Dickey-Fuller = -1.9337, Lag order = 2, p-value = 0.5976
## alternative hypothesis: stationary

Với kết quả này, vì giá trị p-value = 0.5976 lớn hơn mức ý nghĩa thông thường nên chưa đủ cơ sở bác bỏ giả thuyết HO. Vậy chuỗi giá đóng không có tính dừng

1.2.3.3 Kiểm định tương quan chuỗi : Ljung-box

Kiểm định tương quan chuỗi Ljung-Box (Ljung-Box test) là một phương pháp thống kê được sử dụng để kiểm tra tính độc lập tương quan trong chuỗi dữ liệu. Phương pháp này dựa trên việc kiểm tra giả thuyết rằng không có tương quan giữa các giá trị trong chuỗi dữ liệu.

Kiểm định Ljung-Box thực hiện kiểm tra xem các giá trị trong chuỗi dữ liệu có liên quan tới nhau hay không, dựa trên giả thuyết không có tương quan. Kỹ thuật này sử dụng một số lượng thời gian trễ (lag) để xác định mức độ tương quan.

Bài toán kiểm định:

H0: Chuỗi giá đóng (giá cuối cùng) không có sự tương quan

H1: Chuỗi giá đóng (giá cuối cùng) có sự tương quan

Box.test(Price, lag = 10, type = "Ljung-Box")
## 
##  Box-Ljung test
## 
## data:  Price
## X-squared = 36.784, df = 10, p-value = 6.166e-05

Với kết quả này, vì giá trị p-value = 6.166e-05 < α=0.05, ta có căn cứ để bác bỏ giả thuyết H0. Điều này cho thấy rằng có sự tương quan đáng kể giữa các giá trị trong chuỗi giá đóng.

1.2.4 Lập bảng tần số và vẽ biểu đồ

1.2.4.1 Lập bảng tần số cho biến “Price” và biến “High”

# Lập bảng tần số và vẽ biểu đồ cho biến “Price” và biến "High"
t1 <- table(hnx$Price, hnx$High)
head(t1,3)
##         
##          225.82 228 228.09 228.35 228.78 228.79 229.02 230.12 230.23 230.54
##   225.08      0   0      1      0      0      0      0      0      0      0
##   225.82      1   0      0      0      0      0      0      0      0      0
##   226.52      0   0      0      0      0      0      1      0      0      0
##         
##          230.55 230.6 231.53 231.69 231.77 231.91 232 232.09 233.3 233.39
##   225.08      0     0      0      0      0      0   0      0     0      0
##   225.82      0     0      0      0      0      0   0      0     0      0
##   226.52      0     0      0      0      0      0   0      0     0      0
#Tính % cho bảng tần số trên
t11 <- prop.table(table(hnx$Price, hnx$High))
head(t11,3)
##         
##              225.82        228     228.09     228.35     228.78     228.79
##   225.08 0.00000000 0.00000000 0.04761905 0.00000000 0.00000000 0.00000000
##   225.82 0.04761905 0.00000000 0.00000000 0.00000000 0.00000000 0.00000000
##   226.52 0.00000000 0.00000000 0.00000000 0.00000000 0.00000000 0.00000000
##         
##              229.02     230.12     230.23     230.54     230.55      230.6
##   225.08 0.00000000 0.00000000 0.00000000 0.00000000 0.00000000 0.00000000
##   225.82 0.00000000 0.00000000 0.00000000 0.00000000 0.00000000 0.00000000
##   226.52 0.04761905 0.00000000 0.00000000 0.00000000 0.00000000 0.00000000
##         
##              231.53     231.69     231.77     231.91        232     232.09
##   225.08 0.00000000 0.00000000 0.00000000 0.00000000 0.00000000 0.00000000
##   225.82 0.00000000 0.00000000 0.00000000 0.00000000 0.00000000 0.00000000
##   226.52 0.00000000 0.00000000 0.00000000 0.00000000 0.00000000 0.00000000
##         
##               233.3     233.39
##   225.08 0.00000000 0.00000000
##   225.82 0.00000000 0.00000000
##   226.52 0.00000000 0.00000000

Giải thích kết quả:

  • Hàng dọc là giá trị cho biến “Price”

  • Hàng ngang là giá trị cho biến “High”

1.2.4.2 Vẽ biểu đồ cột cho biến “Price” và biến “High”__

ggplot(hnx, aes(Price,High)) + geom_point(color = 'blue', size = 1/4) + geom_line(color = 'red')

Quan sát biểu đồ ta kết luận rằng: Biến Price và biến High tỉ lệ thuận với nhau tức khi giá phiên giao dịch đạt ở mức cao nhất (high) thì giá đóng cuối cùng (price) sẽ ảnh hưởng theo (cao nhưng thấp hơn hoặc bằng mức giá cao nhất).

Kết hợp đường hồi quy tuyến tính

ggplot(data=hnx, aes(x=Price, y=High))+ 
  geom_smooth(formula = y~x, method = 'lm', color = 'red')+
  geom_point()+
  labs(title = 'Đồ thị so sánh giữa biến Price và biến High', x= 'Giá cuối cùng phiên giao dịch', y ='Giá cao nhất của phiên giao dịch')

Phân tích biểu đồ trên:

  • Tuyến tính: Biểu đồ trên là dữ liệu dạng tuyến tính / đường thẳng.

  • Bờ dốc: Hướng thay đổi của giá đóng cửa theo mức giá cao nhất. Biểu đồ cho thấy, giá cuối cùng cao khi mức giá cao nhất ngày càng cao ta dễ dang thấy được biểu đồ này dốc dương.

  • Độ tập trung : Mức độ dàn trải của các điểm phân tán trong biểu đồ. Ta thấy rằng, các điểm phân tán rộng, mối quan hệ sẽ là yếu

1.2.5 Một số cách vễ biểu đồ, đồ thị khác

1.2.5.1 Đồ thị biến price và biến open

library(ggplot2)
library(dplyr)
library(TTR)
Price <- hnx$Price
Open <- hnx$Open
plot(Price, Open)

Từ biểu đồ trên, ta có nhận xét như sau:

  • So sánh hai chuỗi giá (price) và giá mở (open) ta có thấy rằng giữa 2 chuỗi giá có mối quan hệ tỉ lệ thuận với nhau tức là khi giá mở tăng thì giá đóng tăng theo
  • Điểm chung giữa hai chuỗi giá là sự tăng (giảm) tùy theo thời gian

1.2.5.2 Biểu đồ Histogram

hist(Price)

Với tần suất từ 0 đến 6 thì chỉ số giá đóng (close) tăng cao nhất ở tần suất = 4 và thấp nhất ở tần suất = 2 tính theo đơn vị tiền tệ là đô la

1.2.5.3 Đồ thị phân phối xác xuất bằng hàm plot(density)

plot(density(Price), add= TRUE)

Giải thích đồ thị:

  • N=21: Chuỗi giá đóng được lấy trong vòng 21 ngày gần nhất
  • Bandwidth = 0.9919: Tốc độ truyền là 0.9919 bit/s

Nhận xét:

  • Đồ thị phân phối cao nhất ở mức giá 230 USD
  • Đồ thị phân phối thấp nhất ở mức giá nhỏ hơn 222 và lớn hơn 234 tính theo USD

1.2.5.4 Biểu đồ tròn

pie(table(cut(Price,5)))

Biểu đồ chuỗi giá đóng được phân chia thành 5 nhóm như sau:

  • Màu trắng là nhóm giá trị từ khoảng 225 đến bằng 226

  • Màu xanh lam là nhóm giá trị từ khoảng 226 đến bằng 228

  • Màu hồng là nhóm giá trị từ khoảng 228 đến bằng 229

  • Màu xanh mint là nhóm giá trị từ khoảng 229 đến bằng 231

  • Màu tím là nhóm giá trị từ khoảng 231 đến bằng 232

1.3 Viết function giải quyết 1 công việc

Tôi muốn viết 1 function làm thuật toán thống kê cho dữ liệu scrape ở trên với các phép tính sau:

  • sum: tính tổng các giá trị

  • Sd: độ lệch chuẩn

  • mean: giá trị trung bình

  • median: trung vị

  • var: phương sai

  • quantiles: Giá trị phân vị khi 25%, 50% và 75%

tk <- function(x){
  my_hnx <- hnx[,c(0,1,2,3,4,5,6)]
  my_hnx <- data.frame(sapply(my_hnx, as.numeric))
  dstk <- list(
    sum <- sum(x),
    sd <- sd(x, na.rm = T),
    mean <- mean(x, na.rm = T),
    median <- median(x, na.rm = T),
    var <- var(x),
    quantiles <- quantile(x, probs = c(0.25, 0.5, 0.75), na.rm = T),
    min <- min(x, na.rm = T),
    max <- max(x, na.rm = T)
  )
  list(sum=sum, sd=sd, mean=mean, median=median,var=var, quantiles=quantiles, min=min, max=max)
}

Kiểm tra kết quả tổng quát sau khi viết function:

# Test function
tk(hnx$Price)
## $sum
## [1] 4809.07
## 
## $sd
## [1] 2.026138
## 
## $mean
## [1] 229.0033
## 
## $median
## [1] 228.88
## 
## $var
## [1] 4.105233
## 
## $quantiles
##    25%    50%    75% 
## 227.48 228.88 230.82 
## 
## $min
## [1] 225.08
## 
## $max
## [1] 231.91

2 TUẦN 4+5+6: Tổng hợp tất cả bài

2.1 Giới thiệu dataset

Dataset “Affairs” là dữ liệu đánh giá các yếu tố liên quan cho việc xem xét mức độ ngoại tình trong hôn nhân là như thế nào. Đây là dữ liệu chéo từ một cuộc khảo sát được thực hiện bởi các nhà Tâm lý học vào năm 1969

Định dạng: Dữ liệu chứa 601 quan sát và trên 9 biến:

  • affairs: Tần suất quan hệ tình dục ngoài hôn nhân
  • gender: giới tính.
  • age: số tuổi
  • yearsmarried: số năm kết hôn
  • children: Có bao nhiêu đứa con trong cuộc hôn nhân?
  • religiousness: niềm tin về tôn giáo của người được khảo sát
  • education: Trình độ học vấn
  • occupation: Nghề nghiệp theo phân loại Hollingshead (đánh số đảo ngược).
  • rating: tự đánh giá mức độ hạnh phúc trong hôn nhân

2.2 Các thao tác cơ bản

2.2.1 Cài đặt thư viện và tạo bản sao

Trước khi tôi phân tích dataset “Affairs” thì phải cài đặt thư viện “AER” bằng lệnh: install.package(“AER”)

Tương tự khi cài các thư viện kháckhác Sau đó, gọi tên dataset mà tôi muốn phân tích

library(AER)
library(DT)
library(tidyverse)
library(dplyr)
library(magrittr)
data("Affairs")
h <- Affairs

2.2.2 Trình chiếu dữ liệu

# Hiển thị dữ liệu thu thập được
fix(h)
# Xem cấu trúc dữ liệu của các biến trong dừ liệu 
str(h)
## 'data.frame':    601 obs. of  9 variables:
##  $ affairs      : num  0 0 0 0 0 0 0 0 0 0 ...
##  $ gender       : Factor w/ 2 levels "female","male": 2 1 1 2 2 1 1 2 1 2 ...
##  $ age          : num  37 27 32 57 22 32 22 57 32 22 ...
##  $ yearsmarried : num  10 4 15 15 0.75 1.5 0.75 15 15 1.5 ...
##  $ children     : Factor w/ 2 levels "no","yes": 1 1 2 2 1 1 1 2 2 1 ...
##  $ religiousness: num  3 4 1 5 2 2 2 2 4 4 ...
##  $ education    : num  18 14 12 18 17 17 12 14 16 14 ...
##  $ occupation   : num  7 6 1 6 6 5 1 4 1 4 ...
##  $ rating       : num  4 4 4 5 3 5 3 4 2 5 ...
# Hiển thị 6 dữ liệu đầu tiên của tập dữ liệu
head(h)
##    affairs gender age yearsmarried children religiousness education occupation
## 4        0   male  37        10.00       no             3        18          7
## 5        0 female  27         4.00       no             4        14          6
## 11       0 female  32        15.00      yes             1        12          1
## 16       0   male  57        15.00      yes             5        18          6
## 23       0   male  22         0.75       no             2        17          6
## 29       0 female  32         1.50       no             2        17          5
##    rating
## 4       4
## 5       4
## 11      4
## 16      5
## 23      3
## 29      5
# Hiển thị 6 dừ liệu gần nhất của tập dữ liệu
tail(h)
##      affairs gender age yearsmarried children religiousness education
## 1935       7   male  47         15.0      yes             3        16
## 1938       1   male  22          1.5      yes             1        12
## 1941       7 female  32         10.0      yes             2        18
## 1954       2   male  32         10.0      yes             2        17
## 1959       2   male  22          7.0      yes             3        18
## 9010       1 female  32         15.0      yes             3        14
##      occupation rating
## 1935          4      2
## 1938          2      5
## 1941          5      4
## 1954          6      5
## 1959          6      2
## 9010          1      5
# Hiển thị dữ liệu bảng
datatable(h)

2.3 Các thuật toán được áp dụng vào

2.3.0.1 Trung bình

mean(h$rating)
## [1] 3.93178
#Tính trung bình theo giới tính
aggregate(h$rating, list(h$gender), FUN = "mean") 
##   Group.1        x
## 1  female 3.939683
## 2    male 3.923077

Đánh giá mức độ hạnh phúc trung bình của các khảo sát là 3.93178.

Đánh giá mức độ hạnh phúc trung bình của các khảo sát theo giới tính nữ là 3.939683

Đánh giá mức độ hạnh phúc trung bình của các khảo sát theo giới tính nam là 3.923077

2.3.0.2 Trung vị

median(h$rating, na.rm = FALSE)
## [1] 4

2.3.0.3 Độ lệch chuẩn

sd(h$rating)
## [1] 1.103179

2.3.0.4 Phương sai

var(h$rating)
## [1] 1.217005

2.3.0.5 Tính tổng

sum(h$rating)
## [1] 2363

2.3.0.6 Thống kê dữ liệu

summary(h$rating)
##    Min. 1st Qu.  Median    Mean 3rd Qu.    Max. 
##   1.000   3.000   4.000   3.932   5.000   5.000

2.4 Sử dụng một số câu lệnh và hàm

2.4.1 Nhân tử pipe trong R

Nhân tử pipe kí hiệu là %>% (tổ hợp tắt trong window là ctr+shift+M) là một trong những phương thức giúp cách triển khai code trở nên gọn gàng hơn. Nhân tử pipe là một thuộc tính trong package magrittr của Stefan Milton và được phát triển theo đề xuất của Tal Galili. Ý tưởng của nhân tử pipe là triển khai thuật toán từ trong ra ngoài, trong đó kết quả của phép toán trước làm input cho phép toán sau

#1. Tao dataframe
hf <- data.frame(a=c(0,1,2,3,4),b=c(5,6,7,8,9))
#2. Attach dataframe để truy cập các biến mà không cần tên bảng
attach(hf)

2.4.1.1 Sử dụng nhân tử pipe với các hàm thống kê summarize, group_by

Trong thống kê và tổng hợp dữ liệu với R, nhân tử pipe thường được sử dụng kết hợp với các hàm summary, group_by sẽ giúp cho các tính toán trở nên đơn giản và ngắn gọn hơn. Chẳng hạn chúng ta muốn thống kê theo nhóm những chủng loại với kích cỡ trung bình trong bảng iris ta làm như sau

# Thông kê theo giới tính
h %>% subset(rating = 4) %>% 
  group_by(gender) %>% 
  summarise(Tuoi = mean(age), TrinhDoHocVan = mean(education))
## Warning: In subset.data.frame(., rating = 4) :
##  extra argument 'rating' will be disregarded
## # A tibble: 2 × 3
##   gender  Tuoi TrinhDoHocVan
##   <fct>  <dbl>         <dbl>
## 1 female  30.8          15.3
## 2 male    34.3          17.2

Để sử dụng được các hàm group_by và summarize thì phải import package dplyr.

  • Hàm group_by sẽ qui định các trường để định danh dữ liệu hay còn gọi là dimension.

  • Hàm summarise sẽ tính toán các chỉ tiêu từ các trường có tính chất đo lường (chẳng hạn như tổng, trung bình, min, max) hay còn gọi là measurement. Kết quả trả về là bảng tổng hợp các chỉ tiêu theo từng giới tính (gender). Trong ví dụ trên ta sử dụng hàm subset để lọc theo điều kiện của dataframe là chỉ lấy những mẫu có rating =4 (Người khảo sat cho rằng họ hạnh phúc trong hân nhân của họ). Giải thích kết quả theo điều kiện trên:

  • Với nữ, độ tuổi trung bình là 31 và trình độ học vấn trung bình là 15.25714 (tốt nghiệp đại học)

  • Với nam, độ tuổi trung bình là 34 và trình độ học vấn trung bình là 17.16783 (Thạc sĩ)

2.4.1.2 Nhân tử pipe overwrite:

Nhân tử pipe overwrite có tính chất như nhân tử pipe nhưng cho phép ghi đè lên dữ liệu gốc ban đầu. Vì thể kí hiệu của nó là sự kết hợp của nhân tử pipe thông thường %>% và phép gán <- thành kí hiệu %<>%

#1. Lấy danh sách theo giới tính
h %>% distinct(gender)
##   gender
## 4   male
## 5 female
#2. Sử dụng nhân tử pipe overwite để ghi đè lên dữ liệu Affairs(h) ban đầu
h %<>% subset(gender %>% equals("male"))
#3. Lấy danh sách theo giới tính sau khi ghi đè lên Affairs (h), hiện tại Affairs sẽ chỉ còn "male" (nam)
h %>% distinct(gender)
##   gender
## 4   male

Hàm subset có công thức và chức năng tương tự như filter tuy nhiên subset là một function trong base nên không cần phải load package. Cú pháp của subset:

subset(data.frame, điều kiện)

2.4.2 Hàm các hàm điều kiện với dataframe

Trong xử lý các bảng dữ liệu lớn chúng ta có thể chỉ quan tâm đến một phần nhỏ dữ liệu thay vì quan tâm đến toàn bộ bảng dữ liệu. Vì thể các hàm điều kiện để lọc bảng rất thường xuyên được sử dụng chẳng hạn như if, ifelse, filter, subset

Xử lý dữ liệu không cần hàm:

Đây là cách xử lý dữ liệu cơ bản nhất dành cho những bạn mới bắt đầu làm quen với R. Chúng ta sẽ không phải thông qua một hàm nào để xử lý dữ liệu. Cú pháp như sau:

dataframe[điều kiện lọc, vị trí các cột]

Trong đó điều kiện lọc luôn để ở đầu, sau điều kiện lọc là danh sách các cột

#1. Chỉ lấy giới tính nam
subh <- h[h$gender=="male",]
#2. Kiểm tra các trường của subh
head(subh)
##    affairs gender age yearsmarried children religiousness education occupation
## 4        0   male  37        10.00       no             3        18          7
## 16       0   male  57        15.00      yes             5        18          6
## 23       0   male  22         0.75       no             2        17          6
## 45       0   male  57        15.00      yes             2        14          4
## 49       0   male  22         1.50       no             4        14          4
## 50       0   male  37        15.00      yes             2        20          7
##    rating
## 4       4
## 16      5
## 23      3
## 45      4
## 49      5
## 50      2
#4. Nếu chỉ muốn lấy một số cột nhất định thì truyền vào vị trí cột sau điều kiện
head(h[h$gender=="male",1:3])
##    affairs gender age
## 4        0   male  37
## 16       0   male  57
## 23       0   male  22
## 45       0   male  57
## 49       0   male  22
## 50       0   male  37

Trường hợp có từ 2 điều kiện trở lên thì sử dụng các hàm logic như and , or và các nhân tử logic & , | để truy xuất dữ liệu.

#1. Lấy những dữ liệu là giới tính nam và có age > 27
subh <- h[and(h$gender=="male", h$age > 27),]

#2. Min và max của biến age
min(subh$age)
## [1] 32
max(subh$age)
## [1] 57

2.4.3 Biến đổi dữ liệu nhanh với mutate

Trong quá trình phân tích dữ liệu sẽ có thể phát sinh việc chúng ta muốn tạo thêm những biến mới - phát sinh từ những biến sẵn có trong dữ liệu. Trong bài viết này, ta sử dụng hàm mutate() và nhóm hàm mutate_if(), mutate_at(), mutate_all() để thêm 1 hoặc nhiều biến vào tập dữ liệu.

# Summary dữ liệu
Affairs %>% summary
##     affairs          gender         age         yearsmarried    children 
##  Min.   : 0.000   female:315   Min.   :17.50   Min.   : 0.125   no :171  
##  1st Qu.: 0.000   male  :286   1st Qu.:27.00   1st Qu.: 4.000   yes:430  
##  Median : 0.000                Median :32.00   Median : 7.000            
##  Mean   : 1.456                Mean   :32.49   Mean   : 8.178            
##  3rd Qu.: 0.000                3rd Qu.:37.00   3rd Qu.:15.000            
##  Max.   :12.000                Max.   :57.00   Max.   :15.000            
##  religiousness     education       occupation        rating     
##  Min.   :1.000   Min.   : 9.00   Min.   :1.000   Min.   :1.000  
##  1st Qu.:2.000   1st Qu.:14.00   1st Qu.:3.000   1st Qu.:3.000  
##  Median :3.000   Median :16.00   Median :5.000   Median :4.000  
##  Mean   :3.116   Mean   :16.17   Mean   :4.195   Mean   :3.932  
##  3rd Qu.:4.000   3rd Qu.:18.00   3rd Qu.:6.000   3rd Qu.:5.000  
##  Max.   :5.000   Max.   :20.00   Max.   :7.000   Max.   :5.000
# 6 quan sát đầu tiên của tập dữ liệu
Affairs %>% head
##    affairs gender age yearsmarried children religiousness education occupation
## 4        0   male  37        10.00       no             3        18          7
## 5        0 female  27         4.00       no             4        14          6
## 11       0 female  32        15.00      yes             1        12          1
## 16       0   male  57        15.00      yes             5        18          6
## 23       0   male  22         0.75       no             2        17          6
## 29       0 female  32         1.50       no             2        17          5
##    rating
## 4       4
## 5       4
## 11      4
## 16      5
## 23      3
## 29      5

2.4.3.1 Hàm mutate().

Để tạo thêm 1 biến mới trong tập dữ liệu, chúng ta sử dụng hàm mutate().

data <- Affairs %>% 
  # Thêm biến mới rating_new theo điều kiện sau:
  mutate(rating_new = case_when(
    rating < 5 ~ "thấp",
    rating >= 5 & rating <= 6 ~ "trung bình",
    TRUE ~ "cao"
  ) %>% as.factor)

# 6 quan sát đầu tiên của tập dữ liệu sau khi thêm 1 biến mới
data %>% head
##    affairs gender age yearsmarried children religiousness education occupation
## 4        0   male  37        10.00       no             3        18          7
## 5        0 female  27         4.00       no             4        14          6
## 11       0 female  32        15.00      yes             1        12          1
## 16       0   male  57        15.00      yes             5        18          6
## 23       0   male  22         0.75       no             2        17          6
## 29       0 female  32         1.50       no             2        17          5
##    rating rating_new
## 4       4       thấp
## 5       4       thấp
## 11      4       thấp
## 16      5 trung bình
## 23      3       thấp
## 29      5 trung bình

Kết quả nhận được là cột biên mới tên rating_new được phân loại cao - trung bình - thấp

Đến lúc này, câu hỏi đặt ra là: Làm thế nào để thêm nhiều biến cùng 1 lúc?

Câu trả lời là: Sử dùng nhóm hàm

  • mutate_all(): áp dụng đối với tất cả các biến trong tập dữ liệu

  • mutate_at(): chỉ áp dụng đối với những biến nhất định mà chúng ta chỉ định

  • mutate_if(): chỉ áp dụng đối với những biến thỏa mãn những điều kiện mà chúng ta đã đặt ra

2.4.3.2 Hàm mutate_all()

Giả sử, chúng ta muốn thêm các biến mới (đơn vị: aa) -> dùng hàm mutate_all()

Affairs %>% 
  # Bỏ biến Children vì chỉ có thể áp dụng đối với những biến định lượng
  select(-children) %>% 
  # Thêm những biến mới = những biến cũ nhân thêm 10 (tên biến lấy từ biến cũ thêm đuôi "_aa")
  mutate_all(funs(aa = . * 10)) %>% 
  head
##    affairs gender age yearsmarried religiousness education occupation rating
## 4        0   male  37        10.00             3        18          7      4
## 5        0 female  27         4.00             4        14          6      4
## 11       0 female  32        15.00             1        12          1      4
## 16       0   male  57        15.00             5        18          6      5
## 23       0   male  22         0.75             2        17          6      3
## 29       0 female  32         1.50             2        17          5      5
##    affairs_aa gender_aa age_aa yearsmarried_aa religiousness_aa education_aa
## 4           0        NA    370           100.0               30          180
## 5           0        NA    270            40.0               40          140
## 11          0        NA    320           150.0               10          120
## 16          0        NA    570           150.0               50          180
## 23          0        NA    220             7.5               20          170
## 29          0        NA    320            15.0               20          170
##    occupation_aa rating_aa
## 4             70        40
## 5             60        40
## 11            10        40
## 16            60        50
## 23            60        30
## 29            50        50

Các biến mới của tất cả biến định lượng được nhân thêm 10 khi dùng lệnh funs()

2.4.3.3 Hàm mutate_if()

Trong trường hợp này, chúng ta cũng có thể dùng cách khác để chỉ áp dụng đối với những biến số (numeric) bằng việc sử dụng hàm mutate_if().

Affairs %>% 
  mutate_if(is.numeric,        # Lọc điều kiện: Chỉ áp dụng đối với những biến numeric
            funs(aa = . * 10)  # Các biến numeric sẽ nhân với 10 để lấy đơn vị mm
            ) %>% 
  head
##    affairs gender age yearsmarried children religiousness education occupation
## 4        0   male  37        10.00       no             3        18          7
## 5        0 female  27         4.00       no             4        14          6
## 11       0 female  32        15.00      yes             1        12          1
## 16       0   male  57        15.00      yes             5        18          6
## 23       0   male  22         0.75       no             2        17          6
## 29       0 female  32         1.50       no             2        17          5
##    rating affairs_aa age_aa yearsmarried_aa religiousness_aa education_aa
## 4       4          0    370           100.0               30          180
## 5       4          0    270            40.0               40          140
## 11      4          0    320           150.0               10          120
## 16      5          0    570           150.0               50          180
## 23      3          0    220             7.5               20          170
## 29      5          0    320            15.0               20          170
##    occupation_aa rating_aa
## 4             70        40
## 5             60        40
## 11            10        40
## 16            60        50
## 23            60        30
## 29            50        50

2.4.3.4 Hàm mutate_at()

Nếu chúng ta chỉ muốn thêm những biến mà phát sinh từ biến rating và religiousness thôi, thì có thể dùng hàm mutate_at()

Affairs %>% mutate_at(c("rating", "religiousness"), # Tạo thêm những biến mới phái sinh từ những biến này
funs(aa = . * 10)           
) %>% 
head
##    affairs gender age yearsmarried children religiousness education occupation
## 4        0   male  37        10.00       no             3        18          7
## 5        0 female  27         4.00       no             4        14          6
## 11       0 female  32        15.00      yes             1        12          1
## 16       0   male  57        15.00      yes             5        18          6
## 23       0   male  22         0.75       no             2        17          6
## 29       0 female  32         1.50       no             2        17          5
##    rating rating_aa religiousness_aa
## 4       4        40               30
## 5       4        40               40
## 11      4        40               10
## 16      5        50               50
## 23      3        30               20
## 29      5        50               20

Như vậy, chúng ta đã vừa được học cách thêm nhiều biến cùng 1 lúc bằng việc sử dụng nhóm hàm mutate_if(), mutate_at(), mutate_all() trong dataset Affairs

2.4.4 Sử dụng Pivot

2.4.4.1 PPivot_longer()

Hàm pivot_longer() từ gói tidyr trong R có thể được sử dụng để xoay khung dữ liệu từ định dạng rộng sang định dạng dài.

h1 <- h |> pivot_longer(cols = starts_with('r'), names_to = 'DANHGIA', values_to = 'rank')

Việc chuyển đổi dữ liệu có tên bắt đầu là chữ “r” được xếp hạng chuyển đổi từ định dạng rộng sang định dạng dài bằng pivot_longer() để chúng ta phân tích chi tiết hơn.

# Từ dữ liệu trên, dữ liệu nào không thuộc "na" sẽ bị loại bỏ 
h2 <- h |> pivot_longer(cols = starts_with('r'), names_to = 'DANHGIA', values_to = 'rank',values_drop_na = T) 

Tất cả các giá trị bắt đầu bằng chữ “r” nếu không thuộc điều kiện values_drop_na sẽ bị loại bỏ

2.4.4.2 Pivot_wider()

Tạo một bảng dữ liệu mới gồm các biến AGE, EDUCATION, GENDER từ dataset Affairs.

Dùng hàm ” pivot wider” để chuyển đổi dữ liệu từ định dạng dài sang định dạng rộng

hh <- h |> select(age, education, gender) |> pivot_wider(names_from = age, values_from = c(education, gender))

Dữ liệu được tạo ra từ ba biến “age”, “education”, “gender”. Trong đó, biến “age” lấy làm cột mốc chính để biến “education” và biến “gender” sẽ được phân theo biến “age”.

2.5 Lập bảng tần số và vẽ biểu đồ

2.5.1 Lập bảng tần số và vẽ biểu đồ cho biến “rating”

2.5.1.1 Lập bảng tần số

# Lập bảng tần số theo biến "education"
table(h$gender)
## 
## female   male 
##    315    286
#Tính % cho bảng tần số trên
prop.table(table(h$gender))
## 
##    female      male 
## 0.5241265 0.4758735

Dựa vào bảng tần số, giới tính của người được khảo sát là:

  • Giới tính nữ có 315 người chiếm 52.4%
  • Giới tính nam có 286 người chiếm 47.6%

2.5.1.2 Vẽ biểu đồ cột cho biến “gender”

h %>% ggplot(aes(x = gender, y = after_stat(count))) + geom_bar(fill = 'darkgreen')+ geom_text(aes(label = scales::percent(after_stat(count/sum(count)))), stat = 'count', color = 'red', vjust = -0.5) + theme_classic() + labs(x = 'Giới tính', y = 'số người ')

2.5.2 Lập bảng tần số và vẽ biểu đồ cho biến “rating” và biến “gender”

2.5.2.1 Lập bảng tần số

# Lập bảng tần số 2 biến "rating" và "gender"
table(h$rating, h$gender)
##    
##     female male
##   1     11    5
##   2     35   31
##   3     46   47
##   4     93  101
##   5    130  102
#Tính % cho bảng tần số trên
prop.table(table(h$rating, h$gender))
##    
##          female        male
##   1 0.018302829 0.008319468
##   2 0.058236273 0.051580699
##   3 0.076539101 0.078202995
##   4 0.154742097 0.168053245
##   5 0.216306156 0.169717138

Dựa vào bảng tần số giữa hai biến rating và gender ta có kết luận như sau:

Đối với nữ:

  • Họ hoàn toàn không hạnh phúc có 11 người chiếm 1.83%
  • Họ không hạnh phúc có 35 người chiếm 5.82%
  • Họ trung lập (bình thường) có 46 người chiếm 7.65%
  • Họ hạnh phúc có 93 người chiếm 15.47%
  • Họ hoàn toàn hạnh phúc có 130 người chiếm xấp xỉ 21.63%

Đối với nam:

  • Họ hoàn toàn không hạnh phúc có 5 người chiếm 0.83%
  • Họ không hạnh phúc có 31 người chiếm 5.16%
  • Họ trung lập (bình thường) có 47 người chiếm 7.82%
  • Họ hạnh phúc có 101 người chiếm 16.81%
  • Họ hoàn toàn hạnh phúc có 102 người chiếm 16.97%

2.5.2.2 Vẽ biểu đồ cột cho 2 biến “rating” và “gender”

h |> ggplot(aes(x = rating, y = after_stat(count))) +
  geom_bar(fill = 'skyblue') +
  geom_text(aes(label = scales::percent(after_stat(count/sum(count)))), stat = 'count', color = 'black', vjust = - 0.5) +
  facet_grid(. ~ gender) +
 # theme_classic() +
  labs(x = 'Mức độ hạnh phúc', y = 'Số người tham gia khảo sát')

Đồ thị cột đôi thể hiện số người khảo sát và giới tính theo mức độ đánh giá hạnh phúc. Trong đó nhóm bên trái là nhóm đánh giá hạnh phúc của nữ, nhóm bên phải là nhóm đánh giá hạnh phúc của nam.

h %>% count(rating,gender) %>% group_by(rating) %>% mutate(pr=n/sum(n)) %>% ggplot(aes(x=rating,y=n,fill = gender)) + geom_col(position = 'dodge') + geom_text(aes(label = scales::percent(pr, accuracy = .01)), position = position_dodge(1), vjust = 0.25, size = 3) + ylab('Số người tham gia') + xlab('Mức độ đánh giá hạnh phúc')

Đồ thị trên thể hiện mức độ đánh giá hạnh phúc theo giới tính nam và nữ. Trong đó màu xanh là giới tính nam và màu đỏ là giới tính nữ. Ta có nhận xét như sau:

  • Đối tượng khảo sát đưa ra cảm nhận họ hoàn toàn không hạnh phúc (1) với nữ là 68.75% và nam là 31.25%
  • Đối tượng khảo sát đưa ra cảm nhận họ không hạnh phúc (2) với nữ là 53.03% và nam là 46.97%
  • Đối tượng khảo sát đưa ra cảm nhận họ trung lập (3) với nữ là 49.46% và nam là 50.54%
  • Đối tượng khảo sát đưa ra cảm nhận họ hạnh phúc (4) với nữ là 47.94% và nam là 52.06%
  • Đối tượng khảo sát đưa ra cảm nhận họ hoàn toàn hạnh phúc (5) với nữ là 56.03% và nam là 43.97%
h %>% count(rating, gender) %>% group_by(rating) %>% mutate(pra=n/sum(n)) %>% ggplot(aes(x=rating, y = n, fill = gender)) + geom_col()+geom_text(aes(label= scales::percent(pra, accuracy = .01)), position = position_stack(vjust = 0.5), size = 3) + ylab('số người tham gia khảo sát') + xlab('Mức độ đánh giá hạnh phúc')

Đồ thị cột chồng trên đều thể hiện mức độ hạnh phúc và tỉ lệ phần trăm việc giới tính theo đánh giá hạnh phúc. Trong đó, màu đỏ là giới tính nữ và màu xanh là giới tính nam. Từ đồ thị ta có nhận xét:

  • Đánh giá hạnh phúc cho rằng họ hoàn toàn hạnh phúc (5) là cao nhất

  • Đánh giá rằng họ hoàn toàn không hạnh phúc (1) là thấp nhất

  • Số người khảo sát là nữ chiếm nhiều nhất ở mức hoàn toàn không hạnh phúc (1) là 68.75% và ít nhất ở mức hạnh phúc (4) là 47.94%

  • Số người khảo sát là nam chiếm nhiều nhất ở mức hạnh phúc (4) là 52.06% và ít nhất ở mức hoàn toàn không hạnh phúc (1) là 31.25%

2.6 Bài toán kiểm định

2.6.1 Kiểm định chi bình phương (chi-squared)

Ta sử dụng biến “rating” và biến “gender” để làm bài toán kiểm định

Trong kiểm định này, chúng ta phải kiểm tra các giá trị p-value và đặt ra bài toán kiểm định gồm có giả thuyết H0 và H1.

Chúng ta sẽ bác bỏ giả thuyết H0 nếu giá trị p-value xuất hiện trong kết quả nhỏ hơn mức ý nghĩa xác định trước, mức ý nghĩa thường là 0,05.

H0: Hai biến độc lập

H1: Hai biến phụ thuộc

chisq.test(h$rating, h$gender, correct=FALSE)
## 
##  Pearson's Chi-squared test
## 
## data:  h$rating and h$gender
## X-squared = 4.8243, df = 4, p-value = 0.3058

Ta thấy giá trị p-value = 0.3058 lớn hơn mức ý nghĩa là 0,05 nên ta bác bỏ H0.

Kết luận: Biến “rating” và biến “gender” phụ thuộc nhau

2.6.2 Kiểm định tỉ lệ (prop.test)

Ta tiếp tục sử dụng biến “rating” và biển “gender” để làm bài toán kiểm định

table(h$rating, h$gender)
##    
##     female male
##   1     11    5
##   2     35   31
##   3     46   47
##   4     93  101
##   5    130  102

Chọn giá trị để phân tích:

  • Nhóm A: Số người khảo sát nữ có 315 người và nam có 286 người

  • Nhóm B: Số người khảo sát sau khi loại bỏ giá trị “1”, “2” theo giới tính nữ có 269 người và theo giới tính nam là 250

Để kiểm định xem hai tỉ lệ này có thật sự khác nhau, chúng ta có thể sử dụng hàm prop.test(x, n, π) như sau:

Bài toán kiểm định:

H0: Mức độ đánh giá hạnh phúc giữa nhóm A và B như nhau (A=B)

H1: Mức độ đánh giá hạnh phúc nhóm A thấp nhóm B (A<B)

# Lấy giá trị nhóm B
fracture <- c(269, 250) 
# Lấy giá trị nhóm A
total <- c(315, 286)
# Kiểm định
prop.test(fracture, total)
## 
##  2-sample test for equality of proportions with continuity correction
## 
## data:  fracture out of total
## X-squared = 0.36002, df = 1, p-value = 0.5485
## alternative hypothesis: two.sided
## 95 percent confidence interval:
##  -0.07825350  0.03793826
## sample estimates:
##    prop 1    prop 2 
## 0.8539683 0.8741259

Kết quả phân tích trên cho thấy tỉ lệ A là 0.85 và nhóm B là 0.87. Phân tích trên còn cho thấy xác suất 95% rằng độ khác biệt giữa hai nhóm có thể -0.078 đến -0.038 (tức 3.8% đến 7.8%). Với trị số p = 0.5485 Vì p > 0.05 nên chấp nhận H0. Vậy, mức độ đánh giá hạnh phúc giữa nhóm A và B như nhau (A=B)

2.7 Đồ thị scatter và biểu đồ ma trận tương quan

2.7.1 Đồ thị dạng scatter

Biểu đồ phân tán (hay tiếng anh còn gọi là scatter plot, scatter chart) sử dụng các dấu chấm để thể hiên giá trị (điểm giao nhau) của hai biến số khác nhau. Vị trí của mỗi dấu chấm trên trục tung và trục hoành tương ứng với một khía cạnh của một điểm dữ liệu riêng lẻ. Biểu đồ phân tán thường được sử dụng để quan sát mối tương quan giữa hai yếu tố khác nhau.

Nói một cách đơn giản, biểu đồ phân tán là một biểu đồ sử dụng tọa độ để hiển thị các giá trị của dữ liệu trong không gian 2 chiều. Và hai biến số của chúng ta được thể hiện trên trục tung (trục Y) và trục hoành (trục X).

Chúng ta sẽ sử dụng dataset “Affairs” từ thư viện “AER” để thực hiện thao tác vẽ đồ thị.

ggplot(data=h, aes(x=age, y= education, color=gender)) + 
  geom_point()+
  xlab('Độ tuổi') +
  ylab('Trình độ học vấn')

Đồ thị trên thể hiện sự phân tán của số tuổi và trình độ học vấn theo giới tính người khảo sát. Trong đó, màu đỏ là các điểm thuộc giới tính nữ và màu xanh thuộc giới tính nam. Từ đó, ta có nhận xét sau:

  • Số người ở độ tuổi 32, 42 và 52 khảo sát nhiều nhất
  • Số người ở độ tuổi 17.5 khảo sát ít nhất
h %>% ggplot(aes(x = age, y = education, shape = gender)) + geom_point(na.rm = TRUE, size = 3, color = 'black', size =3 ) + geom_point(data = h %>% filter(gender == 'male'),size = 3,color = 'pink') + labs(title = 'Biểu đồ phân tán của độ tuổi và trình độ học vấn theo giới tính', x = 'Độ tuổi', y = 'Trình độ học vấn')

Đồ thị trên thể hiện sự phân tán của độ tuổi và trình độ học vấn theo giới tính cụ thể là giới tính “nam”. Trong đó, hình dạng tròn là nữ và hình dạng tam giác là nam. Và màu đen hiển thị kết quả bình thường (của cả nam và nữ) và màu hồng hiển thị kết quả riêng của giới tính nam.

Ta có thể sử dụng geom_line() để tạo một biểu đồ đường nối các điểm trong khung dữ liệu dữ liệu với biến số x và y đại diện cho giá trị cho mỗi quan sát.

ggplot(data=h, aes(x=age, y=yearsmarried, color=gender)) + 
  geom_point()+
  geom_line(color= 'black')+
  xlab('Độ tuổi') +
  ylab('Trình độ học vấn')

Kết quả hiển thị là đường nối các điểm lại với nhau.

2.7.1.1 Kết hợp với đường hồi quy tuyến tính

Biểu đồ phân tán được sử dụng để phân tích các hình mẫu được sinh ra theo dạng tuyến tính, bờ dốc và độ tập trung.

Nhưng nếu chỉ nhìn các dấu chấm ở trong biểu đồ thì có vẻ khó nhận ra được xu hướng, ta có thể thêm một đường biểu diễn xu hướng như sau (được thể hiện bằng màu đỏ):

ggplot(data=h, aes(x=age, y=yearsmarried, color=gender))+ 
  geom_smooth(formula = y~x, method = 'lm', color = 'red')+
  geom_point()+
  labs(title = 'Đồ thị dạng Scatter', x= 'Độ tuổi', y ='Trình độ học vấn')

Hoặc vẽ biểu đồ bằng nhiều đường tuyến tính phân theo giới tính

ggplot(data=h, aes(x=age, y=yearsmarried)) + 
  geom_point(aes(color=gender),na.rm = T) +
  geom_smooth(aes(color = gender), formula = y ~ x, method = 'lm', na.rm = T) +
  xlab('Độ tuổi') +
  ylab('Trình độ học vấn')

Phân tích biểu đồ trên:

  • Tuyến tính: Biểu đồ trên là dữ liệu dạng tuyến tính / đường thẳng.
  • Bờ dốc: Hướng thay đổi của trình độ học vấn theo số tuổi người khảo sát. Biểu đồ cho thấy, trình độ học vấn cao khi độ tuổi càng cao ta dễ dang thấy được biểu đồ này dốc dương.
  • Độ tập trung : Mức độ dàn trải của các điểm phân tán trong biểu đồ. Ta thấy rằng, các điểm phân tán rộng, mối quan hệ sẽ là yếu

Lưu ý xuất hiện cảnh báo: Nếu chỉ sử dụng mỗi geom_smooth(formula = y~x) tuy không phải lỗi nhưng bị cảnh báo vì chúng ta không cung cấp công thức phù hợp. Geom_smooth(formula = y~x) nó chỉ là mối quan hệ tuyến tính giữa x và y. Để tránh cảnh báo ta sử dụng geom_smooth(formula = y ~ x, method = ‘lm’)

2.7.1.2 Đa biểu đồ scatter

Chúng ta có thể nhiều biểu đồ tương ứng với giới tính như sau:

# facet_grid(. ~ gender)

ggplot(data=h, aes(x=age, y=education)) + 
  geom_point(aes(color=gender),na.rm = T) +
  geom_smooth(aes(color = gender), formula = y ~ x, method = 'lm', na.rm = T) +
  facet_grid(. ~ gender) +
  xlab('Độ tuổi') +
  ylab('Trình độ học vấn')

Hoặc chúng ta có thể xắp xếp các đồ thị này theo phương ngang như sau:

# facet_grid(gender ~ .)

ggplot(data=h, aes(x=age, y=education)) + 
  geom_point(aes(color=gender),na.rm = T) +
  geom_smooth(aes(color = gender), formula = y ~ x, method = 'lm', na.rm = T) +
  facet_grid(gender ~ .) +
  xlab('Độ tuổi') +
  ylab('Trình độ học vấn')

2.7.2 Biểu đồ ma trận tương quan

2.7.2.1 Sử dụng chart.Correlation(): Vẽ các ô scatter

Sử dụng hàm PerformanceAnalytics.

Tiếp theo, tôi cài packages PerformanceAnalytics.

Giải thích câu lệnh:

chart.Correlation: Biểu đồ ma trận tương quan

histogram=TRUE: kiểm tra các đối tượng

pch=19: thêm điểm (vòng tròn rắn) vào đồ thị

library("PerformanceAnalytics")
mydata <- h[,c(0,1,2,3,4,5,6,7,8,9)]
mydata <- data.frame(sapply(mydata, as.numeric))

chart.Correlation(mydata, histogram=T, pch=19)

Nhận xét: Đồ thị trên cho chúng ta biết tất cả hệ số tương quan giữa tất cả các biến số (biến liên tục). Cụ thể như, hệ số tương quan cao nhất (0.78) giữa biến “age” với biến “yearsmarried” (có ý nghĩa thống kê). Tuy nhiên giữa biến “religiousness” và biến “education” có hệ số tương quan quá thấp và không có ý nghĩa thống kê. Ngoài ra, đồ thị trên còn cung cấp cho ta biểu đồ tán xạ, biểu đồ histogram cho từng cặp biến số và cho biết hệ số tương quan càng cao, kích thước của font chữ (số) càng lớn.

Giải thích biểu đồ: Phân phối của từng biến được hiển thị trên đường chéo. Ở dưới cùng của đường chéo: các biểu đồ phân tán hai chiều với một đường phù hợp được hiển thị Trên cùng của đường chéo : giá trị của mối tương quan cộng với mức ý nghĩa như các ngôi sao Mỗi mức ý nghĩa được liên kết với một ký hiệu : giá trị p(0, 0,001, 0,01, 0,05, 0,1, 1) <=> ký hiệu(“”, ””, ””, “.”, ” “)

2.7.2.2 Sử dụng hàm corrplot(): Vẽ một correlogram

Đầu tiên, chúng em cài packages corrplot : install.packages(“corrplot”)

Giải thích câu lệnh: type = “upper” để hiển thị nửa trên ma trận tương quan. Ma trận tương quan được sắp xếp lại theo hệ số tương quan sử dụng phương pháp “hclust”. tl.col và tl.srt được sử dụng để thay đổi màu và xoay label.

library(corrplot)
mydata<- cor(mydata)
corrplot(mydata, type = "upper", order = "hclust", tl.col = "black", tl.srt = 45)

Nhận xét: Tương quan thuận được hiển thị bằng màu xanh lam và tương quan nghịch bằng màu đỏ. Cường độ màu và kích thước của hình tròn tỉ lệ với các hệ số tương quan. Ở bên phải của biểu đồ tương quan, thang màu chú thích hiển thị hệ số tương quan với các màu tương ứng.

Ví dụ như: Cặp tương quan Examination - Agriculture là tương quan nghịch với kích thước gần bằng 0.8 được thể hiện là màu đỏ. Cặp tương quan Examination - Education là tương quan thuận với kích thước gần bằng 0.8 được thể hiện là màu xanh lam đậm. Từ đó, chúng ta kết luận rằng biểu đồ có các cặp tương quan thuận nhiều hơn các cặp tương quan nghịch.

2.7.2.3 Sử dụng heatmap(): Biểu đồ nhiệt

Giải thích câu lệnh:

  • colorRampPalette(c(“skyblue”, “slateblue”, “beige”)) : để thể hiện các màu trong package

  • x = mydata: ma trận tương quan được vẽ từ dữ liệu Affairs

  • col : dùng bảng màu colorRampPalette

  • symm = TRUE: kiểm tra các đối tượng

heatmap(x = mydata, col = colorRampPalette(c("skyblue", "slateblue", "beige"))(20), symm = TRUE)

3 TUẦN 4: Vẽ biểu đồ

3.1 Đồ thị scatter cơ bản

Chúng ta sẽ sử dụng dataset “Afairs” từ thư viện “AER” để thực hiện thao tác vẽ đồ thị.

ggplot(data=h, aes(x=age, y=education)) + 
  geom_point()

Theo biểu đồ trên, biểu đồ phân tán cho chúng ta biết được mối quan hệ giữa độ tuổi và trình độ học vấn. Như bạn có thể thấy, 2 yếu tố này có một mối quan hệ tỉ lệ thuận với nhau, khi độ tuổi càng cao thì trình độ học vấn càng cao.

  • Hàm aes() là một hàm trích dẫn. Điều này có nghĩa là đầu vào của nó được trích dẫn để được đánh giá trong bối cảnh dữ liệu. Điều này giúp bạn dễ dàng làm việc với các biến từ khung dữ liệu vì bạn có thể đặt tên trực tiếp cho chúng.

  • Hàm Geom_point() là điểm được sử dụng để tạo các biểu đồ phân tán. Biểu đồ tán xạ hữu ích nhất để hiển thị mối quan hệ giữa hai biến liên tục. Nó có thể được sử dụng để so sánh một biến liên tục và một biến phân loại, hoặc hai biến phân loại.

Để phân tích biểu đồ chi tiết hơn bằng cách thêm color=gender có nghĩa là màu sắc được phân theo giới tính người khảo sát.

ggplot(data=h, aes(x=age, y=education, color=gender)) + 
  geom_point()

Tiếp theo, các thao tác sau đây thay đổi tên trục hoành (x) và trục tung (y):

ggplot(data=h, aes(x=age, y= education, color=gender)) + 
  geom_point()+
  xlab('Độ tuổi') +
  ylab('Trình độ học vấn')

Đồ thị trên thể hiện sự phân tán của số tuổi và trình độ học vấn theo giới tính người khảo sát. Trong đó, màu đỏ là các điểm thuộc giới tính nữ và màu xanh thuộc giới tính nam. Từ đó, ta có nhận xét sau:

  • Số người ở độ tuổi 32, 42 và 52 khảo sát nhiều nhất
  • Số người ở độ tuổi 17.5 khảo sát ít nhất

Tuy nhiên chúng ta còn có thể có cái nhìn sâu hơn về tương quan giữa 2 biến này theo độ tuổi với năm kết hôn của người khảo sát:

ggplot(data=h, aes(x=age, y=yearsmarried, color= gender)) + 
  geom_point(na.rm = T) +
  xlab('Độ tuổi') +
  ylab('Năm kết hôn')

na.rm = T: Để loại bỏ các giá trị bị thiếu khỏi phép tính có nghĩa là loại bỏ các giá trị NA.

Nhận xét biểu đồ trên:

  • Với số năm kết hôn từ 2 tháng đến 10 năm và độ tuổi từ 17.5 đến 42 dựa theo giới tính thể hiện rằng người khảo sát thuộc khoảng trên là đông nhất.

Sau đây là biểu đồ thay đổi color=gender thành color=children tức là màu sắc được phân loại theo mức độ trong suốt của kim cương

ggplot(data=h, aes(x=age, y=yearsmarried, color= children)) + 
  geom_point(na.rm = T) +
  xlab('Độ tuổi') +
  ylab('Năm kết hôn')

Nhận xét: Từ biểu đồ trên ta quan sát thấy được tỉ lệ có con chiếm đa số và nhiều nhất ở năm 37 tuổi.

3.1.1 Kết hợp với đường hồi quy tuyến tính

Biểu đồ phân tán được sử dụng để phân tích các hình mẫu được sinh ra theo dạng tuyến tính, bờ dốc và độ tập trung.

Nhưng nếu chỉ nhìn các dấu chấm ở trong biểu đồ thì có vẻ khó nhận ra được xu hướng, ta có thể thêm một đường biểu diễn xu hướng như sau (được thể hiện bằng màu đỏ):

ggplot(data=h, aes(x=age, y=yearsmarried, color=gender))+ 
  geom_smooth(formula = y~x, method = 'lm', color = 'red')+
  geom_point()+
  labs(title = 'Đồ thị dạng Scatter', x= 'Độ tuổi', y ='Trình độ học vấn')

Hoặc vẽ biểu đồ bằng nhiều đường tuyến tính phân theo giới tính

ggplot(data=h, aes(x=age, y=yearsmarried)) + 
  geom_point(aes(color=gender),na.rm = T) +
  geom_smooth(aes(color = gender), formula = y ~ x, method = 'lm', na.rm = T) +
  xlab('Độ tuổi') +
  ylab('Trình độ học vấn')

Phân tích biểu đồ trên:

  • Tuyến tính: Biểu đồ trên là dữ liệu dạng tuyến tính / đường thẳng.
  • Bờ dốc: Hướng thay đổi của trình độ học vấn theo số tuổi người khảo sát. Biểu đồ cho thấy, trình độ học vấn cao khi độ tuổi càng cao ta dễ dang thấy được biểu đồ này dốc dương.
  • Độ tập trung: Mức độ dàn trải của các điểm phân tán trong biểu đồ. Ta thấy rằng, các điểm phân tán rộng, mối quan hệ sẽ là yếu

Để có vẽ thêm đường xu hướng tuyến tính ta phải sử dụng hàm geom_smooth() để giải thích cú pháp và hiển thị các ví dụ từng bước về cách sử dụng hàm này.

Lưu ý xuất hiện cảnh báo: Nếu chỉ sử dụng mỗi geom_smooth(formula = y~x) tuy không phải lỗi nhưng bị cảnh báo vì chúng ta không cung cấp công thức phù hợp. Geom_smooth(formula = y~x) nó chỉ là mối quan hệ tuyến tính giữa x và y. Để tránh cảnh báo ta sử dụng geom_smooth(formula = y ~ x, method = ‘lm’)

3.1.2 Thay đổi hình dáng dữ liệu

Ta có thể sử dụng geom_line() để tạo một biểu đồ đường nối các điểm trong khung dữ liệu dữ liệu với biến số x và y đại diện cho giá trị cho mỗi quan sát.

ggplot(data=h, aes(x=age, y=yearsmarried, color=gender)) + 
  geom_point()+
  geom_line(color= 'black')+
  xlab('Độ tuổi') +
  ylab('Trình độ học vấn')

Kết quả hiển thị là đường nối các điểm lại với nhau.

Ngoài việc phân loại dữ liệu bằng màu sắc chúng ta còn có thể phân biệt dữ liệu bằng hình dáng như sau:

# Shape 1 màu
ggplot(data=h, aes(x=age, y=education)) + 
  geom_point(aes(shape = gender),na.rm = T, color = 'brown', size = 3) +
  xlab('Độ tuổi') +
  ylab('Trình độ học vấn')

## Shape theo biến gender = male
h %>% ggplot(aes(x = age, y = education, shape = gender)) + geom_point(na.rm = TRUE, size = 3, color = 'brown', size =3 ) + geom_point(data = h %>% filter(gender == 'male'),size = 3,color = 'pink') + labs(title = 'Biểu đồ phân tán của độ tuổi và trình độ học vấn theo giới tính', x = 'Độ tuổi', y = 'Trình độ học vấn')
## Warning: Duplicated aesthetics after name standardisation: size

Đồ thị trên thể hiện sự phân tán của độ tuổi và trình độ học vấn theo giới tính cụ thể là giới tính “nam”. Trong đó, hình dạng tròn là nữ và hình dạng tam giác là nam. Và màu nâu hiển thị kết quả bình thường (của cả nam và nữ) và màu hồng hiển thị kết quả riêng của giới tính nam.

3.2 Đa biểu đồ scatter

Chúng ta có thể nhiều biểu đồ tương ứng với giới tính như sau:

# facet_grid(. ~ gender)

ggplot(data=h, aes(x=age, y=education)) + 
  geom_point(aes(color=gender),na.rm = T) +
  geom_smooth(aes(color = gender), formula = y ~ x, method = 'lm', na.rm = T) +
  facet_grid(. ~ gender) +
  xlab('Độ tuổi') +
  ylab('Trình độ học vấn')

Hoặc chúng ta có thể xắp xếp các đồ thị này theo phương ngang như sau:

# facet_grid(gender ~ .)

ggplot(data=h, aes(x=age, y=education)) + 
  geom_point(aes(color=gender),na.rm = T) +
  geom_smooth(aes(color = gender), formula = y ~ x, method = 'lm', na.rm = T) +
  facet_grid(gender ~ .) +
  xlab('Độ tuổi') +
  ylab('Trình độ học vấn')

3.3 Đồ thị cột

Chúng ta sẽ đồ thị cột cho biến “rating”.

h|> ggplot(aes(x = rating )) +
  geom_bar( fill = 'slateblue')

Nhận xét: Theo đồ thị trên, ta có thế quan sát thấy rằng khi số lượng người khảo sát càng tăng thì mức độ đánh giá hạnh phúc càng chứng minh rằng họ ngày càng hạnh phúc.

Biểu đồ dưới đây sẽ thể hiện số người khảo sát và mức độ đánh giá hạnh phúc:

h |> ggplot(aes(x = rating, y = after_stat(count))) +
  geom_bar(fill = 'slateblue') +
  geom_text(aes(label = scales::percent(after_stat(count/sum(count)))), stat = 'count', color = 'black', vjust = - .5) +
  theme_classic() +
  labs(x = 'Mức độ hạnh phúc', y = 'Số người khảo sát')

Nhận xét: Tỷ lệ % của biểu đồ trên cho biết kết quả chi tiết của số người khảo sát tăng thì mức độ đánh giá hạnh phúc càng tăng

Ngoài việc tính tỷ lệ % và đếm số người theo mức độ đánh giá hạnh phúc thì chúng ta có thể phân chia đồ thị theo một một số tiêu chí (biến) khác để phân tích. Ví dụ chúng ta phân chia theo biến “gender”:

h |> ggplot(aes(x = rating, y = after_stat(count))) +
  geom_bar(fill = 'slateblue') +
  geom_text(aes(label = scales::percent(after_stat(count/sum(count)))), stat = 'count', color = 'black', vjust = - 0.5) +
  facet_grid(. ~ gender) +
 # theme_classic() +
  labs(x = 'Mức độ hạnh phúc', y = 'Số người khảo sát')

Đồ thị cột đôi thể hiện số người khảo sát và giới tính theo mức độ đánh giá hạnh phúc. Trong đó nhóm bên trái là nhóm đánh giá hạnh phúc của nữ, nhóm bên phải là nhóm đánh giá hạnh phúc của nam.

3.3.1 Biểu đồ cột đôi

Chúng ta cũng có thể vẽ đồ thị dạng cột theo biến “rating” nhưng đồng thời chúng ta sẽ phân đồ thì này thành 2 nhóm theo biến “gender” như sau:

h |> ggplot(aes(x = rating, y = after_stat(count),fill = gender)) +
  geom_bar(position = 'dodge') +
  ylab('Số người khảo sát') +
  xlab('Mức độ hạnh phúc')

# Thêm tỷ lệ phân % để phân tích
h %>% count(rating,gender) %>% group_by(rating) %>% mutate(pr=n/sum(n)) %>% ggplot(aes(x=rating,y=n,fill = gender)) + geom_col(position = 'dodge') + geom_text(aes(label = scales::percent(pr, accuracy = .01)), position = position_dodge(1), vjust = 0.25, size = 3) + ylab('số người khảo sát') + xlab('Mức độ hạnh phúc')

Đồ thị trên thể hiện mức độ đánh giá hạnh phúc theo giới tính nam và nữ. Trong đó màu xanh là giới tính nam và màu đỏ là giới tính nữ. Ta có nhận xét như sau:

  • Đối tượng khảo sát đưa ra cảm nhận họ hoàn toàn không hạnh phúc (1) với nữ là 68.75% và nam là 31.25%
  • Đối tượng khảo sát đưa ra cảm nhận họ không hạnh phúc (2) với nữ là 53.03% và nam là 46.97%
  • Đối tượng khảo sát đưa ra cảm nhận họ trung lập (3) với nữ là 49.46% và nam là 50.54%
  • Đối tượng khảo sát đưa ra cảm nhận họ hạnh phúc (4) với nữ là 47.94% và nam là 52.06%
  • Đối tượng khảo sát đưa ra cảm nhận họ hoàn toàn hạnh phúc (5) với nữ là 56.03% và nam là 43.97%

3.3.2 Biểu đồ cột chồng

Với dạng đồ thị như trên thay vì để 2 cột cạnh nhau, chúng ta có thể chồng nó lên nhau như sau để dễ phân tích hơn.

h |> ggplot(aes(x = rating)) +
  geom_bar(aes(y = after_stat(count), fill = gender), stat = 'count') +
  ylab('Số người khảo sát') +
  xlab('Mức độ hạnh phúc')

# Thêm tỷ lệ phân % để phân tích
h %>% count(rating, gender) %>% group_by(rating) %>% mutate(pra=n/sum(n)) %>% ggplot(aes(x=rating, y = n, fill = gender)) + geom_col()+geom_text(aes(label= scales::percent(pra, accuracy = .01)), position = position_stack(vjust = 0.5), size = 3) + ylab('số người') + xlab('Mức đọ hạnh phúc')

Đồ thị cột chồng trên đều thể hiện mức độ hạnh phúc và tỉ lệ phần trăm việc giới tính theo đánh giá hạnh phúc. Trong đó, màu đỏ là giới tính nữ và màu xanh là giới tính nam. Từ đồ thị ta có nhận xét:

  • Đánh giá hạnh phúc cho rằng họ hoàn toàn hạnh phúc (5) là cao nhất

  • Đánh giá rằng họ hoàn toàn không hạnh phúc (1) là thấp nhất

  • Số người khảo sát là nữ chiếm nhiều nhất ở mức hoàn toàn không hạnh phúc (1) là 68.75% và ít nhất ở mức hạnh phúc (4) là 47.94%

  • Số người khảo sát là nam chiếm nhiều nhất ở mức hạnh phúc (4) là 52.06% và ít nhất ở mức hoàn toàn không hạnh phúc (1) là 31.25%

3.4 Biểu đồ ma trận tương quan

3.4.1 Sử dụng chart.Correlation(): Vẽ các ô scatter

Sử dụng hàm PerformanceAnalytics.

Tiếp theo, tôi cài packages PerformanceAnalytics.

Giải thích câu lệnh:

chart.Correlation: Biểu đồ ma trận tương quan

histogram=TRUE: kiểm tra các đối tượng

pch=19: thêm điểm (vòng tròn rắn) vào đồ thị

library("PerformanceAnalytics")
mydata <- h[,c(0,1,2,3,4,5,6,7,8,9)]
mydata <- data.frame(sapply(mydata, as.numeric))

chart.Correlation(mydata, histogram=T, pch=19)

Nhận xét: Đồ thị trên cho chúng ta biết tất cả hệ số tương quan giữa tất cả các biến số (biến liên tục). Cụ thể như, hệ số tương quan cao nhất (0.78) giữa biến “age” với biến “yearsmarried” (có ý nghĩa thống kê). Tuy nhiên giữa biến “religiousness” và biến “education” có hệ số tương quan quá thấp và không có ý nghĩa thống kê. Ngoài ra, đồ thị trên còn cung cấp cho ta biểu đồ tán xạ, biểu đồ histogram cho từng cặp biến số và cho biết hệ số tương quan càng cao, kích thước của font chữ (số) càng lớn.

Giải thích biểu đồ: Phân phối của từng biến được hiển thị trên đường chéo. Ở dưới cùng của đường chéo: các biểu đồ phân tán hai chiều với một đường phù hợp được hiển thị Trên cùng của đường chéo : giá trị của mối tương quan cộng với mức ý nghĩa như các ngôi sao Mỗi mức ý nghĩa được liên kết với một ký hiệu : giá trị p(0, 0,001, 0,01, 0,05, 0,1, 1) <=> ký hiệu(“”, ””, ””, “.”, ” “)

3.4.2 Sử dụng hàm corrplot(): Vẽ một correlogram

Đầu tiên, chúng em cài packages corrplot : install.packages(“corrplot”)

Giải thích câu lệnh: type = “upper” để hiển thị nửa trên ma trận tương quan. Ma trận tương quan được sắp xếp lại theo hệ số tương quan sử dụng phương pháp “hclust”. tl.col và tl.srt được sử dụng để thay đổi màu và xoay label.

library(corrplot)
mydata<- cor(mydata)
corrplot(mydata, type = "upper", order = "hclust", tl.col = "black", tl.srt = 45)

Nhận xét: Tương quan thuận được hiển thị bằng màu xanh lam và tương quan nghịch bằng màu đỏ. Cường độ màu và kích thước của hình tròn tỉ lệ với các hệ số tương quan. Ở bên phải của biểu đồ tương quan, thang màu chú thích hiển thị hệ số tương quan với các màu tương ứng.

Ví dụ như: Cặp tương quan Examination - Agriculture là tương quan nghịch với kích thước gần bằng 0.8 được thể hiện là màu đỏ. Cặp tương quan Examination - Education là tương quan thuận với kích thước gần bằng 0.8 được thể hiện là màu xanh lam đậm. Từ đó, chúng ta kết luận rằng biểu đồ có các cặp tương quan thuận nhiều hơn các cặp tương quan nghịch.

3.4.3 Sử dụng heatmap(): Biểu đồ nhiệt

Giải thích câu lệnh:

  • colorRampPalette(c(“skyblue”, “slateblue”, “beige”)) : để thể hiện các màu trong package

  • x = mydata: ma trận tương quan được vẽ từ dữ liệu Affairs

  • col : dùng bảng màu colorRampPalette

  • symm = TRUE: kiểm tra các đối tượng

heatmap(x = mydata, col = colorRampPalette(c("skyblue", "slateblue", "beige"))(20), symm = TRUE)

4 TUẦN 3: Phân tích và tìm hiểu một số hàm

MÔ TẢ DỮ LIỆU CỦA DATASET: AFFAIRS - PACKAGE: AER

Dataset “Affairs” là dữ liệu ngoại tình, được gọi là Fair’s Affairs. Dữ liệu chéo từ một cuộc khảo sát được thực hiện bởi các nhà Tâm lý học vào năm 1969

Định dạng: Dữ liệu chứa 601 quan sát và trên 9 biến

  • affairs: Tần suất quan hệ tình dục ngoài hôn nhân
  • gender: giới tính.
  • age: số tuổi
  • yearsmarried: số năm kết hôn
  • children: Có bao nhiêu đứa con trong cuộc hôn nhân?
  • religiousness: niềm tin về tôn giáo của người được khảo sát
  • education: Trình độ học vấn
  • occupation: Nghề nghiệp theo phân loại Hollingshead (đánh số đảo ngược).
  • rating: tự đánh giá mức độ hạnh phúc trong hôn nhân

4.1 Biến đổi dữ liệu nhanh với mutate

Trong quá trình phân tích dữ liệu sẽ có thể phát sinh việc chúng ta muốn tạo thêm những biến mới - phát sinh từ những biến sẵn có trong dữ liệu. Trong bài viết này, ta sử dụng hàm mutate() và nhóm hàm mutate_if(), mutate_at(), mutate_all() để thêm 1 hoặc nhiều biến vào tập dữ liệu.

# Summary dữ liệu
Affairs %>% summary
##     affairs          gender         age         yearsmarried    children 
##  Min.   : 0.000   female:315   Min.   :17.50   Min.   : 0.125   no :171  
##  1st Qu.: 0.000   male  :286   1st Qu.:27.00   1st Qu.: 4.000   yes:430  
##  Median : 0.000                Median :32.00   Median : 7.000            
##  Mean   : 1.456                Mean   :32.49   Mean   : 8.178            
##  3rd Qu.: 0.000                3rd Qu.:37.00   3rd Qu.:15.000            
##  Max.   :12.000                Max.   :57.00   Max.   :15.000            
##  religiousness     education       occupation        rating     
##  Min.   :1.000   Min.   : 9.00   Min.   :1.000   Min.   :1.000  
##  1st Qu.:2.000   1st Qu.:14.00   1st Qu.:3.000   1st Qu.:3.000  
##  Median :3.000   Median :16.00   Median :5.000   Median :4.000  
##  Mean   :3.116   Mean   :16.17   Mean   :4.195   Mean   :3.932  
##  3rd Qu.:4.000   3rd Qu.:18.00   3rd Qu.:6.000   3rd Qu.:5.000  
##  Max.   :5.000   Max.   :20.00   Max.   :7.000   Max.   :5.000
# 6 quan sát đầu tiên của tập dữ liệu
Affairs %>% head
##    affairs gender age yearsmarried children religiousness education occupation
## 4        0   male  37        10.00       no             3        18          7
## 5        0 female  27         4.00       no             4        14          6
## 11       0 female  32        15.00      yes             1        12          1
## 16       0   male  57        15.00      yes             5        18          6
## 23       0   male  22         0.75       no             2        17          6
## 29       0 female  32         1.50       no             2        17          5
##    rating
## 4       4
## 5       4
## 11      4
## 16      5
## 23      3
## 29      5

4.1.1 Hàm mutate().

Để tạo thêm 1 biến mới trong tập dữ liệu, chúng ta sử dụng hàm mutate().

data <- Affairs %>% 
  # Thêm biến mới rating_new theo điều kiện sau:
  mutate(rating_new = case_when(
    rating < 5 ~ "thấp",
    rating >= 5 & rating <= 6 ~ "trung bình",
    TRUE ~ "cao"
  ) %>% as.factor)

# 6 quan sát đầu tiên của tập dữ liệu sau khi thêm 1 biến mới
data %>% head
##    affairs gender age yearsmarried children religiousness education occupation
## 4        0   male  37        10.00       no             3        18          7
## 5        0 female  27         4.00       no             4        14          6
## 11       0 female  32        15.00      yes             1        12          1
## 16       0   male  57        15.00      yes             5        18          6
## 23       0   male  22         0.75       no             2        17          6
## 29       0 female  32         1.50       no             2        17          5
##    rating rating_new
## 4       4       thấp
## 5       4       thấp
## 11      4       thấp
## 16      5 trung bình
## 23      3       thấp
## 29      5 trung bình

Kết quả nhận được là cột biên mới tên rating_new được phân loại cao - trung bình - thấp

Đến lúc này, câu hỏi đặt ra là: Làm thế nào để thêm nhiều biến cùng 1 lúc?

Câu trả lời là: Sử dùng nhóm hàm

  • mutate_all(): áp dụng đối với tất cả các biến trong tập dữ liệu

  • mutate_at(): chỉ áp dụng đối với những biến nhất định mà chúng ta chỉ định

  • mutate_if(): chỉ áp dụng đối với những biến thỏa mãn những điều kiện mà chúng ta đã đặt ra

4.1.2 Hàm mutate_all()

Giả sử, chúng ta muốn thêm các biến mới (đơn vị: aa) -> dùng hàm mutate_all()

Affairs %>% 
  # Bỏ biến Children vì chỉ có thể áp dụng đối với những biến định lượng
  select(-children) %>% 
  # Thêm những biến mới = những biến cũ nhân thêm 10 (tên biến lấy từ biến cũ thêm đuôi "_aa")
  mutate_all(funs(aa = . * 10)) %>% 
  head
##    affairs gender age yearsmarried religiousness education occupation rating
## 4        0   male  37        10.00             3        18          7      4
## 5        0 female  27         4.00             4        14          6      4
## 11       0 female  32        15.00             1        12          1      4
## 16       0   male  57        15.00             5        18          6      5
## 23       0   male  22         0.75             2        17          6      3
## 29       0 female  32         1.50             2        17          5      5
##    affairs_aa gender_aa age_aa yearsmarried_aa religiousness_aa education_aa
## 4           0        NA    370           100.0               30          180
## 5           0        NA    270            40.0               40          140
## 11          0        NA    320           150.0               10          120
## 16          0        NA    570           150.0               50          180
## 23          0        NA    220             7.5               20          170
## 29          0        NA    320            15.0               20          170
##    occupation_aa rating_aa
## 4             70        40
## 5             60        40
## 11            10        40
## 16            60        50
## 23            60        30
## 29            50        50

Các biến mới của tất cả biến định lượng được nhân thêm 10 khi dùng lệnh funs()

4.1.3 Hàm mutate_if()

Trong trường hợp này, chúng ta cũng có thể dùng cách khác để chỉ áp dụng đối với những biến số (numeric) bằng việc sử dụng hàm mutate_if().

Affairs %>% 
  mutate_if(is.numeric,        # Lọc điều kiện: Chỉ áp dụng đối với những biến numeric
            funs(aa = . * 10)  # Các biến numeric sẽ nhân với 10 để lấy đơn vị mm
            ) %>% 
  head
##    affairs gender age yearsmarried children religiousness education occupation
## 4        0   male  37        10.00       no             3        18          7
## 5        0 female  27         4.00       no             4        14          6
## 11       0 female  32        15.00      yes             1        12          1
## 16       0   male  57        15.00      yes             5        18          6
## 23       0   male  22         0.75       no             2        17          6
## 29       0 female  32         1.50       no             2        17          5
##    rating affairs_aa age_aa yearsmarried_aa religiousness_aa education_aa
## 4       4          0    370           100.0               30          180
## 5       4          0    270            40.0               40          140
## 11      4          0    320           150.0               10          120
## 16      5          0    570           150.0               50          180
## 23      3          0    220             7.5               20          170
## 29      5          0    320            15.0               20          170
##    occupation_aa rating_aa
## 4             70        40
## 5             60        40
## 11            10        40
## 16            60        50
## 23            60        30
## 29            50        50

4.1.4 Hàm mutate_at()

Nếu chúng ta chỉ muốn thêm những biến mà phát sinh từ biến rating và religiousness thôi, thì có thể dùng hàm mutate_at()

Affairs %>% mutate_at(c("rating", "religiousness"), # Tạo thêm những biến mới phái sinh từ những biến này
funs(aa = . * 10)           
) %>% 
head
##    affairs gender age yearsmarried children religiousness education occupation
## 4        0   male  37        10.00       no             3        18          7
## 5        0 female  27         4.00       no             4        14          6
## 11       0 female  32        15.00      yes             1        12          1
## 16       0   male  57        15.00      yes             5        18          6
## 23       0   male  22         0.75       no             2        17          6
## 29       0 female  32         1.50       no             2        17          5
##    rating rating_aa religiousness_aa
## 4       4        40               30
## 5       4        40               40
## 11      4        40               10
## 16      5        50               50
## 23      3        30               20
## 29      5        50               20

Như vậy, chúng ta đã vừa được học cách thêm nhiều biến cùng 1 lúc bằng việc sử dụng nhóm hàm mutate_if(), mutate_at(), mutate_all() trong dataset Affairs

4.2 Sử dụng Pivot

4.2.1 PPivot_longer()

Hàm pivot_longer() từ gói tidyr trong R có thể được sử dụng để xoay khung dữ liệu từ định dạng rộng sang định dạng dài.

h1 <- h |> pivot_longer(cols = starts_with('r'), names_to = 'DANHGIA', values_to = 'rank')

Việc chuyển đổi dữ liệu có tên bắt đầu là chữ “r” được xếp hạng chuyển đổi từ định dạng rộng sang định dạng dài bằng pivot_longer() để chúng ta phân tích chi tiết hơn.

# Từ dữ liệu trên, dữ liệu nào không thuộc "na" sẽ bị loại bỏ 
h2 <- h |> pivot_longer(cols = starts_with('r'), names_to = 'DANHGIA', values_to = 'rank',values_drop_na = T) 

Tất cả các giá trị bắt đầu bằng chữ “r” nếu không thuộc điều kiện values_drop_na sẽ bị loại bỏ

4.2.2 Pivot_wider()

Tạo một bảng dữ liệu mới gồm các biến AGE, EDUCATION, GENDER từ dataset Affairs.

Dùng hàm ” pivot wider” để chuyển đổi dữ liệu từ định dạng dài sang định dạng rộng

hh <- h |> select(age, education, gender) |> pivot_wider(names_from = age, values_from = c(education, gender))

Dữ liệu được tạo ra từ ba biến “age”, “education”, “gender”. Trong đó, biến “age” lấy làm cột mốc chính để biến “education” và biến “gender” sẽ được phân theo biến “age”.

4.3 Tìm hiểu: Sử dụng R cho các phép tính ma trận

4.3.1 Tạo ma trận

Như chúng ta biết ma trận (matrix), nói đơn giản, gồm có dòng (row) và cột (column). Khi viết A[m, n], chúng ta hiểu rằng ma trận A có m dòng và n cột. Trong R, chúng ta cũng có thể thể hiện như thế. Ví dụ: chúng ta muốn tạo một ma trận vuông A gồm 3 dòng và 3 cột, với các phần tử (element) 1, 2, 3, 4, 5, 6, 7, 8, 9, chúng ta viết:

y <- c(1,2,3,4,5,6,7,8,9)
A <- matrix(y, nrow=3)
A
##      [,1] [,2] [,3]
## [1,]    1    4    7
## [2,]    2    5    8
## [3,]    3    6    9

Kết quả hiện thị cho thấy ma trận A gồm có 3 cột và 3 dòng (3x3)

4.3.2 Ma trận chuyển vị

Để tạo một ma trận hoán vị là dùng t(). Ví dụ: B = A’

B <- t(A)
B
##      [,1] [,2] [,3]
## [1,]    1    2    3
## [2,]    4    5    6
## [3,]    7    8    9

4.3.3 Ma trận vô hướng

là một ma trận vuông (tức số dòng bằng số cột), và tất cả các phần tử ngoài đường chéo (off-diagonal elements) là 0, và phần tử đường chéo là 1. Chúng ta có thể tạo một ma trận như thế bằng R như sau:

# tạo ra mộ ma trận 3 x 3 với tất cả phần tử là 0, 3, 3.
A <- matrix(0, 3, 3) 
# cho các phần tử đường chéo bằng 1
diag(A) <- 1
diag(A)
## [1] 1 1 1
# bây giờ ma trận A sẽ là:
A
##      [,1] [,2] [,3]
## [1,]    1    0    0
## [2,]    0    1    0
## [3,]    0    0    1

4.3.4 Tính toán với ma trận

Cho hai ma trận A và B như sau:

# Ma trận A
A <- matrix(1:12, 3, 4)
A
##      [,1] [,2] [,3] [,4]
## [1,]    1    4    7   10
## [2,]    2    5    8   11
## [3,]    3    6    9   12
# Ma trận B
B <- matrix(-1:-12, 3, 4)
B
##      [,1] [,2] [,3] [,4]
## [1,]   -1   -4   -7  -10
## [2,]   -2   -5   -8  -11
## [3,]   -3   -6   -9  -12

4.3.4.1 Cộng và trừ hai ma trận

# cộng hai ma trận A và B
C <- A+B
# Trừ hai ma trận A và B
D <- A-B

4.3.4.2 Nhân hai ma trận

# Ma trận AB
AB <- A*B
# Ma trận BA
BA <- B*A

4.3.4.3 Nghịch đảo ma trận và giải hệ phương trình

Ví dụ chúng ta có hệ phương trình sau đây:

Hệ phương trình này có thể viết bằng kí hiệu ma trận: AX = Y, trong đó:

# Nghiệm của hệ phương trình này là: X = A^(-1)Y, hay trong R:
A <- matrix(c(3,1,4,6), nrow=2)
Y <- matrix(c(4,2), nrow=2)
X <- solve(A)%*%Y
X
##           [,1]
## [1,] 1.1428571
## [2,] 0.1428571

Nghiệm của hệ phương trình X=(1.1428571, 0.1428571)

4.3.4.4 Định thức

Làm sao chúng ta xác định một ma trận có thể đảo nghịch hay không? Ma trận mà định thức bằng 0 là ma trận suy biến và không thể đảo nghịch. Để kiểm tra định thức, R dùng lệnh det():

E <- matrix((1:9), 3, 3)
E
##      [,1] [,2] [,3]
## [1,]    1    4    7
## [2,]    2    5    8
## [3,]    3    6    9
det(E)
## [1] 0

Kết quả cho thấy định thức ma trận E: det(E)=0

4.4 Biểu đồ

4.4.1 Biểu đồ hình tròn [ dùng pie()]

Sử dụng biến religiousness (tôn giáo) để vẽ biểu đồ hình tròn dựa trên 5 nhóm phân loại đánh giá về niềm tin về tôn giáo của người được khảo sát.

# Phân 5 nhóm cho biến religiousness
table(cut(h$religiousness,5))
## 
## (0.996,1.8]   (1.8,2.6]   (2.6,3.4]   (3.4,4.2]     (4.2,5] 
##          48         164         129         190          70
# vẽ biểu đồ dựa trên 5 nhóm đã phân loại
pie(table(cut(h$religiousness,5)))

  • Màu trắng là nhóm giá trị từ khoảng 0.996 đến bằng 1.8

  • Màu xanh lam là nhóm giá trị từ khoảng 1.8 đến bằng 2.6

  • Màu hồng là nhóm giá trị từ khoảng 2.6 đến bằng 3.4

  • Màu xanh mint là nhóm giá trị từ khoảng 3.4 đến bằng 4.2

  • Màu tím là nhóm giá trị từ khoảng 4.2 đến bằng 5

4.4.2 Đồ thị phân phối xác xuất bằng hàm plot(density)

Đồ thị mật độ phân phối xác suất cho biến “age” bằng hàm density()

plot(density(h$age),add=TRUE)

  • Từ đồ thị cho thấy, phân phối của biến “age” ở độ tuổi từ khoảng 25 đến 30 là cao nhất và từ 30 trở đi phân phối ngày càng giảm dần. Điều đó có nghĩa là người được khảo sát đa số là những người trung niên.

4.5 Phân tích thống kê mô tả

4.5.1 Kiểm định tỉ lệ (prop.test)

Dựa vào bảng tần số biến “gender” ở tuần 1, chúng ta thấy có 315 nữ và 286 nam. Như vậy tỉ lệ nữ là 0.52 (hay 52%). Để kiểm định xem tỉ lệ này có thật sự khác với tỉ lệ 0.5 hay không, chúng ta có thể sử dụng hàm prop.test(x, n, π) như sau:

prop.test(52, 100, 0.50)
## 
##  1-sample proportions test with continuity correction
## 
## data:  52 out of 100, null probability 0.5
## X-squared = 0.09, df = 1, p-value = 0.7642
## alternative hypothesis: true p is not equal to 0.5
## 95 percent confidence interval:
##  0.4183183 0.6201278
## sample estimates:
##    p 
## 0.52

Trong kết quả trên, prop.test ước tính tỉ lệ nữ giới là 0.52, và khoảng tin cậy 95% là 0.4183183 đến 0.6201278. Giá trị Chi bình phương là 0.09, với trị số p = 0.7642. Như vậy, nghiên cứu này có tỉ lệ nữ cao hơn 50%.

4.5.2 Kiểm định nhị phân bionom.test(x, n, π)

Một cách tính chính xác hơn kiểm định tỉ lệ trên là kiểm định nhị phân bionom.test(x, n, π) như sau:

binom.test(52, 100, 0.50) 
## 
##  Exact binomial test
## 
## data:  52 and 100
## number of successes = 52, number of trials = 100, p-value = 0.7644
## alternative hypothesis: true probability of success is not equal to 0.5
## 95 percent confidence interval:
##  0.4177898 0.6209945
## sample estimates:
## probability of success 
##                   0.52

Nói chung, kết quả của kiểm định nhị phân không khác gì so với kiểm định Chi bình phương, với trị số p = 0.7644, chúng ta càng có bằng chứng để kết luận rằng tỉ lệ nữ giới trong nghiên cứu này thật sự cao hơn 50%.

4.5.3 So sánh hai tỉ lệ (prop.test)

Trước khi so sánh tỉ lệ ta cần lập bảng tần số biến “education” theo biến “gender”

# Bẩng tần số biến "education" theo biến "gender"
table(h$education, h$gender)
##     
##      female male
##   9       4    3
##   12     36    8
##   14    106   48
##   16     70   45
##   17     52   37
##   18     45   67
##   20      2   78

Người khảo sát được chia thành hai nhóm: nhóm giáo dục A gồm có 315 nữ, và nhóm giáo dục B gồm có 286 nam. Sau khi loại bỏ giáo dục mang giá trị “16” - bậc đại học , nhóm A có 245 nữ, và nhóm B có 241 nam. Vấn đề đặt ra là tỉ lệ giáo dục trong hai nhóm này như nhau hay không?

Để kiểm định xem hai tỉ lệ này có thật sự khác nhau, chúng ta có thể sử dụng hàm prop.test(x, n, π) như sau:

Bài toán kiểm định:

  • H0: Giáo dục giữa nhóm A và B như nhau (A=B)
  • H1: Giáo dục nhóm A cao hơn nhóm B (A>B)
fracture <- c(245, 241) 
total <- c(315, 286)
prop.test(fracture, total)
## 
##  2-sample test for equality of proportions with continuity correction
## 
## data:  fracture out of total
## X-squared = 3.6693, df = 1, p-value = 0.05542
## alternative hypothesis: two.sided
## 95 percent confidence interval:
##  -0.1305741397  0.0008150099
## sample estimates:
##    prop 1    prop 2 
## 0.7777778 0.8426573

Kết quả phân tích trên cho thấy tỉ lệ giáo dục trong nhóm 1 là 0.77 và nhóm 2 là 0.84. Phân tích trên còn cho thấy xác suất 95% rằng độ khác biệt giữa hai nhóm có thể 0.0008 đến 0.1305 (tức 0 đến 13%). Với trị số p = 0.05542. Vì p > 0.05 nên chưa đủ cơ sở để bác bỏ H0. Vây, tỉ lệ giáo dục giữa nữ và nam là như nhau


5 TUẦN 2: Phân tích sự tác động của biến định lượng yearsmarried (Năm kết hôn) và rating (đánh giá mức độ hạnh phúc ) và biến định tính gender (Giới tính)

5.1 Các đại lượng đo lường độ tập trung và phân tán dữ liệu của biến định lượng

5.1.1 Biến yearsmarried (Năm Kết Hôn)

5.1.1.1 Trung bình

mean(h$yearsmarried)
## [1] 8.177696
#Tính trung bình theo giới tính
aggregate(h$yearsmarried, list(h$gender), FUN = "mean") 
##   Group.1        x
## 1  female 8.017070
## 2    male 8.354608

Số năm kết hôn trung bình của các khảo sát là 8.177696.

Số năm kết hôn trung bình của các khảo sát theo giới tính nữ là 8.017070

Số năm kết hôn trung bình của các khảo sát theo giới tính nam là 8.354608

5.1.1.2 Trung vị

median(h$yearsmarried, na.rm = FALSE)
## [1] 7

5.1.1.3 Độ lệch chuẩn

sd(h$yearsmarried)
## [1] 5.571303

5.1.1.4 Phương sai

var(h$yearsmarried)
## [1] 31.03942

5.1.1.5 Tính tổng

sum(h$yearsmarried)
## [1] 4914.795

5.1.1.6 Tạo biểu đồ histogram để xem phân bố dữ liệu

hist(h$yearsmarried)

5.1.1.7 Thống kê dữ liệu

summary(h$yearsmarried)
##    Min. 1st Qu.  Median    Mean 3rd Qu.    Max. 
##   0.125   4.000   7.000   8.178  15.000  15.000

5.1.2 Biến rating (Mức độ hạnh phúc)

5.1.2.1 Trung bình

mean(h$rating)
## [1] 3.93178
#Tính trung bình theo giới tính
aggregate(h$rating, list(h$gender), FUN = "mean") 
##   Group.1        x
## 1  female 3.939683
## 2    male 3.923077

Đánh giá mức độ hạnh phúc trung bình của các khảo sát là 3.93178.

Đánh giá mức độ hạnh phúc trung bình của các khảo sát theo giới tính nữ là 3.939683

Đánh giá mức độ hạnh phúc trung bình của các khảo sát theo giới tính nam là 3.923077

5.1.2.2 Trung vị

median(h$rating, na.rm = FALSE)
## [1] 4

5.1.2.3 Độ lệch chuẩn

sd(h$rating)
## [1] 1.103179

5.1.2.4 Phương sai

var(h$rating)
## [1] 1.217005

5.1.2.5 Tính tổng

sum(h$rating)
## [1] 2363

5.1.2.6 Tạo biểu đồ histogram để xem phân bố dữ liệu

hist(h$rating)

#### Thống kê dữ liệu

summary(h$rating)
##    Min. 1st Qu.  Median    Mean 3rd Qu.    Max. 
##   1.000   3.000   4.000   3.932   5.000   5.000

5.2 LẬP BẢNG TẦN SỐ

5.2.1 Biến GioiTinh (gender)

5.2.1.1 Lập bảng tần số của biến GioiTinh (gender) như sau:

table(h$gender)
## 
## female   male 
##    315    286
tabgender=table(h$gender)
tabgender
## 
## female   male 
##    315    286

5.2.1.2 Đồ thị của biến GioiTinh (gender)

barplot(tabgender, xlab = "Giới Tính", ylab = "Tần số",  main = "Biểu đồ tần số giới tính", col = c("pink","skyblue"))

Giải thích kêt quả trên: Người được khảo sát là nữ giới nhiều hơn so với nam giới với tỉ lệ 315/601 > 286/601

5.2.2 Biến HanhPhuc (rating)

5.2.2.1 Lập bảng tần số của biến đánh giá mức độ hạnh phúc (rating)

HanhPhuc <- cut(h$rating, breaks = c(0, 1, 2, 3, 4, 5 ), labels = c("Hoàn toàn không hạnh phúc","Không hạnh phúc", "Bình thường", "Hạnh phúc", "Hoàn toàn hạnh phúc"), right = TRUE)
tabrating=table(h$rating)
tabrating
## 
##   1   2   3   4   5 
##  16  66  93 194 232

5.2.2.2 Đồ thị của biến HanhPhuc (rating)

barplot(tabrating, xlab = "Mức độ hạnh phúc", ylab = "Tần số",  main = "Biểu đồ tần số mức độ hạnh phúc", col = c("ivory","pink", "salmon", "red","brown"))

Giải thích kết quả trên: Hầu hết người được khảo sát đánh giá rằng họ rất hạnh phúc trong hôn nhân của họ. Tần số cho thấy mức độ đánh gia hạnh phúc từ hoàn toàn không hạnh phúc tăng dần đến hoàn toàn hạnh phúc

5.2.3 Biến NamKetHon (yearsmarried)

5.2.3.1 Lập bảng tần số của biến NamKetHon (yearsmarried)

BangNamKetHon <- cut(h$yearsmarried, breaks = c(0, 0.125, 0.417, 0.75, 1.5, 4, 7, 10, 15 ), labels = c("3 tháng hoặc ít hơn", "4 đến 6 tháng", "6 tháng đến 1 năm", "1 đến 2 năm", "3 đến 5 năm", "6 đến 8 năm", "9 đến 11 năm", "12 năm trở lên"), right = TRUE)
tabyearsmarried=table(h$yearsmarried)
tabyearsmarried
## 
## 0.125 0.417  0.75   1.5     4     7    10    15 
##    11    10    31    88   105    82    70   204

5.2.3.2 Đồ thị của biến NamKetHon (yearsmarried)

barplot(tabyearsmarried, xlab = "Số năm kết hôn", ylab = "Tần số",  main = "Biểu đồ tần số năm kết hôn", col = c("ivory","lavender", "skyblue", "turquoise","magenta", "purple", "blue", "navy" ))

Giải thích kết quả trên: Dựa vào biểu đồ trên ta thấy, người được khảo sat đa số là người kết hôn lâu năm. Trong đó, lớn nhất là kết hôn hơn 12 năm chiếm 204 người và thấp nhất là người kết hôn từ 4 đến 6 tháng chiếm khoảng 10 người

5.3 Phân tích sự tác động của biến yearsmarried (năm kết hôn) lên biến gender (giới tính)

5.3.0.1 Phân tích cho biết số năm kết hôn thì có ảnh hưởng đến giới tính hay không ?

5.3.1 Lập bảng kết hơp của 2 biến

tabN1 = table(h$gender,h$yearsmarried)
tabN1
##         
##          0.125 0.417 0.75 1.5   4   7  10  15
##   female     5     6   21  53  41  49  36 104
##   male       6     4   10  35  64  33  34 100

Kiểm định chi bình phương (chi-squared):

Trong kiểm định này, chúng ta phải kiểm tra các giá trị p-value và đặt ra bài toán kiểm định gồm có giả thuyết H0 và H1.

Chúng ta sẽ bác bỏ giả thuyết H0 nếu giá trị p-value xuất hiện trong kết quả nhỏ hơn mức ý nghĩa xác định trước, mức ý nghĩa thường là 0,05.

H0: Hai biến độc lập

H1: Hai biến phụ thuộc

chisq.test(h$gender, h$yearsmarried, correct=FALSE)
## Warning in chisq.test(h$gender, h$yearsmarried, correct = FALSE): Chi-squared
## approximation may be incorrect
## 
##  Pearson's Chi-squared test
## 
## data:  h$gender and h$yearsmarried
## X-squared = 15.007, df = 7, p-value = 0.03591

Ta thấy giá trị p-value = 0.03591 có nghĩa là con số đó rất nhỏ nên ta xem nó bằng 0 và vì giá trị P-value nhỏ hơn mức ý nghĩa lầ 0,05 nên ta bác bỏ H0.

Kết luận: Giữa 2 biến có sự liên quan đến nhau hay nói cách khác đây là 2 biến phụ thuộc

5.4 5. Phân tích sự tác động của biến ratingrating (mức độ hạnh phúc) lên biến gender (giới tính)

5.4.0.1 Phân tích cho biết mức độ đánh giá hạnh phúc thì có ảnh hưởng đến giới tính hay không ?

tabN2 = table(h$gender,h$rating)
tabN2
##         
##            1   2   3   4   5
##   female  11  35  46  93 130
##   male     5  31  47 101 102

Kiểm định chi bình phương (chi-squared):

Trong kiểm định này, chúng ta phải kiểm tra các giá trị p-value và đặt ra bài toán kiểm định gồm có giả thuyết H0 và H1.

Chúng ta sẽ bác bỏ giả thuyết H0 nếu giá trị p-value xuất hiện trong kết quả nhỏ hơn mức ý nghĩa xác định trước, mức ý nghĩa thường là 0,05.

H0: Hai biến độc lập

H1: Hai biến phụ thuộc

chisq.test(h$gender, h$rating, correct=FALSE)
## 
##  Pearson's Chi-squared test
## 
## data:  h$gender and h$rating
## X-squared = 4.8243, df = 4, p-value = 0.3058

Ta thấy giá trị p-value = 0.3058 và vì giá trị P-value lớn hơn mức ý nghĩa lầ 0,05 nên ta chưa đủ cơ sở để bác bỏ H0.

Kết luận: Giữa 2 biến không có liên quan đến nhau hay nói cách khác đây là 2 biến độc lập nhau


6 TUẦN 1: Phân tích dữ liệu chéo của biến định lượng và biến định tính của dataset “Affairs” - Package “AER”

6.1 MÔ TẢ DỮ LIỆU

6.1.1 Dataset “Affairs” là dữ liệu ngoại tình, được gọi là Fair’s Affairs. Dữ liệu chéo từ một cuộc khảo sát được thực hiện bởi các nhà Tâm lý học vào năm 1969

6.1.2 Định dạng: Dữ liệu chứa 601 quan sát và trên 9 biến

  • affairs: Tần suất quan hệ tình dục ngoài hôn nhân
  • gender: giới tính.
  • age: số tuổi
  • yearsmarried: số năm kết hôn
  • children: Có bao nhiêu đứa con trong cuộc hôn nhân?
  • religiousness: niềm tin về tôn giáo của người được khảo sát
  • education: Trình độ học vấn
  • occupation: Nghề nghiệp theo phân loại Hollingshead (đánh số đảo ngược).
  • rating: tự đánh giá mức độ hạnh phúc trong hôn nhân

6.2 XỬ LÝ DỮ LIỆU

6.2.1 Tạo bản sao và đặt lại tên dữ liệu

library(AER)
data("Affairs")
h <- Affairs
str(h)
## 'data.frame':    601 obs. of  9 variables:
##  $ affairs      : num  0 0 0 0 0 0 0 0 0 0 ...
##  $ gender       : Factor w/ 2 levels "female","male": 2 1 1 2 2 1 1 2 1 2 ...
##  $ age          : num  37 27 32 57 22 32 22 57 32 22 ...
##  $ yearsmarried : num  10 4 15 15 0.75 1.5 0.75 15 15 1.5 ...
##  $ children     : Factor w/ 2 levels "no","yes": 1 1 2 2 1 1 1 2 2 1 ...
##  $ religiousness: int  3 4 1 5 2 2 2 2 4 4 ...
##  $ education    : num  18 14 12 18 17 17 12 14 16 14 ...
##  $ occupation   : int  7 6 1 6 6 5 1 4 1 4 ...
##  $ rating       : int  4 4 4 5 3 5 3 4 2 5 ...

6.2.2 Chọn 3 dữ liệu con để phân tích: GioiTinh(gender), HanhPhuc(rating), NamKetHon(yearsmarried)

GioiTinh <- h$gender
HanhPhuc <- h$rating
NamKetHon <- h$yearsmarried
str(h)
## 'data.frame':    601 obs. of  9 variables:
##  $ affairs      : num  0 0 0 0 0 0 0 0 0 0 ...
##  $ gender       : Factor w/ 2 levels "female","male": 2 1 1 2 2 1 1 2 1 2 ...
##  $ age          : num  37 27 32 57 22 32 22 57 32 22 ...
##  $ yearsmarried : num  10 4 15 15 0.75 1.5 0.75 15 15 1.5 ...
##  $ children     : Factor w/ 2 levels "no","yes": 1 1 2 2 1 1 1 2 2 1 ...
##  $ religiousness: int  3 4 1 5 2 2 2 2 4 4 ...
##  $ education    : num  18 14 12 18 17 17 12 14 16 14 ...
##  $ occupation   : int  7 6 1 6 6 5 1 4 1 4 ...
##  $ rating       : int  4 4 4 5 3 5 3 4 2 5 ...

6.2.3 Lọc dữ liệu theo điều kiện

6.2.3.1 Tiến hành lọc ra những quan sát có giới tính là nữ(female) và họ hoàn toàn hạnh phúc trong hôn nhân của họ (giá trị thể hiện là 5)

# Chỉ lấy giới tính "Nam" và giá trị hạnh phúc là "5"
fh <- h[GioiTinh=='female' & HanhPhuc =='5',]
str(fh)
## 'data.frame':    130 obs. of  9 variables:
##  $ affairs      : num  0 0 0 0 0 0 0 0 0 0 ...
##  $ gender       : Factor w/ 2 levels "female","male": 1 1 1 1 1 1 1 1 1 1 ...
##  $ age          : num  32 37 22 27 22 22 32 22 27 22 ...
##  $ yearsmarried : num  1.5 15 1.5 10 1.5 1.5 10 1.5 7 1.5 ...
##  $ children     : Factor w/ 2 levels "no","yes": 1 2 1 2 1 1 2 1 1 1 ...
##  $ religiousness: int  2 1 2 2 2 2 3 2 4 3 ...
##  $ education    : num  17 17 16 14 16 16 14 18 16 16 ...
##  $ occupation   : int  5 5 5 1 5 5 1 5 1 5 ...
##  $ rating       : int  5 5 5 5 5 5 5 5 5 5 ...

6.2.3.2 Sắp xếp biến HanhPhuc (rating) tăng dần

HanhPhuctangdan=h[order(HanhPhuc),]
head(HanhPhuctangdan)
##      affairs gender age yearsmarried children religiousness education
## 224        0 female  27            4      yes             2        18
## 277        0 female  37           15      yes             4        14
## 491        0   male  57           15      yes             3        16
## 751        0 female  52           15      yes             5        17
## 1160       0 female  37           15      yes             2        14
## 1207       0 female  27            7      yes             2        12
##      occupation rating
## 224           6      1
## 277           3      1
## 491           6      1
## 751           1      1
## 1160          1      1
## 1207          5      1

6.3 LẬP BẢNG TẦN SỐ

6.3.1 Lập bảng tần số của biến giới tính (gender) như sau:

GioiTinh <- Affairs$gender
table(GioiTinh)
## GioiTinh
## female   male 
##    315    286
tabgender=table(GioiTinh)
tabgender
## GioiTinh
## female   male 
##    315    286

6.3.2 Lập bảng tần số của biến đánh giá mức độ hạnh phúc (rating)

HanhPhuc <- Affairs$rating
BangHanhPhuc <- cut(HanhPhuc, breaks = c(1, 2, 3, 4, 5 ), labels = c("Không hạnh phúc", "Bình thường", "Hạnh phúc", "Hoàn toàn hạnh phúc"), right = TRUE)
tabrating=table(HanhPhuc)
tabrating
## HanhPhuc
##   1   2   3   4   5 
##  16  66  93 194 232
table(cut(HanhPhuc,3))
## 
## (0.996,2.33]  (2.33,3.67]     (3.67,5] 
##           82           93          426

Kết quả hiển thị:

  • Với giá trị hạnh phúc “1” có 16 người
  • Với giá trị hạnh phúc “2” có 66 người
  • Với giá trị hạnh phúc “3” có 93 người
  • Với giá trị hạnh phúc “4” có 194 người
  • Với giá trị hạnh phúc “5” có 232 người

Và được chia thành 3 nhóm:

  • Nhóm 1 mang giá trị từ 0.996 đến 2.33
  • Nhóm 2 mang giá trị từ 2.33 đến 3.67
  • Nhóm 3 mang giá trị từ 3.67 đến 5

6.3.3 Lập bảng tần số của biến số năm kết hôn (yearsmarried)

NamKetHon <- Affairs$yearsmarried
BangNam <- cut(NamKetHon, breaks = c(0.125, 0.417, 0.75, 1.5, 4, 7, 10, 15 ), labels = c("3 tháng hoặc ít hơn", "4 đến 6 tháng", "6 tháng đến 1 năm", "1 đến 2 năm", "3 đến 5 năm", "6 đến 8 năm", "9 năm hoặc hơn"), right = TRUE)
tabyearsmarried=table(NamKetHon)
tabyearsmarried
## NamKetHon
## 0.125 0.417  0.75   1.5     4     7    10    15 
##    11    10    31    88   105    82    70   204
table(cut(NamKetHon,6))
## 
##  (0.11,2.6]  (2.6,5.08] (5.08,7.56]   (7.56,10]   (10,12.5]   (12.5,15] 
##         140         105          82          70           0         204

Kết quả hiển thị:

  • Số năm kết hôn mang giá trị “0.125” có 11 người
  • Số năm kết hôn mang giá trị “0.417” có 10 người
  • Số năm kết hôn mang giá trị “0.75” có 31 người
  • Số năm kết hôn mang giá trị “1.5” có 88 người
  • Số năm kết hôn mang giá trị “4” có 105 người
  • Số năm kết hôn mang giá trị “7” có 82 người
  • Số năm kết hôn mang giá trị “10” có 70 người
  • Số năm kết hôn mang giá trị “15” có 204 người

Và được chia thành 5 nhóm:

  • Nhóm 1 mang giá trị từ 0.11 đến 2.6
  • Nhóm 2 mang giá trị từ 2.6 đến 5.08
  • Nhóm 3 mang giá trị từ 5.08 đến 7.56
  • Nhóm 4 mang giá trị từ 7.56 đến 10
  • Nhóm 5 mang giá trị từ 10 đến 12.5
  • Nhóm 6 mang giá trị từ 12.5 đến 15