## Warning: package 'readxl' was built under R version 4.5.1

1. Thông tin cơ bản về dữ liệu

1.1. Kích thước bộ dữ liệu

dim(data)
## [1] 100000     17

Kết luận

Bộ dữ liệu gồm 100.000 quan sát và 17 biến, cho thấy đây là một tập dữ liệu lớn, giàu thông tin, đủ để thực hiện các phân tích thống kê mô tả và mô hình dự đoán với độ tin cậy cao. Quy mô này giúp kết quả phân tích có tính đại diện tốt và giảm sai số ngẫu nhiên.

1.2. Tên các biến

names(data)
##  [1] "year"                 "gender"               "age"                 
##  [4] "location"             "race:AfricanAmerican" "race:Asian"          
##  [7] "race:Caucasian"       "race:Hispanic"        "race:Other"          
## [10] "hypertension"         "heart_disease"        "smoking_history"     
## [13] "bmi"                  "hbA1c_level"          "blood_glucose_level" 
## [16] "diabetes"             "clinical_notes"

Kết luận

Các biến được tổ chức hợp lý, bao quát thông tin nhân khẩu học (age, gender, location), đặc điểm chủng tộc (race.*), chỉ số y tế (bmi, hbA1c_level, blood_glucose_level, hypertension, heart_disease) và hành vi sức khỏe (smoking_history), cùng biến nhãn diabetes thể hiện tình trạng bệnh. Cấu trúc này cho phép phân tích cả yếu tố cá nhân lẫn lối sống ảnh hưởng đến nguy cơ tiểu đường.

1.3. Số lượng biến định tính và định lượng

1.3.1. Số biến định lượng

sum(sapply(data, is.numeric)) 
## [1] 13

1.3.2. Số biến định tính

sum(sapply(data, is.character) | sapply(data, is.factor))  
## [1] 4

Kết luận

Dữ liệu có 13 biến định lượng và 4 biến định tính, cho thấy phần lớn các biến là dạng số, thuận lợi cho việc tính toán, so sánh và mô hình hóa. Các biến định tính như gender, smoking_history, location giúp nhóm và phân loại đối tượng, hỗ trợ so sánh giữa các nhóm trong phân tích thống kê.

1.4. Kiểm tra dòng trùng lặp

sum(duplicated(data))
## [1] 14
data <- data[!duplicated(data), ]
sum(duplicated(data))
## [1] 0

Kết luận

Kết quả sum(duplicated(data)) = 14 cho thấy kết quả có 14 dòng trùng lặp trong 100.000 quan sát, chiếm tỷ lệ 0,014%, rất nhỏ. Điều này chứng tỏ dữ liệu được nhập khá chính xác, ít trùng lặp, có thể coi là sạch và ổn định để sử dụng trực tiếp trong các phân tích tiếp theo.

1.5. Kiểm tra giá trị bị thiếu

any(is.na(data))  
## [1] FALSE
colSums(is.na(data)) 
##                 year               gender                  age 
##                    0                    0                    0 
##             location race:AfricanAmerican           race:Asian 
##                    0                    0                    0 
##       race:Caucasian        race:Hispanic           race:Other 
##                    0                    0                    0 
##         hypertension        heart_disease      smoking_history 
##                    0                    0                    0 
##                  bmi          hbA1c_level  blood_glucose_level 
##                    0                    0                    0 
##             diabetes       clinical_notes 
##                    0                    0

Kết luận

Kết quả kiểm tra cho thấy không có giá trị bị thiếu (NA) trong toàn bộ bộ dữ liệu. Cụ thể, hàm any(is.na(data)) trả về FALSE, và tổng số giá trị NA ở tất cả các cột (colSums(is.na(data))) đều bằng 0.

1.6. Ý nghĩa của các biến

Tên biến Ý nghĩa
year Năm ghi nhận dữ liệu của bệnh nhân
gender Giới tính của người tham gia (Nam/Nữ)
age Tuổi của người tham gia (năm)
location Khu vực sinh sống hoặc nơi khám bệnh
race:AfricanAmerican Thuộc nhóm chủng tộc Người Mỹ gốc Phi (1: Có, 0: Không)
race:Asian Thuộc nhóm chủng tộc Châu Á (1: Có, 0: Không)
race:Caucasian Thuộc nhóm chủng tộc Da trắng (1: Có, 0: Không)
race:Hispanic Thuộc nhóm chủng tộc gốc Tây Ban Nha (1: Có, 0: Không)
race:Other Thuộc nhóm chủng tộc khác (1: Có, 0: Không)
hypertension Tình trạng tăng huyết áp (1: Có, 0: Không)
heart_disease Bệnh tim mạch (1: Có, 0: Không)
smoking_history Tiền sử hút thuốc (Never, Former, Current, Unknown)
bmi Chỉ số khối cơ thể (BMI) - đo độ béo cơ thể (kg/m²)
hbA1c_level Chỉ số HbA1c - phản ánh đường huyết trung bình 3 tháng gần nhất (%)
blood_glucose_level Nồng độ đường huyết hiện tại (mg/dL)
diabetes Tình trạng tiểu đường (1: Có, 0: Không)
clinical_notes Ghi chú lâm sàng hoặc nhận xét của bác sĩ

