In this introduction to flow cytometry data in R, we will showcase how to parse a flowjo workspace and inspect and plot the data which is loaded.

Setup

We load some previously installed libraries, which offer specific functionality for flow cytometry data analysis. You can have a look at http://bioconductor.org/packages/release/BiocViews.html#___FlowCytometry to see more packages which might be of interest.

library(flowCore) # For general fcs file handling
library(flowDensity) # For flow data plotting
library(flowWorkspace) # For loading a flowjo workspace
library(FlowSOM) # For the FlowSOM algorithm
library(FlowSOMworkshop) # Additional functions for this workshop

We point to where the FlowJo workspace and the fcs file are saved on our computer. Try to autocomplete with "Tab" to make sure you can access the files and the path is correct.

wsp_file <- "../inst/extdata/manualGating.wsp"
fcs_file <- "../inst/extdata/21-10-15_Tube_011.fcs"

Exercise on finding files:

1) Change the value of fcs_file to Tube 28, using Tab to find the right filename

fcs_file <- "../inst/extdata/21-10-15_Tube_028.fcs"

Reading a FlowJo workspace

We parse how this file is processed in FlowJo. This returns a list with two elements: "flowFrame" contains all information from the fcs file itself, while "gates" includes all information regarding the gating of the file.

flowjo_res <- parse_flowjo(fcs_file, wsp_file, plot = TRUE)

We put the flowFrame and the gating information in variables with a short name, so we have to type less.

ff <- flowjo_res$flowFrame
gates <- flowjo_res$gates

Inspect the flowFrame

The measurements are saved in a flowFrame object, which internally contains a matrix. In this matrix, each row represents a cell and every column represents a marker.

nrow(ff)

Notice that the column names correspond to the detector names in your machine.

colnames(ff)

We can make use of some functions from the FlowSOM package to easily access the actual marker names.

get_markers(ff, "Comp-PE-A")

This also works on a vector instead of a single value:

get_markers(ff, colnames(ff))

We also have a function available to do the reverse:

get_channels(ff, "CD3")

To access the actual matrix, we need to look at the exprs element of the flowframe object. Note that these values have been compensated and transformed!

head(ff@exprs)

Additionally, all metadata describing the fcs file is also stored in the flowframe, in the description element.

head(ff@description, n = 20)

This is a list, so we can also access specific values of interest.

ff@description$`$DATE`
ff@description$`$CYT`

Exercises on the flowFrame object:

2) Show the number of columns in the flowFrame

ncol(ff)

3) Show the values measured for the 150th event

ff@exprs[150, ]

4) Show which channel was used to measure CD19

get_channels(ff, "CD19")

5) Show the CD19 values measured for the first 6 events

ff@exprs[1:6, get_channels(ff, "CD19")]

6) Show the median CD19 value

median(ff@exprs[, get_channels(ff, "CD19")])

7) Show at what time the FCS file began recording

ff@description$`$BTIM`

Inspect the manual gating

gates is a matrix in which each row represents a cell and each column represents a FlowJo gate. It contains TRUE or FALSE indicating whether the cell belongs to the gate (taking the full gating hierarchy into account).

head(gates)

As FALSE is internally coded as 0 and TRUE as 1, we can calculate the sum per column to identify how many cells are present in each gate. These numbers should be close to the numbers you see in the FlowJo workspace.

colSums(gates)

If one specific gate is of interest, we can select this one column from the matrix. Spelling should be exactly the same as in FlowJo!

data_live <- gating_subset(flowjo_res, "Live")

Exercise:

8) Show how many cells are selected in selection_live

nrow(data_live$flowFrame)

We can then use this new flowFrame to plot the data of interest

channels_to_plot <- get_channels(ff, c("CD64", "AmCyan-A"))

plotDens(data_live$flowFrame, 
         channels_to_plot)

Exercise: 10) Plot the B cells on CD3 vs CD19

data_B <- gating_subset(flowjo_res, "B cells")
channels_to_plot <- get_channels(ff, c("CD3", "CD19"))
plotDens(data_B$flowFrame, 
         channels_to_plot)

If we want to assign a color to each cell based on these FALSE/TRUE labels, we can change the internal 0/1 to 1/2 by adding one, and using the result to pick the colors

color_macrophages <- c("black", "red")[1 + data_live$gates[,"Macrophages"]]
head(color_macrophages, n = 10)
channels_to_plot <- get_channels(ff, c("CD64", "AmCyan-A"))

plotDens(data_live$flowFrame, 
         channels_to_plot,
         col = color_macrophages)

Exercise: 10) Show all live cells on CD3 vs CD19, with the B cells colored blue

color_B <- c("black", "blue")[1 + data_live$gates[,"B cells"]]

channels_to_plot <- get_channels(ff, c("CD3", "CD19"))

plotDens(data_live$flowFrame, 
         channels_to_plot,
         col = color_B)


saeyslab/FlowSOM_workshop documentation built on Sept. 3, 2021, 9:21 a.m.