1 The Sequential and Orthogonalised PLS Discriminant Analysis method

Metabolomics is a powerful phenotyping tool, generating complex data that need dedicated treatments to enrich knowledge of biological systems. In particular, to investigate relations between experimental factors and metabolism, discriminant statistical analyses are generally performed on metabolomic datasets. In this context, the SOPLSDA method makes it possible to assess the complementarity of data blocks in predicting or explaining a categorical variable.

Reference: Næs T, Tomic O, Afseth NK, Segtnan V, Måge I. Multi block regression based on combinations of orthogonalisation, PLS-regression and canonical correlation analysis. Chemom Intel Lab Syst. 2013;124:32-42.

A selection of reduced non-targeted metabolomics datasets from an article of Zhang et al. have been used to illustrate the method application. (Zhang, Y.; Barupal, D.K.; Fan, S.; Gao, B.; Zhu, C.; Flenniken, A.M.; McKerlie, C.; Nutter, L.M.J.; Lloyd, K.C.K.; Fiehn, O. Sexual Dimorphism of the Mouse Plasma Metabolome Is Associated with Phenotypes of 30 Gene Knockout Lines. Metabolites 2023, 13, 947. https://doi.org/10.3390/metabo13080947).

In our example, the 6 samples from 5 mutant groups (Dhfr, Gnpda1, Plk1, Sra1, Ulk3) and the 40 controls were retained, with the exception of 2 animals that had missing values in non-targeted metabolomics. Three HILIC-NEG and 2 HILIC-POS variables were then removed due to missing or infinite values. Lastly, we kept only 2 data blocks (GCTOF and HILIC NEG) to reduce the computation time. Always in our example, the objective was to highlight metabolites discriminating males and females.

2 R environment preparation

#install.packages("knitr")
library(knitr)
opts_chunk$set(echo = TRUE)

# To ensure reproducibility
set.seed(12)
pkgs <- c("rchemo")
sapply(pkgs, function(x) {
  if (!requireNamespace(x, quietly = TRUE)) {
    install.packages(x)
  }
})
library(rchemo)  # to load rchemo

3 Data preprocessing

A demonstration dataset used for this example is imported. It contains 2 metabolomics datasets and 1 sample metadata block, with the groups to be discriminated.

data(Zhang2023, package = "rchemo")

All data blocks should have exactly the same samples (rows). The block dimension can be checked with the following command:

# Check dimension
BlockNames <- names(Zhang2023)
nbrBlocs <- length(BlockNames)
dims <- lapply(X=Zhang2023[BlockNames], FUN=dim)
names(dims) <- BlockNames
dims
## $CHSNEG
## [1]  68 163
## 
## $CHSPOS
## [1]  68 288
## 
## $GCTOF
## [1]  68 108
## 
## $HILICPOS
## [1]  68 133
## 
## $HILICNEG
## [1] 68 44
## 
## $metadata
## [1] 68  2
# Remove unuseful object for the next steps
rm(nbrBlocs, dims)

The identical order of samples in the three blocks should be ensured.

# Check rows names in any order
row_names <- lapply(X=Zhang2023[BlockNames], FUN=rownames)
rns <- do.call(cbind, row_names)
rns.unique <- apply(rns, 1, function(x) length(unique(x)))
if (max(rns.unique) > 1) {
  stop("Rows names are not identical between blocks.")
}

# Check order of samples
check_row_names <- all(sapply(X=row_names, FUN=identical, y = row_names[[1]]))
if (!check_row_names && max(rns.unique) == 1) {
  print("Rows names are not in the same order for all blocks.")
}

# Remove unuseful object for the next steps
rm(row_names, rns, rns.unique, check_row_names)
GCTOF <- Zhang2023$GCTOF
HILICNEG <- Zhang2023$HILICNEG
sample_metadata <- Zhang2023$metadata
rm(Zhang2023)

4 Data visualization by PCA on separate data blocks

PCA on different datablocks is necessary to verify that there is no outlier, and that the data scaling is suited. In our example, unit variance scaling is suited: For both metabolomic dataset, the scatterplot of loadings is homogeneous, and there are no outliers. With other datasets, particularly those containing more noise, it would have been necessary to apply a log transformation with Pareto scaling.

# GCTOF with unit variance scaling
pcaGCTOF <- pcanipalsna(X = scale(GCTOF[,1:dim(GCTOF)[2]]), nlv = nrow(GCTOF), 
                         gs = TRUE,
                         tol = .Machine$double.eps^0.5, maxit = 200)

## diagram of explained variance
barplot(summary(pcaGCTOF,X = scale(GCTOF[,1:dim(GCTOF)[2]]))$explvar$pvar * 100, names.arg = 1:nrow(summary(pcaGCTOF,X = scale(GCTOF[,1:dim(GCTOF)[2]]))$explvar), main = "diagram of explained variance - PCA GCTOF")

## score plot
plotxy(X= pcaGCTOF$T, group = sample_metadata$Gender, 
       asp = 0, col = 3:4, alpha.f = .8,
       zeroes = TRUE, circle = FALSE, ellipse = FALSE,
       labels = FALSE,
       legend = TRUE, main = "scores - PCA GCTOF", ncol = 1,
       pch=16)

## loading plot
plotxy(X= pcaGCTOF$P, group = NULL, 
       asp = 0, col = NULL, alpha.f = .8,
       zeroes = TRUE, circle = FALSE, ellipse = FALSE,
       labels = TRUE,
       legend = FALSE, main = "loadings - PCA GCTOF", ncol = 1,
       cex=0.8) 

#HILICNEG with unit variance scaling
pcaHILICNEG <- pcanipalsna(X = scale(HILICNEG[,1:dim(HILICNEG)[2]]), nlv = nrow(HILICNEG), 
                         gs = TRUE,
                         tol = .Machine$double.eps^0.5, maxit = 200)

## diagram of explained variance
barplot(summary(pcaHILICNEG,X = scale(HILICNEG[,1:dim(HILICNEG)[2]]))$explvar$pvar * 100, names.arg = 1:nrow(summary(pcaHILICNEG,X = scale(HILICNEG[,1:dim(HILICNEG)[2]]))$explvar), main = "diagram of explained variance - PCA HILIC NEG")

## score plot
plotxy(X= pcaHILICNEG$T, group = sample_metadata$Gender, 
       asp = 0, col = 3:4, alpha.f = .8,
       zeroes = TRUE, circle = FALSE, ellipse = FALSE,
       labels = FALSE,
       legend = TRUE, main = "scores - PCA HILIC NEG", ncol = 1,
       pch=16)

## loading plot
plotxy(X= pcaHILICNEG$P, group = NULL, 
       asp = 0, col = NULL, alpha.f = .8,
       zeroes = TRUE, circle = FALSE, ellipse = FALSE,
       labels = TRUE,
       legend = FALSE, main = "loadings - PCA HILIC NEG", ncol = 1,
       cex=0.8)

# Remove unuseful object for the next steps
rm(pcaGCTOF, pcaHILICNEG)

5 SO-PLS-DA model

In SO-PLS-DA, datablocks are involved sequentially in the model.

  • The first explanatory block is scaled and a PLS-DA model is build to predict the response variable.

  • Then, the next explanatory block is orthogonalised to the PLS components, before a PLS model to explain the residuals, etc…

  • The final prediction is the results of the sum of the predictions by the PLS models.

The interpretation is based on the separate PLS models included in the SO-PLS modelling.

The main steps to apply this method are:

  • the determination of the optimal number of latent variables of each model included in the SO-PLS-DA one, proposed in the package by cross-validation

  • the model validation, proposed by permutation test

  • the model analysis, based on the scatter plot, the loading plot, the Variable Importance in Projection of each PLS model

  • the calculation of the predicted categories for each observation.

In rchemo, all these steps can be performed with a single function.

  • Xlist: list of training X-data (n, p).

  • Xnames: names of the X-matrices

  • Xscaling: vector of Xlist length. X variable scaling among “none” (mean-centering only), “pareto” (mean-centering and pareto scaling), “sd” (mean-centering and unit variance scaling). If “pareto” or “sd”, uncorrected standard deviation is used.

  • Y: Training Y-data (n, 1).

  • Yscaling: Y variable scaling among “none” (mean-centering only), “pareto” (mean-centering and pareto scaling), “sd” (mean-centering and unit variance scaling). If “pareto” or “sd”, uncorrected standard deviation is used.

  • weights Weights (n, 1) to apply to the training observations. Internally, weights are “normalized” to sum to 1. Default to NULL (weights are set to 1/n).

  • newXlist: list of new X-data (m, p) to consider.

  • newXnames: names of the newX-matrices

  • method: method to apply among “soplsrda”,“soplslda”,“soplsqda”

  • prior: for soplslda or soplsqda models : The prior probabilities of the classes. Possible values are “unif” (default; probabilities are set equal for all the classes) or “prop” (probabilities are set equal to the observed proportions of the classes in y).

  • step: step of the analysis among “nlvtest” (cross-validation to help determine the optimal number of latent variables), “permutation” (permutation test), “model” (model calculation),“prediction” (prediction of newX-data or X-data if any))

  • nlv: if step is not “nlvtest”. A vector of same length as the number of blocks defining the number of scores to calculate for each block, or a single number. In this last case, the same number of scores is used for all the blocks.

  • nlvlist: if step is “nlvtest”. A list of same length as the number of X-blocks. Each component of the list gives the number of PLS components of the corresponding X-block to test.

  • modeloutput: if step is “model”: outputs among “scores”, “loadings”, “coef” (regression coefficients), “vip” (Variable Importance in Projection; the VIP calculation being based on the proportion of Y-variance explained by the components, as proposed by Mehmood et al (2012, 2020).)

  • cvmethod: if step is “nlvtest” or “permutation”: “kfolds” for k-folds cross-validation, or “loo” for leave-one-out.

  • nbrep: if step is “nlvtest” and cvmethod is “kfolds”: An integer, setting the number of CV repetitions. Default value is 30. Must me set to 1 if cvmethod is “loo”

  • seed: if step is “nlvtest” and cvmethod is “kfolds”, or if step is “permutation: a numeric. Seed used for the repeated resampling

  • samplingk: A vector of length n. The elements are the values of a qualitative variable used for stratified partition creation. If NULL, the first observation is set in the first fold, the second observation in the second fold, etc…

  • nfolds: if cvmethod is “kfolds”. An integer, setting the number of partitions to create.Default value is 10.

  • npermut: if step is “permutation”: An integer, setting the number of Y-Block with permutated responses to create. Default value is 30.

  • optimisation: if step is “nlvtest”, method for the error optimisation among “global” (the optimal number of latent variables is determined after all the ordred block combination have been computed), or “sequential” (the optimal number of latent variables is determined after each addition of X-block).

  • criterion: if step is “nlvtest” or “permutation” and method is “soplsrda”, “soplslda” or “soplsqda”: optimisation criterion among “rmse” and “err” (for classification error rate)))

  • selection: if step is “nlvtest”: a character indicating the selection method to use to choose the optimal combination of components, among “localmin”, “globalmin”,“1std”. If “localmin”: the optimal combination corresponds to the first local minimum of the mean CV rmse or error rate. If “globalmin” : the optimal combination corresponds to the minimum mean CV rmse or error rate. If “1std” (one standard error rule) : it corresponds to the first combination after which the mean cross-validated rmse or error rate does not decrease significantly.