Kết luận

Các biến được định nghĩa rõ ràng và bao quát các khía cạnh quan trọng trong nghiên cứu tiểu đường. Nhóm age, gender, race.*, location mô tả đặc điểm cá nhân; nhóm bmi, hbA1c_level, blood_glucose_level, hypertension, heart_disease thể hiện tình trạng sức khỏe; smoking_history phản ánh hành vi lối sống; và diabetes là biến mục tiêu cho phân tích dự đoán. Cấu trúc biến rõ ràng, dễ hiểu và phù hợp cho cả mô tả thống kê lẫn mô hình dự báo.

1.7. TÓM TẮT VÀ KIỂM TRA TỔNG QUAN DỮ LIỆU

1.7.1. Năm ghi nhận dữ liệu (Year)

summary(data$year)
##    Min. 1st Qu.  Median    Mean 3rd Qu.    Max. 
##    2015    2019    2019    2018    2019    2022

Kết luận

Biến year cho biết năm ghi nhận thông tin bệnh nhân có giá trị từ 2015 đến 2022, chứng tỏ dữ liệu được thu thập liên tục qua nhiều năm, phản ánh tốt xu hướng theo thời gian.

1.7.2. Giới tính (Gender)

table(data$gender)
## 
## Female   Male  Other 
##  58546  41422     18

Kết luận

Kết quả thống kê cho thấy trong tổng số 99.986 quan sát, nhóm Female chiếm đa số (58.546 trường hợp), tiếp đến là Male (41.422 trường hợp), và Other chỉ có 18 trường hợp, chiếm tỷ lệ rất nhỏ.Điều này cho thấy mẫu dữ liệu có sự chênh lệch giới tính rõ rệt, với nữ giới chiếm ưu thế, có thể phản ánh thực tế rằng phụ nữ thường quan tâm đến sức khỏe và đi khám bệnh thường xuyên hơn, hoặc cũng có thể do đặc điểm thu thập dữ liệu của nghiên cứu.

1.7.3. Tuổi (Age)

summary(data$age)
##    Min. 1st Qu.  Median    Mean 3rd Qu.    Max. 
##    0.08   24.00   43.00   41.89   60.00   80.00

Kết luận

Biến age có giá trị dao động từ 0.08 đến 80 tuổi, trung bình khoảng 41.9 tuổi và trung vị 43 tuổi, cho thấy dữ liệu tập trung chủ yếu ở nhóm trung niên (30–60 tuổi). Điều này cho thấy phần lớn mẫu thuộc độ tuổi lao động, là nhóm có nguy cơ cao mắc các bệnh chuyển hóa như tiểu đường hoặc tăng huyết áp.

1.7.4. Khu vực (Location)

table(data$location)
## 
##              Alabama               Alaska              Arizona 
##                 2036                 2034                 1986 
##             Arkansas           California             Colorado 
##                 2037                 1986                 2035 
##          Connecticut             Delaware District of Columbia 
##                 2035                 2036                 2036 
##              Florida              Georgia                 Guam 
##                 2037                 2035                 1203 
##               Hawaii                Idaho             Illinois 
##                 2038                 1988                 2036 
##              Indiana                 Iowa               Kansas 
##                 1987                 2037                 2036 
##             Kentucky            Louisiana                Maine 
##                 2038                 2036                 2036 
##             Maryland        Massachusetts             Michigan 
##                 2034                 2036                 2036 
##            Minnesota          Mississippi             Missouri 
##                 2037                 2035                 2035 
##              Montana             Nebraska               Nevada 
##                 2033                 2037                 1985 
##        New Hampshire           New Jersey           New Mexico 
##                 2034                 2037                 2032 
##             New York       North Carolina         North Dakota 
##                 2035                 2035                 2034 
##                 Ohio             Oklahoma               Oregon 
##                 1985                 1985                 2036 
##         Pennsylvania          Puerto Rico         Rhode Island 
##                 2035                 1295                 2035 
##       South Carolina         South Dakota            Tennessee 
##                 1986                 2033                 1574 
##                Texas        United States                 Utah 
##                 1337                 1401                 1359 
##              Vermont       Virgin Islands             Virginia 
##                 1338                  763                 1350 
##           Washington        West Virginia            Wisconsin 
##                 1363                 1132                  388 
##              Wyoming 
##                  388

Kết luận

