Skip to main content
v2026.11,986 entries · CC-BY 4.0

XCMS: LC-MS Data Processing in R

Process LC-MS data with XCMS in R: follow the official example, distinguish peaks from features, and inspect grouping, gap filling and abundance outputs.

Written and maintained by CASRAI Editorial Board

Published

On this page

XCMS is an R/Bioconductor package that turns chromatographic mass-spectrometry signals into aligned features and sample abundance matrices. Its LC-MS workflow separates peak detection, retention-time alignment, correspondence and gap filling. Keeping those stages distinct makes it easier to explain which signals entered an analysis and how missing measurements were handled.

This guide follows the official version-4 example using the faahKO demonstration data. It also connects each processing step to the object or matrix you should inspect, rather than treating a completed script as evidence that every feature is reliable.

What it is used for in research

XCMS supports preprocessing of LC-MS, GC-MS and LC-MS/MS data for untargeted profiling. The Bioconductor package listing names NetCDF, mzXML, mzData and mzML inputs. In the version-4 workflow, raw spectra and sample descriptions enter an MsExperiment object, while preprocessing results are held in an XcmsExperiment object. These containers serve different stages of the same analysis; they are not competing file formats.

The practical output is a set of features matched across samples, with a matrix of associated signal measurements. The workflow therefore sits between instrument data and downstream statistical interpretation. Acquisition design remains a separate decision: the guide to metabolomics platform choice and QC samples covers that earlier stage.

The maintainer documentation describes integration with Spectra and other Bioconductor packages. That matters when handing data to another analyst: name the object class as well as the software package. A reference to an older XCMSnExp workflow does not establish that every example uses the newer XcmsExperiment interface.

Install or access XCMS

Install the package from Bioconductor through BiocManager. The official package page supplies the installation commands, and the maintainer recommends BiocManager because it manages packages within the same Bioconductor release. XCMS is distributed under GPL version 2 or later with an accompanying LICENSE file.

if (!require("BiocManager", quietly = TRUE))
    install.packages("BiocManager")

BiocManager::install("xcms")
BiocManager::install("faahKO")
browseVignettes("xcms")

The first installation is the software; faahKO supplies the official demonstration files used below. The final command opens documentation for the installed package. Use the Bioconductor release appropriate to your R installation, following the release link on the package page rather than selecting an arbitrary package archive.

Keep documentation versions explicit. The release vignette identifies its package version, while the maintainer’s documentation website can show a development version. For this walkthrough, the release vignette is the authority for the sequence and demonstration settings; reference pages explain the functions and their parameters. For repeatable environment management around the analysis, see locking R package versions with renv.

Step-by-step task: preprocess the demonstration data

The task is to build a feature abundance matrix from the official example’s eight selected CDF files. The commands below retain the documented function names and example settings. They are a teaching configuration for that dataset, rather than an instrument-independent processing recipe. Run the blocks in order in the same R session.

1. Import files with their sample descriptions

library(xcms)
library(faahKO)
library(MsExperiment)

cdfs <- dir(system.file("cdf", package = "faahKO"),
            full.names = TRUE, recursive = TRUE)[c(1, 2, 5, 6, 7, 8, 11, 12)]
pd <- data.frame(
    sample_name = sub(basename(cdfs), pattern = ".CDF",
                      replacement = "", fixed = TRUE),
    sample_group = c(rep("KO", 4), rep("WT", 4)),
    stringsAsFactors = FALSE)
faahko <- readMsExperiment(spectraFiles = cdfs, sampleData = pd)
faahko

The file selection and group assignments come from the official vignette. In your own experiment, replace both together with your actual files and metadata. Inspect the object before processing: the important checkpoint is the association between each file and its sample description, not merely whether import returned without an error.

2. Restrict the example interval and detect peaks

faahko <- filterRt(faahko, rt = c(2550, 4250))
cwp <- CentWaveParam(peakwidth = c(20, 80), noise = 5000,
                     prefilter = c(6, 5000))
faahko <- findChromPeaks(faahko, param = cwp)
head(chromPeaks(faahko))

The vignette restricts retention time and uses elevated noise and prefilter settings to shorten its demonstration. Those settings are not general detection limits. The centWave reference defines peakwidth in seconds, noise as a minimum centroid intensity, and prefilter as a required number of mass-trace points meeting an intensity threshold.

After detection, chromPeaks contains individual chromatographic peaks. A row belongs to one sample; it is not yet a feature matched across the whole study. Keep that distinction when recording how many signals survived a processing stage.

