suppressPackageStartupMessages(library(flowWorkspace))
suppressPackageStartupMessages(library(SummarizedExperiment))

Load cytoframe

dataDir <- system.file("extdata",package="flowWorkspaceData")
fcs_file <- list.files(dataDir, "Cyto", full.names = TRUE)[1]
cf <- load_cytoframe_from_fcs(fcs_file)
#lock cytoframe to prevent it from being accidentally modified
cf_lock(cf)

Wrap it into SummarizedExperiment

ce <- cytoexperiment(cf)
ce
## class: cytoexperiment 
## dim: 12 119531 
## metadata(0):
## assays(1): intensity
## rownames(12): FSC-A FSC-H ... G780-A Time
## rowData names(4): desc range minRange maxRange
## colnames: NULL
## colData names(0):
## backend is a cytoframe
ce@assays@data@listData$intensity@seed@obj
## cytoframe object 'CytoTrol_CytoTrol_1.fcs'
## with 119531 cells and 12 observables:
##        name         desc  range minRange maxRange
## $P1   FSC-A         <NA> 262143        0   262143
## $P2   FSC-H         <NA> 262143        0   262143
## $P3   FSC-W         <NA> 262143        0   262143
## $P4   SSC-A         <NA> 262143        0   262143
## $P5  B710-A  CD4 PcpCy55 262143     -111   262143
## $P6  R660-A     CD38 APC 262143     -111   262143
## $P7  R780-A    CD8 APCH7 262143     -111   262143
## $P8  V450-A     CD3 V450 262143     -111   262143
## $P9  V545-A  HLA-DR V500 262143     -111   262143
## $P10 G560-A      CCR7 PE 262143     -111   262143
## $P11 G780-A CD45RA PECy7 262143     -111   262143
## $P12   Time         <NA> 262143        0   262143
## 199 keywords are stored in the 'description' slot

assign cell id and populations to each cell through colData

colData(ce) <- DataFrame(row.names = paste0("cell#", seq_len(ncol(ce)))
                         , pop = c(rep(c("CD4", "CD8"), ncol(ce)/2), "CD4")
                          )
colData(ce)
## DataFrame with 119531 rows and 1 column
##                     pop
##             <character>
## cell#1              CD4
## cell#2              CD8
## cell#3              CD4
## cell#4              CD8
## cell#5              CD4
## ...                 ...
## cell#119527         CD4
## cell#119528         CD8
## cell#119529         CD4
## cell#119530         CD8
## cell#119531         CD4

All accessors of SE work out-of-box

dim(ce)
## [1]     12 119531
rowData(ce) 
## DataFrame with 12 rows and 4 columns
##                desc     range  minRange  maxRange
##         <character> <numeric> <numeric> <numeric>
## FSC-A            NA    262143         0    262143
## FSC-H            NA    262143         0    262143
## FSC-W            NA    262143         0    262143
## SSC-A            NA    262143         0    262143
## B710-A  CD4 PcpCy55    262143      -111    262143
## ...             ...       ...       ...       ...
## V450-A     CD3 V450    262143      -111    262143
## V545-A  HLA-DR V500    262143      -111    262143
## G560-A      CCR7 PE    262143      -111    262143
## G780-A CD45RA PECy7    262143      -111    262143
## Time             NA    262143         0    262143
assayNames(ce)
## [1] "intensity"
assay(ce)
## <12 x 119531> matrix of class DelayedMatrix and type "double":
##             cell#1      cell#2      cell#3 ... cell#119530 cell#119531
##  FSC-A   140733.05    26195.32    64294.02   .    49740.74    51276.66
##  FSC-H   133376.00    26207.00    51594.00   .    48850.00    46311.00
##  FSC-W    69150.98    65506.79    81667.89   .    66731.00    72563.05
##  SSC-A    91113.96    10115.28   174620.03   .    42917.28    73106.88
## B710-A    22311.24        5.04      371.28   .      128.52      123.48
##    ...           .           .           .   .           .           .
## V450-A    16232.65       43.70      335.35   .       -2.85      321.10
## V545-A     7644.65       77.90      971.85   .      228.95      693.50
## G560-A     4113.60      -91.20      273.60   .      443.52      820.80
## G780-A    12672.00       18.24      271.68   .     -106.56      370.56
##   Time        0.20        0.40        0.60   .    29538.80    29539.20

setter operation stays in R

assays(ce) <- endoapply(assays(ce), asinh)
assay(ce)
## <12 x 119531> matrix of class DelayedMatrix and type "double":
##             cell#1      cell#2      cell#3 ... cell#119530 cell#119531
##  FSC-A   12.547767   10.866483   11.764369   .   11.507727   11.538138
##  FSC-H   12.494075   10.866929   11.544308   .   11.489657   11.436282
##  FSC-W   11.837195   11.783056   12.003563   .   11.801572   11.885358
##  SSC-A   12.113014    9.914950   12.763515   .   11.360177   11.892825
## B710-A   10.705993    2.320253    6.610105   .    5.549247    5.509243
##    ...           .           .           .   .           .           .
## V450-A  10.3879271   4.4706262   6.5083242   .   -1.769914    6.464902
## V545-A   9.6349085   5.0486143   7.5723489   .    6.126656    7.234899
## G560-A   9.0152011  -5.2062321   6.3048177   .    6.787891    7.403427
## G780-A  10.1402973   3.5975147   6.2977754   .   -5.361877    6.608164
##   Time   0.1986901   0.3900353   0.5688249   .   10.986607   10.986621

