# Cài đặt các gói cần thiết
install.packages("dplyr")
install.packages("ggplot2")
install.packages("readr")
install.packages("caret")
install.packages("readxl")
install.packages("knitr")
install.packages("epiR")
library(epiR)
library(knitr)
library(dplyr)    
library(ggplot2)  
library(readr)    
library(caret)
library(readxl)

1. Tìm hiểu và nhập dữ liệu

1.1 Nhập dữ liệu

dulieu <- read.csv("dulieu.csv", stringsAsFactors = TRUE)
str(dulieu)

Bộ dữ liệu bao gồm 1259 quan sát với 9 biến chính: thời gian ghi nhận (Timestamp), độ tuổi (Age), giới tính (Gender), quốc gia (Country), tiền sử bệnh gia đình (family_history), tình trạng điều trị (treatment), làm việc từ xa (remote_work), làm việc tại công ty công nghệ (tech_company) và một biến bổ sung. Dữ liệu được thu thập từ bộ dữ liệu UCI Heart Disease, phản ánh thông tin nhân khẩu học và các yếu tố liên quan đến sức khỏe cũng như môi trường làm việc của người tham gia khảo sát. Đây là tập dữ liệu tổng hợp có tính đa dạng về mặt đặc điểm dân số và tình trạng sức khỏe, phù hợp cho việc phân tích các mối quan hệ giữa yếu tố nhân khẩu học, tiền sử bệnh và điều kiện làm việc đối với các kết quả sức khỏe. Việc sử dụng dữ liệu này góp phần hỗ trợ nghiên cứu dịch tễ học, xác định các yếu tố nguy cơ, cũng như xây dựng mô hình dự báo trong lĩnh vực y tế một cách hiệu quả và có cơ sở khoa học vững chắc.

1.2 Kiểm tra giá trị thiếu

sum(is.na(dulieu))

Kết quả cho thấy dữ liệu không có giá trị bị thiếu.

2. Phân tích mô tả biến định tính

2.1 Biến Gender

dulieu$Gender <- as.character(dulieu$Gender)
dulieu$Gender[grepl("^m(ale)?", dulieu$Gender, ignore.case = TRUE)] <- "Nam giới"
dulieu$Gender[grepl("^f(emale)?", dulieu$Gender, ignore.case = TRUE)] <- "Nữ giới"
dulieu$Gender[!(dulieu$Gender %in% c("Nam giới", "Nữ giới"))] <- "Khác / Không xác định giới"
dulieu$Gender <- factor(dulieu$Gender, levels = c("Nam giới", "Nữ giới", "Khác / Không xác định giới"))
gender_freq <- table(dulieu$Gender)
gender_percent <- prop.table(gender_freq) * 100
gender_summary <- data.frame(
  Giới_tính = names(gender_freq),
  Tần_số = as.vector(gender_freq),
  Tỷ_lệ_phần_trăm = round(gender_percent, 2)
)
print(gender_summary)

Dữ liệu về giới tính cho thấy đa số người tham gia là nam giới với 988 quan sát, chiếm tỷ lệ lớn nhất khoảng 78.47%. Nữ giới chiếm 19.38% với 244 quan sát, trong khi nhóm khác hoặc không xác định giới tính chiếm tỷ lệ nhỏ nhất, khoảng 2.14% với 27 quan sát. Phân bố này cho thấy mẫu khảo sát có sự chênh lệch rõ rệt về giới tính, tập trung chủ yếu vào nam giới. Điều này cần được lưu ý khi phân tích vì có thể ảnh hưởng đến tính đại diện và kết quả nghiên cứu liên quan đến các yếu tố sức khỏe hoặc đặc điểm khác theo giới.

ggplot(data = dulieu, aes(x = Gender)) +
  geom_bar(fill = "steelblue") +
  labs(title = "Biểu đồ tần số biến Giới tính",
       x = "Giới tính",
       y = "Tần số") +
  theme_minimal()

