Date: 2026-04-28

# tidyFlowCore

Timothy Keyes1*

1Stanford University School of Medicine

*tkeyes@stanford.edu

#### 28 April 2026

#### Package

tidyFlowCore 1.6.0

# 1 Basics

## 1.1 Installing `tidyFlowCore`

`R` is an open-source statistical environment which can be easily modified to enhance its functionality via packages. tidyFlowCore is an `R` package available via Bioconductor, an open-source repository for R packages related to biostatistics and biocomputing.

`R` can be installed on any operating system from CRAN, after which you can install tidyFlowCore by using the following commands in your `R` session:

    if (!requireNamespace("BiocManager", quietly = TRUE)) {
          install.packages("BiocManager")
      }

    BiocManager::install("tidyFlowCore")

    ## Check that you have a valid Bioconductor installation
    BiocManager::valid()

## 1.2 Preliminaries

tidyFlowCore adopts the so-called “tidy” functional programming paradigm developed by Wickham et al. in the `tidyverse` ecosystem of R packages (Wickham, François, Henry, Müller, and Vaughan, 2026). For information about the `tidyverse` ecosytem broadly, feel free to reference the (free) R for Data Science book, the tidyverse website, or this paper describing the larger `tidyomics` project.

tidyFlowCore integrates the `flowCore` Bioconductor package’s data analysis capabilities with those of the `tidyverse`. If you’re relatively unfamiliar with the Bioconductor project, you might be interested in this blog post.

## 1.3 Asking for help

Learning to use `R` and `Bioconductor` can be challenging, so it’s important to know where to get help. The main place to ask questions about `tidyFlowCore` is the Bioconductor support site. Use the `tidyFlowCore` tag there and look at previous posts.

You can also ask questions on GitHub or Twitter. But remember, if you’re asking for help, follow the posting guidelines. Make sure to include a simple example that reproduces your issue (a “reprex”) and your session info to help developers understand and solve your problem.

## 1.4 Citing `tidyFlowCore`

If you use tidyFlowCore for your research, please use the following citation.

    citation("tidyFlowCore")
    #> Warning in person1(given = given[[i]], family = family[[i]], middle =
    #> middle[[i]], : It is recommended to use 'given' instead of 'middle'.
    #> To cite package 'tidyFlowCore' in publications use:
    #>
    #>   Keyes TJ (2026). _tidyFlowCore: Bringing flowCore to the tidyverse_.
    #>   doi:10.18129/B9.bioc.tidyFlowCore
    #>   <https://doi.org/10.18129/B9.bioc.tidyFlowCore>.
    #>   https://github.com/keyes-timothy/tidyflowCore/tidyFlowCore - R
    #>   package version 1.6.0,
    #>   <http://www.bioconductor.org/packages/tidyFlowCore>.
    #>
    #> A BibTeX entry for LaTeX users is
    #>
    #>   @Manual{,
    #>     title = {tidyFlowCore: Bringing flowCore to the tidyverse},
    #>     author = {Timothy J Keyes},
    #>     year = {2026},
    #>     url = {http://www.bioconductor.org/packages/tidyFlowCore},
    #>     note = {https://github.com/keyes-timothy/tidyflowCore/tidyFlowCore - R package version 1.6.0},
    #>     doi = {10.18129/B9.bioc.tidyFlowCore},
    #>   }

# 2 `tidyFlowCore` quick start

`tidyFlowCore` allows you to treat `flowCore` data structures like tidy `data.frame`s or `tibbles`. It does so by implementing dplyr, tidyr, and ggplot2 verbs that can be deployed directly on the `flowFrame` and `flowSet` S4 classes.

In this section, we give a brief example of how `tidyFlowCore` can enable a data analysis pipeline to use all the useful functions of the `flowCore` package and many of the functions of the `dplyr`, `tidyr`, and `ggplot2` packages.

## 2.1 Load required packages

    library(tidyFlowCore)
    library(flowCore)

## 2.2 Read data

For our example here, we download some publicly available mass cytometry (CyTOF) data downloadable through the (Weber, M, Soneson, and Charlotte, 2019) package. These data are made available as a `flowCore::flowSet` S4 object, `Bioconductor`’s standard data structure for cytometry data.

    # read data from the HDCytoData package
    bcr_flowset <- HDCytoData::Bodenmiller_BCR_XL_flowSet()
    #> see ?HDCytoData and browseVignettes('HDCytoData') for documentation
    #> loading from cache
    #> Warning in updateObjectFromSlots(object, ..., verbose = verbose): dropping
    #> slot(s) 'colnames' from object = 'flowSet'