5.1 determination by cross-validation of the optimal number of latent variables of the model

In this example,the soplslda method with an uniform prior is performed: a linear discriminant analysis is applied on the PLS scores to obtain the classifications. In the soplsrda method, the classification step is performed according to the predicted value, and consequently, it doesn’t take into account the variance of the scatter plot. And the soplsqda method is mode suited when the scatter plot has an atypical shape.

The cvmethod is to choose according to the number of observations. If this number is small, a leave-one-out cross-validation is more suited, but can lead to optimistic results. In the other cases, it could be better to apply a k-fold cross-validation, usually with 3, 5 or 10 folds. In order to reduce the computational time, in this example, the number of cross- validation repetition is set to 10. But it must be higher (at least 30).

Concerning the criterion, in a discriminant context, it is more logical to choose the classification error rate. However, this can result in an error plot depending on the number of latent variables that is not smooth, so some prefer to use rmsecv instead.

In the example, the selection parameter is set to “localmin”. Normally, the cross-validated error decreases until it reaches the optimal number of latent variables, before rising again. Sometimes it fluctuates before this rise, so choosing “localmin” allows for a more parsimonious model. The “1std” option is also very parsimonious because it only considers a larger number of latent variables if doing so significantly improves the cross-validated error.

The plot of the results (called “Mage plot”) indicates the number of latent variables of each block (in the order of the block involvement in the model), and the corresponding error rates and sum of latent variables.

