diff --git a/DESCRIPTION b/DESCRIPTION
index 4b5ba23cbcea4498c818378f23a4eba2e9ff8660..cff3bef59a083a1064a9a0bcd04121c0fd1ba037 100644
--- a/DESCRIPTION
+++ b/DESCRIPTION
@@ -2,7 +2,7 @@ Package: phoenics
 Type: Package
 Title: Pathways Longitudinal and Differential Analysis in Metabolomics
 Version: 0.4
-Date: 2024-09-23
+Date: 2024-11-29
 Depends: R (>= 4.0.0)
 Imports: lme4, blme, tibble, FactoMineR, factoextra, tidyr, stats
 Suggests: KEGGREST
diff --git a/NAMESPACE b/NAMESPACE
index 68a007efd95b14c6563a7aa31014d056acce4978..026f39e151b1492f34a8ac387c8f4e17b203aed0 100644
--- a/NAMESPACE
+++ b/NAMESPACE
@@ -13,9 +13,12 @@ export(head)
 export(overlap_coefficient)
 export(pathway_search)
 export(test_pathway)
+importFrom(FactoMineR,MFA)
 importFrom(FactoMineR,PCA)
 importFrom(blme,blmer)
 importFrom(factoextra,fviz_eig)
+importFrom(factoextra,fviz_mfa_ind)
+importFrom(factoextra,fviz_mfa_var)
 importFrom(factoextra,fviz_pca_ind)
 importFrom(factoextra,fviz_pca_var)
 importFrom(lme4,lmer)
@@ -26,5 +29,6 @@ importFrom(stats,p.adjust.methods)
 importFrom(tibble,column_to_rownames)
 importFrom(tibble,remove_rownames)
 importFrom(tibble,rownames_to_column)
+importFrom(tidyr,pivot_wider)
 importFrom(tidyr,separate)
 importFrom(utils,read.table)
diff --git a/NEWS.md b/NEWS.md
index a8c313b5a98d842b94d32dbd91a84d0cebceff14..608aa340845aa997881564c241a3f3064c28f78a 100644
--- a/NEWS.md
+++ b/NEWS.md
@@ -1,4 +1,8 @@
-# phoenics 0.4 [2024-09-23]
+# phoenics 0.4 [2024-11-26]
+
+## New features
+
+* added MFA to calculate pathway scores in `pathway_test`
 
 ## Improvement:
 
diff --git a/R/pathwayRes-class.R b/R/pathwayRes-class.R
index f0264458ab8ff46ba3370cb8d2db600ae0188f0d..b79d8fe7197e510c5d3013c5d8d883c92ef8c8cd 100644
--- a/R/pathwayRes-class.R
+++ b/R/pathwayRes-class.R
@@ -16,8 +16,12 @@ NULL
 #' quantif <- from_ASICS_to_PHOENICS(quantif)
 #' out_test <- test_pathway(quantif, design, pathways, 
 #'                          fixed = c("Age", "Treatment"), random = "Mouse", 
-#'                          npc = 2, model = "blmer")
+#'                          analysis = "PCA", npc = 2, model = "blmer")
 #' summary(out_test)
