| Title: | Hierarchical Permutation Tests for Functional Measurement Invariance |
|---|---|
| Description: | Provides a suite of functions to test for Functional Measurement Invariance (FMI) between two groups. Implements hierarchical permutation tests for configural, metric, and scalar invariance, adapting concepts from Multi-Group Confirmatory Factor Analysis (MGCFA) to functional data. Methods are based on concepts from: Meredith, W. (1993) <doi:10.1007/BF02294825>,5 Yao, F., Müller, H. G., & Wang, J. L. (2005) <doi:10.1198/016214504000001745>, and Lee, K. Y., & Li, L. (2022) <doi:10.1111/rssb.12471>. |
| Authors: | Hyeri Kim [aut, cre] |
| Maintainer: | Hyeri Kim <[email protected]> |
| License: | MIT + file LICENSE |
| Version: | 0.1.7 |
| Built: | 2026-05-17 05:36:17 UTC |
| Source: | https://github.com/cran/fmi |
Creates a ggplot2 scree plot comparing the PVE by FPCs for two groups.
build_scree_plot(fpca_A, fpca_B, groups)build_scree_plot(fpca_A, fpca_B, groups)
fpca_A |
An |
fpca_B |
An |
groups |
A character vector of the two group names. |
A ggplot object.
sim <- simulate_fmi_data(N_A = 20, N_B = 20, T_points = 30) g_fac <- factor(sim$group_vec) idx_A <- which(g_fac == levels(g_fac)[1]) # --- FIX: Added Y= and argvals= --- fpca_A <- refund::fpca.sc(Y = sim$Y_mat[idx_A, ], argvals = sim$argvals, npc = 3) fpca_B <- refund::fpca.sc(Y = sim$Y_mat[-idx_A, ], argvals = sim$argvals, npc = 3) build_scree_plot(fpca_A, fpca_B, levels(g_fac))sim <- simulate_fmi_data(N_A = 20, N_B = 20, T_points = 30) g_fac <- factor(sim$group_vec) idx_A <- which(g_fac == levels(g_fac)[1]) # --- FIX: Added Y= and argvals= --- fpca_A <- refund::fpca.sc(Y = sim$Y_mat[idx_A, ], argvals = sim$argvals, npc = 3) fpca_B <- refund::fpca.sc(Y = sim$Y_mat[-idx_A, ], argvals = sim$argvals, npc = 3) build_scree_plot(fpca_A, fpca_B, levels(g_fac))
Performs Welch's t-tests on FPC scores between groups. This function should only be run after scalar invariance is established.
compare_latent_means(fmi_results, group_vec)compare_latent_means(fmi_results, group_vec)
fmi_results |
The list object returned by |
group_vec |
The original group vector used in |
A tibble summarizing the t-test results for each FPC.
sim <- simulate_fmi_data(N_A = 20, N_B = 20, T_points = 30) fmi_results <- run_fmi( Y_mat = sim$Y_mat, group_vec = sim$group_vec, argvals = sim$argvals, n_perms = 9, progress = FALSE ) # This will run only if scalar invariance passed if (!is.null(fmi_results$scalar) && fmi_results$scalar$passed) { mean_results <- compare_latent_means(fmi_results, sim$group_vec) print(mean_results) }sim <- simulate_fmi_data(N_A = 20, N_B = 20, T_points = 30) fmi_results <- run_fmi( Y_mat = sim$Y_mat, group_vec = sim$group_vec, argvals = sim$argvals, n_perms = 9, progress = FALSE ) # This will run only if scalar invariance passed if (!is.null(fmi_results$scalar) && fmi_results$scalar$passed) { mean_results <- compare_latent_means(fmi_results, sim$group_vec) print(mean_results) }
Determines the number of functional principal components (FPCs) required to meet a target Proportion of Variance Explained (PVE).
determine_npc(Y_mat, argvals, target_pve = 0.95, max_npc = 6L)determine_npc(Y_mat, argvals, target_pve = 0.95, max_npc = 6L)
Y_mat |
A numeric matrix (N x M) where N is subjects, M is time points. |
argvals |
A numeric vector of length M listing the observation points. |
target_pve |
The target cumulative PVE to reach (default: 0.95). |
max_npc |
The maximum number of components to retain (default: 6L). |
A list containing:
npc |
The selected number of components. |
pooled_fpca |
The |
scree |
A tibble with PVE and cumulative PVE for each component. |
sim <- simulate_fmi_data(N_A = 20, N_B = 20, T_points = 30) npc_info <- determine_npc(sim$Y_mat, sim$argvals) print(npc_info$npc)sim <- simulate_fmi_data(N_A = 20, N_B = 20, T_points = 30) npc_info <- determine_npc(sim$Y_mat, sim$argvals) print(npc_info$npc)
A helper function to load and pre-process the DTI dataset from the 'refund' package for use in examples.
run_dti_example(n_perms = 499L)run_dti_example(n_perms = 499L)
n_perms |
The number of permutations (default: 499L).
Passed to |
Invisibly returns the FMI results list.
# n_perms=9 is for a quick check. Use 499+ for real analysis. if (requireNamespace("refund", quietly = TRUE)) { dti_results <- run_dti_example(n_perms = 9) }# n_perms=9 is for a quick check. Use 499+ for real analysis. if (requireNamespace("refund", quietly = TRUE)) { dti_results <- run_dti_example(n_perms = 9) }
A wrapper function that performs a sequence of permutation tests for configural, metric, scalar, and (optionally) strict invariance.
run_fmi( Y_mat, group_vec, argvals, alpha = 0.05, npc = NULL, target_pve = 0.95, max_npc = 6L, n_perms = 499L, strict_test = FALSE, progress = interactive() )run_fmi( Y_mat, group_vec, argvals, alpha = 0.05, npc = NULL, target_pve = 0.95, max_npc = 6L, n_perms = 499L, strict_test = FALSE, progress = interactive() )
Y_mat |
A numeric matrix (N x M) where N is subjects, M is time points. |
group_vec |
A vector of length N specifying group membership (2 groups). |
argvals |
A numeric vector of length M listing the observation points. |
alpha |
Significance level (default: 0.05). |
npc |
Optional. The number of FPCs. If NULL (default), it is
determined automatically by |
target_pve |
The target PVE if |
max_npc |
The max FPCs if |
n_perms |
The number of permutations (default: 499L). |
strict_test |
Boolean. Whether to perform the strict invariance test (default: FALSE). |
progress |
Boolean. Show progress bars? (default: interactive()). |
A list containing test results for each invariance level, settings, and the pooled FPCA object.
# Use small N and n_perms for a quick example sim <- simulate_fmi_data(N_A = 20, N_B = 20, T_points = 30) fmi_results <- run_fmi( Y_mat = sim$Y_mat, group_vec = sim$group_vec, argvals = sim$argvals, n_perms = 9, # Use 499+ for actual research progress = FALSE ) print(fmi_results)# Use small N and n_perms for a quick example sim <- simulate_fmi_data(N_A = 20, N_B = 20, T_points = 30) fmi_results <- run_fmi( Y_mat = sim$Y_mat, group_vec = sim$group_vec, argvals = sim$argvals, n_perms = 9, # Use 499+ for actual research progress = FALSE ) print(fmi_results)
A helper function to load and pre-process the Growth dataset from the 'fda' package for use in examples.
run_growth_example(n_perms = 499L)run_growth_example(n_perms = 499L)
n_perms |
The number of permutations (default: 499L).
Passed to |
Invisibly returns the FMI results list.
# n_perms=9 is for a quick check. Use 499+ for real analysis. if (requireNamespace("fda", quietly = TRUE)) { growth_results <- run_growth_example(n_perms = 9) }# n_perms=9 is for a quick check. Use 499+ for real analysis. if (requireNamespace("fda", quietly = TRUE)) { growth_results <- run_growth_example(n_perms = 9) }
Generates functional data for two groups with optional differences in latent means or scalar intercepts.
simulate_fmi_data( N_A = 50, N_B = 50, T_points = 51, mean_shift = 0, scalar_shift = 0, eigenvalues = c(4, 1, 0.5, 0.1), noise_sd = 0.5, seed = NULL )simulate_fmi_data( N_A = 50, N_B = 50, T_points = 51, mean_shift = 0, scalar_shift = 0, eigenvalues = c(4, 1, 0.5, 0.1), noise_sd = 0.5, seed = NULL )
N_A |
Sample size for Group A (default: 50). |
N_B |
Sample size for Group B (default: 50). |
T_points |
Number of time points (default: 51). |
mean_shift |
A shift added to FPC 1 scores for Group B (default: 0). |
scalar_shift |
A shift added to the mean function for Group B (default: 0). |
eigenvalues |
A vector of eigenvalues for FPCs (default: c(4, 1, 0.5, 0.1)). |
noise_sd |
Standard deviation of measurement error (default: 0.5). |
seed |
Optional. A random seed for reproducibility. |
A list with Y_mat, group_vec, and argvals.
sim_data <- simulate_fmi_data(N_A = 10, N_B = 10, T_points = 20, seed = 123) str(sim_data)sim_data <- simulate_fmi_data(N_A = 10, N_B = 10, T_points = 20, seed = 123) str(sim_data)
Permutation test to check if the cumulative PVE is equivalent across groups.
test_configural(Y_mat, group_vec, argvals, npc, n_perms, alpha, progress)test_configural(Y_mat, group_vec, argvals, npc, n_perms, alpha, progress)
Y_mat |
A numeric matrix (N x M) where N is subjects, M is time points. |
group_vec |
A vector of length N specifying group membership (2 groups). |
argvals |
A numeric vector of length M listing the observation points. |
npc |
Optional. The number of FPCs. If NULL (default), it is
determined automatically by |
n_perms |
The number of permutations (default: 499L). |
alpha |
Significance level (default: 0.05). |
progress |
Boolean. Show progress bars? (default: interactive()). |
A list with passed (boolean), p_value, statistic, and plot.
sim <- simulate_fmi_data(N_A = 20, N_B = 20, T_points = 30) res <- test_configural(sim$Y_mat, sim$group_vec, sim$argvals, npc = 3, n_perms = 9, alpha = 0.05, progress = FALSE) print(res$p_value)sim <- simulate_fmi_data(N_A = 20, N_B = 20, T_points = 30) res <- test_configural(sim$Y_mat, sim$group_vec, sim$argvals, npc = 3, n_perms = 9, alpha = 0.05, progress = FALSE) print(res$p_value)
Permutation test to check if the eigenfunctions are equivalent across groups.
test_metric(Y_mat, group_vec, argvals, npc, n_perms, alpha, progress)test_metric(Y_mat, group_vec, argvals, npc, n_perms, alpha, progress)
Y_mat |
A numeric matrix (N x M) where N is subjects, M is time points. |
group_vec |
A vector of length N specifying group membership (2 groups). |
argvals |
A numeric vector of length M listing the observation points. |
npc |
Optional. The number of FPCs. If NULL (default), it is
determined automatically by |
n_perms |
The number of permutations (default: 499L). |
alpha |
Significance level (default: 0.05). |
progress |
Boolean. Show progress bars? (default: interactive()). |
A list with passed (boolean), p_value, and statistic.
sim <- simulate_fmi_data(N_A = 20, N_B = 20, T_points = 30) res <- test_metric(sim$Y_mat, sim$group_vec, sim$argvals, npc = 3, n_perms = 9, alpha = 0.05, progress = FALSE) print(res$p_value)sim <- simulate_fmi_data(N_A = 20, N_B = 20, T_points = 30) res <- test_metric(sim$Y_mat, sim$group_vec, sim$argvals, npc = 3, n_perms = 9, alpha = 0.05, progress = FALSE) print(res$p_value)
Permutation test to check if the mean functions (intercepts) are equivalent across groups, after accounting for latent factors.
test_scalar(Y_mat, group_vec, argvals, pooled_fpca, n_perms, alpha, progress)test_scalar(Y_mat, group_vec, argvals, pooled_fpca, n_perms, alpha, progress)
Y_mat |
Numeric matrix (N x M). |
group_vec |
A vector of length N specifying group membership. |
argvals |
Numeric vector of length M. |
pooled_fpca |
The |
n_perms |
Integer, number of permutations. |
alpha |
Significance level (default: 0.05). |
progress |
Boolean, show progress bar? (default: interactive()). |
A list with passed (boolean), p_value, and statistic.
sim <- simulate_fmi_data(N_A = 20, N_B = 20, T_points = 30) npc_info <- determine_npc(sim$Y_mat, sim$argvals, max_npc = 3) res <- test_scalar(sim$Y_mat, sim$group_vec, sim$argvals, pooled_fpca = npc_info$pooled_fpca, n_perms = 9, alpha = 0.05, progress = FALSE) print(res$p_value)sim <- simulate_fmi_data(N_A = 20, N_B = 20, T_points = 30) npc_info <- determine_npc(sim$Y_mat, sim$argvals, max_npc = 3) res <- test_scalar(sim$Y_mat, sim$group_vec, sim$argvals, pooled_fpca = npc_info$pooled_fpca, n_perms = 9, alpha = 0.05, progress = FALSE) print(res$p_value)
Permutation test to check if the residual error variances are equivalent across groups.
test_strict(Y_mat, group_vec, argvals, npc, n_perms, alpha, progress)test_strict(Y_mat, group_vec, argvals, npc, n_perms, alpha, progress)
Y_mat |
A numeric matrix (N x M) where N is subjects, M is time points. |
group_vec |
A vector of length N specifying group membership (2 groups). |
argvals |
A numeric vector of length M listing the observation points. |
npc |
Optional. The number of FPCs. If NULL (default), it is
determined automatically by |
n_perms |
The number of permutations (default: 499L). |
alpha |
Significance level (default: 0.05). |
progress |
Boolean. Show progress bars? (default: interactive()). |
A list with passed (boolean), p_value, and statistic.
sim <- simulate_fmi_data(N_A = 20, N_B = 20, T_points = 30) res <- test_strict(sim$Y_mat, sim$group_vec, sim$argvals, npc = 3, n_perms = 9, alpha = 0.05, progress = FALSE) print(res$p_value)sim <- simulate_fmi_data(N_A = 20, N_B = 20, T_points = 30) res <- test_strict(sim$Y_mat, sim$group_vec, sim$argvals, npc = 3, n_perms = 9, alpha = 0.05, progress = FALSE) print(res$p_value)