Biến ‘location’ thể hiện nơi cư trú hoặc cơ sở khám. Thông tin này có thể dùng để phân tích theo vùng địa lý hoặc khu vực điều trị. Dữ liệu được thu thập từ nhiều bang và vùng lãnh thổ của Hoa Kỳ, thể hiện phạm vi khảo sát rộng. Tuy nhiên, số mẫu giữa các bang không đồng đều, trong đó các bang đông dân như California, Texas, Florida có số liệu cao hơn, còn các bang nhỏ như Wyoming, Guam có ít hơn. Điều này phản ánh sự khác biệt về mật độ dân cư và khả năng tiếp cận dữ liệu giữa các khu vực.

1.7.5. Chủng tộc (Race)

table(data$race)
## Warning: Unknown or uninitialised column: `race`.
## < table of extent 0 >

Kết luận

Các biến chủng tộc được mã hóa nhị phân (1 = Có, 0 = Không). Giúp xác định phân bố dân tộc và xem sự khác biệt nguy cơ bệnh giữa các nhóm, trong đó nhóm phổ biến nhất là Caucasian (người da trắng), cho thấy sự đa dạng chủng tộc trong dữ liệu.

1.7.6. Tăng huyết áp (Hypertension)

summary(data$hypertension)
##    Min. 1st Qu.  Median    Mean 3rd Qu.    Max. 
## 0.00000 0.00000 0.00000 0.07486 0.00000 1.00000

Kết luận

Kết quả cho thấy giá trị trung bình của biến hypertension là 0.07486, nghĩa là khoảng 7.5% người trong mẫu mắc tăng huyết áp, trong khi phần lớn (median = 0) không mắc bệnh. Biến này được mã hóa nhị phân (0 = không, 1 = có), cho thấy số người không bị tăng huyết áp chiếm tỷ lệ áp đảo, phản ánh xu hướng chung trong quần thể mẫu.

1.7.7. Bệnh tim mạch (Heart disease)

summary(data$heart_disease)
##    Min. 1st Qu.  Median    Mean 3rd Qu.    Max. 
## 0.00000 0.00000 0.00000 0.03943 0.00000 1.00000

Kết luận

Giá trị trung bình của biến heart_disease là 0.03943, cho thấy khoảng 3,9% người trong mẫu mắc bệnh tim mạch, trong khi đa số (median = 0) không mắc bệnh. Biến này được mã hóa nhị phân (0 = không, 1 = có), phản ánh rằng tỷ lệ mắc bệnh tim mạch trong quần thể nghiên cứu tương đối thấp so với tổng số mẫu.

1.7.8. Tiền sử hút thuốc (Smoking history)

table(data$smoking_history)
## 
##     current        ever      former       never     No Info not current 
##        9286        4004        9352       35091       35806        6447

Kết luận

Kết quả cho thấy nhóm chưa từng hút thuốc (never) và không có thông tin (No Info) chiếm tỷ lệ lớn nhất, lần lượt hơn 35.000 mẫu, trong khi các nhóm đang hút (current), đã từng (former) và đã hút nhưng ngừng (ever) có số lượng thấp hơn đáng kể. Điều này cho thấy phần lớn đối tượng trong bộ dữ liệu không có hoặc chưa từng có thói quen hút thuốc, yếu tố quan trọng khi phân tích nguy cơ mắc bệnh tim mạch và tiểu đường.

1.7.9. Chỉ số khối cơ thể (BMI)

summary(data$bmi)
##    Min. 1st Qu.  Median    Mean 3rd Qu.    Max. 
##   10.01   23.63   27.32   27.32   29.58   95.69

Kết luận

Giá trị BMI dao động từ 10.01 đến 95.69, trung bình 27.32 và trung vị 27.32, cho thấy phần lớn đối tượng thuộc nhóm thừa cân nhẹ (BMI > 25). Một số trường hợp có BMI rất cao, thể hiện sự chênh lệch đáng kể về thể trạng trong mẫu nghiên cứu, có thể ảnh hưởng đến nguy cơ mắc bệnh tim mạch và tiểu đường.

1.7.10. Chỉ số HbA1c (đường huyết trung bình 3 tháng)

summary(data$hbA1c_level)
##    Min. 1st Qu.  Median    Mean 3rd Qu.    Max. 
##   3.500   4.800   5.800   5.528   6.200   9.000

Kết luận

Giá trị HbA1c dao động từ 3.5 đến 9.0, với trung bình 5.53 và trung vị 5.8, cho thấy phần lớn người trong mẫu có mức HbA1c trong giới hạn bình thường (<5.7%), trong khi một số trường hợp cao hơn ngưỡng này có thể nguy cơ tiền tiểu đường hoặc tiểu đường. Điều này phản ánh phần lớn đối tượng có kiểm soát đường huyết ổn định, nhưng vẫn tồn tại nhóm nhỏ cần theo dõi.