2.2 Biến Country

country_freq <- table(dulieu$Country)
country_percent <- prop.table(country_freq) * 100
country_summary <- data.frame(
  Quốc_gia = names(country_freq),
  Tần_số = as.vector(country_freq),
  Tỷ_lệ_phần_trăm = round(country_percent, 2)
)
print(country_summary, row.names = FALSE)

Bảng phân phối tần số và tỷ lệ phần trăm theo quốc gia phản ánh sự đa dạng trong dữ liệu, tuy nhiên tập trung chủ yếu ở một số quốc gia nhất định. Hoa Kỳ chiếm phần lớn với 751 quan sát, tương đương 59.65%, tiếp theo là Vương quốc Anh với 185 quan sát (14.69%). Các quốc gia khác đều có tỷ lệ rất thấp, đa số dưới 1%, dẫn đến phân bố không đồng đều. Sự tập trung mạnh ở các quốc gia phát triển như Mỹ và Anh có thể ảnh hưởng đến tính đại diện của dữ liệu khi phân tích. Điều này cần được cân nhắc kỹ lưỡng để tránh kết luận sai lệch hoặc áp dụng không phù hợp cho các nhóm dân số đa dạng về quốc gia.

ggplot(data = dulieu, aes(y = Country)) +
  geom_bar(fill = "steelblue") +
  labs(title = "Biểu đồ tần số biến Quốc gia",
       x = "Tần số",
       y = "Quốc gia") +
  theme_minimal()

2.3 Biến family_history

family_freq <- table(dulieu$family_history)
family_percent <- prop.table(family_freq) * 100

family_summary <- data.frame(
  Tiền_sử_gia_đình = names(family_freq),
  Tần_số = as.vector(family_freq),
  Tỷ_lệ_phần_trăm = round(family_percent, 2)
)
print(family_summary)

Phân bố biến “Tiền sử gia đình” cho thấy 60.92% người tham gia không có tiền sử bệnh trong gia đình, trong khi 39.08% còn lại có tiền sử bệnh. Tỷ lệ này cho thấy một phần đáng kể mẫu khảo sát có yếu tố di truyền hoặc liên quan đến tiền sử bệnh gia đình, điều này có thể ảnh hưởng đến nguy cơ và các kết quả sức khỏe trong các phân tích tiếp theo.

ggplot(data = dulieu, aes(x = family_history)) +
  geom_bar(fill = "steelblue") +
  labs(title = "Biểu đồ tần số biến Family History",
       x = "Family History",
       y = "Tần số") +
  theme_minimal()

2.4 Biến treatment

treatment_freq <- table(dulieu$treatment)
treatment_percent <- prop.table(treatment_freq) * 100
treatment_summary <- data.frame(
  Treatment = names(treatment_freq),
  Tần_số = as.vector(treatment_freq),
  Tỷ_lệ_phần_trăm = round(treatment_percent, 2)
)
print(treatment_summary)

Phân bố biến “Treatment” cho thấy tỷ lệ giữa hai nhóm gần như cân bằng, với 49.4% người tham gia không điều trị và 50.6% có điều trị. Điều này giúp đảm bảo tính đại diện và cân đối trong phân tích tác động của việc điều trị đối với các biến khác trong dữ liệu.

ggplot(dulieu, aes(x = treatment)) +
  geom_bar(fill = "steelblue") +
  labs(title = "Biểu đồ tần số biến Treatment",
       x = "Treatment",
       y = "Tần số") +
  theme_minimal()

2.5 Biến remote_work

remote_freq <- table(dulieu$remote_work)
remote_percent <- prop.table(remote_freq) * 100
remote_summary <- data.frame(
  Trạng_thái = names(remote_freq),
  Tần_số = as.vector(remote_freq),
  Tỷ_lệ_phần_trăm = round(remote_percent, 2)
)
print(remote_summary, row.names = FALSE)

