2  Data Preparation

This chapter describes how to prepare input data for the FeatureMAP pipeline. Unlike traditional workflows, FeatureMAP starts from feature-level metabolomics data.

2.1 Input Data Format Requirements

2.1.1 Required feature_table

FeatureMAP requires a data frame named feature_table with the following columns:

Column Type Description
variable_id character Unique feature ID (no duplicates)
mz numeric Feature m/z
rt numeric Retention time
polarity character Ion mode, must be "positive" or "negative"
mean_intensity numeric Mean intensity of the feature
condition numeric Numeric value representing the direction and magnitude of association for each feature, such as a log fold change, regression coefficient, or correlation coefficient
pvalue numeric Statistical p-value corresponding to the association measure in condition, used to reflect the strength of evidence
Note

condition captures the effect direction and size, while pvalue reflects its statistical significance. Together, they are used downstream to prioritize features before PCSF subnetwork extraction. In Subnetwork Extraction, FeatureMAP combines the two into a single feature importance score.

Tip

Positive- and negative-mode features can be analysed together in one table: keep the feature IDs unique across modes and set polarity accordingly.

2.1.2 Optional ms2_table

You can optionally provide an MS2 annotation table to improve feature-to-metabolite mapping confidence. MS2-based metabolite annotations can be obtained using the tidymass ecosystem.

Expected columns:

  • variable_id (character, unique)
  • HMDB.ID and/or KEGG.ID (character, can contain NA)

The MS2 table is used as auxiliary evidence only: a feature–metabolite pair generated by MS1 matching is flagged as MS2-supported when variable_id + HMDB.ID or variable_id + KEGG.ID also appears in the MS2 table. HMDB.ID is used first, and KEGG.ID serves as a fallback. MS2 rows that do not match any MS1 candidate do not create new annotations.

If ms2_table = NULL, FeatureMAP will proceed with MS1-based annotation only.

2.2 Load Demo Data

FeatureMAP provides a built-in demo feature table and a matching demo MS2 table:

data("demo_feature_table", package = "featuremap")
data("demo_ms2", package = "featuremap")

dim(demo_feature_table)
head(demo_feature_table, 3)
# [1] 1189    7
#    variable_id       mz      rt polarity mean_intensity  condition       pvalue
# 1 M105T384_POS 105.0334 383.851 positive      371369.28 -0.5029755 1.998631e-01
# 2  M110T34_POS 110.0085  33.907 positive       58184.51 -0.4755627 9.740936e-05
# 3  M116T49_POS 116.0700  49.496 positive      695843.03 -0.4107283 3.401449e-02

dim(demo_ms2)
head(demo_ms2, 3)
# [1] 207   6
# # A tibble: 3 x 6
# # Groups:   variable_id [3]
#   variable_id  HMDB.ID     KEGG.ID Compound.name               SS Level
#   <chr>        <chr>       <chr>   <chr>                    <dbl> <dbl>
# 1 M116T49_POS  HMDB0003411 C00763  D-Proline                0.829     2
# 2 M132T103_POS HMDB0000172 C00407  L-Isoleucine             0.757     2
# 3 M134T420_POS HMDB0032609 C03005  N-Methylanthranilic Acid 0.619     2

demo_ms2 contains the columns variable_id, HMDB.ID, KEGG.ID, Compound.name, SS (MS2 similarity score) and Level (annotation confidence level). Only the first three are used by FeatureMAP; the rest are kept for your own inspection.

2.3 Prepare Your Own Data

A typical preprocessing pattern is:

library(readr)
library(dplyr)

feature_table <- read_csv("your_feature_table.csv") %>%
  transmute(
    variable_id = as.character(variable_id),
    mz = as.numeric(mz),
    rt = as.numeric(rt),
    polarity = as.character(polarity),
    mean_intensity = as.numeric(mean_intensity),
    condition = as.numeric(condition),
    pvalue = as.numeric(pvalue)
  )

2.4 Pre-run Checklist

Run these checks before Step 2:

required_cols <- c("variable_id", "mz", "rt", "polarity", "mean_intensity", "condition", "pvalue")
setdiff(required_cols, colnames(feature_table))
# should return character(0)

anyDuplicated(feature_table$variable_id)
# should return 0

all(feature_table$polarity %in% c("positive", "negative"))
# should return TRUE

sum(is.na(feature_table[, required_cols]))
# ideally 0 for required fields

2.5 Next Step

Once your input tables are ready, continue to Feature Annotation to generate the first-round metabolite annotation results.