To read more about this dataset, run the following command:

    ?HDCytoData::Bodenmiller_BCR_XL_flowSet

## 2.3 Data transformation

The `flowCore` package natively supports multiple types of data preprocessing and transformations for cytometry data through the use of its `tranform` class.

For example, if we want to apply the standard arcsinh transformation often used for CyTOF data to our current dataset, we could use the following code:

    asinh_transformation <- flowCore::arcsinhTransform(a = 0, b = 1/5, c = 0)
    transformation_list <-
      flowCore::transformList(
        colnames(bcr_flowset),
        asinh_transformation
      )

    transformed_bcr_flowset <- flowCore::transform(bcr_flowset, transformation_list)

Alternatively, we can also use the `tidyverse`’s functional programming paradigm to perform the same transformation. For this, we use the `mutate`-`across` framework via `tidyFlowCore`:

    transformed_bcr_flowset <-
      bcr_flowset |>
      dplyr::mutate(across(-ends_with("_id"), \(.x) asinh(.x / 5)))

## 2.4 Cell type counting

Suppose we’re interested in counting the number of cells that belong to each cell type (encoded in the `population_id` column of `bcr_flowset`) in our dataset. Using standard `flowCore` functions, we could perform this calculation in a few steps:

    # extract all expression matrices from our flowSet
    combined_matrix <- flowCore::fsApply(bcr_flowset, exprs)

    # take out the concatenated population_id column
    combined_population_id <- combined_matrix[, 'population_id']

    # perform the calculation
    table(combined_population_id)
    #> combined_population_id
    #>     1     2     3     4     5     6     7     8
    #>  3265  6651 62890 51150  1980 18436 24518  3901

`tidyFlowCore` allows us to perform the same operation simply using the `dplyr` package’s `count` function, with output provided in the convenient form of a `tibble`:

    bcr_flowset |>
      dplyr::count(population_id)
    #> # A tibble: 8 × 2
    #>   population_id     n
    #>           <dbl> <int>
    #> 1             1  3265
    #> 2             2  6651
    #> 3             3 62890
    #> 4             4 51150
    #> 5             5  1980
    #> 6             6 18436
    #> 7             7 24518
    #> 8             8  3901

`tidyFlowCore` also makes it easy to perform the counting after grouping by other variables in our metadata. For example, we can see that `bcr_flowset` contains data from multiple .FCS files, each of which is associated with a file name.

    flowCore::pData(object = bcr_flowset)
    #>                                                                  name
    #> PBMC8_30min_patient1_BCR-XL.fcs       PBMC8_30min_patient1_BCR-XL.fcs
    #> PBMC8_30min_patient1_Reference.fcs PBMC8_30min_patient1_Reference.fcs
    #> PBMC8_30min_patient2_BCR-XL.fcs       PBMC8_30min_patient2_BCR-XL.fcs
    #> PBMC8_30min_patient2_Reference.fcs PBMC8_30min_patient2_Reference.fcs
    #> PBMC8_30min_patient3_BCR-XL.fcs       PBMC8_30min_patient3_BCR-XL.fcs
    #> PBMC8_30min_patient3_Reference.fcs PBMC8_30min_patient3_Reference.fcs
    #> PBMC8_30min_patient4_BCR-XL.fcs       PBMC8_30min_patient4_BCR-XL.fcs
    #> PBMC8_30min_patient4_Reference.fcs PBMC8_30min_patient4_Reference.fcs
    #> PBMC8_30min_patient5_BCR-XL.fcs       PBMC8_30min_patient5_BCR-XL.fcs
    #> PBMC8_30min_patient5_Reference.fcs PBMC8_30min_patient5_Reference.fcs
    #> PBMC8_30min_patient6_BCR-XL.fcs       PBMC8_30min_patient6_BCR-XL.fcs
    #> PBMC8_30min_patient6_Reference.fcs PBMC8_30min_patient6_Reference.fcs
    #> PBMC8_30min_patient7_BCR-XL.fcs       PBMC8_30min_patient7_BCR-XL.fcs
    #> PBMC8_30min_patient7_Reference.fcs PBMC8_30min_patient7_Reference.fcs
    #> PBMC8_30min_patient8_BCR-XL.fcs       PBMC8_30min_patient8_BCR-XL.fcs
    #> PBMC8_30min_patient8_Reference.fcs PBMC8_30min_patient8_Reference.fcs