Biến Remote Work phản ánh tình trạng làm việc từ xa của người tham gia khảo sát, trong đó có 883 trường hợp (chiếm 70.14%) không làm việc từ xa, trong khi 376 trường hợp (chiếm 29.86%) có trạng thái làm việc từ xa. Điều này cho thấy phần lớn người tham gia khảo sát không thực hiện hình thức làm việc từ xa trong khoảng thời gian thu thập dữ liệu.

library(ggplot2)
ggplot(dulieu, aes(x = remote_work)) +
  geom_bar(fill = "steelblue") +
  labs(title = "Biểu đồ tần số biến Remote Work",
       x = "Remote Work",
       y = "Tần số") +
  theme_minimal()

2.6 Biến tech_company

tech_freq <- table(dulieu$tech_company)
tech_percent <- prop.table(tech_freq) * 100
tech_summary <- data.frame(
  Giá_trị = names(tech_freq),
  Tần_số = as.vector(tech_freq),
  Tỷ_lệ_phần_trăm = round(tech_percent, 2)
)
print(tech_summary, row.names = FALSE)

Biến tech_company cho biết người tham gia khảo sát có làm việc trong công ty công nghệ hay không. Kết quả cho thấy đa số người tham gia (1,031 trường hợp, tương ứng 81.89%) làm việc tại các công ty công nghệ, trong khi chỉ có 228 trường hợp (18.11%) không thuộc nhóm này. Điều này phản ánh rằng dữ liệu chủ yếu tập trung vào nhóm người làm việc trong ngành công nghệ, có thể ảnh hưởng đến đặc điểm và kết quả phân tích tổng thể của nghiên cứu.

ggplot(dulieu, aes(x = tech_company)) +
  geom_bar(fill = "steelblue") +
  labs(title = "Biểu đồ tần số biến Tech Company",
       x = "Tech Company",
       y = "Tần số") +
  theme_minimal()

3. Ước lượng Khoảng và Kiểm định Giả thuyết cho Tỷ lệ (Một biến)

3.1 hạng mục quan tâm

Mỗi biến ta chọn 1 hạng mục quan tâm, cụ thể: Hạng mục “Female” (nữ) của biến “Gender” (giới tính) Hạng mục “Canada” (Canada) của biến “Country” (quốc gia) Hạng mục “Yes” (có) của biến “family_history” (tiền sử gia đình) Hạng mục “Yes” (có) của biến “treatment” (điều trị) Hạng mục “Yes” (có) của biến “remote_work” (làm việc từ xa) Hạng mục “Yes” (có) của biến “tech_company” (công ty công nghệ) # 3.1.1 Hạng mục “Female” (nữ) của biến “Gender” (giới tính)

x <- sum(dulieu$Gender == "Female")
n <- length(dulieu$Gender)
p_hat <- x / n
alpha <- 0.05
z <- qnorm(1 - alpha / 2)
se <- sqrt(p_hat * (1 - p_hat) / n)
lower <- p_hat - z * se
upper <- p_hat + z * se
cat("Tỷ lệ mẫu (Female) =", round(p_hat, 4), "\n")
cat("Khoảng tin cậy 95%: [", round(lower, 4), ",", round(upper, 4), "]\n")
p0 <- 0.5
z_stat <- (p_hat - p0) / se
p_value <- 2 * (1 - pnorm(abs(z_stat)))
cat("Thống kê z =", round(z_stat, 4), "\n")
cat("Giá trị p =", format.pval(p_value, digits = 4), "\n")
if (p_value < alpha) {
  cat("Kết luận: Bác bỏ giả thuyết không. Tỉ lệ nữ khác 50%.\n")
} else {
  cat("Kết luận: Không đủ bằng chứng bác bỏ giả thuyết không.\n")
}

3.1.2 Hạng mục “Canada” (Canada) của biến “Country” (quốc gia)