3. Align retention times

faahko <- adjustRtime(faahko, param = ObiwarpParam(binSize = 0.6))
head(adjustedRtime(faahko))

This is the vignette’s obiwarp example. Alignment changes the retention-time coordinates used to compare samples, including coordinates associated with detected peaks. The official walkthrough evaluates alignment with chromatogram plots and plots of the adjustment. A successful function call alone does not answer whether the alignment is sensible for the data.

4. Match peaks across samples

pdp <- PeakDensityParam(
    sampleGroups = sampleData(faahko)$sample_group,
    minFraction = 0.4, bw = 30)
faahko <- groupChromPeaks(faahko, param = pdp)
head(featureDefinitions(faahko))

Correspondence groups peaks with compatible mass-to-charge and retention-time positions into features. The grouping reference defines minFraction within at least one sample group. It does not require a feature to appear in that fraction of the entire experiment.

Illustrative calculation: with four samples in each group, a fraction of 0.4 requires at least two detected samples in one group to satisfy that fraction criterion, because one out of four is 0.25 and two out of four is 0.5. This calculation illustrates only the fraction condition; mass and retention-time grouping conditions still apply. A feature need not be detected in both groups to meet it.

5. Fill missing peak areas and extract abundances

faahko <- fillChromPeaks(faahko, param = ChromPeakAreaParam())
head(featureValues(faahko, value = "into"))

Gap filling integrates signal from the expected region when a feature lacks a detected chromatographic peak in a sample. The recommended ChromPeakAreaParam approach derives that region from peaks assigned to the feature. It is a targeted integration step, not a declaration that every newly reported value was independently detected as a peak.

Output and how to read it

Read the results at three levels: individual sample peaks, feature definitions across samples, and feature values within each sample. The data table below provides an original command-to-output crosswalk compiled from the walkthrough and function references. Use it to identify the object that answers a question before changing settings elsewhere in the pipeline.

  • Peak records: chromPeaks reports detected peaks, including mass-to-charge coordinates, retention-time coordinates and integrated intensity. Its sample field identifies the originating sample.
  • Feature definitions: featureDefinitions describes groups of peaks, including feature coordinates and the contributing peak indices.
  • Abundance matrix: featureValues returns features in rows and samples in columns. With value set to “into”, entries represent integrated chromatographic signal.

Multiple peaks in one sample can belong to the same feature. The XcmsExperiment reference documents three resolution strategies: medret selects the peak nearest the feature’s median retention time; maxint selects the largest signal; sum adds the assigned values. The choice changes what a matrix cell represents, so preserve it alongside the exported result.

Filled peaks are marked in chromPeakData by is_filled. The extraction interface can include them or report missing values in their place. An abundance matrix should therefore travel with a clear statement of its aggregation and filling choices. For a structured Bioconductor handoff, quantify returns a SummarizedExperiment containing the assay, feature metadata and sample metadata.

Do not treat processing completion as a statistical conclusion. The official vignette explicitly warns that its unnormalized PCA example can reflect technical effects. A downstream environment such as MetaboAnalyst for metabolomics analysis addresses another part of the analysis; preparation and interpretation of the input matrix still need to be explicit.

Troubleshooting

Unexpectedly few detected peaks

Inspect detection settings before relaxing correspondence requirements. The centWave reference explains that prefilter and noise can remove candidate signal before peak detection. It also defines peakwidth as the expected chromatographic width range. An unsuitable early-stage restriction cannot be repaired simply by changing the fraction of samples required during grouping.

For a study dataset, compare the configured widths and intensity restrictions with representative chromatograms. Document the reason for each changed parameter. The objective is a defensible processing choice, rather than maximizing the number of reported features.

Missing values remain after filling

The release vignette states that a missing value can remain when no signal is measured for that sample. Gap filling does not guarantee a complete matrix. Its reference also distinguishes ChromPeakAreaParam from the older FillChromPeaksParam approach, which is unavailable for XcmsExperiment objects.

Check the object class, selected parameter class and filled-peak annotations together. Avoid interpreting the absence of a value as a measured zero merely to simplify later calculations. Retain the distinction between a detected peak, an integrated gap and an unresolved measurement.

Group assignments or memory settings cause surprises

PeakDensityParam requires one group assignment per sample, including when the experiment has only one group. Its reference allows NA assignments to exclude samples such as blanks from defining new features, while still assigning their peaks to features defined from other samples. Preserve that policy when describing feature retention.