`tidyFlowCore` makes it easy to perform grouped tidy operations, like counting, using information in our `flowSet`’s metadata:

    bcr_flowset |>
      # use the .tidyFlowCore_identifier pronoun to access the name of
      # each experiment in the flowSet
      dplyr::count(.tidyFlowCore_identifier, population_id)
    #> # A tibble: 128 × 3
    #>    .tidyFlowCore_identifier           population_id     n
    #>    <chr>                                      <dbl> <int>
    #>  1 PBMC8_30min_patient1_BCR-XL.fcs                1    31
    #>  2 PBMC8_30min_patient1_BCR-XL.fcs                2   112
    #>  3 PBMC8_30min_patient1_BCR-XL.fcs                3   761
    #>  4 PBMC8_30min_patient1_BCR-XL.fcs                4  1307
    #>  5 PBMC8_30min_patient1_BCR-XL.fcs                5     5
    #>  6 PBMC8_30min_patient1_BCR-XL.fcs                6   127
    #>  7 PBMC8_30min_patient1_BCR-XL.fcs                7   444
    #>  8 PBMC8_30min_patient1_BCR-XL.fcs                8    51
    #>  9 PBMC8_30min_patient1_Reference.fcs             1    52
    #> 10 PBMC8_30min_patient1_Reference.fcs             2   132
    #> # ℹ 118 more rows

## 2.5 Nesting and unnesting

`flowFrame` and `flowSet` data objects have a clear relationship with one another in the `flowCore` application programming interface (API). Essentially, `flowSet`s are nested `flowFrame`s - or, in other words, `flowSet`s are made up of multiple `flowFrame`s!

`tidyFlowCore` provides a useful API for converting between `flowSet` and `flowFrame` data structures at various degrees of nesting using the `group`/`nest` and `ungroup`/`unnest` verbs. Note that in the `dplyr` and `tidyr` APIs, `group`/`nest` and `ungroup`/`unnest` are not synonyms (grouped `data.frames` are different from nested `data.frames`). However, because of how `flowFrame`s and `flowSet`s are structured, `tidyFlowCore`’s `group`/`nest` and `ungroup`/`unnest` functions have identical behavior, respectively.

    # unnesting a flowSet results in a flowFrame with an additional column,
    # 'tidyFlowCore_name` that identifies cells based on which experiment in the
    # original flowSet they come from
    bcr_flowset |>
      dplyr::ungroup()
    #> flowFrame object 'file7ed868a8b2a1'
    #> with 172791 cells and 40 observables:
    #>                    name               desc     range  minRange  maxRange
    #> $P1                Time               Time   2399633    0.0000   2399632
    #> $P2         Cell_length        Cell_length        69    0.0000        68
    #> $P3      CD3(110:114)Dd     CD3(110:114)Dd      9383  -61.6796      9382
    #> $P4       CD45(In115)Dd      CD45(In115)Dd      5035    0.0000      5034
    #> $P5        BC1(La139)Dd       BC1(La139)Dd     14306 -100.8797     14305
    #> ...                 ...                ...       ...       ...       ...
    #> $P36           group_id           group_id         3         0         2
    #> $P37         patient_id         patient_id         9         0         8
    #> $P38          sample_id          sample_id        17         0        16
    #> $P39      population_id      population_id         9         0         8
    #> $P40 .tidyFlowCore_name .tidyFlowCore_name        17         0        16
    #> 297 keywords are stored in the 'description' slot

    # flowSets can be unnested and re-nested for various analyses
    bcr_flowset |>
      dplyr::ungroup() |>
      # group_by cell type
      dplyr::group_by(population_id) |>
      # calculate the mean HLA-DR expression of each cell population
      dplyr::summarize(mean_hladr_expression = mean(`HLA-DR(Yb174)Dd`)) |>
      dplyr::select(population_id, mean_hladr_expression)
    #> # A tibble: 8 × 2
    #>   population_id mean_hladr_expression
    #>           <dbl>                 <dbl>
    #> 1             3                  3.67
    #> 2             7                  3.33
    #> 3             4                  4.33
    #> 4             2                 87.1
    #> 5             6                 88.2
    #> 6             8                  3.12
    #> 7             1                 51.4
    #> 8             5                 18.0