x_canada <- sum(dulieu$Country == "Canada")
n_canada <- length(dulieu$Country)
p_hat_canada <- x_canada / n_canada
alpha <- 0.05
z <- qnorm(1 - alpha / 2)
se_canada <- sqrt(p_hat_canada * (1 - p_hat_canada) / n_canada)
lower_canada <- p_hat_canada - z * se_canada
upper_canada <- p_hat_canada + z * se_canada
cat("Tỷ lệ mẫu (Canada) =", round(p_hat_canada, 4), "\n")
cat("Khoảng tin cậy 95% (Canada): [", round(lower_canada, 4), ",", round(upper_canada, 4), "]\n")
p0 <- 0.05
z_stat_canada <- (p_hat_canada - p0) / se_canada
p_value_canada <- 2 * (1 - pnorm(abs(z_stat_canada)))
cat("Thống kê z =", round(z_stat_canada, 4), "\n")
cat("Giá trị p =", format.pval(p_value_canada, digits = 4), "\n")
if (p_value_canada < alpha) {
  cat("Kết luận: Bác bỏ giả thuyết không. Tỷ lệ Canada khác 5%.\n")
} else {
  cat("Kết luận: Không đủ bằng chứng bác bỏ giả thuyết không.\n")
}

3.1.3 Hạng mục “yes” (có) của biến “family_history” (tiền sử gia đình)

x_fh <- sum(dulieu$family_history == "yes")
n_fh <- length(dulieu$family_history)
p_hat_fh <- x_fh / n_fh
alpha <- 0.05
z <- qnorm(1 - alpha / 2)
se_fh <- sqrt(p_hat_fh * (1 - p_hat_fh) / n_fh)
lower_fh <- p_hat_fh - z * se_fh
upper_fh <- p_hat_fh + z * se_fh
cat("Tỷ lệ mẫu (family_history = yes) =", round(p_hat_fh, 4), "\n")
cat("Khoảng tin cậy 95% (family_history = yes): [", round(lower_fh, 4), ",", round(upper_fh, 4), "]\n")
p0 <- 0.5
z_stat_fh <- (p_hat_fh - p0) / se_fh
p_value_fh <- 2 * (1 - pnorm(abs(z_stat_fh)))
cat("Thống kê z =", round(z_stat_fh, 4), "\n")
cat("Giá trị p =", format.pval(p_value_fh, digits = 4), "\n")
if (p_value_fh < alpha) {
  cat("Kết luận: Bác bỏ giả thuyết không. Tỷ lệ family_history = yes khác 50%.\n")
} else {
  cat("Kết luận: Không đủ bằng chứng bác bỏ giả thuyết không.\n")
}

3.1.4 Hạng mục “Yes” (có) của biến “treatment” (điều trị)

x_treat <- sum(dulieu$treatment == "yes")
n_treat <- length(dulieu$treatment)
p_hat_treat <- x_treat / n_treat
alpha <- 0.05
z <- qnorm(1 - alpha / 2)
se_treat <- sqrt(p_hat_treat * (1 - p_hat_treat) / n_treat)
lower_treat <- p_hat_treat - z * se_treat
upper_treat <- p_hat_treat + z * se_treat
cat("Tỷ lệ mẫu (treatment = yes) =", round(p_hat_treat, 4), "\n")
cat("Khoảng tin cậy 95% (treatment = yes): [", round(lower_treat, 4), ",", round(upper_treat, 4), "]\n")
p0 <- 0.5
z_stat_treat <- (p_hat_treat - p0) / se_treat
p_value_treat <- 2 * (1 - pnorm(abs(z_stat_treat)))
cat("Thống kê z =", round(z_stat_treat, 4), "\n")
cat("Giá trị p =", format.pval(p_value_treat, digits = 4), "\n")
if (p_value_treat < alpha) {
  cat("Kết luận: Bác bỏ giả thuyết không. Tỷ lệ treatment = yes khác 50%.\n")
} else {
  cat("Kết luận: Không đủ bằng chứng bác bỏ giả thuyết không.\n")
}