1.7.11. Nồng độ đường huyết hiện tại (Blood_glucose_level)

summary(data$blood_glucose_level)
##    Min. 1st Qu.  Median    Mean 3rd Qu.    Max. 
##    80.0   100.0   140.0   138.1   159.0   300.0

Kết luận

Chỉ số dao động từ 80–300 mg/dL. Giá trị trung bình khoảng 140, cao hơn ngưỡng bình thường (dưới 125), phù hợp với mẫu bệnh nhân có rối loạn đường huyết

1.7.12. Tình trạng tiểu đường (diabetes)

summary(data$diabetes)
##    Min. 1st Qu.  Median    Mean 3rd Qu.    Max. 
## 0.00000 0.00000 0.00000 0.08501 0.00000 1.00000

Kết luận

Giá trị trung bình của biến diabetes là 0.085, nghĩa là khoảng 8,5% người trong mẫu mắc bệnh tiểu đường, trong khi đa số (median = 0) không mắc bệnh. Biến này được mã hóa nhị phân (0 = không, 1 = có), cho thấy tỷ lệ người mắc tiểu đường trong dữ liệu tương đối thấp, nhưng vẫn đủ để phục vụ cho việc phân tích mối liên hệ giữa tiểu đường và các yếu tố nguy cơ khác như tuổi, BMI hay huyết áp.

1.7.13. Ghi chú lâm sàng (clinical_notes)

table(data$clinical_notes)

Kết luận

Biến clinical_notes là ghi chú văn bản từ bác sĩ hoặc chuyên viên y tế. Dữ liệu này có thể được khai thác bằng kỹ thuật xử lý ngôn ngữ tự nhiên (NLP)

2. Phân tổ các biến

Hàm cut() được sử dụng để chuyển các biến liên tục thành biến phân loại (categorical), giúp thuận tiện cho việc thống kê mô tả, so sánh nhóm và trực quan hóa dữ liệu.:

  • Tuổi: chia 3 nhóm (Trẻ, Trung niên, Cao tuổi).

  • BMI: phân loại theo tiêu chuẩn của Tổ chức Y tế Thế giới (WHO).

  • HbA1c và Glucose: phân loại theo mức bình thường, tiền tiểu đường và tiểu đường.

  • Giới tính: phân nhóm Male – Female – Other để so sánh tỷ lệ và khác biệt ở các chỉ số sức khỏe.

Việc phân tổ giúp so sánh tỷ lệ, mô tả và nhận diện nguy cơ trong từng nhóm cụ thể.

library(dplyr)
## Warning: package 'dplyr' was built under R version 4.5.1
## 
## Attaching package: 'dplyr'
## The following objects are masked from 'package:stats':
## 
##     filter, lag
## The following objects are masked from 'package:base':
## 
##     intersect, setdiff, setequal, union
library(scales)
library(knitr)
df2 <- data

2.1. Phân nhóm theo độ tuổi

if("age" %in% names(df2)){
  df2 <- df2 %>%
    mutate(age_group = cut(age,
                           breaks = c(-Inf, 17, 29, 44, 59, 74, Inf),
                           labels = c("0-17", "18-29", "30-44", "45-59", "60-74", "75+")))

  age_table <- df2 %>%
    group_by(age_group) %>%
    summarise(Tan_so = n()) %>%
    mutate(Ty_le = percent(Tan_so / sum(Tan_so)))

  kable(age_table, caption = "Bảng 2.1. Phân bố mẫu theo nhóm tuổi")
}
Bảng 2.1. Phân bố mẫu theo nhóm tuổi
age_group Tan_so Ty_le
0-17 17215 17.22%
18-29 15214 15.22%
30-44 19972 19.97%
45-59 22535 22.54%
60-74 15944 15.95%
75+ 9106 9.11%

Nhận xét

Kết quả cho thấy nhóm tuổi 45–59 chiếm tỷ lệ cao nhất (22,54%), tiếp theo là nhóm 30–44 (19,97%) và 0–17 (17,22%). Nhóm 75+ chiếm tỷ lệ thấp nhất (9,11%). Phân bố này cho thấy mẫu dữ liệu tập trung chủ yếu ở người trưởng thành và trung niên, là các nhóm tuổi có nguy cơ mắc bệnh tiểu đường cao hơn so với nhóm trẻ.

2.2. Phân tổ theo nhóm BMI