## 2.6 Plotting

`tidyFlowCore` also provides a direct interface between `ggplot2` and `flowFrame` or `flowSet` data objects. For example…

    # cell population names, from the HDCytoData documentation
    population_names <-
      c(
        "B-cells IgM-",
        "B-cells IgM+",
        "CD4 T-cells",
        "CD8 T-cells",
        "DC",
        "monocytes",
        "NK cells",
        "surface-"
      )

    # calculate mean CD20 expression across all cells
    mean_cd20_expression <-
      bcr_flowset |>
      dplyr::ungroup() |>
      dplyr::summarize(mean_expression = mean(asinh(`CD20(Sm147)Dd` / 5))) |>
      dplyr::pull(mean_expression)

    # calculate mean CD4 expression across all cells
    mean_cd4_expression <-
      bcr_flowset |>
      dplyr::ungroup() |>
      dplyr::summarize(mean_expression = mean(asinh(`CD4(Nd145)Dd` / 5))) |>
      dplyr::pull(mean_expression)

    bcr_flowset |>
      # preprocess all columns that represent protein measurements
      dplyr::mutate(dplyr::across(-ends_with("_id"), \(.x) asinh(.x / 5))) |>
      # plot a CD4 vs. CD45 scatterplot
      ggplot2::ggplot(ggplot2::aes(x = `CD20(Sm147)Dd`, y = `CD4(Nd145)Dd`)) +
      # add some reference lines
      ggplot2::geom_hline(
        yintercept = mean_cd4_expression,
        color = "red",
        linetype = "dashed"
      ) +
      ggplot2::geom_vline(
        xintercept = mean_cd20_expression,
        color = "red",
        linetype = "dashed"
      ) +
      ggplot2::geom_point(size = 0.1, alpha = 0.1) +
      # facet by cell population
      ggplot2::facet_wrap(
        facets = ggplot2::vars(population_id),
        labeller =
          ggplot2::as_labeller(
            \(population_id) population_names[as.numeric(population_id)]
          )
      ) +
      # axis labels
      ggplot2::labs(
        x = "CD20 expression (arcsinh)",
        y = "CD4 expression (arcsinh)"
      )

Using some standard functions from the `ggplot2` library, we can create a scatterplot of CD4 vs. CD20 expression in the different cell populations included in the `bcr_flowset` `flowSet`. We can see, unsurprisingly, that both B-cell populations are highest for CD20 expression, whereas CD4+ T-helper cells are highest for CD4 expression.

# 3 Reproducibility

The tidyFlowCore package (Keyes, 2026) was made possible thanks to the following:

- R (R Core Team, 2026)
- BiocStyle (Oleś, 2026)
- knitr (Xie, 2025)
- RefManageR (McLean, 2017)
- rmarkdown (Allaire, Xie, Dervieux, McPherson, Luraschi, Ushey, Atkins, Wickham, Cheng, Chang, and Iannone, 2026)
- sessioninfo (Wickham, Chang, Flight, Müller, and Hester, 2025)
- testthat (Wickham, 2011)
- tidyverse (Wickham, François, Henry et al., 2026)

This package was developed using biocthis.

Code for creating the vignette

    ## Create the vignette
    library("rmarkdown")
    system.time(render("tidyFlowCore.Rmd", "BiocStyle::html_document"))

    ## Extract the R code
    library("knitr")
    knit("tidyFlowCore.Rmd", tangle = TRUE)

Date the vignette was generated.

    #> [1] "2026-04-28 19:45:10 EDT"

Wallclock time spent generating the vignette.

    #> Time difference of 17.837 secs

