Skip to contents

Manual

Common errors and questions, grouped by workflow stage. For installation problems, check_setup() reports what the R environment is missing; unresolved bugs belong on GitHub Issues.

Installation and setup

Q: How do I confirm my R environment is ready for MRMhub?

A: check_setup() checks the R version (≥ 4.1.0 is required), the packages MRMhub needs, and the optional packages that unlock extra features. Missing required packages are listed with a copy-pasteable install command.

Q: build_workflow() reports that shiny or bslib is not installed.

A: The Workflow Builder is an optional feature, so shiny and bslib are not installed with MRMhub. Run interactively, build_workflow() offers to install them; otherwise add them yourself.

install.packages(c("shiny", "bslib"))

If instead it reports “Could not find the workflow builder app. Try reinstalling mrmhub.”, the app files are missing from the installed package — reinstall MRMhub.

Q: On Windows, installation fails with “cannot remove prior installation of package ‘X’” or “permission denied”.

A: A dependency’s DLL is locked by another running R session, RStudio, or Positron, and Restart R does not always release the lock on Windows. Quit the IDE entirely (close all windows), confirm no R.exe/Rterm.exe is left in Task Manager, reopen, and run the install command before opening any project that auto-attaches a tidyverse package.

Q: “namespace ‘rlang’ is already loaded” (or another core package).

A: A package that others depend on is pinned in the current namespace. Restart R, update the named package first in the fresh session, then retry.

Q: After updating MRMhub, a function fails with “lazy-load database ‘…/mrmhub.rdb’ is corrupt”.

A: The package was reinstalled while it was loaded in the running session, so R still holds the index of the previous installation and looks up functions at offsets that no longer match the new file on disk. Nothing is actually damaged. Restart R and attach the package again.

Restarting R after every install or update of MRMhub avoids this. In RStudio and Positron, Session ▸ Restart R (Ctrl/Cmd+Shift+F10).

Q: “Rtools is required to build R packages” (Windows).

A: Install Rtools matching your R version (Rtools43 for R 4.3, Rtools44 for R 4.4, …), restart R, and retry. Rtools compiles the source packages a few dependencies still need when no Windows binary is available yet.

Q: remotes keeps failing on a locked or transitive dependency.

A: pak resolves the dependency graph in one pass, handles locked packages more cleanly on Windows, and gives clearer messages on transitive failures.

install.packages("pak")
pak::pak("SLINGhub/mrmhub")

Q: “installation of package ‘X’ had non-zero exit status”.

A: By default every optional (Suggests) dependency is installed too, so one broken optional package aborts the whole install. Install only the strictly required dependencies and add optional ones later.

remotes::install_github(
  "SLINGhub/mrmhub",
  dependencies = c("Depends", "Imports", "LinkingTo")
)

Importing data

Q: Which importer should I use?

A: See Import and prepare data files for a decision flowchart matching each vendor/file layout to its importer.

Q: import_data_masshunter() aborts with “Data file is in an unsupported or corrupted format…”.

A: Almost always the wrong importer for the file — a plain, Skyline, or INTEGRATOR CSV passed to the MassHunter parser. Use the importer that matches the file’s format. If the file really is a MassHunter export, re-export it from MH Quant with compounds as columns.

Q: An importer aborts with “Required analysis_id column is missing” (or feature_id).

A: The column holding the analysis or feature identifier was not recognised. Map it explicitly with column_mapping (names are matched case-insensitively).

import_data_csv_long(
  mexp,
  path = "your_file.csv",
  column_mapping = c(analysis_id = "Sample", feature_id = "Compound")
)

Q: “The file was read as a single column using the ‘,’ delimiter.”

A: The file is semicolon- or tab-delimited (common in European Excel locales), so a comma reader sees one column. Re-export as CSV UTF-8 (Comma delimited) and re-import.

Q: “Imported data measures the same feature more than once in the same analysis.”

A: Read the values in the message. Identical values mean the same data was read twice (the same result file, or an overlapping part of it). Differing values mean two real measurements carry the same IDs: two injections sharing a raw_data_filename (the default analysis_id), or the wrong column mapped to analysis_id/feature_id.

Q: A wide CSV aborts with “All columns with feature values must be numeric.”

A: Metadata columns are mixed into the feature block. Point first_feature_column at the first real feature column, and pass na_strings for any text missing-value tokens.

import_data_csv_wide(
  mexp,
  path = "your_file.csv",
  first_feature_column = 5,
  na_strings = c("NA", "n.a.", "")
)

Q: Skyline import aborts with Molecule Name is not unique identifier for each transition.”

A: Several transitions share a molecule name. Build unique IDs from the precursor/product names or masses.

import_data_skyline(
  mexp,
  path = "your_file.csv",
  transition_id_columns = "name"
)

Q: Feature names in the data don’t match the feature annotation.

A: Trailing whitespace or case differences ("Compound A " vs "Compound A") break the join. Compare both directions:

