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.
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"
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
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`
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)
Add the following code to your website.
For more information on customizing the embed code, read Embedding Snippets.