1. Hands-on example of fitting a group-based trajectory model
This tutorial aims to provide a quick example for implementing flexmix R package to run a group-based trajectory model.
1.1 The ICTUS (Impact of Cholinergic Treatment USe) cohort
Design: Prospective, multicenter longitudinal observational cohort of Alzheimer’s disease (AD) patients in Europe
A cohort of 1380 patients with Alzheimer disease followed-up in 12 European countries.
These patients were included between February 2003 and July 2005 in 29 centres specialized in neurology, geriatrics, psychiatry, or psycho-geriatrics with a recognized experience in the diagnosis and management of Alzheimer disease.
These patients were examined at six-month intervals over two years. Each examination included (though not exclusively) an Mini Mental Score (MMS) assessment.
Recruitment period: 2003–2005
Study aims including to describe natural history and clinical course of mild–moderate AD
Reynish, E., Cortes, F., Andrieu, S., Cantet, C., Olde Rikkert, M., Melis, R., Froelich, L., Frisoni, G., Jonsson, L., Visser, P., et al., 2007. The ictus study: A prospective longitudinal observational study of 1,380 ad patients in europe. Neuroepidemiology 29 (1-2), 29-38
Vellas, B., Hausner, L., Frolich, L., Cantet, C., Gardette, V., Reynish, E., Gillette, S., Aguera-Morales, E., Auriacombe, S., Boada, M., et al., 2012. Progression of alzheimer disease in europe: Data from the european ictus study. Current Alzheimer Research 9 (8), 902-912.
library(tidyverse)library(DT)ictusShort <-read.csv("ictusShort.csv", header =TRUE)# look at new data;datatable(ictusShort,rownames =FALSE,options =list(dom ='t'))
1.3 Group-based trajectory modelling with flexmix R package
Model 1 Three classes
library(flexmix)set.seed(123)# 3-class modelmod3 <-flexmix( MMS ~poly(visit, 2, raw =TRUE) | id,data = ictus_long,k =3,control =list(minprior=0) # by default flexmix drop a class if miniprior threshold less than 0.05;)# BIC for 3-classBIC(mod3)
# comparing BIC (lower better);# Five clusters best model;bic_comp <-tibble(k =c(3, 4, 5),BIC =c(BIC(mod3), BIC(mod4), BIC(mod5)))bic_comp
# A tibble: 3 × 2
k BIC
<dbl> <dbl>
1 3 103097.
2 4 98081.
3 5 96095.
# we can also compare using likelihood ratio test Lo–Mendell–Rubin test;library(tidyLPA)# LMR for k vs k–1 needs the k–1 model, so we add a 2-class modelmod2 <-flexmix( MMS ~poly(visit, 2, raw =TRUE) | id,data = ictus_long,k =2)BIC(mod2)
[1] 110131
# log-likelihoodsll2 <-as.numeric(logLik(mod2))ll3 <-as.numeric(logLik(mod3))ll4 <-as.numeric(logLik(mod4))ll5 <-as.numeric(logLik(mod5))# number of parameters (flexmix stores this in attr(logLik, "df"))p2 <-attr(logLik(mod2), "df")p3 <-attr(logLik(mod3), "df")p4 <-attr(logLik(mod4), "df")p5 <-attr(logLik(mod5), "df")# 2-class (null) vs 3-class (alt)lmr_2_vs_3 <-calc_lrt(n =1374,null_ll = ll2,null_param = p2,null_classes =2,alt_ll = ll3,alt_param = p3,alt_classes =3)lmr_2_vs_3
Lo-Mendell-Rubin ad-hoc adjusted likelihood ratio rest:
LR = 7083.361, LMR LR (df = 5) = 6770.995, p < 0.001
Lo-Mendell-Rubin ad-hoc adjusted likelihood ratio rest:
LR = 2036.369, LMR LR (df = 5) = 1946.568, p < 0.001
Final model: five classes
# assess class certainty;# For everyone assigned to class k, what is the mean posterior probability of that class?;post5_mat <-posterior(mod5)head(post5_mat)
# hard class label for each row by highest proability;class_vec <-clusters(mod5) # posterior probability *for the assigned class* for each rowassigned_prob <- post5_mat[cbind(seq_len(nrow(post5_mat)), class_vec)]# mean posterior for assigned class by classmean_assigned_by_class <-tapply(assigned_prob, class_vec, mean)mean_assigned_by_class