`R` session information.

    #> ─ Session info ───────────────────────────────────────────────────────────────────────────────────────────────────────
    #>  setting  value
    #>  version  R version 4.6.0 Patched (2026-04-24 r89963)
    #>  os       macOS Tahoe 26.3.1
    #>  system   aarch64, darwin23
    #>  ui       X11
    #>  language (EN)
    #>  collate  C
    #>  ctype    en_US.UTF-8
    #>  tz       America/New_York
    #>  date     2026-04-28
    #>  pandoc   3.1.12.3 @ /opt/homebrew/bin/ (via rmarkdown)
    #>  quarto   1.7.32 @ /usr/local/bin/quarto
    #>
    #> ─ Packages ───────────────────────────────────────────────────────────────────────────────────────────────────────────
    #>  package              * version   date (UTC) lib source
    #>  abind                  1.4-8     2024-09-12 [2] CRAN (R 4.6.0)
    #>  AnnotationDbi          1.74.0    2026-04-28 [2] Bioconductor 3.23 (R 4.6.0)
    #>  AnnotationHub        * 4.2.0     2026-04-28 [2] Bioconductor 3.23 (R 4.6.0)
    #>  backports              1.5.1     2026-04-03 [2] CRAN (R 4.6.0)
    #>  bibtex                 0.5.2     2026-02-03 [2] CRAN (R 4.6.0)
    #>  Biobase              * 2.72.0    2026-04-28 [2] Bioconductor 3.23 (R 4.6.0)
    #>  BiocFileCache        * 3.2.0     2026-04-28 [2] Bioconductor 3.23 (R 4.6.0)
    #>  BiocGenerics         * 0.58.0    2026-04-28 [2] Bioconductor 3.23 (R 4.6.0)
    #>  BiocManager            1.30.27   2025-11-14 [2] CRAN (R 4.6.0)
    #>  BiocStyle            * 2.40.0    2026-04-28 [2] Bioconductor 3.23 (R 4.6.0)
    #>  BiocVersion            3.23.1    2026-04-28 [2] Bioconductor 3.23 (R 4.6.0)
    #>  Biostrings             2.80.0    2026-04-28 [2] Bioconductor 3.23 (R 4.6.0)
    #>  bit                    4.6.0     2025-03-06 [2] CRAN (R 4.6.0)
    #>  bit64                  4.8.0     2026-04-21 [2] CRAN (R 4.6.0)
    #>  blob                   1.3.0     2026-01-14 [2] CRAN (R 4.6.0)
    #>  bookdown               0.46      2025-12-05 [2] CRAN (R 4.6.0)
    #>  bslib                  0.10.0    2026-01-26 [2] CRAN (R 4.6.0)
    #>  cachem                 1.1.0     2024-05-16 [2] CRAN (R 4.6.0)
    #>  cli                    3.6.6     2026-04-09 [2] CRAN (R 4.6.0)
    #>  crayon                 1.5.3     2024-06-20 [2] CRAN (R 4.6.0)
    #>  curl                   7.1.0     2026-04-22 [2] CRAN (R 4.6.0)
    #>  cytolib                2.24.0    2026-04-28 [2] Bioconductor 3.23 (R 4.6.0)
    #>  DBI                    1.3.0     2026-02-25 [2] CRAN (R 4.6.0)
    #>  dbplyr               * 2.5.2     2026-02-13 [2] CRAN (R 4.6.0)
    #>  DelayedArray           0.38.0    2026-04-28 [2] Bioconductor 3.23 (R 4.6.0)
    #>  dichromat              2.0-0.1   2022-05-02 [2] CRAN (R 4.6.0)
    #>  digest                 0.6.39    2025-11-19 [2] CRAN (R 4.6.0)
    #>  dplyr                  1.2.1     2026-04-03 [2] CRAN (R 4.6.0)
    #>  evaluate               1.0.5     2025-08-27 [2] CRAN (R 4.6.0)
    #>  ExperimentHub        * 3.2.0     2026-04-28 [2] Bioconductor 3.23 (R 4.6.0)
    #>  farver                 2.1.2     2024-05-13 [2] CRAN (R 4.6.0)
    #>  fastmap                1.2.0     2024-05-15 [2] CRAN (R 4.6.0)
    #>  filelock               1.0.3     2023-12-11 [2] CRAN (R 4.6.0)
    #>  flowCore             * 2.24.0    2026-04-28 [2] Bioconductor 3.23 (R 4.6.0)
    #>  generics             * 0.1.4     2025-05-09 [2] CRAN (R 4.6.0)
    #>  GenomicRanges        * 1.64.0    2026-04-28 [2] Bioconductor 3.23 (R 4.6.0)
    #>  ggplot2                4.0.3     2026-04-22 [2] CRAN (R 4.6.0)
    #>  glue                   1.8.1     2026-04-17 [2] CRAN (R 4.6.0)
    #>  gtable                 0.3.6     2024-10-25 [2] CRAN (R 4.6.0)
    #>  HDCytoData           * 1.31.0    2025-11-04 [2] Bioconductor 3.23 (R 4.6.0)
    #>  htmltools              0.5.9     2025-12-04 [2] CRAN (R 4.6.0)
    #>  httr                   1.4.8     2026-02-13 [2] CRAN (R 4.6.0)
    #>  httr2                  1.2.2     2025-12-08 [2] CRAN (R 4.6.0)
    #>  IRanges              * 2.46.0    2026-04-28 [2] Bioconductor 3.23 (R 4.6.0)
    #>  jquerylib              0.1.4     2021-04-26 [2] CRAN (R 4.6.0)
    #>  jsonlite               2.0.0     2025-03-27 [2] CRAN (R 4.6.0)
    #>  KEGGREST               1.52.0    2026-04-28 [2] Bioconductor 3.23 (R 4.6.0)
    #>  knitr                  1.51      2025-12-20 [2] CRAN (R 4.6.0)
    #>  labeling               0.4.3     2023-08-29 [2] CRAN (R 4.6.0)
    #>  lattice                0.22-9    2026-02-09 [2] CRAN (R 4.6.0)
    #>  lifecycle              1.0.5     2026-01-08 [2] CRAN (R 4.6.0)
    #>  lubridate              1.9.5     2026-02-04 [2] CRAN (R 4.6.0)
    #>  magrittr               2.0.5     2026-04-04 [2] CRAN (R 4.6.0)
    #>  Matrix                 1.7-5     2026-03-21 [2] CRAN (R 4.6.0)
    #>  MatrixGenerics       * 1.24.0    2026-04-28 [2] Bioconductor 3.23 (R 4.6.0)
    #>  matrixStats          * 1.5.0     2025-01-07 [2] CRAN (R 4.6.0)
    #>  memoise                2.0.1     2021-11-26 [2] CRAN (R 4.6.0)
    #>  otel                   0.2.0     2025-08-29 [2] CRAN (R 4.6.0)
    #>  pillar                 1.11.1    2025-09-17 [2] CRAN (R 4.6.0)
    #>  pkgconfig              2.0.3     2019-09-22 [2] CRAN (R 4.6.0)
    #>  plyr                   1.8.9     2023-10-02 [2] CRAN (R 4.6.0)
    #>  png                    0.1-9     2026-03-15 [2] CRAN (R 4.6.0)
    #>  purrr                  1.2.2     2026-04-10 [2] CRAN (R 4.6.0)
    #>  R6                     2.6.1     2025-02-15 [2] CRAN (R 4.6.0)
    #>  rappdirs               0.3.4     2026-01-17 [2] CRAN (R 4.6.0)
    #>  RColorBrewer           1.1-3     2022-04-03 [2] CRAN (R 4.6.0)
    #>  Rcpp                   1.1.1-1.1 2026-04-24 [2] CRAN (R 4.6.0)
    #>  RefManageR           * 1.4.0     2022-09-30 [2] CRAN (R 4.6.0)
    #>  rlang                  1.2.0     2026-04-06 [2] CRAN (R 4.6.0)
    #>  rmarkdown              2.31      2026-03-26 [2] CRAN (R 4.6.0)
    #>  RProtoBufLib           2.24.0    2026-04-28 [2] Bioconductor 3.23 (R 4.6.0)
    #>  RSQLite                2.4.6     2026-02-06 [2] CRAN (R 4.6.0)
    #>  S4Arrays               1.12.0    2026-04-28 [2] Bioconductor 3.23 (R 4.6.0)
    #>  S4Vectors            * 0.50.0    2026-04-28 [2] Bioconductor 3.23 (R 4.6.0)
    #>  S7                     0.2.2     2026-04-22 [2] CRAN (R 4.6.0)
    #>  sass                   0.4.10    2025-04-11 [2] CRAN (R 4.6.0)
    #>  scales                 1.4.0     2025-04-24 [2] CRAN (R 4.6.0)
    #>  Seqinfo              * 1.2.0     2026-04-28 [2] Bioconductor 3.23 (R 4.6.0)
    #>  sessioninfo          * 1.2.3     2025-02-05 [2] CRAN (R 4.6.0)
    #>  SparseArray            1.12.0    2026-04-28 [2] Bioconductor 3.23 (R 4.6.0)
    #>  stringi                1.8.7     2025-03-27 [2] CRAN (R 4.6.0)
    #>  stringr                1.6.0     2025-11-04 [2] CRAN (R 4.6.0)
    #>  SummarizedExperiment * 1.42.0    2026-04-28 [2] Bioconductor 3.23 (R 4.6.0)
    #>  tibble                 3.3.1     2026-01-11 [2] CRAN (R 4.6.0)
    #>  tidyFlowCore         * 1.6.0     2026-04-28 [1] Bioconductor 3.23 (R 4.6.0)
    #>  tidyr                  1.3.2     2025-12-19 [2] CRAN (R 4.6.0)
    #>  tidyselect             1.2.1     2024-03-11 [2] CRAN (R 4.6.0)
    #>  timechange             0.4.0     2026-01-29 [2] CRAN (R 4.6.0)
    #>  utf8                   1.2.6     2025-06-08 [2] CRAN (R 4.6.0)
    #>  vctrs                  0.7.3     2026-04-11 [2] CRAN (R 4.6.0)
    #>  withr                  3.0.2     2024-10-28 [2] CRAN (R 4.6.0)
    #>  xfun                   0.57      2026-03-20 [2] CRAN (R 4.6.0)
    #>  xml2                   1.5.2     2026-01-17 [2] CRAN (R 4.6.0)
    #>  XVector                0.52.0    2026-04-28 [2] Bioconductor 3.23 (R 4.6.0)
    #>  yaml                   2.3.12    2025-12-10 [2] CRAN (R 4.6.0)
    #>
    #>  [1] /private/var/folders/r0/l4fjk6cj5xj0j3brt4bplpl40000gt/T/RtmpyZmFvq/Rinst7d51719d2366
    #>  [2] /Library/Frameworks/R.framework/Versions/4.6/Resources/library
    #>  * ── Packages attached to the search path.
    #>
    #> ──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────

