A fully transparent R workflow for conventional flow cytometry. Nothing here is a black box: every gate is an object you can print, plot on the data, and edit. Worked example: mouse bone marrow from the EµTCL1 model of chronic lymphocytic leukemia (CLL), compared against wild-type controls.
Built for wet-lab scientists who are new to coding but serious about reproducibility — you should be able to run it, understand it, modify it, and present it to collaborators.
Automated cytometry tools are fast, but they hide the decisions that matter and can label populations the data cannot actually support. This workflow takes the opposite stance: supervised, hierarchical gating with visible thresholds and hedged, marker-grounded annotation. You see — and own — every choice.
The output is your editable code.
See docs/tool_comparison.md for a fair, non-marketing comparison.
- Read FCS files and attach a sample sheet (metadata travels with the data).
- Handle compensation (embedded matrix, user matrix, or already-compensated).
- Logicle-transform fluorescence channels (scatter stays linear).
- Gate step by step: debris → singlets → live → CD45⁺ → CD19⁺ → CD5⁺.
- Read IgM/IgD as a maturation continuum on CD19⁺ cells (not force-gated).
- Extract counts, frequencies, and a plain-language annotation table.
- Produce gating plots, ridgeline "joyplots", stacked-density, and summary comparison figures.
- Export tidy tables and figures to
results/.
flowGateR/
├── README.md
├── LICENSE
├── CITATION.cff
├── .gitignore
├── flowGateR.Rproj
├── config/
│ ├── sample_sheet_example.csv # copy -> your sample sheet
│ └── marker_mapping_example.csv # copy -> your marker/channel map
├── data/
│ ├── raw_fcs/ # PUT YOUR .fcs FILES HERE (git-ignored)
│ └── metadata/ # any extra metadata (git-ignored)
├── R/
│ ├── 00_install_packages.R # one-time setup
│ ├── 01_helpers.R # reusable functions
│ ├── 02_import_and_qc.R # read + compensate + transform -> gs
│ ├── 03_gating_template.R # the gating funnel
│ ├── 04_annotation_and_summary.R # counts, frequencies, annotation
│ └── 05_visualization.R # gating plots, ridgelines, summaries
├── scripts/
│ └── run_analysis.R # master script — edit options, Source it
├── docs/
│ ├── overview.md # philosophy + package rationale
│ ├── gating_notes.md # biology behind every gate
│ ├── beginner_rstudio_guide.md # step-by-step for RStudio newcomers
│ └── tool_comparison.md # vs CellScope.ai and CytometryInR
└── results/
├── figures/ # written by the workflow (git-ignored)
└── tables/ # written by the workflow (git-ignored)
- Install R (≥ 4.2) and RStudio.
- Open
flowGateR.Rprojin RStudio (this sets the working directory). - Run
R/00_install_packages.Ronce. - Put your
.fcsfiles indata/raw_fcs/. - Copy the two
config/*_example.csvfiles to your own versions and edit them (sample sheet + marker→channel mapping). - Open
scripts/run_analysis.R, edit the### TODOoptions, and Source. - Open
results/figures/gate*.pngand confirm every gate by eye.
New to all this? Read docs/beginner_rstudio_guide.md first.
- No universal gating tree. Gate placement depends on panel design, fluorochromes, controls, compensation quality, acquisition quality, instrument settings, and the biological question. The template is a starting point.
- CD5 is not uniquely malignant. Normal B1a cells are CD19⁺CD5⁺, and T cells
are strongly CD5⁺.
CD19⁺CD5⁺here is a phenotype, not a diagnosis. - Bone marrow ≠ spleen ≠ blood. Marrow contains the full B-developmental series and abundant non-leukocytes; frequencies are not comparable across tissues.
- Dead-cell exclusion uses a viability dye and scatter/QC, not one shortcut.
- Controls matter. Use unstained, single-stain (compensation), and FMO controls; anchor positivity thresholds on FMO where possible.
Details in docs/gating_notes.md.
Core: flowCore (FCS I/O, compensation, transforms), flowWorkspace
(GatingSet), openCyto (data-driven 1D/2D gate helpers), ggcyto (plot
gates on data). Wrangling/plotting: dplyr, tidyr, purrr, tibble, readr, stringr,
forcats, ggplot2, ggridges, here. Rationale in docs/overview.md.
MIT licensed (see LICENSE). If this workflow helps your work, please cite it
using CITATION.cff.