if("bmi" %in% names(df2)){
  df2 <- df2 %>%
    mutate(bmi_group = case_when(
      is.na(bmi) ~ NA_character_,
      bmi < 18.5 ~ "Gầy",
      bmi < 25   ~ "Bình thường",
      bmi < 30   ~ "Thừa cân",
      TRUE       ~ "Béo phì"))

  bmi_table <- df2 %>%
    group_by(bmi_group) %>%
    summarise(Tan_so = n()) %>%
    mutate(Ty_le = percent(Tan_so / sum(Tan_so)))

  kable(bmi_table, caption = "Bảng 2.2. Phân bố mẫu theo nhóm BMI")
}
Bảng 2.2. Phân bố mẫu theo nhóm BMI
bmi_group Tan_so Ty_le
Béo phì 23536 23.5%
Bình thường 22219 22.2%
Gầy 8494 8.5%
Thừa cân 45737 45.7%

Nhận xét

Kết quả cho thấy nhóm thừa cân chiếm tỷ lệ cao nhất (45,7%), tiếp theo là nhóm béo phì (23,5%) và bình thường (22,2%), trong khi nhóm gầy chỉ chiếm 8,5%. Phân bố này cho thấy phần lớn người trong mẫu có chỉ số BMI cao hơn mức chuẩn, phản ánh xu hướng thừa cân – béo phì phổ biến, đây cũng là yếu tố nguy cơ chính dẫn đến bệnh tiểu đường.

2.3. Phân nhóm theo mức đường huyết

if("blood_glucose_level" %in% names(df2)){
  q <- quantile(df2$blood_glucose_level, probs = c(0, 1/3, 2/3, 1), na.rm = TRUE)

  df2 <- df2 %>%
    mutate(glucose_level_group = cut(blood_glucose_level,
                                     breaks = unique(q),
                                     include.lowest = TRUE,
                                     labels = c("Thấp", "Trung bình", "Cao")))

  glucose_table <- df2 %>%
    group_by(glucose_level_group) %>%
    summarise(Tan_so = n()) %>%
    mutate(Ty_le = percent(Tan_so / sum(Tan_so)))

  kable(glucose_table, caption = "Bảng 2.3. Phân bố mẫu theo mức đường huyết")
}
Bảng 2.3. Phân bố mẫu theo mức đường huyết
glucose_level_group Tan_so Ty_le
Thấp 35838 35.8%
Trung bình 37803 37.8%
Cao 26345 26.3%

Nhận xét

Kết quả cho thấy nhóm đường huyết trung bình chiếm tỷ lệ cao nhất (37,8%), tiếp theo là nhóm thấp (35,8%) và cao (26,3%). Phân bố này phản ánh phần lớn người trong mẫu có mức đường huyết nằm trong hoặc gần ngưỡng bình thường, tuy nhiên tỷ lệ nhóm cao vẫn đáng chú ý, cho thấy có một bộ phận đáng kể có nguy cơ hoặc đang mắc tiểu đường, cần được theo dõi và can thiệp y tế.

2.4. Phân nhóm theo chỉ số HbA1c

if("hbA1c_level" %in% names(df2)){
  df2 <- df2 %>%
    mutate(hba1c_group = cut(hbA1c_level,
                             breaks = c(-Inf, 5.6, 6.4, Inf),
                             labels = c("Bình thường", "Tiền tiểu đường", "Tiểu đường")))

  hba1c_table <- df2 %>%
    group_by(hba1c_group) %>%
    summarise(Tan_so = n()) %>%
    mutate(Ty_le = percent(Tan_so / sum(Tan_so)))

  kable(hba1c_table, caption = "Bảng 2.4. Phân bố mẫu theo chỉ số HbA1c")
}
Bảng 2.4. Phân bố mẫu theo chỉ số HbA1c
hba1c_group Tan_so Ty_le
Bình thường 37851 37.9%
Tiền tiểu đường 41343 41.3%
Tiểu đường 20792 20.8%

Nhận xét

Kết quả cho thấy nhóm tiền tiểu đường chiếm tỷ lệ cao nhất (41,3%), tiếp theo là nhóm bình thường (37,9%) và nhóm tiểu đường (20,8%). Phân bố này phản ánh thực tế rằng phần lớn người trong mẫu đang ở giai đoạn nguy cơ – có chỉ số HbA1c cao hơn mức bình thường nhưng chưa đến ngưỡng bệnh. Điều này cho thấy nguy cơ tiềm ẩn về sức khỏe chuyển hóa khá lớn và cần được theo dõi, can thiệp sớm để phòng ngừa tiểu đường.

2.5. Phân nhóm theo giới tính

if("gender" %in% names(df2)){
  gender_table <- df2 %>%
    group_by(gender) %>%
    summarise(Tan_so = n()) %>%
    mutate(Ty_le = percent(Tan_so / sum(Tan_so)))

  kable(gender_table, caption = "Bảng 2.5. Phân bố mẫu theo giới tính")
}
Bảng 2.5. Phân bố mẫu theo giới tính
gender Tan_so Ty_le
Female 58546 59%
Male 41422 41%
Other 18 0%

Nhận xét