data_ids  <- unique(mexp@dataset$feature_id)
annot_ids <- mexp@annot_features$feature_id
setdiff(data_ids, annot_ids)  # in data, not annotated
setdiff(annot_ids, data_ids)  # annotated, not in data

Adding metadata

Q: “None of the analyses in the data match the imported analysis metadata.”

A: Either the wrong metadata file, or the analysis_ids are formatted differently in the two sources. Import strips raw-file extensions and squishes whitespace, so a residual mismatch means the IDs genuinely differ — compare them with setdiff() as above.

Q: “Not all analyses in the data have corresponding metadata.”

A: Some analyses have no row in the analysis metadata. Add the missing rows, or import with excl_unmatched_analyses = TRUE to drop the unannotated analyses.

Q: The metadata import aborts on validation warnings.

A: A validation report is printed, then “Please verify warnings in corresponding metadata. Use ignore_warnings = TRUE to ignore warnings.” Fix the flagged issues, or re-import with ignore_warnings = TRUE. A hard “Metadata validation failed — see the report above.” (duplicate IDs, missing mandatory values) cannot be bypassed and must be corrected.

Processing

Q: Normalised intensities come back NA.

A: normalize_by_istd() aborts by default when a feature has no internal standard assigned (“…no ISTD was defined…”), or when no feature carries an istd_feature_id at all (“No ISTDs defined in feature metadata.”). Find the unassigned features, then assign an istd_feature_id to each — or pass ignore_missing_annotation = TRUE to set them to NA and continue.

mexp@annot_features |>
  dplyr::select(feature_id, istd_feature_id) |>
  dplyr::filter(is.na(istd_feature_id))

Q: “Data needs to be ISTD normalized, please run ‘normalize_by_istd’ first.”

A: Quantitation and drift/batch correction on normalised or concentration variables run after normalisation. Run normalize_by_istd() before quantify_by_istd() or quantify_by_calibration().

Q: “Acquisition timestamps are not present in analysis results.”

A: The vendor export carries no acquisition time, so set_analysis_order() cannot order by "timestamp". Order by the result-file name or by a column in the metadata instead.

set_analysis_order(mexp, order_by = "resultfile")

Q: Drift or batch correction aborts with “One or more specified qc_types are not present in the dataset.”

A: The reference QC label has no matching rows — a misspelled QC type, no such QC samples in the run, or add_metadata() was not run so qc_type is still empty. Drift and batch correction fit on QC samples only, so a valid QC type must be present.

Q: Correction fails with “Normalized intensities not available” or “Concentration data are not available”.

A: You asked to correct a variable that has not been produced yet. Run the upstream step first (normalize_by_istd(), then a quantify_*()), or correct variable = "intensity".

Q: “Batch correction was not applied as there is only one batch.”

A: Between-batch correction needs more than one batch_id. With a single batch there is nothing to centre — skip it and run the rest of the pipeline normally.

Q: Drift correction makes the data worse.

A: Loess fitting needs enough evenly-spaced QC samples per batch; with too few, or when the QC trend is flat (noise, not drift), the fit can add variance. Inspect the QC trend before correcting, and skip drift correction for batches where it is flat.

plot_runscatter(
  mexp,
  variable = "norm_intensity",
  qc_types = c("BQC", "SPL"),
  include_feature_filter = "your_feature"
)

Quantitation and calibration

Q: quantify_by_istd() aborts about missing ISTD concentrations or amounts.

A: ISTD quantitation needs internal-standard concentrations plus per-analysis amounts. Import ISTD metadata (annot_istds) with concentrations in nmol/L or ng/mL, and make sure sample_amount and istd_volume are present in the analysis metadata. Missing amounts can be tolerated with ignore_missing_annotation = TRUE.

Q: “Calibration curve data missing…”

A: No calibrator samples and no concentrations are annotated. Flag the calibrator analyses with qc_type = "CAL" in the analysis metadata, and supply their known concentrations in the QC-concentration metadata (annot_qcconcentrations).

Q: “Calibration curve annotations for N features are missing.”

A: Those features have no concentrations in annot_qcconcentrations, which is keyed on sample_id and analyte_id. Add the missing entries, or skip those features with ignore_missing_annotation = TRUE.

Q: A calibration curve has R² < 0.9.

A: Inspect the fits, then try removing outlier calibration points, switching fit_model ("linear"/"quadratic") or fit_weighting ("none", "1/x", "1/x^2") — globally or per feature via the curve_fit_model / curve_fit_weighting metadata columns — and check for saturation at high concentrations.

get_calibration_metrics(mexp) |>
  dplyr::filter(r2 < 0.9)

QC and filtering

Q: What do the QC metrics mean?

Metric Meaning Typical threshold
CV (%) Coefficient of variation in QC samples < 20–30%
Bias (%) Systematic deviation from expected value < 20%
n_detected Number of QC samples with signal ≥ 50–67% of QCs

