1. Data Import and Integrity Check
# Direct path to downloaded CSV file
data_path <- "C:/Users/user/Downloads/archive (7)/alzheimers_disease_data.csv"
alzheimers <- read.csv(data_path)
# Verify dimensions and initial structure
dim(alzheimers)
## [1] 2149 35
str(alzheimers[, 1:8])
## 'data.frame': 2149 obs. of 8 variables:
## $ PatientID : int 4751 4752 4753 4754 4755 4756 4757 4758 4759 4760 ...
## $ Age : int 73 89 73 74 89 86 68 75 72 87 ...
## $ Gender : int 0 0 0 1 0 1 0 0 1 0 ...
## $ Ethnicity : int 0 0 3 0 0 1 3 0 1 0 ...
## $ EducationLevel : int 2 0 1 1 0 1 2 1 0 0 ...
## $ BMI : num 22.9 26.8 17.8 33.8 20.7 ...
## $ Smoking : int 0 0 0 1 0 0 1 0 0 1 ...
## $ AlcoholConsumption: num 13.3 4.54 19.56 12.21 18.45 ...
# Check for missing values across the dataset
missing_total <- sum(is.na(alzheimers))
cat("Total Missing Values in Dataset:", missing_total, "\n")
## Total Missing Values in Dataset: 0
2. Data Cleaning and Factor Recoding
# Create analysis copy
alz_clean <- alzheimers
# Recode binary variables to factors with clear labels
alz_clean$Diagnosis <- factor(alz_clean$Diagnosis, levels = c(0, 1), labels = c("No", "Yes"))
alz_clean$Gender <- factor(alz_clean$Gender, levels = c(0, 1), labels = c("Male", "Female"))
# Check class frequencies
table(Diagnosis = alz_clean$Diagnosis)
## Diagnosis
## No Yes
## 1389 760
prop.table(table(Diagnosis = alz_clean$Diagnosis)) * 100
## Diagnosis
## No Yes
## 64.63471 35.36529
3. Exploratory Data Analysis & Group Comparisons
# Summary table of clinical indicators grouped by Diagnosis
clinical_summary <- alz_clean %>%
group_by(Diagnosis) %>%
summarise(
Count = n(),
Mean_Age = mean(Age, na.rm = TRUE),
SD_Age = sd(Age, na.rm = TRUE),
Mean_MMSE = mean(MMSE, na.rm = TRUE),
SD_MMSE = sd(MMSE, na.rm = TRUE),
Mean_BMI = mean(BMI, na.rm = TRUE),
SD_BMI = sd(BMI, na.rm = TRUE)
)
clinical_summary
## # A tibble: 2 × 8
## Diagnosis Count Mean_Age SD_Age Mean_MMSE SD_MMSE Mean_BMI SD_BMI
## <fct> <int> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl>
## 1 No 1389 74.9 8.90 16.3 8.93 27.5 7.17
## 2 Yes 760 74.8 9.15 12.0 7.23 27.9 7.30
4. Visualizations
# 1. Boxplot of MMSE (Cognitive Function) by Diagnosis
ggplot(alz_clean, aes(x = Diagnosis, y = MMSE, fill = Diagnosis)) +
geom_boxplot(alpha = 0.7, outlier.colour = "red") +
theme_minimal() +
labs(
title = "MMSE Cognitive Score Distribution by Diagnosis",
x = "Alzheimer's Diagnosis",
y = "MMSE Score"
) +
theme(legend.position = "none")

# 2. Age Density Distribution across Diagnosis Groups
ggplot(alz_clean, aes(x = Age, fill = Diagnosis)) +
geom_density(alpha = 0.4) +
theme_minimal() +
labs(
title = "Age Density Distribution Across Diagnosis Groups",
x = "Age (Years)",
y = "Density"
)

5. Binary Logistic Regression Analysis
# Multivariable logistic regression model
logit_model <- glm(
Diagnosis ~ Age + Gender + BMI + MMSE,
data = alz_clean,
family = binomial(link = "logit")
)
summary(logit_model)
##
## Call:
## glm(formula = Diagnosis ~ Age + Gender + BMI + MMSE, family = binomial(link = "logit"),
## data = alz_clean)
##
## Coefficients:
## Estimate Std. Error z value Pr(>|z|)
## (Intercept) 0.165233 0.439463 0.376 0.707
## Age -0.001374 0.005178 -0.265 0.791
## GenderFemale -0.067322 0.093003 -0.724 0.469
## BMI 0.007743 0.006442 1.202 0.229
## MMSE -0.059972 0.005574 -10.759 <2e-16 ***
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
##
## (Dispersion parameter for binomial family taken to be 1)
##
## Null deviance: 2792.3 on 2148 degrees of freedom
## Residual deviance: 2666.9 on 2144 degrees of freedom
## AIC: 2676.9
##
## Number of Fisher Scoring iterations: 4
# Compute Odds Ratios (OR) and 95% Wald Confidence Intervals
odds_ratios <- exp(coef(logit_model))
conf_intervals <- exp(confint.default(logit_model))
model_table <- cbind(
Odds_Ratio = odds_ratios,
conf_intervals,
p_value = summary(logit_model)$coefficients[, 4]
)
round(model_table, 4)
## Odds_Ratio 2.5 % 97.5 % p_value
## (Intercept) 1.1797 0.4985 2.7915 0.7069
## Age 0.9986 0.9885 1.0088 0.7908
## GenderFemale 0.9349 0.7791 1.1218 0.4691
## BMI 1.0078 0.9951 1.0206 0.2294
## MMSE 0.9418 0.9316 0.9521 0.0000
6. Model Evaluation and ROC Curve
# Generate predicted probabilities
alz_clean$pred_prob <- predict(logit_model, type = "response")
# Classification at default 0.5 threshold
alz_clean$pred_class <- factor(
ifelse(alz_clean$pred_prob >= 0.5, "Yes", "No"),
levels = c("No", "Yes")
)
# Confusion Matrix & Classification Accuracy
conf_mat <- table(Predicted = alz_clean$pred_class, Actual = alz_clean$Diagnosis)
print(conf_mat)
## Actual
## Predicted No Yes
## No 1231 630
## Yes 158 130
accuracy <- sum(diag(conf_mat)) / sum(conf_mat)
cat("Classification Accuracy:", round(accuracy * 100, 2), "%\n")
## Classification Accuracy: 63.33 %
# ROC Curve and Area Under the Curve (AUC)
roc_curve <- roc(alz_clean$Diagnosis, alz_clean$pred_prob, levels = c("No", "Yes"))
cat("Area Under Curve (AUC):", round(auc(roc_curve), 4), "\n")
## Area Under Curve (AUC): 0.6441
plot(roc_curve, col = "#1B4F72", lwd = 2.5, main = "ROC Curve: Alzheimer's Diagnosis Model")
abline(a = 0, b = 1, lty = 2, col = "gray60")

7. Discussion and Summary
- Cognitive Function (MMSE): MMSE is the primary
protective predictor (\(OR = 0.9418\),
\(p < 0.001\)). A one-unit increase
in cognitive score corresponds to an approximate 6% reduction in the
odds of an Alzheimer’s diagnosis.
- Demographics and Lifestyle (Age, Gender, BMI):
Holding cognitive score constant, age, gender, and BMI do not show
statistically significant associations with diagnosis status in this
sample.
- Classification Performance: The model provides a
baseline discriminative score quantified by the ROC-AUC for
differentiating diagnostic outcomes.