3.1.5 Hạng mục “Yes” (có) của biến “remote_work” (làm việc từ xa)

x_remote <- sum(dulieu$remote_work == "yes")
n_remote <- length(dulieu$remote_work)
p_hat_remote <- x_remote / n_remote
alpha <- 0.05
z <- qnorm(1 - alpha / 2)
se_remote <- sqrt(p_hat_remote * (1 - p_hat_remote) / n_remote)
lower_remote <- p_hat_remote - z * se_remote
upper_remote <- p_hat_remote + z * se_remote
cat("Tỷ lệ mẫu (remote_work = yes) =", round(p_hat_remote, 4), "\n")
cat("Khoảng tin cậy 95% (remote_work = yes): [", round(lower_remote, 4), ",", round(upper_remote, 4), "]\n")
p0 <- 0.5
z_stat_remote <- (p_hat_remote - p0) / se_remote
p_value_remote <- 2 * (1 - pnorm(abs(z_stat_remote)))
cat("Thống kê z =", round(z_stat_remote, 4), "\n")
cat("Giá trị p =", format.pval(p_value_remote, digits = 4), "\n")
if (p_value_remote < alpha) {
  cat("Kết luận: Bác bỏ giả thuyết không. Tỷ lệ remote_work = yes khác 50%.\n")
} else {
  cat("Kết luận: Không đủ bằng chứng bác bỏ giả thuyết không.\n")
}

3.1.6 Hạng mục “Yes” (có) của biến “tech_company” (công ty công nghệ)

x_tech <- sum(dulieu$tech_company == "yes")
n_tech <- length(dulieu$tech_company)
p_hat_tech <- x_tech / n_tech
alpha <- 0.05
z <- qnorm(1 - alpha / 2)
se_tech <- sqrt(p_hat_tech * (1 - p_hat_tech) / n_tech)
lower_tech <- p_hat_tech - z * se_tech
upper_tech <- p_hat_tech + z * se_tech
cat("Tỷ lệ mẫu (tech_company = yes) =", round(p_hat_tech, 4), "\n")
cat("Khoảng tin cậy 95% (tech_company = yes): [", round(lower_tech, 4), ",", round(upper_tech, 4), "]\n")
p0 <- 0.5
z_stat_tech <- (p_hat_tech - p0) / se_tech
p_value_tech <- 2 * (1 - pnorm(abs(z_stat_tech)))
cat("Thống kê z =", round(z_stat_tech, 4), "\n")
cat("Giá trị p =", format.pval(p_value_tech, digits = 4), "\n")
if (p_value_tech < alpha) {
  cat("Kết luận: Bác bỏ giả thuyết không. Tỷ lệ tech_company = yes khác 50%.\n")
} else {
  cat("Kết luận: Không đủ bằng chứng bác bỏ giả thuyết không.\n")
}

4.Phân tích Mối quan hệ giữa Hai biến Định tính (Bivariate Analysis)

4.1 Biến “Treatment” và “Remote_work”

v <- table(Treatment = dulieu$treatment, RemoteWork = dulieu$remote_work)
addmargins(v)

Bảng tần số chéo giữa Treatment (Việc tham gia điều trị) và RemoteWork (Làm việc từ xa) cho thấy: - Trong nhóm không tham gia điều trị (Treatment = No), số người làm việc không từ xa là 444, trong khi làm việc từ xa là 178. - Trong nhóm tham gia điều trị (Treatment = Yes), số người làm việc không từ xa là 439, làm việc từ xa là 198. - Tổng số người làm việc không từ xa là 883, trong khi làm việc từ xa là 376. => Phân bố số lượng giữa các nhóm Treatment theo trạng thái làm việc từ xa và không từ xa tương đối đồng đều, không có sự chênh lệch lớn giữa hai nhóm. Điều này gợi ý rằng việc tham gia điều trị có thể không ảnh hưởng rõ rệt đến việc làm việc từ xa trong mẫu dữ liệu này.