Kết quả cho thấy nữ giới chiếm 59%, trong khi nam giới chiếm 41%, và nhóm khác chỉ chiếm tỷ lệ rất nhỏ. Phân bố này cho thấy dữ liệu có sự chênh lệch nhẹ về giới tính, trong đó nữ giới chiếm ưu thế. Điều này có thể phản ánh thực tế rằng phụ nữ thường tham gia khám sức khỏe định kỳ và ghi nhận dữ liệu y tế nhiều hơn, giúp bộ dữ liệu có tính đại diện cao cho nhóm này.

3. Phân tích các biến

3.1. Phân tích biến Tuổi (Age)

summary(data$age)
##    Min. 1st Qu.  Median    Mean 3rd Qu.    Max. 
##    0.08   24.00   43.00   41.89   60.00   80.00
hist(data$age,
     main = "Phân bố độ tuổi của người tham gia",
     xlab = "Tuổi",
     col = "lightblue",
     border = "white")

Kết luận

Kết quả thống kê cho thấy độ tuổi dao động từ 0 đến 80, trung bình khoảng 41,9 tuổi, và trung vị 43 tuổi. Biểu đồ histogram cho thấy phân bố tuổi khá đồng đều, tập trung nhiều ở nhóm 30–60 tuổi, là độ tuổi lao động và cũng là nhóm có nguy cơ cao mắc các bệnh chuyển hóa như tiểu đường. Phân bố này cho thấy dữ liệu có tính đại diện tốt cho nhóm người trưởng thành.

3.2. Phân tích biến BMI

summary(data$bmi)
##    Min. 1st Qu.  Median    Mean 3rd Qu.    Max. 
##   10.01   23.63   27.32   27.32   29.58   95.69
hist(data$bmi,
     main = "Phân bố chỉ số BMI",
     xlab = "Giá trị BMI",
     col = "lightgreen",
     border = "white")

data$age_group <- cut(data$age,
                      breaks = c(0, 30, 50, 70, 100),
                      labels = c("Dưới 30", "30-50", "50-70", "Trên 70"),
                      include.lowest = TRUE)

aggregate(bmi ~ age_group, data = data, FUN = mean)
##   age_group      bmi
## 1   Dưới 30 24.02343
## 2     30-50 29.11149
## 3     50-70 29.52905
## 4   Trên 70 27.62677

Kết luận

BMI trung bình dao động quanh mức 25, tức là thừa cân nhẹ.

Kết quả của aggregate() cho thấy BMI tăng dần theo nhóm tuổi, phản ánh thực tế rằng người lớn tuổi có xu hướng tích tụ mỡ và giảm vận động.

3.3. Phân tích biến HbA1c (đường huyết trung bình 3 tháng)

summary(data$hbA1c_level)
##    Min. 1st Qu.  Median    Mean 3rd Qu.    Max. 
##   3.500   4.800   5.800   5.528   6.200   9.000
data$hba1c_group <- cut(data$hbA1c_level,
                        breaks = c(0, 5.6, 6.4, 12),
                        labels = c("Bình thường", "Tiền tiểu đường", "Tiểu đường"),
                        include.lowest = TRUE)

boxplot(data$hbA1c_level ~ data$hba1c_group,
        main = "Phân bố chỉ số HbA1c theo nhóm chẩn đoán",
        xlab = "Nhóm HbA1c",
        ylab = "Giá trị HbA1c",
        col = c("skyblue", "orange", "red"))

Biểu đồ boxplot cho thấy rõ ràng ba nhóm HbA1c có khoảng giá trị khác biệt rõ rệt.

Kết luận

Nhóm “Tiểu đường” có giá trị HbA1c trung bình cao nhất, vượt ngưỡng 6.5%.

Nhóm “Tiền tiểu đường” có độ phân tán rộng, thể hiện giai đoạn chuyển tiếp nguy cơ cao cần can thiệp sớm.

Nhóm “Bình thường” có HbA1c thấp và phân bố hẹp, cho thấy mức kiểm soát đường huyết nhìn chung ổn định.

4. Thống kê mô tả và kiểm tra đặc điểm phân bố dữ liệu

4.1. Thống kê mô tả

Mục tiêu của phần này là mô tả đặc điểm cơ bản của các biến định lượng trong bộ dữ liệu gồm tuổi (age), chỉ số khối cơ thể (BMI) và chỉ số HbA1c (hbA1c_level). Các chỉ tiêu thống kê được sử dụng gồm: trung bình, độ lệch chuẩn, độ lệch (skewness) và độ nhọn (kurtosis), nhằm đánh giá xu hướng phân bố của dữ liệu.

library(ggplot2)
library(dplyr)
library(e1071)  
## Warning: package 'e1071' was built under R version 4.5.1
library(readxl) 