nlvtestsoplsda <- soplsr_soplsda_allsteps(Xlist = list(GCTOF = GCTOF[,1:dim(GCTOF)[2]], 
                                                       HILICNEG = HILICNEG[,1:dim(HILICNEG)[2]]), 
                                          Xnames = c("GCTOF", "HILICNEG"), 
                                          Xscaling = c("none","pareto","sd")[3], 
                                          Y = sample_metadata[,"Gender",drop=FALSE], 
                                          Yscaling = c("none","pareto","sd")[1], weights = NULL,
                                          #newXlist = NULL, newXnames = NULL,
                                          
                                          method = c("soplsrda","soplslda","soplsqda")[2],
                                          prior = c("unif", "prop")[1],
                                          
                                          step = c("nlvtest","permutation","model","prediction")[1],
                                          # nlv = c(),
                                          nlvlist = list(0:3, 0:3), 
                                          # modeloutput = c("scores","loadings","coef","vip"), 
                                          
                                          cvmethod = c("kfolds","loo")[1], 
                                          nbrep = 10, 
                                          seed = 123, 
                                          samplingk = NULL, 
                                          nfolds = 3, 
                                          # npermut = 30, 
                                          
                                          optimisation = c("global","sequential")[1],
                                          criterion = c("err","rmse")[1], 
                                          selection = c("localmin","globalmin","1std")[1],
                                          
                                          #import = c("R","ChemFlow","W4M")[1],
                                          outputfilename = NULL)