+#' out_test2 <- test_pathway(quantif, design, pathways, 
+#'                          fixed = c("Age", "Treatment"), random = "Mouse", 
+#'                          analysis = "MFA", npc = 2, model = "blmer")
+#' summary(out_test2)
 #' @exportS3Method
 summary.pathwayRes <- function(object, ...) {
   cat("Number of pathways: ", length(object), "\n")
@@ -36,29 +40,39 @@ print.pathwayRes <- function(x, ...) {
   cat("$", names(path_res)[2], ": ", "Pathway code \n", sep = "")
   cat("$", names(path_res)[3], ": ", "Metabolites in the pathway \n", sep = "")
   cat("$", names(path_res)[4], ": ", "PCA results \n", sep = "")
-  cat("$", names(path_res)[5], ": ", "Model results \n", sep = "")
-  cat("$", names(path_res)[6], ": ", "Pathway test results \n", sep = "")
+  cat("$", names(path_res)[5], ": ", "MFA results \n", sep = "")
+  cat("$", names(path_res)[6], ": ", "Model results \n", sep = "")
+  cat("$", names(path_res)[7], ": ", "Pathway test results \n", sep = "")
 }
 
 #' @rdname pathwayRes
 #' @aliases plot.pathwayRes
 #' @param pathway_id a character string or vector of pathway codes or names.
 #' Default to \code{NULL} in which case the first pathway is displayed
+#' @param analysis a character string indicating the type of analysis to display 
 #' @param plot a character string indicating the type of plot to return. Default
-#' to \code{"eig"} (the screegraph of the PCA is displayed)
+#' to \code{"eig"} (the screegraph of the PCA or MFA is displayed)
 #' @param habillage a character string indicating the column of the design used 
 #' to color the individuals. Only used when \code{plot = "ind"}. Default to 
 #' \code{"none"} (no color)
-#' @importFrom factoextra fviz_pca_ind fviz_eig fviz_pca_var
+#' @importFrom factoextra fviz_pca_ind fviz_eig fviz_pca_var fviz_mfa_ind fviz_mfa_var
 #' @examples 
-#' plot(out_test)
-#' plot(out_test, pathway_id = "mmu00052", plot = "var")
-#' plot(out_test, pathway_id = "mmu00052", plot = "ind", habillage = "Age")
+#' plot(out_test, analysis = "PCA")
+#' plot(out_test, pathway_id = "mmu00052", analysis = "PCA", plot = "var")
+#' plot(out_test, pathway_id = "mmu00052", analysis = "PCA", plot = "ind", 
+#'      habillage = "Age")
+#' plot(out_test2, pathway_id = "mmu00562", analysis = "MFA", plot = "eig")
+#' plot(out_test2, pathway_id = "mmu00562", analysis = "MFA", plot = "var")
+#' plot(out_test2, pathway_id = "mmu00562", analysis = "MFA", plot = "ind")
+#' plot(out_test2, pathway_id = "mmu00562", analysis = "MFA", plot = "group")
 #' @exportS3Method
 plot.pathwayRes <- function(x, ..., pathway_id = NULL, 
-                            plot = c("eig", "var", "ind"), habillage = "none") {
+                            analysis = c("PCA", "MFA"),
+                            plot = c("eig", "var", "ind", "group"),
+                            habillage = "none") {
   
   plot <- match.arg(plot)
+  analysis <- match.arg(analysis)
   
   if (is.null(pathway_id)) {
     message("`pathway_id` not specified... defaulting to the first pathway")
@@ -66,20 +80,45 @@ plot.pathwayRes <- function(x, ..., pathway_id = NULL,
   }
   
   object_sub <- extract.pathwayRes(x, pathway_id)
+  
   lapply(object_sub, function (path_res) {
-    if (plot == "var") {
-      p <- factoextra::fviz_pca_var(path_res$PCA, title = path_res$pathway_name,
-                                    repel = TRUE)
-    }
-    if (plot == "ind") {
-      p <- factoextra::fviz_pca_ind(path_res$PCA, habillage = habillage, 
-                                    title = path_res$pathway_name, 
-                                    geom = "point", pointsize = 2, 
-                                    mean.point = FALSE)
+    if (analysis == "PCA") {
+      if (plot == "var") {
+        p <- factoextra::fviz_pca_var(path_res$PCA, title = path_res$pathway_name,
+                                      repel = TRUE)
+      }
+      if (plot == "ind") {
+        p <- factoextra::fviz_pca_ind(path_res$PCA, habillage = habillage, 
+                                      title = path_res$pathway_name, 
+                                      geom = "point", pointsize = 2, 
+                                      mean.point = FALSE)
+      }
+      if (plot == "eig") {
+        p <- factoextra::fviz_eig(path_res$PCA, addlabels = TRUE,
+                                  title = path_res$pathway_name)
+      }
     }
-    if (plot == "eig") {
-      p <- factoextra::fviz_eig(path_res$PCA, addlabels = TRUE,
-                                title = path_res$pathway_name)
+    if (analysis == "MFA") {
+      if (plot == "group") {
+        p <- factoextra::fviz_mfa_var(path_res$MFA, choice = "group",
+                                      title = path_res$pathway_name, 
+                                      repel = TRUE)
+      }
+      if (plot == "var") {
+        p <- factoextra::fviz_mfa_var(path_res$MFA, choice = "quanti.var",
+                                      title = path_res$pathway_name, 
+                                      repel = TRUE)
+      }
+      if (plot == "ind") {
+        p <- factoextra::fviz_mfa_ind(path_res$MFA, partial = "all", 
+                                      habillage = habillage,
+                                      title = path_res$pathway_name, 
+                                      pointsize = 2)
+      }
+      if (plot == "eig") {
+        p <- factoextra::fviz_eig(path_res$MFA, addlabels = TRUE,
+                                  title = path_res$pathway_name)
+      }
     }
     return(p)
   })
diff --git a/R/test_pathway.R b/R/test_pathway.R
index fedac69f6ed656af64f2a080139437dfbd65695d..7231e885724dd1d7d0f580f56aaa5ff61724fe65 100644
--- a/R/test_pathway.R
+++ b/R/test_pathway.R
@@ -2,7 +2,7 @@
 #' 
 #' @description Perform a differential analysis at pathway level based on 
 #' metabolite quantifications and information on pathway metabolite composition.
-#' The method relies on a PCA step.
+#' The method relies on a PCA or a MFA step.
 #' 
 #' @param quantif data.frame or matrix of the metabolite quantification with 
 #' samples in rows (sample identifiers must be row names) and metabolites in 
@@ -12,18 +12,21 @@
 #' in columns. Column names must be provided and are used as arguments for
 #' \code{fixed} and \code{random}
 #' @param pathways data.frame or matrix with metabolites in rows (all 
-#' metabolites in columns of \code{quantif} must have a row in this input) and the
-#' following information in columns: \itemize{
+#' metabolites in columns of \code{quantif} must have a row in this input) and
+#' the following information in columns: \itemize{
 #'  \item \code{metabolite_code} metabolite code
 #'  \item \code{metabolite_name} metabolite name
 #'  \item \code{pathway_code} pathway code (identifier)
 #'  \item \code{pathway_name} name of the pathway
 #' }
 #' @param npc number of PCs for the PCA step
+#' @param analysis character string indicating if the pathway scores are
+#' obtained using \link[FactoMineR]{PCA} or \link[FactoMineR]{MFA}
 #' @param model a character string indicating if the model has to be fitted
 #' using \link[lme4]{lmer} or \link[blme]{blmer}. Default to \code{"lmer"}
 #' @param fixed character vector of fixed effects to be included in the model.
-#' They must correspond to column names of \code{design}
+#' They must correspond to column names of \code{design}. If \code{analysis} is
+#' "MFA", the first fixed effect must correspond to the time effect
 #' @param random character vector of random effects to be included in the model.
 #' They must correspond to column names of \code{design}
 #' @param organism organism code in KEGG database. Required if
@@ -38,32 +41,42 @@
 #' \item{metabolites}{a data.frame with the names and codes of the quantified
 #' metabolites in the pathway}
 #' \item{PCA}{the result of the pathway PCA (a \code{PCA} object as obtained 
-#' from \link[FactoMineR]{PCA})}
+#' from \link[FactoMineR]{PCA}), is equal to \code{NULL} if
+#' \code{analysis = "MFA"}}
+#' \item{MFA}{the result of the pathway MFA (a \code{MFA} object as obtained 
+#' from \link[FactoMineR]{MFA}), is equal to \code{NULL} if
+#' \code{analysis = "PCA"}}
 #' \item{model}{the output of the mixed model fit}
 #' \item{test_pathway}{a data.frame with the p-values for each tested fixed
 #' effect}
 #' 
-#' @importFrom FactoMineR PCA
+#' @importFrom FactoMineR PCA MFA
 #' @importFrom lme4 lmer
 #' @importFrom blme blmer
 #' @importFrom tibble column_to_rownames rownames_to_column
 #' @importFrom stats as.formula anova
-#' @importFrom tidyr separate
+#' @importFrom tidyr separate pivot_wider
 #' 
 #' @examples 
 #' data("MTBLS422")
 #' quantif <- from_ASICS_to_PHOENICS(quantif)
 #' out_test <- test_pathway(quantif, design, pathways, 
 #'                          fixed = c("Age", "Treatment"), random = "Mouse", 
-#'                          npc = 2, model = "blmer")
+#'                          npc = 2, analysis = "PCA", model = "blmer")
 #' out_test
 #' 
+#' out_test2 <- test_pathway(quantif, design, pathways, 
+#'                          fixed = c("Age", "Treatment"), random = "Mouse", 
+#'                          npc = 2, analysis = "MFA", model = "blmer")
+#' out_test2
+#' 
 #' if (requireNamespace("KEGGREST", quietly = TRUE)) { 
 #' \donttest{
-#'   out_test2 <- test_pathway(quantif, design, pathways = "auto", 
+#'   out_test3 <- test_pathway(quantif, design, pathways = "auto", 
 #'                             fixed = c("Age", "Treatment"), random = "Mouse", 
-#'                             npc = 2, model = "blmer", organism = "mmu")
-#'   out_test2
+#'                             npc = 2, analysis = "PCA", model = "blmer",
+#'                             organism = "mmu")
+#'   out_test3
 #'  }
 #' }
 #' 
@@ -85,8 +98,9 @@
 #' @export
 
 test_pathway <- function(quantif, design, pathways = "auto", fixed, random, 
-                         npc = 1L, model = c("lmer", "blmer"),
-                         organism = NULL, min_size = 2) {
+                         npc = 1L, analysis = c("PCA", "MFA"),
+                         model = c("lmer", "blmer"), organism = NULL,
+                         min_size = 2) {
   
   # Inputs tests
   if (!is.character(fixed)) {
@@ -105,7 +119,6 @@ test_pathway <- function(quantif, design, pathways = "auto", fixed, random,
     stop("Random effect must be in `design` column names.")
   }
   
-  
   if (!identical(sort(rownames(quantif)), sort(rownames(design)))) {
     stop("`quantif` and `design` row names must be identical.")
   } 
@@ -118,6 +131,7 @@ test_pathway <- function(quantif, design, pathways = "auto", fixed, random,
   }
   
   model <- match.arg(model)
+  analysis <- match.arg(analysis)
   
   if (round(npc) != npc) {
     stop("`npc` must be an integer.")
@@ -188,16 +202,48 @@ test_pathway <- function(quantif, design, pathways = "auto", fixed, random,
     quantif_path <- merge(quantif_path, design, by = 0)
     quantif_path <- column_to_rownames(quantif_path, "Row.names")
     
-    res_pca <- PCA(quantif_path, graph = FALSE, ncp = npc,
-                   quali.sup = colnames(design))
+    if (analysis == "PCA") {
+      res_pca <- PCA(quantif_path, graph = FALSE, ncp = npc,
+                     quali.sup = colnames(design))
+      
+      score <- data.frame(res_pca$ind$coord[, 1:npc, drop = FALSE])
+      colnames(score) <- paste0(path, "_PC", 1:ncol(score))
+      
+      score_path <- merge(score, design, by = 0)
+      score_path <- column_to_rownames(score_path, "Row.names")
+    }
     
-    score <- data.frame(res_pca$ind$coord[, 1:npc, drop = FALSE])
-    colnames(score) <- paste0(path, "_PC", 1:ncol(score))
+    if (analysis == "MFA") {
+      nb_metab <- length(metab_path)
+      timepoints <- unique(quantif_path[, fixed[1]])
+      
+      quantif_path_wide <- pivot_wider(quantif_path,
+                                       id_cols = c(fixed[-1], random),
+                                       names_from = fixed[1],
+                                       values_from = metab_path,
+                                       names_vary = "slowest")
+      quantif_path_wide <- as.data.frame(quantif_path_wide)
+      rownames(quantif_path_wide) <- quantif_path_wide[, random[1]]
+      
+      res_mfa <- MFA(quantif_path_wide,
+                     group = c(length(c(fixed[-1], random)),
+                               rep(nb_metab, length(timepoints))),
+                     type = c("n", rep("s", length(timepoints))),
+                     name.group = c("supplementary",
+                                    paste0("date_", timepoints)),
+                     num.group.sup = 1, graph = FALSE)
+      
+      score <- data.frame(res_mfa$ind$coord.partiel[, 1:npc, drop = FALSE])
+      colnames(score) <- paste0(path, "_PC", 1:ncol(score))
+      
+      score_path <- rownames_to_column(score, "ind")
+      score_path <- separate(score_path, col = "ind",
+                             into = c(random[1], fixed[1]), sep = ".date_")
+      score_path <- merge(unique(design[, c(fixed[-1], random)]), score_path, 
+                          by = c(random[1]))
+    }
     
     # Mixed model
-    score_path <- merge(score, design, by = 0)
-    score_path <- column_to_rownames(score_path, "Row.names")
-    
     form <- paste0("~ ", paste(fixed, collapse = " + "), " + ", 
                    paste(paste0("(1|", random, ")"), collapse = " + "))
     fmla <- sapply(paste0(colnames(score), form), as.formula)
@@ -262,9 +308,17 @@ test_pathway <- function(quantif, design, pathways = "auto", fixed, random,
     path_code <- unique(pathways_sub[, "pathway_code"])
     out_met <- unique(pathways_sub[, c("metabolite_code", "metabolite_name")])
     
-    res <- list("pathway_name" = path_name, "pathway_code" = path_code,
-                "metabolites" = out_met, "PCA" = res_pca, "model" = res_lmm,
-                "test_pathway" = res_test)
+    if (analysis == "PCA") {
+      res <- list("pathway_name" = path_name, "pathway_code" = path_code,
+                  "metabolites" = out_met, "PCA" = res_pca, "MFA" = NULL,
+                  "model" = res_lmm, "test_pathway" = res_test)
+    }
+    if (analysis == "MFA") {
+      res <- list("pathway_name" = path_name, "pathway_code" = path_code,
+                  "metabolites" = out_met, "PCA" = NULL, "MFA" = res_mfa,
+                  "model" = res_lmm, "test_pathway" = res_test)
+    }
+    
     return(res)
   })
   
diff --git a/man/pathwayRes.Rd b/man/pathwayRes.Rd
index b57c12868d606c23b260a020e539cb7ce4eafdd7..3e2089c1e2f9f288660d515f071e4ee8f1a4af43 100644
--- a/man/pathwayRes.Rd
+++ b/man/pathwayRes.Rd
@@ -21,7 +21,8 @@
   x,
   ...,
   pathway_id = NULL,
-  plot = c("eig", "var", "ind"),
+  analysis = c("PCA", "MFA"),
+  plot = c("eig", "var", "ind", "group"),
   habillage = "none"
 )
 
@@ -38,8 +39,10 @@ adjust_pval(object, method = p.adjust.methods, n = length(object))
 
 \item{pathway_id}{a character string or vector of pathway codes or names}
 
+\item{analysis}{a character string indicating the type of analysis to display}
+
 \item{plot}{a character string indicating the type of plot to return. Default
-to \code{"eig"} (the screegraph of the PCA is displayed)}
+to \code{"eig"} (the screegraph of the PCA or MFA is displayed)}
 
 \item{habillage}{a character string indicating the column of the design used 
 to color the individuals. Only used when \code{plot = "ind"}. Default to 
@@ -75,12 +78,21 @@ data("MTBLS422")
 quantif <- from_ASICS_to_PHOENICS(quantif)
 out_test <- test_pathway(quantif, design, pathways, 
                          fixed = c("Age", "Treatment"), random = "Mouse", 
-                         npc = 2, model = "blmer")
+                         analysis = "PCA", npc = 2, model = "blmer")
 summary(out_test)
+out_test2 <- test_pathway(quantif, design, pathways, 
+                         fixed = c("Age", "Treatment"), random = "Mouse", 
+                         analysis = "MFA", npc = 2, model = "blmer")
+summary(out_test2)
 print(out_test)
-plot(out_test)
-plot(out_test, pathway_id = "mmu00052", plot = "var")
-plot(out_test, pathway_id = "mmu00052", plot = "ind", habillage = "Age")
+plot(out_test, analysis = "PCA")
+plot(out_test, pathway_id = "mmu00052", analysis = "PCA", plot = "var")
+plot(out_test, pathway_id = "mmu00052", analysis = "PCA", plot = "ind", 
+     habillage = "Age")
+plot(out_test2, pathway_id = "mmu00562", analysis = "MFA", plot = "eig")
+plot(out_test2, pathway_id = "mmu00562", analysis = "MFA", plot = "var")
+plot(out_test2, pathway_id = "mmu00562", analysis = "MFA", plot = "ind")
+plot(out_test2, pathway_id = "mmu00562", analysis = "MFA", plot = "group")
 head(out_test)
 extract(out_test, "mmu00562")
 adj_pval <- adjust_pval(out_test)
diff --git a/man/test_pathway.Rd b/man/test_pathway.Rd
index ea5f024087292bc55b9c196277b496af6d2c1f61..6efa704c0e3ffea9074e44a6cfcdca7a09ec7b9b 100644
--- a/man/test_pathway.Rd
+++ b/man/test_pathway.Rd
@@ -11,6 +11,7 @@ test_pathway(
   fixed,
   random,
   npc = 1L,
+  analysis = c("PCA", "MFA"),
   model = c("lmer", "blmer"),
   organism = NULL,
   min_size = 2
@@ -27,8 +28,8 @@ in columns. Column names must be provided and are used as arguments for
 \code{fixed} and \code{random}}
 
 \item{pathways}{data.frame or matrix with metabolites in rows (all 
-metabolites in columns of \code{quantif} must have a row in this input) and the
-following information in columns: \itemize{
+metabolites in columns of \code{quantif} must have a row in this input) and
+the following information in columns: \itemize{
  \item \code{metabolite_code} metabolite code
  \item \code{metabolite_name} metabolite name
  \item \code{pathway_code} pathway code (identifier)
@@ -36,13 +37,17 @@ following information in columns: \itemize{
 }}
 
 \item{fixed}{character vector of fixed effects to be included in the model.
-They must correspond to column names of \code{design}}
+They must correspond to column names of \code{design}. If \code{analysis} is
+"MFA", the first fixed effect must correspond to the time effect}
 
 \item{random}{character vector of random effects to be included in the model.
 They must correspond to column names of \code{design}}
 
 \item{npc}{number of PCs for the PCA step}
 
+\item{analysis}{character string indicating if the pathway scores are
+obtained using \link[FactoMineR]{PCA} or \link[FactoMineR]{MFA}}
+
 \item{model}{a character string indicating if the model has to be fitted
 using \link[lme4]{lmer} or \link[blme]{blmer}. Default to \code{"lmer"}}
 
@@ -60,7 +65,11 @@ results. Each element of the list contain the following entries:
 \item{metabolites}{a data.frame with the names and codes of the quantified
 metabolites in the pathway}
 \item{PCA}{the result of the pathway PCA (a \code{PCA} object as obtained 
-from \link[FactoMineR]{PCA})}
+from \link[FactoMineR]{PCA}), is equal to \code{NULL} if
+\code{analysis = "MFA"}}
+\item{MFA}{the result of the pathway MFA (a \code{MFA} object as obtained 
+from \link[FactoMineR]{MFA}), is equal to \code{NULL} if
+\code{analysis = "PCA"}}
 \item{model}{the output of the mixed model fit}
 \item{test_pathway}{a data.frame with the p-values for each tested fixed
 effect}
@@ -68,7 +77,7 @@ effect}
 \description{
 Perform a differential analysis at pathway level based on 
 metabolite quantifications and information on pathway metabolite composition.
-The method relies on a PCA step.
+The method relies on a PCA or a MFA step.
 }
 \details{
 If \code{pathways = "auto"}, information on pathways in which metabolites are
@@ -82,15 +91,21 @@ data("MTBLS422")
 quantif <- from_ASICS_to_PHOENICS(quantif)
 out_test <- test_pathway(quantif, design, pathways, 
                          fixed = c("Age", "Treatment"), random = "Mouse", 
-                         npc = 2, model = "blmer")
+                         npc = 2, analysis = "PCA", model = "blmer")
 out_test
 
+out_test2 <- test_pathway(quantif, design, pathways, 
+                         fixed = c("Age", "Treatment"), random = "Mouse", 
+                         npc = 2, analysis = "MFA", model = "blmer")
+out_test2
+
 if (requireNamespace("KEGGREST", quietly = TRUE)) { 
 \donttest{
-  out_test2 <- test_pathway(quantif, design, pathways = "auto", 
+  out_test3 <- test_pathway(quantif, design, pathways = "auto", 
                             fixed = c("Age", "Treatment"), random = "Mouse", 
-                            npc = 2, model = "blmer", organism = "mmu")
-  out_test2
+                            npc = 2, analysis = "PCA", model = "blmer",
+                            organism = "mmu")
+  out_test3
  }
 }