## Warning: package 'readxl' was built under R version 4.5.1
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.
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.
sum(sapply(data, is.numeric))
## [1] 13
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ê.
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.
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.
| 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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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
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.
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)
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
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")
}
| 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ẻ.
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")
}
| 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.
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")
}
| 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ế.
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")
}
| 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.
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")
}
| 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.
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.
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.
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.
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.
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.
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.