# to plot the results of the cross-validation
plot(nlvtestsoplsda[,"nlvsum"],nlvtestsoplsda[,"mean"], type = "n", xlab = "nlv sum", ylab = "classification error rate", 
     main = "error rates obtained from the different numbers \n of latent variable combinaisons of the 2 datablocks")
text(x=nlvtestsoplsda[,"nlvsum"], y=nlvtestsoplsda[,"mean"], 
     labels=paste0(nlvtestsoplsda[,"Xlist1"],",",nlvtestsoplsda[,"Xlist2"]))

nlvoptsoplsda <- nlvtestsoplsda[which(nlvtestsoplsda[,"optimum"]==1),c("Xlist1","Xlist2")] # to obtain the optimal number of LV.

# Remove unuseful object for the next steps
rm(nlvtestsoplsda)

5.2 model validation by permutation test

Usually, the cross-validation parameters are the same than for the determination of the optimal number of latent variables. In this example, as for the determination of the optimal number of latent variables, in order to reduce the computational time, the number of cross- validation repetition and the number of permuted responses are set to 10. But they must be higher (at least 30).

To be valid, all the cross-validated errors obtained on permuted data must be lower than the cross-validated error obtained on the original data.

permutsoplsda <- soplsr_soplsda_allsteps(Xlist = list(GCTOF = GCTOF[,1:dim(GCTOF)[2]], 
                                                      HILICNEG = HILICNEG[,1:dim(HILICNEG)[2]]), 
                                         Xnames = c("GCTOF", "HILICNEG"), 
                                         Xscaling = c("none","pareto","sd")[3], 
                                         Y = sample_metadata[,"Gender",drop=FALSE], 
                                         Yscaling = c("none","pareto","sd")[1], weights = NULL,
                                         #newXlist = NULL, newXnames = NULL,
                                         
                                         method = c("soplsrda","soplslda","soplsqda")[2],
                                         prior = c("unif", "prop")[1],
                                         
                                         step = c("nlvtest","permutation","model","prediction")[2],
                                         nlv = nlvoptsoplsda,
                                         #nlvlist = list(),
                                         #modeloutput = c("scores","loadings","coef","vip"), 
                                         
                                         cvmethod = c("kfolds","loo")[1], 
                                         nbrep = 10, 
                                         seed = 123, 
                                         samplingk = NULL, 
                                         nfolds = 3, 
                                         npermut = 10, 
                                         
                                         # optimisation = c("global","sequential")[1],
                                         criterion = c("err","rmse")[1], 
                                         # selection = c("localmin","globalmin","1std")[1],
                                         
                                         #import = c("R","ChemFlow","W4M")[1],
                                         outputfilename = NULL)