data <- read_excel("D:/data.xlsx")

vars <- c("age", "bmi", "hbA1c_level")

for (v in vars) {
  cat("\n===== Phân tích biến:", v, "=====\n")
  cat("Trung bình:", mean(data[[v]], na.rm = TRUE), "\n")
  cat("Độ lệch chuẩn:", sd(data[[v]], na.rm = TRUE), "\n")
  cat("Hệ số lệch (Skewness):", skewness(data[[v]], na.rm = TRUE), "\n")
  cat("Độ nhọn (Kurtosis):", kurtosis(data[[v]], na.rm = TRUE), "\n")
}
## 
## ===== Phân tích biến: age =====
## Trung bình: 41.88586 
## Độ lệch chuẩn: 22.51684 
## Hệ số lệch (Skewness): -0.05197744 
## Độ nhọn (Kurtosis): -1.003885 
## 
## ===== Phân tích biến: bmi =====
## Trung bình: 27.32077 
## Độ lệch chuẩn: 6.636783 
## Hệ số lệch (Skewness): 1.043804 
## Độ nhọn (Kurtosis): 3.520405 
## 
## ===== Phân tích biến: hbA1c_level =====
## Trung bình: 5.527507 
## Độ lệch chuẩn: 1.070672 
## Hệ số lệch (Skewness): -0.06685176 
## Độ nhọn (Kurtosis): 0.2152572

Kết luận

Nhìn chung, các biến định lượng trong bộ dữ liệu có xu hướng phân bố gần chuẩn. Biến BMI thể hiện độ lệch phải rõ rệt, phù hợp với thực tế rằng có ít trường hợp béo phì so với người có chỉ số trung bình. Biến tuổi và HbA1c có phân bố tương đối cân đối, cho thấy dữ liệu đại diện khá tốt cho nhiều nhóm dân số khác nhau.

4.2. Phân bố và mật độ các biến

Kiểm tra hình dạng phân bố của các biến định lượng để nhận diện lệch/phân tán và các cụm giá trị nổi bật bằng biểu đồ histogram và đường mật độ density

plot_density <- function(df, var, color) {
  ggplot(df, aes(x = .data[[var]])) +
    geom_histogram(aes(y = ..density..),
                   bins = 30, fill = color, alpha = 0.5, color = "white") +
    geom_density(color = "black", linewidth = 1) +
    labs(
      title = paste("Phân bố và mật độ của biến", var),
      x = var, y = "Mật độ"
    ) +
    theme_minimal(base_size = 14)
}

Age

plot_density(data, "age", "lightblue")
## Warning: The dot-dot notation (`..density..`) was deprecated in ggplot2 3.4.0.
## ℹ Please use `after_stat(density)` instead.
## This warning is displayed once every 8 hours.
## Call `lifecycle::last_lifecycle_warnings()` to see where this warning was
## generated.

Đường mật độ tương đối phẳng, đỉnh nhẹ ở 40–60 tuổi → mẫu tập trung vào trung niên.

Phân bố gần đối xứng, lệch phải rất nhẹ; không thấy cụm ngoại lệ rõ rệt.

BMI

plot_density(data, "bmi", "lightgreen")

Đỉnh rõ ở ~24–28; đuôi phải kéo dài với một số giá trị rất cao → lệch phải mạnh.

Phần lớn quan sát ở bình thường–thừa cân, còn một nhóm nhỏ béo phì kéo đuôi.

HbA1c_level

plot_density(data, "hbA1c_level", "lightcoral")

Mật độ tạo cụm rõ quanh 5.8–6.2% (giáp ranh tiền tiểu đường); một số điểm cao >6.5% (nhóm tiểu đường).

Phân bố lệch phải nhẹ và có xu hướng đa đỉnh (bình thường – tiền bệnh – bệnh).

Nhận xét chung

Age: gần chuẩn, tập trung trung niên.

BMI: lệch phải mạnh, cho thấy thừa cân/béo phì là vấn đề nổi bật.

HbA1c: đa đỉnh quanh ngưỡng chẩn đoán, phản ánh bức tranh ba tầng (bình thường–tiền bệnh–bệnh).

=> Các đặc điểm phân bố này giải thích vì sao ở phần 2, nhóm thừa cân và tiền tiểu đường chiếm tỷ lệ cao; đồng thời gợi ý các phân tích tiếp theo nên stratify theo BMI/HbA1c và kiểm định khác biệt giữa các nhóm.

5. Phân tích tần số và tần suất tích lũy

Phân tích được thực hiện cho ba biến định lượng chính: Tuổi (Age), Chỉ số khối cơ thể (BMI), và Chỉ số HbA1c.

# Gọi thư viện
library(ggplot2)
library(dplyr)
library(knitr)
library(readxl) 

data <- read_excel("D:/data.xlsx")