Q: All my features are filtered out.

A: filter_features_qc() requires you to state include_qualifier and include_istd explicitly. If every feature then fails the thresholds it raises no error — dataset_filtered simply comes back empty, and the next step aborts with “Data has not been QC-filtered.” Inspect the metrics and loosen the thresholds.

mexp <- filter_features_qc(
  mexp,
  include_qualifier = FALSE,
  include_istd = FALSE,
  max.cv.normintensity.bqc = 40,
  max.prop.missing.normintensity.spl = 0.5
)

Working with the object

Q: The pipeline does not run through, or the results look wrong.

A: A common cause is an inconsistent object name across chunks — assigning a step to one name but running the next step on another (a typo, or mixing mexp and myexp). Because every function takes and returns the MRMhubExperiment, a mismatched name quietly processes an earlier or wrong object instead of raising an error. Use a single name throughout, assign each step back to it, and confirm with mrmhub_status() that the steps you expect have run.

Q: How do I extract the final data as a data frame?

A: get_analyticaldata() returns the metadata-joined working table; the filtered table is a slot.

final <- get_analyticaldata(mexp, annotated = TRUE)
final_filtered <- mexp@dataset_filtered

Q: How do I check what processing has been applied?

A: The status flags record it.

mexp@is_istd_normalized
mexp@is_quantitated
mexp@var_drift_corrected
mexp@var_batch_corrected

Q: How do I go back to the original data?

A: The raw import is always preserved in dataset_orig. Restoring it resets the working table (which drops the processing columns added since import).

mexp@dataset <- mexp@dataset_orig

Workflow Builder

Q: Some processing steps are greyed out with a yellow badge.

A: Steps are gated by the metadata you imported; the badge names what is missing — No feature metadata, No ISTDs defined, No ISTD concentrations, No QC concentrations, No sample_id metadata, or Only one batch. Import the metadata that step needs (or, for the batch step, a run with more than one batch) to enable it.

Q: A banner says “N things to check before this will run.”

A: The builder pre-checks each selected step. Amber means warnings only — it still generates the workflow; red means errors to fix first. Open Show details to see each message, then import the missing metadata or select the upstream step it names.

Q: The banner says “Configure your columns.”

A: A generic long/wide CSV cannot be read until its columns are mapped. Click Configure columns… at the top of the sidebar, map the identifier and value columns, and Apply — the sidebar then shows columns configured.

Q: Which metadata source do I choose, and why did “Embedded in the data file” disappear?

A: There are four sources: embedded in the data file, an MSOrganiser workbook, separate metadata tables (one .xlsx), or none for now. The app probes your uploaded file and only offers Embedded when the data actually carries in-file metadata columns; when it does not, that option is removed — use one of the workbook routes.

Q: A red banner says “Import failed:”

A: The importer threw while reading your files. The most common causes are the wrong importer for the file’s format, or a non-MSOrganiser workbook (or an unsupported template version) fed to the MSOrganiser route. The message after “Import failed:” is the underlying error — see the import and metadata sections above.

Q: I clicked Browse… and nothing happened.

A: The native file and folder pickers only work when the app runs locally with a system dialog available. On a server or headless session there is no picker — type or paste the path into the text field instead.

Q: Will my large INTEGRATOR file upload?

A: Yes, up to 500 MB (the app raises Shiny’s default 5 MB cap). The data input accepts .csv, .tsv, and .txt; Excel files are only for the metadata routes.

Q: Did the app run my analysis?

A: No — the Workflow Builder validates your inputs and generates a Quarto workflow (mrmhub_workflow.qmd); it never runs the pipeline. Download or copy the .qmd, then render it yourself.

quarto render mrmhub_workflow.qmd

Q: How do I try it without my own data?

A: Try the example loads the bundled demo dataset (with embedded metadata) so you can reach a green Ready to render banner end to end.

FAQ

Q: Can I change the default text size, point size, or legend in plots?

A: mrmhub_set_plot_defaults() sets session-wide defaults for the shared appearance arguments of the plot_*() functions, so you can set them once at the top of a notebook instead of on every call.

mrmhub_set_plot_defaults(font_base_size = 8, point_size = 0.8)

It also accepts legend_position, legend_size, show_legend_title, and strip_bg_color; a value passed directly to a plotting function always wins. mrmhub_get_plot_defaults() shows the active settings and mrmhub_reset_plot_defaults() clears them. See Customising plots for the full reference.

Q: Can I use MRMhub with non-MRM data (PRM, SRM)?

A: Yes, provided the data can be formatted as a long CSV with feature IDs and peak areas. The processing is agnostic to acquisition mode.

Q: Can I process only one batch?

A: Yes. Skip batch correction; every other function works with single-batch data.

Q: Is there a size limit?

A: No hard limit, but very large datasets are slower in the drift and batch steps. If needed, process batches separately and merge.

Q: Where do I report bugs?

A: GitHub Issues.

Next steps