## Warning in predict.Lda(object$fm[[2]], z): mF_214 has/have equal posterior
## probabilities and has/have been classified in the first category in
## alphabetical orderNA has/have equal posterior probabilities and has/have been
## classified in the first category in alphabetical order
## Warning in predict.Lda(object$fm[[2]], z): mF_214 has/have equal posterior
## probabilities and has/have been classified in the first category in
## alphabetical orderNA has/have equal posterior probabilities and has/have been
## classified in the first category in alphabetical order
#plot of the results
plot(permutsoplsda, pch = 16, ylab = "CV classification error rate", xlab = "dyssimilarity Y-Ypermuted")

# Remove unuseful object for the next steps
rm(permutsoplsda)

5.3 model analysis, based on the scatter plot, the loading plot, the Variable Importance in Projection

The score plot allows to show the group discrimination. Based on the VIP curve, the threshold to consider that a variable is important can be set.

In our example, latent variables of the 2 matrices are retained by the SO-PLS-DA method to best discriminate the groups. Consequently, we have two loading plots and two VIP curves, and the scores obtained from the two matrices could be concatenated.

modelsoplsda <- soplsr_soplsda_allsteps(Xlist = list(GCTOF = GCTOF[,1:dim(GCTOF)[2]], 
                                                     HILICNEG = HILICNEG[,1:dim(HILICNEG)[2]]), 
                                         Xnames = c("GCTOF", "HILICNEG"), 
                                         Xscaling = c("none","pareto","sd")[3], 
                                         Y = sample_metadata[,"Gender",drop=FALSE], 
                                         Yscaling = c("none","pareto","sd")[1], weights = NULL,
                                         #newXlist = NULL, newXnames = NULL,
                                         
                                         method = c("soplsrda","soplslda","soplsqda")[2],
                                         prior = c("unif", "prop")[1],
                                         
                                         step = c("nlvtest","permutation","model","prediction")[3],
                                         nlv = nlvoptsoplsda,
                                         #nlvlist = list(), 
                                         modeloutput = c("scores","loadings","coef","vip"), 
                                         
                                         # cvmethod = c("kfolds","loo")[1], 
                                         # nbrep = 30, 
                                         # seed = 123, 
                                         # samplingk = NULL, 
                                         # nfolds = 5, 
                                         # npermut = 30, 
                                         # 
                                         # criterion = c("err","rmse")[1], 
                                         # selection = c("localmin","globalmin","1std")[1],
                                         
                                         #import = c("R","ChemFlow","W4M")[1],
                                         outputfilename = NULL)
# score plot

plotxy(do.call("cbind",modelsoplsda$scores)[,1:2], group = sample_metadata[,"Gender"],
       asp = 0, col = 3:4, alpha.f = .8,
       zeroes = TRUE, circle = FALSE, ellipse = FALSE,
       labels = FALSE,
       legend = TRUE, main = "scores - SO PLS DA \n first model (GCTOF variables)", ncol = 1,
       pch=16,
       xlab="lv1 GCTOF",
       ylab="lv2 GCTOF")

plotxy(do.call("cbind",modelsoplsda$scores)[,3:4], group = sample_metadata[,"Gender"],
       asp = 0, col = 3:4, alpha.f = .8,
       zeroes = TRUE, circle = FALSE, ellipse = FALSE,
       labels = FALSE,
       legend = TRUE, main = "scores - SO PLS DA \n 2nd model (HILIC NEG variables)", ncol = 1,
       pch=16,
       xlab="lv1 HILICNEG",
       ylab="lv2 HILICNEG")

# loading plot
plotxy(modelsoplsda$loadings[[1]], pch = 16, xlab="lv1 GCTOF", ylab="lv2 GCTOF",
       main = "loadings - SO PLS DA \n first model (GCTOF variables)")

