epilepsy <- read_csv("/Users/drlakeshialegettejones/Downloads/dataset.csv") %>%
clean_names()
glimpse(epilepsy)
## Rows: 1,000
## Columns: 30
## $ age <dbl> 15, 4, 36, 32, 29, 18, 14, 70, 12, 76…
## $ gender <chr> "Male", "Female", "Female", "Female",…
## $ weight <dbl> 48.3, 56.0, 44.8, 70.4, 54.5, 62.1, 5…
## $ height <dbl> 168.2, 174.5, 156.2, 180.4, 161.7, 16…
## $ medication_status <chr> "On Medication", "On Medication", "On…
## $ alcohol_or_drug_use <chr> "Yes", "No", "No", "No", "No", "No", …
## $ eeg_abnormality_detected <chr> "Yes", "Yes", "Yes", "Yes", "Yes", "Y…
## $ mri_ct_scan_result <chr> "Normal", "Abnormal", "Abnormal", "No…
## $ seizure_frequency <dbl> 1, 1, 3, 0, 1, 1, 2, 1, 1, 5, 3, 1, 0…
## $ seizure_duration <dbl> 60, 30, 30, 60, 60, 30, 30, 30, 90, 3…
## $ seizure_type <chr> "Tonic-Clonic", "Generalized", "Tonic…
## $ aura_before_seizure <chr> "No", "Yes", "Yes", "Yes", "No", "Yes…
## $ loss_of_consciousness <chr> "Yes", "Yes", "No", "Yes", "Yes", "Ye…
## $ muscle_stiffness <chr> "No", "Yes", "Yes", "No", "Yes", "No"…
## $ jerky_movements <chr> "Yes", "Yes", "Yes", "Yes", "Yes", "Y…
## $ postictal_confusion <chr> "Yes", "Yes", "No", "Yes", "Yes", "Ye…
## $ blank_stare_episodes <chr> "No", "No", "Yes", "Yes", "No", "Yes"…
## $ eye_rolling <chr> "Yes", "No", "Yes", "No", "No", "No",…
## $ stress_or_anxiety_before_episode <chr> "Yes", "No", "Yes", "Yes", "Yes", "Ye…
## $ lack_of_sleep_before_episode <chr> "Yes", "No", "No", "Yes", "No", "Yes"…
## $ flashing_lights_sensitivity <chr> "Yes", "No", "No", "Yes", "No", "Yes"…
## $ loud_sound_sensitivity <chr> "Yes", "No", "Yes", "Yes", "Yes", "No…
## $ missed_medication <chr> "No", "No", "Yes", "No", "No", "No", …
## $ family_history_of_epilepsy <chr> "No", "Yes", "Yes", "No", "Yes", "Yes…
## $ head_injury_history <chr> "No", "Yes", "No", "No", "No", "No", …
## $ brain_tumor <chr> "No", "Yes", "No", "No", "Yes", "No",…
## $ history_of_stroke <chr> "No", "No", "No", "No", "No", "No", "…
## $ genetic_disorder <chr> "No", "No", "No", "No", "No", "No", "…
## $ developmental_delay_in_children <chr> "Yes", "No", "No", "No", "No", "No", …
## $ target_epilepsy_type <chr> "Generalized", "Generalized", "Genera…
epilepsy <- epilepsy %>%
mutate(
age_group = case_when(
age >= 12 & age <= 19 ~ "Adolescent",
age >= 20 ~ "Adult",
age < 12 ~ "Child"
),
age_group = factor(age_group, levels = c("Adolescent", "Adult", "Child"))
)
analysis_data <- epilepsy %>%
filter(age_group %in% c("Adolescent", "Adult")) %>%
mutate(age_group = droplevels(age_group))
analysis_data %>%
count(age_group) %>%
mutate(percent = round(100 * n / sum(n), 1))
## # A tibble: 2 × 3
## age_group n percent
## <fct> <int> <dbl>
## 1 Adolescent 92 10.6
## 2 Adult 773 89.4
analysis_data %>%
group_by(age_group) %>%
summarise(
n = n(),
mean_age = mean(age, na.rm = TRUE),
sd_age = sd(age, na.rm = TRUE),
mean_weight = mean(weight, na.rm = TRUE),
sd_weight = sd(weight, na.rm = TRUE),
mean_height = mean(height, na.rm = TRUE),
sd_height = sd(height, na.rm = TRUE)
)
## # A tibble: 2 × 8
## age_group n mean_age sd_age mean_weight sd_weight mean_height sd_height
## <fct> <int> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl>
## 1 Adolescent 92 15.2 2.11 64.1 15.3 165. 9.27
## 2 Adult 773 49.7 17.6 66.1 15.3 165. 10.3
analysis_data %>%
count(age_group, gender) %>%
group_by(age_group) %>%
mutate(percent = round(100 * n / sum(n), 1))
## # A tibble: 6 × 4
## # Groups: age_group [2]
## age_group gender n percent
## <fct> <chr> <int> <dbl>
## 1 Adolescent Female 30 32.6
## 2 Adolescent Male 60 65.2
## 3 Adolescent Other 2 2.2
## 4 Adult Female 332 42.9
## 5 Adult Male 424 54.9
## 6 Adult Other 17 2.2
ggplot(analysis_data, aes(x = age, fill = age_group)) +
geom_histogram(bins = 30, alpha = 0.7, position = "identity") +
labs(
title = "Age Distribution by Group",
x = "Age",
y = "Count"
)
ggplot(analysis_data, aes(x = gender, fill = age_group)) +
geom_bar(position = "dodge") +
labs(
title = "Gender Distribution by Age Group",
x = "Gender",
y = "Count"
)
symptom_vars <- c(
"aura_before_seizure",
"loss_of_consciousness",
"muscle_stiffness",
"jerky_movements",
"postictal_confusion",
"blank_stare_episodes",
"eye_rolling"
)
risk_vars <- c(
"alcohol_or_drug_use",
"stress_or_anxiety_before_episode",
"lack_of_sleep_before_episode",
"flashing_lights_sensitivity",
"loud_sound_sensitivity",
"missed_medication",
"family_history_of_epilepsy",
"head_injury_history",
"brain_tumor",
"history_of_stroke",
"genetic_disorder"
)
clinical_vars <- c(
"medication_status",
"eeg_abnormality_detected",
"mri_ct_scan_result",
"seizure_frequency",
"seizure_duration",
"seizure_type",
"target_epilepsy_type"
)
analysis_data %>%
select(age_group, all_of(symptom_vars)) %>%
pivot_longer(
cols = all_of(symptom_vars),
names_to = "symptom",
values_to = "response"
) %>%
count(age_group, symptom, response) %>%
group_by(age_group, symptom) %>%
mutate(percent = 100 * n / sum(n)) %>%
filter(response == "Yes") %>%
ggplot(aes(x = symptom, y = percent, fill = age_group)) +
geom_col(position = "dodge") +
coord_flip() +
labs(
title = "Symptom Profiles by Age Group",
x = "Symptom",
y = "Percent Reporting Symptom"
)
analysis_data %>%
select(age_group, all_of(risk_vars)) %>%
pivot_longer(
cols = all_of(risk_vars),
names_to = "risk_factor",
values_to = "response"
) %>%
count(age_group, risk_factor, response) %>%
group_by(age_group, risk_factor) %>%
mutate(percent = 100 * n / sum(n)) %>%
filter(response == "Yes") %>%
ggplot(aes(x = risk_factor, y = percent, fill = age_group)) +
geom_col(position = "dodge") +
coord_flip() +
labs(
title = "Risk Factors by Age Group",
x = "Risk Factor",
y = "Percent Reporting Risk Factor"
)
vars_to_test <- c(clinical_vars, symptom_vars, risk_vars)
chi_square_results <- map_df(vars_to_test, function(var) {
test_data <- analysis_data %>%
select(age_group, all_of(var)) %>%
drop_na()
tbl <- table(test_data$age_group, test_data[[var]])
if (nrow(tbl) < 2 || ncol(tbl) < 2) {
return(tibble(
variable = var,
chi_square = NA,
df = NA,
p_value = NA
))
}
test <- suppressWarnings(chisq.test(tbl))
tibble(
variable = var,
chi_square = round(as.numeric(test$statistic), 3),
df = as.numeric(test$parameter),
p_value = round(test$p.value, 4)
)
})
chi_square_results %>%
arrange(p_value)
## # A tibble: 25 × 4
## variable chi_square df p_value
## <chr> <dbl> <dbl> <dbl>
## 1 seizure_type 41.1 3 0
## 2 target_epilepsy_type 24.0 5 0.0002
## 3 aura_before_seizure 2.03 1 0.154
## 4 seizure_duration 4.45 3 0.217
## 5 jerky_movements 1.48 1 0.224
## 6 loss_of_consciousness 1.39 1 0.239
## 7 postictal_confusion 1.30 1 0.255
## 8 history_of_stroke 0.863 1 0.353
## 9 mri_ct_scan_result 1.54 2 0.463
## 10 family_history_of_epilepsy 0.438 1 0.508
## # ℹ 15 more rows
model_data <- analysis_data %>%
mutate(
adolescent = ifelse(age_group == "Adolescent", 1, 0)
) %>%
select(
adolescent,
gender,
weight,
height,
medication_status,
alcohol_or_drug_use,
eeg_abnormality_detected,
mri_ct_scan_result,
seizure_frequency,
seizure_duration,
seizure_type,
aura_before_seizure,
loss_of_consciousness,
muscle_stiffness,
jerky_movements,
postictal_confusion,
blank_stare_episodes,
eye_rolling,
stress_or_anxiety_before_episode,
lack_of_sleep_before_episode,
missed_medication,
family_history_of_epilepsy,
head_injury_history,
genetic_disorder,
target_epilepsy_type
) %>%
mutate(across(where(is.character), as.factor)) %>%
drop_na()
logit_model <- glm(
adolescent ~ .,
data = model_data,
family = binomial
)
logit_results <- tidy(
logit_model,
exponentiate = TRUE,
conf.int = TRUE
) %>%
arrange(p.value)
logit_results
## # A tibble: 33 × 7
## term estimate std.error statistic p.value conf.low conf.high
## <chr> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl>
## 1 seizure_typeFocal 0.121 0.524 -4.03 5.64e-5 0.0425 0.334
## 2 seizure_typeGenerali… 0.230 0.500 -2.94 3.30e-3 0.0854 0.610
## 3 seizure_typeTonic-Cl… 0.359 0.511 -2.00 4.52e-2 0.130 0.973
## 4 genderMale 1.61 0.250 1.91 5.67e-2 0.994 2.65
## 5 seizure_duration 0.992 0.00432 -1.77 7.64e-2 0.984 1.00
## 6 jerky_movementsYes 0.611 0.298 -1.66 9.77e-2 0.340 1.10
## 7 postictal_confusionY… 0.655 0.261 -1.62 1.05e-1 0.394 1.10
## 8 weight 0.989 0.00781 -1.40 1.63e-1 0.974 1.00
## 9 loss_of_consciousnes… 1.41 0.294 1.16 2.44e-1 0.797 2.53
## 10 mri_ct_scan_resultNo… 0.745 0.257 -1.14 2.52e-1 0.449 1.24
## # ℹ 23 more rows
rf_data <- model_data %>%
mutate(
adolescent = factor(
adolescent,
levels = c(0, 1),
labels = c("Adult", "Adolescent")
)
)
set.seed(123)
rf_model <- randomForest(
adolescent ~ .,
data = rf_data,
importance = TRUE,
ntree = 500
)
importance_df <- importance(rf_model) %>%
as.data.frame() %>%
rownames_to_column("variable") %>%
arrange(desc(MeanDecreaseGini))
importance_df
## variable Adult Adolescent
## 1 weight 1.21225533 0.41573211
## 2 height -0.29711248 1.09277451
## 3 seizure_type 3.39799091 8.69402249
## 4 seizure_frequency -0.76198080 -2.32756338
## 5 target_epilepsy_type 1.24128761 1.44187408
## 6 seizure_duration -1.20245006 -0.80013987
## 7 mri_ct_scan_result -0.68716582 -0.34488143
## 8 eye_rolling 1.18580219 4.09113751
## 9 gender -1.41888108 -0.25370992
## 10 muscle_stiffness 2.50258063 -1.03090560
## 11 jerky_movements 1.82391510 3.01553318
## 12 lack_of_sleep_before_episode -0.38653867 -0.77670047
## 13 aura_before_seizure 0.08913831 -0.62671879
## 14 postictal_confusion 1.92697174 -0.05460891
## 15 family_history_of_epilepsy -1.99128271 1.50908312
## 16 stress_or_anxiety_before_episode -2.98509348 1.45899237
## 17 medication_status -1.69400793 -0.13358916
## 18 head_injury_history 0.06250515 0.82008398
## 19 blank_stare_episodes -3.25933420 0.22925981
## 20 loss_of_consciousness 0.51963175 0.20733471
## 21 missed_medication 0.78761861 -1.31314838
## 22 eeg_abnormality_detected -0.90039778 -1.10666739
## 23 genetic_disorder -2.89393562 2.55601013
## 24 alcohol_or_drug_use -1.37169823 -2.12010005
## MeanDecreaseAccuracy MeanDecreaseGini
## 1 1.22935484 24.996569
## 2 0.04969975 23.477850
## 3 6.30307802 11.374333
## 4 -1.50160457 10.863905
## 5 1.69840313 9.637369
## 6 -1.41328297 8.079422
## 7 -0.76666042 7.247477
## 8 2.55016127 4.766428
## 9 -1.50951374 4.584075
## 10 1.88172618 4.310033
## 11 2.67638799 4.174650
## 12 -0.59280314 4.133665
## 13 -0.08336847 4.095214
## 14 1.77196560 4.013726
## 15 -1.29984603 3.994467
## 16 -2.19681833 3.921945
## 17 -1.63109118 3.540770
## 18 0.36480064 3.534973
## 19 -3.03923438 3.493657
## 20 0.59903114 3.453896
## 21 0.34830511 3.416778
## 22 -1.24630948 2.762019
## 23 -1.88584648 2.569827
## 24 -2.11521592 2.108855
varImpPlot(rf_model)
tda_data <- analysis_data %>%
select(
age_group,
gender,
medication_status,
alcohol_or_drug_use,
eeg_abnormality_detected,
mri_ct_scan_result,
seizure_frequency,
seizure_duration,
seizure_type,
aura_before_seizure,
loss_of_consciousness,
muscle_stiffness,
jerky_movements,
postictal_confusion,
blank_stare_episodes,
eye_rolling,
stress_or_anxiety_before_episode,
lack_of_sleep_before_episode,
missed_medication,
family_history_of_epilepsy,
head_injury_history,
genetic_disorder,
target_epilepsy_type
) %>%
drop_na()
age_labels <- tda_data$age_group
risk_profiles <- tda_data %>%
select(-age_group) %>%
mutate(across(where(is.character), as.factor))
str(risk_profiles)
## tibble [865 × 22] (S3: tbl_df/tbl/data.frame)
## $ gender : Factor w/ 3 levels "Female","Male",..: 2 1 1 2 2 2 1 2 1 2 ...
## $ medication_status : Factor w/ 2 levels "Not on Medication",..: 2 2 1 2 2 1 2 1 2 2 ...
## $ alcohol_or_drug_use : Factor w/ 2 levels "No","Yes": 2 1 1 1 1 1 1 1 1 1 ...
## $ eeg_abnormality_detected : Factor w/ 2 levels "No","Yes": 2 2 2 2 2 1 2 1 2 2 ...
## $ mri_ct_scan_result : Factor w/ 3 levels "Abnormal","Normal",..: 2 1 3 3 1 3 2 2 1 2 ...
## $ seizure_frequency : num [1:865] 1 3 0 1 1 2 1 1 5 3 ...
## $ seizure_duration : num [1:865] 60 30 60 60 30 30 30 90 30 30 ...
## $ seizure_type : Factor w/ 4 levels "Absence","Focal",..: 4 4 2 4 4 1 1 4 4 3 ...
## $ aura_before_seizure : Factor w/ 2 levels "No","Yes": 1 2 2 1 2 1 2 2 1 2 ...
## $ loss_of_consciousness : Factor w/ 2 levels "No","Yes": 2 1 2 2 2 1 2 2 1 2 ...
## $ muscle_stiffness : Factor w/ 2 levels "No","Yes": 1 2 1 2 1 2 1 1 1 1 ...
## $ jerky_movements : Factor w/ 2 levels "No","Yes": 2 2 2 2 2 1 1 1 2 2 ...
## $ postictal_confusion : Factor w/ 2 levels "No","Yes": 2 1 2 2 2 2 1 1 2 1 ...
## $ blank_stare_episodes : Factor w/ 2 levels "No","Yes": 1 2 2 1 2 2 2 1 1 1 ...
## $ eye_rolling : Factor w/ 2 levels "No","Yes": 2 2 1 1 1 2 2 2 2 2 ...
## $ stress_or_anxiety_before_episode: Factor w/ 2 levels "No","Yes": 2 2 2 2 2 1 1 2 2 2 ...
## $ lack_of_sleep_before_episode : Factor w/ 2 levels "No","Yes": 2 1 2 1 2 1 2 2 2 2 ...
## $ missed_medication : Factor w/ 2 levels "No","Yes": 1 2 1 1 1 1 1 1 1 1 ...
## $ family_history_of_epilepsy : Factor w/ 2 levels "No","Yes": 1 2 1 2 2 2 1 2 2 1 ...
## $ head_injury_history : Factor w/ 2 levels "No","Yes": 1 1 1 1 1 2 1 1 1 2 ...
## $ genetic_disorder : Factor w/ 2 levels "No","Yes": 1 1 1 1 1 2 1 1 1 1 ...
## $ target_epilepsy_type : Factor w/ 6 levels "Absence","Complicated",..: 4 4 3 4 4 1 1 2 2 4 ...
gower_dist <- daisy(risk_profiles, metric = "gower")
gower_matrix <- as.matrix(gower_dist)
mds <- cmdscale(gower_dist, k = 2)
mds_df <- data.frame(
Dim1 = mds[, 1],
Dim2 = mds[, 2],
age_group = age_labels
)
ggplot(mds_df, aes(x = Dim1, y = Dim2, color = age_group)) +
geom_point(alpha = 0.7) +
labs(
title = "Risk Profile Space Using Gower Distance",
x = "Dimension 1",
y = "Dimension 2"
)
filter_values <- mds[, 1]
mapper_result <- mapper1D(
distance_matrix = gower_matrix,
filter_values = filter_values,
num_intervals = 10,
percent_overlap = 50,
num_bins_when_clustering = 10
)
mapper_vertices <- mapper_result$points_in_vertex
mapper_edges <- mapper_result$adjacency
g <- graph_from_adjacency_matrix(
mapper_edges,
mode = "undirected"
)
node_adolescent_prop <- sapply(mapper_vertices, function(indices) {
mean(age_labels[indices] == "Adolescent")
})
V(g)$adolescent_prop <- node_adolescent_prop
plot(
g,
vertex.size = 8 + 25 * V(g)$adolescent_prop,
vertex.label = NA,
main = "Mapper Graph of Epilepsy Risk Profiles"
)
mapper_summary <- tibble(
node = seq_along(mapper_vertices),
node_size = sapply(mapper_vertices, length),
adolescent_proportion = node_adolescent_prop
) %>%
arrange(desc(adolescent_proportion))
mapper_summary
## # A tibble: 10 × 3
## node node_size adolescent_proportion
## <int> <int> <dbl>
## 1 4 176 0.148
## 2 9 250 0.132
## 3 10 166 0.127
## 4 8 201 0.119
## 5 5 203 0.0985
## 6 3 164 0.0976
## 7 7 160 0.0938
## 8 6 192 0.0677
## 9 1 45 0.0667
## 10 2 109 0.0642
The exploratory analysis describes differences between adolescents and adults in the dataset.
The statistical analysis identifies individual clinical, demographic, and behavioral variables that distinguish adolescent epilepsy patients from adult epilepsy patients.
The TDA analysis treats each patient as a multivariate clinical risk profile. Rather than studying variables one at a time, Mapper studies the shape of the risk-profile space and identifies clusters of patients with similar combinations of symptoms and risk factors.