For memory problems, the detection reference describes chunkSize as the number of samples loaded together. Setting it to the whole experiment can exhaust memory; parallel workers operate on the currently loaded subset. The same reference provides on-disk result storage through hdf5File for large experiments. Choose these settings with the storage and parallel configuration in view.

Free alternatives

Two openly licensed projects provide other routes through mass-spectrometry processing. The table describes their documented interfaces and scope; it is not a claim that their algorithms or outputs are interchangeable with an XCMS analysis.

Project Documented workflow Access and licensing
OpenMS LC-MS data management, analysis and visualization; TOPP command-line tools and Python bindings through pyOpenMS. Open-source C++ library and tools under a three-clause BSD license.
MS-DIAL Graphical processing for untargeted metabolomics, including GC-MS and LC-MS/MS, spectral deconvolution and identification support. The project’s license page assigns LGPL v3 to source code and CC BY 4.0 to binary and other library files.

For a transition between tools, first write down what must be carried over: input files, sample grouping, processing parameters, feature measurements and annotation information. Compare those actual analytical requirements with each project’s documentation. A matching input extension alone does not establish that two pipelines made the same analytical decisions.

Keep a reproducible analysis record

A useful handoff describes both the data and the decisions that generated the matrix. Record the package environment, selected files, metadata-to-file mapping, detection parameters, alignment method, correspondence groups, filling method and matrix extraction strategy. Keep the distinction between demonstration settings and study-specific settings visible in the analysis script.

This is an editorial checklist derived from the separate documented stages, rather than an additional XCMS quality threshold. It makes computational reproducibility concrete: another analyst needs the inputs and choices behind the output, not only a spreadsheet of values. The package’s citation command also supplies its citation information for the research record.

citation("xcms")
sessionInfo()

Sources

Data: XCMS processing stages and result inspection

Original crosswalk combining the official release walkthrough with XCMS function references. It connects each processing operation to its documented configuration and the result accessor used for inspection; it contains no measured experimental results.

XCMS processing stages and result inspection
StageProcessing functionConfigurationResult inspectionSource
Peak detectionfindChromPeaksCentWaveParamchromPeaks: individual peaks within sampleshttps://sneumann.github.io/xcms/reference/findChromPeaks.html
Retention-time alignmentadjustRtimeObiwarpParam in the release exampleadjustedRtime: corrected retention-time coordinateshttps://bioconductor.org/packages/release/bioc/vignettes/xcms/inst/doc/xcms.html
CorrespondencegroupChromPeaksPeakDensityParam: sampleGroups and minFractionfeatureDefinitions: peaks grouped into featureshttps://sneumann.github.io/xcms/reference/groupChromPeaks.html
Gap fillingfillChromPeaksChromPeakAreaParamchromPeakData: is_filled identifies filled peak recordshttps://sneumann.github.io/xcms/reference/fillChromPeaks.html
Abundance extractionfeatureValuesvalue selects the measurement; method resolves multiple peaksMatrix with feature rows and sample columnshttps://sneumann.github.io/xcms/reference/XcmsExperiment.html

Sources

Compiled by CASRAI from the sources above. Free to reuse under CC BY 4.0 with attribution.

Follow CASRAI

Research-administration guidance, standards updates and independent tool reviews.

Ask CASRAI · free to try

Ask about XCMS: LC-MS Data Processing in R

Ask your first 2 questions free below. Subscribers get 150 a day for $29 a month.

An AI assistant specialized in research administration. It cites the sources behind every answer, labels web answers and says when it can't answer.

Answers draw on CASRAI's guides and dictionary plus the federal and funder documents we index: Federal Register, Grants.gov, Regulations.gov and UKRI.

Works on this site and inside Claude, Cursor and the AI tools you already use.

Everything CASRAI publishes — this page, the dictionary, the guides and the news — stays free to read, with no account and no card.

Referenced across the research world

University of Cambridge logoColumbia University logoCrossref logoUniversity of Edinburgh logoHarvard University logoUniversity of Oxford logoPrinceton University logoStanford School of Medicine logoUniversity College London logoORCID logoUniversity of Cambridge logoColumbia University logoCrossref logoUniversity of Edinburgh logoHarvard University logoUniversity of Oxford logoPrinceton University logoStanford School of Medicine logoUniversity College London logoORCID logo
  • University of Cambridge logo
  • Columbia University logo
  • Crossref logo
  • University of Edinburgh logo
  • Harvard University logo
  • University of Oxford logo
  • Princeton University logo
  • Stanford School of Medicine logo
  • University College London logo
  • ORCID logo

View CASRAI adoption →