plotxy(modelsoplsda$loadings[[2]], pch = 16, xlab="lv1 HILIC NEG", ylab="lv2 HILIC NEG",
       main = "loadings - SO PLS DA \n 2nd model (HILIC NEG variables)")

# vip curve
plot(modelsoplsda$vip[[1]][order(modelsoplsda$vip[[1]][,2], decreasing = TRUE),1,drop=FALSE], pch = 16, ylab = "VIP", xlab="GCTOF variables", main = "VIP curve - SO PLS DA \n first model (GCTOF variables)")

plot(modelsoplsda$vip[[2]][order(modelsoplsda$vip[[2]][,2], decreasing = TRUE),1,drop=FALSE], pch = 16, ylab = "VIP", xlab="HILIC NEG variables", main = "VIP curve - SO PLS DA \n 2nd model (HILIC NEG variables)")

# Remove unuseful object for the next steps
rm(modelsoplsda)

5.4 predicted values

The prediction step provides a table with:

  • subjects scores

  • predicted categories

  • probabilities to be predicted for each category.

predsoplsda <- soplsr_soplsda_allsteps(Xlist = list(GCTOF = GCTOF[,1:dim(GCTOF)[2]], 
                                                    HILICNEG = HILICNEG[,1:dim(HILICNEG)[2]]), 
                                        Xnames = c("GCTOF", "HILICNEG"), 
                                        Xscaling = c("none","pareto","sd")[3], 
                                        Y = sample_metadata[,"Gender",drop=FALSE], 
                                        Yscaling = c("none","pareto","sd")[1], 
                                        weights = NULL,
                                        newXlist = list(GCTOF = GCTOF[,1:dim(GCTOF)[2]], 
                                                        HILICNEG = HILICNEG[,1:dim(HILICNEG)[2]]),
                                       newXnames =  c("GCTOF", "HILICNEG"),
                                        
                                        method = c("soplsrda","soplslda","soplsqda")[2],
                                        prior = c("unif", "prop")[1],
                                        
                                        step = c("nlvtest","permutation","model","prediction")[4],
                                        nlv = nlvoptsoplsda, 
                                        # nlvlist = list(),
                                        # modeloutput = c("scores","loadings","coef","vip"), 
                                        # 
                                        # cvmethod = c("kfolds","loo")[1], 
                                        # nbrep = 30, 
                                        # seed = 123, 
                                        # samplingk = NULL, 
                                        # nfolds = 5, 
                                        # npermut = 30, 
                                        # 
                                        # criterion = c("err","rmse")[1], 
                                        # selection = c("localmin","globalmin","1std")[1],
                                        # 
                                        #import = c("R","ChemFlow","W4M")[1],
                                        outputfilename = NULL)

