--- title: "Introduction to the 'fmi' Package" output: rmarkdown::html_vignette vignette: > %\VignetteIndexEntry{Introduction to the 'fmi' Package} %\VignetteEngine{knitr::rmarkdown} %\VignetteEncoding{UTF-8} --- ```{r, include = FALSE} knitr::opts_chunk$set( collapse = TRUE, comment = "#>" ) ``` 1. Introduction to the 'fmi' Package The fmi package provides tools to test for Functional Measurement Invariance (FMI) between two groups of functional data. It adapts the concepts of configural, metric, and scalar invariance from multi-group confirmatory factor analysis (MGCFA) to the context of Functional Data Analysis (FDA). The package's main function, run_fmi(), performs a hierarchical permutation test. If invariance is established, the compare_latent_means() function can be used to test for differences in the underlying FPC scores. 2. FMI Test Procedure using Simulation The package includes simulate_fmi_data() to generate data for demonstrating the FMI testing procedure. 2.1. Generate Simulation Data First, let's generate data where configural, metric, and scalar invariance hold, but a latent mean difference (mean_shift) exists between the two groups. # Load required packages for the vignette suppressPackageStartupMessages(library(dplyr)) suppressPackageStartupMessages(library(ggplot2)) suppressPackageStartupMessages(library(tibble)) suppressPackageStartupMessages(library(knitr)) # We explicitly reference fmi:: functions for clarity set.seed(123) # for reproducibility # Apply a mean_shift of 1.0 to FPC 1 for Group B sim_data <- fmi::simulate_fmi_data( N_A = 50, N_B = 50, mean_shift = 1.0, seed = 456 ) # Check data structure str(sim_data) ```{r} # Load required packages for the vignette suppressPackageStartupMessages(library(dplyr)) suppressPackageStartupMessages(library(ggplot2)) suppressPackageStartupMessages(library(tibble)) suppressPackageStartupMessages(library(knitr)) # We explicitly reference fmi:: functions for clarity set.seed(123) # for reproducibility # Apply a mean_shift of 1.0 to FPC 1 for Group B sim_data <- fmi::simulate_fmi_data( N_A = 50, N_B = 50, mean_shift = 1.0, seed = 456 ) # Check data structure str(sim_data) ``` The generated data includes Y_mat (100 subjects x 51 time points), a group_vec, and argvals. 2.2. Run the Hierarchical FMI Test We use run_fmi() to perform the test. For CRAN checks, we use a very low n_perms = 9. For actual research, 499 or higher is recommended. ```{r} # Run the FMI test with n_perms=9 (to pass CRAN checks) fmi_results <- fmi::run_fmi( Y_mat = sim_data$Y_mat, group_vec = sim_data$group_vec, argvals = sim_data$argvals, n_perms = 9, # Use 499+ for actual research progress = FALSE # Turn off progress bar for vignette ) ``` The run_fmi() function tests each level of invariance sequentially. 2.3. Compare Latent Means Since all levels of invariance (especially scalar) were established, we can now use compare_latent_means() to test for group differences in the FPC scores. ```{r} # Check if fmi_results$scalar$passed is TRUE if (!is.null(fmi_results$scalar) && fmi_results$scalar$passed) { message("Scalar invariance established. Comparing latent means.") mean_diff_results <- fmi::compare_latent_means( fmi_results = fmi_results, group_vec = sim_data$group_vec ) print(mean_diff_results) } else { message("Scalar invariance rejected. Latent mean comparison aborted.") } ``` 3. Real Data Examples 3.1. DTI Example (Patients vs Controls) This example uses the DTI dataset from the refund package. We use n_perms = 9 for CRAN check speed. ```{r} # Load data (requires 'refund' package) if (!requireNamespace("refund", quietly = TRUE)) { knitr::knit_exit() # Stop if refund is not installed } data(DTI, package = "refund") # 1. Pre-process the data (first visit, remove NA, set groups) dti_meta_data <- tibble::tibble( ID = DTI$ID, visit = DTI$visit, case = factor(DTI$case, levels = c(0, 1), labels = c("Control", "Patient")) ) dti_cca_data <- tibble::as_tibble(DTI$cca) %>% setNames(paste0("cca_", 1:ncol(DTI$cca))) dti_filtered_df <- dplyr::bind_cols(dti_meta_data, dti_cca_data) %>% dplyr::filter(visit == 1) %>% dplyr::select(ID, case, dplyr::starts_with("cca_")) %>% tidyr::drop_na() # Use tidyr::drop_na # 2. Prepare inputs for FMI Y_mat <- dti_filtered_df %>% dplyr::select(dplyr::starts_with("cca_")) %>% as.matrix() group_vec <- dti_filtered_df$case argvals <- seq(0, 1, length.out = ncol(Y_mat)) # 3. Run FMI test (n_perms=9 for CRAN) fmi_dti_results <- fmi::run_fmi( Y_mat = Y_mat, group_vec = group_vec, argvals = argvals, n_perms = 9, # Use 499+ for actual research progress = FALSE ) # 4. Compare latent means (if invariance holds) if (!is.null(fmi_dti_results$scalar) && fmi_dti_results$scalar$passed) { message("\n[DTI] Scalar invariance established. Comparing latent means.") fmi::compare_latent_means(fmi_dti_results, group_vec) } else { message("\n[DTI] Scalar invariance rejected. Latent mean comparison aborted.") } ``` 3.2. Berkeley Growth Example (Boys vs Girls) This example uses the growth dataset from the fda package. We will use the run_growth_example() helper function directly, passing n_perms = 9 for CRAN check speed. ```{r} # Check if 'fda' package is installed if (!requireNamespace("fda", quietly = TRUE)) { message("Package 'fda' needed for the Growth example. Skipping.") knitr::knit_exit() } # Run the pre-packaged growth example # (n_perms=9 for CRAN check speed) fmi_growth_results <- fmi::run_growth_example(n_perms = 9) ```