# 4 Bibliography

This vignette was generated using BiocStyle (Oleś, 2026) with knitr (Xie, 2025) and rmarkdown (Allaire, Xie, Dervieux et al., 2026) running behind the scenes.

Citations made with RefManageR (McLean, 2017).

[1] J. Allaire, Y. Xie, C. Dervieux, et al. rmarkdown: Dynamic Documents for R. R package version 2.31. 2026. URL: https://github.com/rstudio/rmarkdown.

[2] T. J. Keyes. tidyFlowCore: Bringing flowCore to the tidyverse. https://github.com/keyes-timothy/tidyflowCore/tidyFlowCore - R package version 1.6.0. 2026. DOI: 10.18129/B9.bioc.tidyFlowCore. URL: http://www.bioconductor.org/packages/tidyFlowCore.

[3] M. W. McLean. “RefManageR: Import and Manage BibTeX and BibLaTeX References in R”. In: The Journal of Open Source Software (2017). DOI: 10.21105/joss.00338.

[4] A. Oleś. BiocStyle: Standard styles for vignettes and other Bioconductor documents. R package version 2.40.0. 2026. DOI: 10.18129/B9.bioc.BiocStyle. URL: https://bioconductor.org/packages/BiocStyle.

[5] R Core Team. R: A Language and Environment for Statistical Computing. R Foundation for Statistical Computing (ROR: <https://ror.org/05qewa988>;). Vienna, Austria, 2026. DOI: 10.32614/R.manuals. URL: https://www.R-project.org/.

[6] Weber, L. M, Soneson, et al. “HDCytoData: Collection of high-dimensional cytometry benchmark datasets in Bioconductor object formats”. In: F1000Research 8.v2 (2019), p. 1459.

[7] H. Wickham. “testthat: Get Started with Testing”. In: The R Journal 3 (2011), pp. 5–10. URL: https://journal.r-project.org/articles/RJ-2011-002/.

[8] H. Wickham, W. Chang, R. Flight, et al. sessioninfo: R Session Information. R package version 1.2.3. 2025. DOI: 10.32614/CRAN.package.sessioninfo. URL: https://CRAN.R-project.org/package=sessioninfo.

[9] H. Wickham, R. François, L. Henry, et al. dplyr: A Grammar of Data Manipulation. R package version 1.2.1. 2026. DOI: 10.32614/CRAN.package.dplyr. URL: https://CRAN.R-project.org/package=dplyr.

[10] Y. Xie. knitr: A General-Purpose Package for Dynamic Report Generation in R. R package version 1.51. 2025. URL: https://yihui.org/knitr/.