phan_tich_tich_luy <- function(df, var, breaks, labels, title) {
  
  df$group <- cut(df[[var]], breaks = breaks, labels = labels, right = FALSE)
  
  freq_table <- df %>%
    group_by(group) %>%
    summarise(Tan_so = n()) %>%
    mutate(
      Tan_suat = Tan_so / sum(Tan_so),
      Tan_so_tich_luy = cumsum(Tan_so),
      Tan_suat_tich_luy = cumsum(Tan_suat)
    )
  
  print(kable(freq_table, caption = paste("Bảng. Tần số và tần suất tích lũy của biến", var)))
  
  p <- ggplot(freq_table, aes(x = group, y = Tan_suat_tich_luy, group = 1)) +
    geom_line(color = "steelblue", linewidth = 1.3) +
    geom_point(size = 3, color = "darkred") +
    labs(
      title = paste("Biểu đồ tần suất tích lũy của", title),
      x = title,
      y = "Tần suất tích lũy"
    ) +
    theme_minimal(base_size = 14)
  
  print(p)
}

breaks_age <- c(0, 18, 30, 45, 60, 75, Inf)
labels_age <- c("Dưới 18", "18–29", "30–44", "45–59", "60–74", "75+")
phan_tich_tich_luy(data, "age", breaks_age, labels_age, "Tuổi (Age)")
## 
## 
## Table: Bảng. Tần số và tần suất tích lũy của biến age
## 
## |group   | Tan_so| Tan_suat| Tan_so_tich_luy| Tan_suat_tich_luy|
## |:-------|------:|--------:|---------------:|-----------------:|
## |Dưới 18 |  17219|  0.17219|           17219|           0.17219|
## |18–29   |  15216|  0.15216|           32435|           0.32435|
## |30–44   |  19973|  0.19973|           52408|           0.52408|
## |45–59   |  22537|  0.22537|           74945|           0.74945|
## |60–74   |  15947|  0.15947|           90892|           0.90892|
## |75+     |   9108|  0.09108|          100000|           1.00000|

breaks_bmi <- c(0, 18.5, 25, 30, 35, 40, Inf)
labels_bmi <- c("Gầy", "Bình thường", "Thừa cân", "Béo phì I", "Béo phì II", "Béo phì nặng")
phan_tich_tich_luy(data, "bmi", breaks_bmi, labels_bmi, "Chỉ số khối cơ thể (BMI)")
## 
## 
## Table: Bảng. Tần số và tần suất tích lũy của biến bmi
## 
## |group        | Tan_so| Tan_suat| Tan_so_tich_luy| Tan_suat_tich_luy|
## |:------------|------:|--------:|---------------:|-----------------:|
## |Gầy          |   8494|  0.08494|            8494|           0.08494|
## |Bình thường  |  22219|  0.22219|           30713|           0.30713|
## |Thừa cân     |  45751|  0.45751|           76464|           0.76464|
## |Béo phì I    |  12737|  0.12737|           89201|           0.89201|
## |Béo phì II   |   6178|  0.06178|           95379|           0.95379|
## |Béo phì nặng |   4621|  0.04621|          100000|           1.00000|

breaks_hba1c <- c(0, 5.6, 6.5, 8, Inf)
labels_hba1c <- c("Bình thường", "Tiền tiểu đường", "Tiểu đường nhẹ", "Tiểu đường nặng")
phan_tich_tich_luy(data, "hbA1c_level", breaks_hba1c, labels_hba1c, "Chỉ số HbA1c (%)")
## 
## 
## Table: Bảng. Tần số và tần suất tích lũy của biến hbA1c_level
## 
## |group           | Tan_so| Tan_suat| Tan_so_tich_luy| Tan_suat_tich_luy|
## |:---------------|------:|--------:|---------------:|-----------------:|
## |Bình thường     |  37857|  0.37857|           37857|           0.37857|
## |Tiền tiểu đường |  41346|  0.41346|           79203|           0.79203|
## |Tiểu đường nhẹ  |  18821|  0.18821|           98024|           0.98024|
## |Tiểu đường nặng |   1976|  0.01976|          100000|           1.00000|

Từ các kết quả cho thấy:

-Tuổi: Khoảng 30–59 chiếm gần 70% tổng mẫu, thể hiện nhóm trung niên là chủ yếu.

-BMI: Khoảng 72% người có BMI dưới 30, nghĩa là phần lớn chưa đến mức béo phì.

-HbA1c: Khoảng 65% người có chỉ số HbA1c dưới 6.5%, nằm trong ngưỡng bình thường hoặc tiền tiểu đường.

Biểu đồ tần suất tích lũy minh họa xu hướng dữ liệu tăng dần ổn định, cho thấy phân bố hợp lý và phản ánh chính xác cấu trúc quần thể nghiên cứu.