predsoplsda
## Warning in attr(x, "align"): 'xfun::attr()' est obsolète.
## Utilisez plutôt ‘xfun::attr2()’.
## Voir help("Deprecated")
lv1 lv2 lv1 lv2 pred.y1 pred.posterior.Female pred.posterior.Male
wM_001 3.1104839 -1.8776428 0.0770304 0.4056080 Male 0.0000000 1.0000000
wM_002 0.8706091 2.7737091 2.2225903 -0.6668222 Male 0.0000001 0.9999999
wF_003 -2.0794685 -4.1513391 1.0347199 -2.2232995 Female 1.0000000 0.0000000
wF_004 -1.3929337 -0.9329952 1.6783179 -2.4544693 Female 0.9999978 0.0000022
wM_005 3.7334737 2.1394137 -5.2925431 -1.9277701 Male 0.0000007 0.9999993
wM_006 0.7942075 3.8988589 2.4108509 0.3622006 Male 0.0000000 1.0000000
wM_007 3.6643372 2.8520330 0.2699604 -0.7877236 Male 0.0000000 1.0000000
wF_008 -1.3424589 -3.4331600 -1.3402091 -1.3009918 Female 1.0000000 0.0000000
wF_009 -2.2679816 2.4862659 -2.5174983 2.7165252 Female 0.9999914 0.0000086
wF_010 -1.1332711 -1.6029086 -1.7438338 -0.2034697 Female 1.0000000 0.0000000
wM_011 3.6796765 -0.3940843 0.2748160 -2.2218624 Male 0.0000000 1.0000000
wM_012 3.2633544 -2.3199987 -0.3575237 0.8005980 Male 0.0000000 1.0000000
wM_013 0.2861742 -1.1453774 1.4488830 1.3429253 Male 0.0082194 0.9917806
wF_014 0.3165370 -1.8671305 -0.1083681 -1.3580651 Female 0.9962255 0.0037745
wF_015 -2.0533100 -0.3641714 -1.4599466 0.4958105 Female 1.0000000 0.0000000
wF_016 -4.3710900 7.0394700 0.4892413 -0.2001255 Female 0.9999988 0.0000012
wM_017 0.0340532 0.9124559 3.0290137 1.4078245 Male 0.0000067 0.9999933
wM_018 2.9234130 3.4090954 -0.4184352 -4.5448741 Male 0.0000000 1.0000000
wM_019 1.4199731 1.6314220 0.1217314 0.2261157 Male 0.0000008 0.9999992
wM_020 1.1464665 -0.0593342 0.8542429 0.1578280 Male 0.0000582 0.9999418
wM_021 2.9133129 -0.1279018 -0.8074042 -0.1200408 Male 0.0000000 1.0000000
wF_022 -4.3823631 1.6150663 2.8335960 -0.3192809 Female 1.0000000 0.0000000
wF_023 -3.7330735 1.0706792 2.1199614 -5.0583544 Female 1.0000000 0.0000000
wF_024 -1.7911988 -3.4660716 0.1885171 1.6547945 Female 1.0000000 0.0000000
wF_025 -1.1943228 -4.4850111 -0.9963431 -0.2678816 Female 1.0000000 0.0000000
wF_026 -3.4018063 -1.5325501 0.3295896 -1.5653166 Female 1.0000000 0.0000000
wM_027 -0.3158025 4.3298378 2.4507067 2.6476981 Male 0.0000000 1.0000000
wM_028 3.2280952 -2.1161162 0.7103836 0.6598328 Male 0.0000000 1.0000000
wM_029 1.2891899 2.9617139 -0.3072041 -0.2990717 Male 0.0000007 0.9999993
wF_030 -0.5947670 -2.4551025 -0.9926484 -0.3064128 Female 0.9999987 0.0000013
wF_031 -1.8940911 -1.7115351 -1.1151626 0.3333495 Female 1.0000000 0.0000000
wF_032 -2.7673921 0.8457167 -1.3196836 1.1537613 Female 1.0000000 0.0000000
wM_033 1.1843349 1.0250102 3.1023207 1.2483962 Male 0.0000000 1.0000000
wM_034 3.5359780 -1.8282374 -0.0788122 0.1201300 Male 0.0000000 1.0000000
wF_036 -1.0117788 -4.1231792 -0.2468068 -0.9453525 Female 1.0000000 0.0000000
wF_037 -1.5061904 -4.0377038 0.2447996 -0.8395652 Female 1.0000000 0.0000000
wF_038 -0.1180256 -2.8205561 -1.2134567 -0.1900882 Female 0.9999891 0.0000109
wM_039 0.8111931 0.2521033 1.9480782 2.2675377 Male 0.0000004 0.9999996
wF_040 -0.8975068 -5.5059690 0.5976171 0.5697094 Female 1.0000000 0.0000000
mM_077 0.3220112 0.1171998 1.0043039 0.6282093 Male 0.0035886 0.9964114
mM_078 2.8217417 -1.6225596 -0.7533944 0.4423057 Male 0.0000006 0.9999994
mM_079 1.5237466 3.0513592 0.0036400 0.3169198 Male 0.0000000 1.0000000
mF_080 -1.8338800 -0.3497817 -0.1841159 -1.0428655 Female 0.9999999 0.0000001
mF_081 -4.8375205 5.0619594 -0.8706144 -0.5990289 Female 1.0000000 0.0000000
mF_082 -5.8419412 4.6167575 -0.5014300 1.7009640 Female 1.0000000 0.0000000
mM_101 4.1926550 -0.3314161 -0.5540947 0.1223141 Male 0.0000000 1.0000000
mM_103 0.4776000 10.7106213 -1.9808585 -0.2555632 Male 0.0000000 1.0000000
mF_104 -1.8799950 0.2839277 0.7816574 -0.7308969 Female 0.9999964 0.0000036
mF_105 -1.5742078 -2.1550735 -4.6159908 1.9116767 Female 1.0000000 0.0000000
mF_106 -1.3057620 -1.8175224 -1.2001472 -0.4268428 Female 1.0000000 0.0000000
mM_173 2.0202999 4.5030661 0.5926989 0.4369854 Male 0.0000000 1.0000000
mM_174 3.6618503 -2.1608924 2.7271224 -2.2106566 Male 0.0000000 1.0000000
mM_175 1.7852842 -0.8297287 1.1608313 0.8468994 Male 0.0000005 0.9999995
mF_176 -1.6110994 -0.6301511 -1.4286656 -0.8421951 Female 1.0000000 0.0000000
mF_177 -2.7431219 1.4419834 -0.3702915 0.5183887 Female 0.9999999 0.0000001
mF_178 -1.7901305 -1.8491227 2.3401256 1.6207216 Female 0.9998437 0.0001563
mM_203 3.2963936 1.1889717 0.7304935 0.6854031 Male 0.0000000 1.0000000
mM_204 3.3437407 -2.2201687 2.5827618 1.7652330 Male 0.0000000 1.0000000
mM_205 3.1143281 1.9839658 -5.7930228 1.9192436 Male 0.0000002 0.9999998
mF_206 -1.7542584 -1.6734108 1.2309001 1.6935894 Female 0.9999770 0.0000230
mF_207 -3.6682668 -0.3065552 0.9116643 1.1038027 Female 1.0000000 0.0000000
mF_208 -2.5626757 -2.2296193 -1.6226746 0.3234678 Female 1.0000000 0.0000000
mM_209 2.4664449 3.2006810 0.6857146 0.0798159 Male 0.0000000 1.0000000
mM_210 2.4082158 2.1849030 0.0616925 0.4069605 Male 0.0000000 1.0000000
mM_211 2.9190337 1.4411327 0.1379715 0.1576950 Male 0.0000000 1.0000000
mF_212 -1.5205098 1.9847685 -1.9591491 -2.2723288 Female 0.9999998 0.0000002
mF_213 -1.5549565 -1.0142881 -0.4349226 0.3489081 Female 0.9999994 0.0000006
mF_214 0.1689490 -9.4657820 -0.8032947 0.5810668 Female 1.0000000 0.0000000
# Remove unuseful object for the next steps
rm(predsoplsda, nlvoptsoplsda)