ggplot(dulieu, aes(x = treatment, fill = remote_work)) +
  geom_bar(position = "dodge") +
  labs(
    title = "Phân bố Treatment theo trạng thái Remote Work",
    x = "Treatment (Việc tham gia điều trị)",
    y = "Số lượng",
    fill = "Remote Work (Làm việc từ xa)"
  ) +
  theme_minimal()
chisq.test(table(dulieu$treatment, dulieu$remote_work))

Kết quả kiểm định Chi-square cho thấy giá trị thống kê X-squared = 0.79963 với bậc tự do = 1 và p-value = 0.3712. Vì p-value > 0.05, ta không đủ bằng chứng để bác bỏ giả thuyết không, tức là không có mối liên hệ có ý nghĩa thống kê giữa việc tham gia Treatment và trạng thái làm việc từ xa trong mẫu dữ liệu này. Nói cách khác, việc tham gia điều trị không ảnh hưởng đáng kể đến việc làm việc từ xa của người tham gia ## 4.2 Biến “Family_history” và “Country”

v <- table(dulieu$family_history, dulieu$Country)
addmargins(v)

Bảng tần số chéo thể hiện phân bố tình trạng tiền sử bệnh gia đình (family history) theo quốc gia (country) cho thấy: - Ở nhiều quốc gia như United States (Hoa Kỳ), United Kingdom (Vương quốc Anh), Australia (Úc), số lượng người không có tiền sử bệnh gia đình (No - Không) chiếm ưu thế so với người có tiền sử (Yes - Có). - Một số quốc gia như Zimbabwe (Zimbabwe), South Africa (Nam Phi), Mexico (Mexico), Ireland (Ireland) có tỷ lệ người có tiền sử gia đình tương đối cao so với tổng số. - Tổng thể dữ liệu cho thấy số người không có tiền sử gia đình (767) nhiều hơn người có tiền sử (492 ).Nhận xét sơ bộ cho thấy sự phân bố tiền sử bệnh gia đình khác nhau theo quốc gia, nhưng để kết luận chính xác về sự khác biệt có ý nghĩa thống kê giữa các quốc gia với tiền sử gia đình, cần thực hiện kiểm định Chi-square hoặc các phương pháp phân tích phù hợp khác.Ngoài ra, sự khác biệt này cũng có thể bị ảnh hưởng bởi kích thước mẫu ở từng quốc gia khác nhau (có quốc gia rất ít mẫu như Slovenia, Bahamas), do đó khi phân tích cần cân nhắc yếu tố này để tránh sai lệch kết quả.

df_summary <- dulieu %>%
  group_by(Country, family_history) %>%
  summarise(count = n()) %>%
  ungroup()
ggplot(df_summary, aes(x = count, y = reorder(Country, count), fill = family_history)) +
  geom_col(position = "dodge") +
  labs(
    title = "Phân bố tiền sử bệnh gia đình theo quốc gia",
    x = "Số lượng",
    y = "Quốc gia (Country)",
    fill = "Tiền sử bệnh gia đình\n(Family History)"
  ) +
  theme_minimal()
chisq.test(table(dulieu$family_history, dulieu$Country))

Kết quả kiểm định Chi-square với giá trị X-squared = 60.461, bậc tự do = 47 và p-value = 0.08985 cho thấy: Vì p-value > 0.05, không đủ bằng chứng để bác bỏ giả thuyết không. Điều này nghĩa là không có mối liên hệ có ý nghĩa thống kê giữa biến tiền sử bệnh gia đình (family_history) và quốc gia (Country) trong mẫu dữ liệu này. Tuy nhiên, p-value khá gần mức 0.05, cho thấy có thể có xu hướng khác biệt nhưng chưa đủ mạnh để kết luận chắc chắn.