verify it by printing the op stack

ce@assays@data@listData$intensity@seed
## 12x119531 double: Set dimnames
## └─ 12x119531 double: Unary iso op stack
##    └─ 12x119531 double: [seed] CytoArraySeed object

verify that the original cytoframe is unchanged

t(head(cf))
##             [,1]     [,2]      [,3]      [,4]       [,5]      [,6]
## FSC-A  140733.05 26195.32  64294.02 128393.87 127717.883 134347.02
## FSC-H  133376.00 26207.00  51594.00 103613.00 119616.000 125651.00
## FSC-W   69150.98 65506.79  81667.89  81210.08  69974.922  70071.60
## SSC-A   91113.96 10115.28 174620.03 150625.44  76954.914  70116.48
## B710-A  22311.24     5.04    371.28   1494.36   2545.200  23052.96
## R660-A  35576.07   447.93    851.62   5672.20   2272.830   1758.54
## R780-A  14302.16   682.56    -66.36   2979.09 124635.930   5281.15
## V450-A  16232.65    43.70    335.35   1492.45   8608.899   4849.75
## V545-A   7644.65    77.90    971.85  28790.70   4190.450   2859.50
## G560-A   4113.60   -91.20    273.60    771.84  14306.880   2249.28
## G780-A  12672.00    18.24    271.68    988.80  58977.598   1560.96
## Time        0.20     0.40      0.60      0.60      0.700      0.70

subset by coldata

ce1 <- ce[ , ce$pop == "CD4"]
ce1
## class: cytoexperiment 
## dim: 12 59766 
## metadata(0):
## assays(1): intensity
## rownames(12): FSC-A FSC-H ... G780-A Time
## rowData names(4): desc range minRange maxRange
## colnames(59766): cell#1 cell#3 ... cell#119529 cell#119531
## colData names(1): pop
assay(ce1)
## <12 x 59766> matrix of class DelayedMatrix and type "double":
##             cell#1      cell#3      cell#5 ... cell#119529 cell#119531
##  FSC-A   12.547767   11.764369   12.450726   .   12.307200   11.538138
##  FSC-H   12.494075   11.544308   12.385189   .   12.270952   11.436282
##  FSC-W   11.837195   12.003563   11.849039   .   11.819750   11.885358
##  SSC-A   12.113014   12.763515   11.944122   .   11.270143   11.892825
## B710-A   10.705993    6.610105    8.535112   .   10.331700    5.509243
##    ...           .           .           .   .           .           .
## V450-A  10.3879271   6.5083242   9.7536989   .    9.400738    6.464902
## V545-A   9.6349085   7.5723489   9.0337105   .    8.596928    7.234899
## G560-A   9.0152011   6.3048177  10.2616430   .    8.506318    7.403427
## G780-A  10.1402973   6.2977754  11.6780601   .   10.041146    6.608164
##   Time   0.1986901   0.5688249   0.6526666   .   10.986580   10.986621
ce1@assays@data@listData$intensity@seed
## 12x59766 double: Set dimnames
## └─ 12x59766 double: Unary iso op stack
##    └─ 12x59766 double: Subset
##       └─ 12x119531 double: [seed] CytoArraySeed object

cbind() combines more cells from another ce

ce1 <- ce
ce2 <- ce1[ , 1:3]
colnames(ce2)
## [1] "cell#1" "cell#2" "cell#3"
colnames(ce2) <- paste0("new cell#", seq_len(ncol(ce2)))
cmb1 <- cbind(ce1, ce2)
dim(cmb1)
## [1]     12 119534
colData(cmb1)
## DataFrame with 119534 rows and 1 column
##                     pop
##             <character>
## cell#1              CD4
## cell#2              CD8
## cell#3              CD4
## cell#4              CD8
## cell#5              CD4
## ...                 ...
## cell#119530         CD8
## cell#119531         CD4
## new cell#1          CD4
## new cell#2          CD8
## new cell#3          CD4
## backend (i.e. seed) remain separate
cmb1@assays@data@listData$intensity@seed
## 12x119534 double: Abind (along=2)
## ├─ 12x119531 double: Set dimnames
## │  └─ 12x119531 double: Unary iso op stack
## │     └─ 12x119531 double: [seed] CytoArraySeed object
## └─ 12x3 double: Set dimnames
##    └─ 12x3 double: Unary iso op stack
##       └─ 12x3 double: Subset
##          └─ 12x119531 double: [seed] CytoArraySeed object

rbind() combines more channels

ce1 <- ce
ce2 <- ce1[1:2, ]
rownames(ce2)
## [1] "FSC-A" "FSC-H"
rownames(ce2) <- letters[1:nrow(ce2)] 
cmb2 <- rbind(ce1, ce2)
dim(cmb2)
## [1]     14 119531
rowData(cmb2)
## DataFrame with 14 rows and 4 columns
##                desc     range  minRange  maxRange
##         <character> <numeric> <numeric> <numeric>
## FSC-A            NA    262143         0    262143
## FSC-H            NA    262143         0    262143
## FSC-W            NA    262143         0    262143
## SSC-A            NA    262143         0    262143
## B710-A  CD4 PcpCy55    262143      -111    262143
## ...             ...       ...       ...       ...
## G560-A      CCR7 PE    262143      -111    262143
## G780-A CD45RA PECy7    262143      -111    262143
## Time             NA    262143         0    262143
## a                NA    262143         0    262143
## b                NA    262143         0    262143