6 Reproducibility

This vignette was produced with the following R session configuration.

sessionInfo()
## R version 4.4.1 (2024-06-14 ucrt)
## Platform: x86_64-w64-mingw32/x64
## Running under: Windows 11 x64 (build 26200)
## 
## Matrix products: default
## 
## 
## locale:
## [1] LC_COLLATE=C                   LC_CTYPE=French_France.utf8   
## [3] LC_MONETARY=French_France.utf8 LC_NUMERIC=C                  
## [5] LC_TIME=French_France.utf8    
## 
## time zone: Europe/Paris
## tzcode source: internal
## 
## attached base packages:
## [1] stats     graphics  grDevices utils     datasets  methods   base     
## 
## other attached packages:
## [1] rchemo_0.1-4 knitr_1.48  
## 
## loaded via a namespace (and not attached):
##  [1] digest_0.6.36     R6_2.5.1          signal_1.8-1      fastmap_1.2.0    
##  [5] xfun_0.53         e1071_1.7-14      cachem_1.1.0      htmltools_0.5.8.1
##  [9] rmarkdown_2.27    lifecycle_1.0.4   cli_3.6.3         sass_0.4.9       
## [13] proxy_0.4-27      data.table_1.15.4 jquerylib_0.1.4   class_7.3-22     
## [17] compiler_4.4.1    highr_0.11        rstudioapi_0.16.0 tools_4.4.1      
## [21] evaluate_0.24.0   bslib_0.7.0       yaml_2.3.9        FNN_1.1.4        
## [25] rlang_1.1.4       jsonlite_1.8.8    MASS_7.3-61