# Seurat-Local - Tutorials

**Pages:** 19

---

## Tutorial: Integrating stimulated vs. control PBMC datasets to learn cell-type specific responses

**URL:** http://127.0.0.1:9173/seurat/archive/v2.4/immune_alignment/index.html

**Contents:**
- Tutorial: Integrating stimulated vs. control PBMC datasets to learn cell-type specific responses
    - Compiled: March 22, 2018
  - Integration goals
  - Setup the Seurat objects
  - Perform a canonical correlation analysis (CCA)
  - Align the CCA subspaces
  - Perform an integrated analysis
  - Identify conserved cell type markers
  - Identify differential expressed genes across conditions

This tutorial walks through an alignment of two groups of PBMCs from Kang et al, 2017. In this experiment, PBMCs were split into a stimulated and control group and the stimulated group was treated with interferon beta. The response to interferon caused cell type specific gene expression changes that makes a joint analysis of all the data difficult, with cells clustering both by stimulation condition and by cell type. Here, we demonstrate our alignment strategy, as described in Butler et al, 2018, for performing integrated analyses to promote the identification of common cell types and enable comparative analyses. While this example demonstrates the integration of two datasets (conditions), these methods have been extended to multiple datasets. This workflow provides an example of integrating four pancreatic islet datasets (raw data here) generated using different technologies. To view the previously posted tutorial aligning two PBMC datasets generated using 10X and SeqWell, click here.

The following tutorial is designed to give you an overview of the kinds of comparative analyses on complex cell types that are possible using the Seurat integration procedure. Here, we address three main goals:

The gene expression matrices can be found here. We first read in the two count matrices and set up the Seurat objects.

Next, we select the genes we want to use in the alignment procedure. Here we take the union of the top 1,000 genes with the highest dispersion (var/mean) from both datasets.

We next run a canonical correlation analysis to identify common sources of variation between the two datasets. RunCCA will also combine the two objects into a single object and store the canonical correlation vectors (the vectors that project each dataset into the maximally correlated subspaces). We also store the original dataset identity as a column in object@meta.data

You can see, for example, that CC1 and CC2 separate myeloid from lymphoid cells in both datasets, but the values remain ‘shifted’ relative to each other. We now need to choose CCs for downstream analysis and then ‘align them’

The problem of choosing CCs for downstream analysis such as clustering is analogous to that of choosing PCs and we provide similar functions for exploring which CCs to include. When choosing PCs, often we look for a saturation in the relationship between the number of principle components and the percentage of the variance explained. Here, we provide MetageneBicorPlot, which examines a measure of correlation strength for each CC and find that this statistic generally saturates after a reasonable number of CCs. Here, we begin to see drop-off in signal after CC20, so we chose CC1-20 for analysis. You can try modifying this parameter (i.e. 1-15 or 1-25) without significant changes in the results.

As with PC selection, it is often also useful to examine heatmaps of the top genes driving each CC. Here, we visualize the first 9 CCs.

Now we align the CCA subspaces, which returns a new dimensional reduction called cca.aligned that can be used for downstream analyses such as clustering.

We can visualize the aligned CCA and perform an integrated analysis.

Now we can run a single integrated analysis on all cells!

To identify canonical cell type marker genes that are conserved across conditions, we provide the FindConservedMarkers function. This function performs differential gene expression testing for each dataset/group and combines the p-values using meta-analysis methods from the MetaDE R package. For example, we can calculated the genes that are conserved markers irrespective of stimulation condition in cluster 7 (NK cells).

We can explore these marker genes for each cluster and use them to annotate our clusters as specific cell types.

The SplitDotPlotGG function can be useful for viewing conserved cell type markers across conditions, showing both the expression level and the percentage of cells in a cluster expressing any given gene. Here we plot 2-3 strong marker genes for each of our 13 clusters.

Now that we’ve aligned the stimulated and control cells, we can start to do comparative analyses and look at the differences induced by stimulation. One way to look broadly at these changes is to plot the average expression of both the stimulated and control cells and look for genes that are visual outliers on a scatter plot. First we define some plotting functions to make labeling genes on the plots a bit easier.

Then, we take the average expression of both the stimulated and control naive T cells and CD14 monocyte populations and generate the scatter plots, highlighting genes that exhibit dramatic responses to interferon stimulation.

As you can see, many of the same genes are upregulated in both of these cell types and likely represent a conserved interferon response pathway.

Because we are confident in having identified common cell types across condition, we can ask what genes change in different conditions for cells of the same type. First, we create a column in the meta.data slot to hold both the cell type and stimulation information and switch the current ident to that column. Then we use FindMarkers to find the genes that are different between stimulated and control B cells. Notice that many of the top genes that show up here are the same as the ones we plotted earlier as core interferon response genes. Additionally, genes like CXCL10 which we saw were specific to monocyte and B cell interferon response show up as highly significant in this list as well.

Another useful way to visualize these changes in gene expression is with the FeatureHeatmap function. This will display FeaturePlots of the list of given genes, split by a grouping variable (stimulation condition here). Genes such as CD3D and GNLY are canonical cell type markers (for T cells and NK/CD8 T cells) that are virtually unaffected by interferon stimulation and display similar gene expression patterns in the control and stimulated group. IFI6 and ISG15, on the other hand, are core interferon response genes and are upregulated accordingly in all cell types. Finally, CD14 and CXCL10 are genes that show a cell type specific interferon response. CD14 expression decreases after stimulation in CD14 monocytes, which could lead to misclassification in a supervised analysis framework, underscoring the value of integrated analysis. CXCL10 shows a distinct upregulation in monocytes and B cells after interferon stimulation but not in other cell types.

**Examples:**

Example 1 (r):
```r
library(Seurat)
ctrl.data <- read.table("~/Downloads/immune_control_expression_matrix.txt.gz", 
    sep = "\t")
stim.data <- read.table("~/Downloads/immune_stimulated_expression_matrix.txt.gz", 
    sep = "\t")

# Set up control object
ctrl <- CreateSeuratObject(raw.data = ctrl.data, project = "IMMUNE_CTRL", min.cells = 5)
ctrl@meta.data$stim <- "CTRL"
ctrl <- FilterCells(ctrl, subset.names = "nGene", low.thresholds = 500, high.thresholds = Inf)
ctrl <- NormalizeData(ctrl)
ctrl <- ScaleData(ctrl, display.progress = F)
# Set up stimulated object
stim <- CreateSeuratObject(raw.data = stim.data, project = "IMMUNE_STIM", min.cells = 5)
stim@meta.data$stim <- "STIM"
stim <- FilterCells(stim, subset.names = "nGene", low.thresholds = 500, high.thresholds = Inf)
stim <- NormalizeData(stim)
stim <- ScaleData(stim, display.progress = F)

# Gene selection for input to CCA
ctrl <- FindVariableGenes(ctrl, do.plot = F)
stim <- FindVariableGenes(stim, do.plot = F)
g.1 <- head(rownames(ctrl@hvg.info), 1000)
g.2 <- head(rownames(stim@hvg.info), 1000)
genes.use <- unique(c(g.1, g.2))
genes.use <- intersect(genes.use, rownames(ctrl@scale.data))
genes.use <- intersect(genes.use, rownames(stim@scale.data))
```

Example 2 (r):
```r
library(Seurat)
ctrl.data <- read.table("~/Downloads/immune_control_expression_matrix.txt.gz", 
    sep = "\t")
stim.data <- read.table("~/Downloads/immune_stimulated_expression_matrix.txt.gz", 
    sep = "\t")

# Set up control object
ctrl <- CreateSeuratObject(raw.data = ctrl.data, project = "IMMUNE_CTRL", min.cells = 5)
ctrl@meta.data$stim <- "CTRL"
ctrl <- FilterCells(ctrl, subset.names = "nGene", low.thresholds = 500, high.thresholds = Inf)
ctrl <- NormalizeData(ctrl)
ctrl <- ScaleData(ctrl, display.progress = F)
# Set up stimulated object
stim <- CreateSeuratObject(raw.data = stim.data, project = "IMMUNE_STIM", min.cells = 5)
stim@meta.data$stim <- "STIM"
stim <- FilterCells(stim, subset.names = "nGene", low.thresholds = 500, high.thresholds = Inf)
stim <- NormalizeData(stim)
stim <- ScaleData(stim, display.progress = F)

# Gene selection for input to CCA
ctrl <- FindVariableGenes(ctrl, do.plot = F)
stim <- FindVariableGenes(stim, do.plot = F)
g.1 <- head(rownames(ctrl@hvg.info), 1000)
g.2 <- head(rownames(stim@hvg.info), 1000)
genes.use <- unique(c(g.1, g.2))
genes.use <- intersect(genes.use, rownames(ctrl@scale.data))
genes.use <- intersect(genes.use, rownames(stim@scale.data))
```

Example 3 (unknown):
```unknown
object@meta.data
```

Example 4 (r):
```r
immune.combined <- RunCCA(ctrl, stim, genes.use = genes.use, num.cc = 30)
```

Example 5 (r):
```r
immune.combined <- RunCCA(ctrl, stim, genes.use = genes.use, num.cc = 30)
```

Example 6 (r):
```r
# visualize results of CCA plot CC1 versus CC2 and look at a violin plot
p1 <- DimPlot(object = immune.combined, reduction.use = "cca", group.by = "stim", 
    pt.size = 0.5, do.return = TRUE)
p2 <- VlnPlot(object = immune.combined, features.plot = "CC1", group.by = "stim", 
    do.return = TRUE)
plot_grid(p1, p2)
```

Example 7 (r):
```r
# visualize results of CCA plot CC1 versus CC2 and look at a violin plot
p1 <- DimPlot(object = immune.combined, reduction.use = "cca", group.by = "stim", 
    pt.size = 0.5, do.return = TRUE)
p2 <- VlnPlot(object = immune.combined, features.plot = "CC1", group.by = "stim", 
    do.return = TRUE)
plot_grid(p1, p2)
```

Example 8 (r):
```r
PrintDim(object = immune.combined, reduction.type = "cca", dims.print = 1:2, 
    genes.print = 10)
```

Example 9 (r):
```r
PrintDim(object = immune.combined, reduction.type = "cca", dims.print = 1:2, 
    genes.print = 10)
```

Example 10 (unknown):
```unknown
## [1] "CC1"
##  [1] "RPS6"   "RPS18"  "RPL21"  "RPL13"  "RPL13A" "RPS14"  "RPL3"  
##  [8] "RPS3"   "RPS2"   "RPL32" 
## [1] ""
##  [1] "TYROBP"   "FCER1G"   "C15orf48" "SOD2"     "FTL"      "ANXA5"   
##  [7] "CST3"     "CD63"     "TIMP1"    "TYMP"    
## [1] ""
## [1] ""
## [1] "CC2"
##  [1] "NKG7"  "GNLY"  "GZMB"  "CCL5"  "PRF1"  "CST7"  "KLRD1" "GZMH" 
##  [9] "CLIC3" "GZMA" 
## [1] ""
##  [1] "RPS9"    "RPL8"    "HLA-DRA" "RPS23"   "RPL11"   "RPS8"    "RPL18A" 
##  [8] "RPL32"   "RPL12"   "RPL26"  
## [1] ""
## [1] ""
```

Example 11 (unknown):
```unknown
## [1] "CC1"
##  [1] "RPS6"   "RPS18"  "RPL21"  "RPL13"  "RPL13A" "RPS14"  "RPL3"  
##  [8] "RPS3"   "RPS2"   "RPL32" 
## [1] ""
##  [1] "TYROBP"   "FCER1G"   "C15orf48" "SOD2"     "FTL"      "ANXA5"   
##  [7] "CST3"     "CD63"     "TIMP1"    "TYMP"    
## [1] ""
## [1] ""
## [1] "CC2"
##  [1] "NKG7"  "GNLY"  "GZMB"  "CCL5"  "PRF1"  "CST7"  "KLRD1" "GZMH" 
##  [9] "CLIC3" "GZMA" 
## [1] ""
##  [1] "RPS9"    "RPL8"    "HLA-DRA" "RPS23"   "RPL11"   "RPS8"    "RPL18A" 
##  [8] "RPL32"   "RPL12"   "RPL26"  
## [1] ""
## [1] ""
```

Example 12 (unknown):
```unknown
MetageneBicorPlot
```

Example 13 (r):
```r
p3 <- MetageneBicorPlot(immune.combined, grouping.var = "stim", dims.eval = 1:30, 
    display.progress = FALSE)
```

Example 14 (r):
```r
p3 <- MetageneBicorPlot(immune.combined, grouping.var = "stim", dims.eval = 1:30, 
    display.progress = FALSE)
```

Example 15 (r):
```r
DimHeatmap(object = immune.combined, reduction.type = "cca", cells.use = 500, 
    dim.use = 1:9, do.balanced = TRUE)
```

Example 16 (r):
```r
DimHeatmap(object = immune.combined, reduction.type = "cca", cells.use = 500, 
    dim.use = 1:9, do.balanced = TRUE)
```

Example 17 (r):
```r
immune.combined <- AlignSubspace(immune.combined, reduction.type = "cca", grouping.var = "stim", 
    dims.align = 1:20)
```

Example 18 (r):
```r
immune.combined <- AlignSubspace(immune.combined, reduction.type = "cca", grouping.var = "stim", 
    dims.align = 1:20)
```

Example 19 (r):
```r
p1 <- VlnPlot(object = immune.combined, features.plot = "ACC1", group.by = "stim", 
    do.return = TRUE)
p2 <- VlnPlot(object = immune.combined, features.plot = "ACC2", group.by = "stim", 
    do.return = TRUE)
plot_grid(p1, p2)
```

Example 20 (r):
```r
p1 <- VlnPlot(object = immune.combined, features.plot = "ACC1", group.by = "stim", 
    do.return = TRUE)
p2 <- VlnPlot(object = immune.combined, features.plot = "ACC2", group.by = "stim", 
    do.return = TRUE)
plot_grid(p1, p2)
```

Example 21 (r):
```r
# t-SNE and Clustering
immune.combined <- RunTSNE(immune.combined, reduction.use = "cca.aligned", dims.use = 1:20, 
    do.fast = T)
immune.combined <- FindClusters(immune.combined, reduction.type = "cca.aligned", 
    resolution = 0.6, dims.use = 1:20)
```

Example 22 (r):
```r
# t-SNE and Clustering
immune.combined <- RunTSNE(immune.combined, reduction.use = "cca.aligned", dims.use = 1:20, 
    do.fast = T)
immune.combined <- FindClusters(immune.combined, reduction.type = "cca.aligned", 
    resolution = 0.6, dims.use = 1:20)
```

Example 23 (r):
```r
# Visualization
p1 <- TSNEPlot(immune.combined, do.return = T, pt.size = 0.5, group.by = "stim")
p2 <- TSNEPlot(immune.combined, do.label = T, do.return = T, pt.size = 0.5)
plot_grid(p1, p2)
```

Example 24 (r):
```r
# Visualization
p1 <- TSNEPlot(immune.combined, do.return = T, pt.size = 0.5, group.by = "stim")
p2 <- TSNEPlot(immune.combined, do.label = T, do.return = T, pt.size = 0.5)
plot_grid(p1, p2)
```

Example 25 (unknown):
```unknown
FindConservedMarkers
```

Example 26 (r):
```r
nk.markers <- FindConservedMarkers(immune.combined, ident.1 = 7, grouping.var = "stim", 
    print.bar = FALSE)
head(nk.markers)
```

Example 27 (r):
```r
nk.markers <- FindConservedMarkers(immune.combined, ident.1 = 7, grouping.var = "stim", 
    print.bar = FALSE)
head(nk.markers)
```

Example 28 (unknown):
```unknown
##        CTRL_p_val CTRL_avg_logFC CTRL_pct.1 CTRL_pct.2 CTRL_p_val_adj
## GNLY            0       4.133571      0.943      0.043              0
## NKG7            0       3.173254      0.956      0.082              0
## GZMB            0       2.895198      0.839      0.042              0
## CLIC3           0       2.395846      0.599      0.023              0
## FGFBP2          0       2.188426      0.489      0.020              0
## CTSW            0       2.062551      0.533      0.029              0
##           STIM_p_val STIM_avg_logFC STIM_pct.1 STIM_pct.2 STIM_p_val_adj
## GNLY    0.000000e+00       4.041565      0.950      0.058   0.000000e+00
## NKG7    0.000000e+00       2.887415      0.962      0.078   0.000000e+00
## GZMB    0.000000e+00       3.101812      0.899      0.058   0.000000e+00
## CLIC3   0.000000e+00       2.392933      0.601      0.030   0.000000e+00
## FGFBP2 7.353053e-180       1.531844      0.266      0.015  1.033325e-175
## CTSW    0.000000e+00       2.131213      0.574      0.035   0.000000e+00
##             max_pval minimump_p_val
## GNLY    0.000000e+00              0
## NKG7    0.000000e+00              0
## GZMB    0.000000e+00              0
## CLIC3   0.000000e+00              0
## FGFBP2 7.353053e-180              0
## CTSW    0.000000e+00              0
```

Example 29 (unknown):
```unknown
##        CTRL_p_val CTRL_avg_logFC CTRL_pct.1 CTRL_pct.2 CTRL_p_val_adj
## GNLY            0       4.133571      0.943      0.043              0
## NKG7            0       3.173254      0.956      0.082              0
## GZMB            0       2.895198      0.839      0.042              0
## CLIC3           0       2.395846      0.599      0.023              0
## FGFBP2          0       2.188426      0.489      0.020              0
## CTSW            0       2.062551      0.533      0.029              0
##           STIM_p_val STIM_avg_logFC STIM_pct.1 STIM_pct.2 STIM_p_val_adj
## GNLY    0.000000e+00       4.041565      0.950      0.058   0.000000e+00
## NKG7    0.000000e+00       2.887415      0.962      0.078   0.000000e+00
## GZMB    0.000000e+00       3.101812      0.899      0.058   0.000000e+00
## CLIC3   0.000000e+00       2.392933      0.601      0.030   0.000000e+00
## FGFBP2 7.353053e-180       1.531844      0.266      0.015  1.033325e-175
## CTSW    0.000000e+00       2.131213      0.574      0.035   0.000000e+00
##             max_pval minimump_p_val
## GNLY    0.000000e+00              0
## NKG7    0.000000e+00              0
## GZMB    0.000000e+00              0
## CLIC3   0.000000e+00              0
## FGFBP2 7.353053e-180              0
## CTSW    0.000000e+00              0
```

Example 30 (r):
```r
FeaturePlot(object = immune.combined, features.plot = c("CD3D", "SELL", "CREM", 
    "CD8A", "GNLY", "CD79A", "FCGR3A", "CCL2", "PPBP"), min.cutoff = "q9", cols.use = c("lightgrey", 
    "blue"), pt.size = 0.5)
```

Example 31 (r):
```r
FeaturePlot(object = immune.combined, features.plot = c("CD3D", "SELL", "CREM", 
    "CD8A", "GNLY", "CD79A", "FCGR3A", "CCL2", "PPBP"), min.cutoff = "q9", cols.use = c("lightgrey", 
    "blue"), pt.size = 0.5)
```

Example 32 (r):
```r
new.ident <- c("CD14 Mono", "CD4 Naive T", "CD4 Memory T", "B", "CD16 Mono", 
    "T activated", "CD8 T", "NK", "DC", "B activated", "Mk", "pDC", "Eryth")
for (i in 0:12) {
    immune.combined <- RenameIdent(object = immune.combined, old.ident.name = i, 
        new.ident.name = new.ident[i + 1])
}

TSNEPlot(immune.combined, do.label = T, pt.size = 0.5)
```

Example 33 (r):
```r
new.ident <- c("CD14 Mono", "CD4 Naive T", "CD4 Memory T", "B", "CD16 Mono", 
    "T activated", "CD8 T", "NK", "DC", "B activated", "Mk", "pDC", "Eryth")
for (i in 0:12) {
    immune.combined <- RenameIdent(object = immune.combined, old.ident.name = i, 
        new.ident.name = new.ident[i + 1])
}

TSNEPlot(immune.combined, do.label = T, pt.size = 0.5)
```

Example 34 (unknown):
```unknown
SplitDotPlotGG
```

Example 35 (r):
```r
immune.combined@ident <- factor(immune.combined@ident, levels = (c("pDC", "Eryth", 
    "Mk", "DC", "CD14 Mono", "CD16 Mono", "B activated", "B", "CD8 T", "NK", 
    "T activated", "CD4 Naive T", "CD4 Memory T")))
markers.to.plot <- c("CD3D", "CREM", "HSPH1", "SELL", "GIMAP5", "CACYBP", "GNLY", 
    "NKG7", "CCL5", "CD8A", "MS4A1", "CD79A", "MIR155HG", "NME1", "FCGR3A", 
    "VMO1", "CCL2", "S100A9", "HLA-DQA1", "GPR183", "PPBP", "GNG11", "HBA2", 
    "HBB", "TSPAN13", "IL3RA", "IGJ")
sdp <- SplitDotPlotGG(immune.combined, genes.plot = rev(markers.to.plot), cols.use = c("blue", 
    "red"), x.lab.rot = T, plot.legend = T, dot.scale = 8, do.return = T, grouping.var = "stim")
```

Example 36 (r):
```r
immune.combined@ident <- factor(immune.combined@ident, levels = (c("pDC", "Eryth", 
    "Mk", "DC", "CD14 Mono", "CD16 Mono", "B activated", "B", "CD8 T", "NK", 
    "T activated", "CD4 Naive T", "CD4 Memory T")))
markers.to.plot <- c("CD3D", "CREM", "HSPH1", "SELL", "GIMAP5", "CACYBP", "GNLY", 
    "NKG7", "CCL5", "CD8A", "MS4A1", "CD79A", "MIR155HG", "NME1", "FCGR3A", 
    "VMO1", "CCL2", "S100A9", "HLA-DQA1", "GPR183", "PPBP", "GNG11", "HBA2", 
    "HBB", "TSPAN13", "IL3RA", "IGJ")
sdp <- SplitDotPlotGG(immune.combined, genes.plot = rev(markers.to.plot), cols.use = c("blue", 
    "red"), x.lab.rot = T, plot.legend = T, dot.scale = 8, do.return = T, grouping.var = "stim")
```

Example 37 (r):
```r
LabelPoint <- function(plot, genes, exp.mat, adj.x.t = 0, adj.y.t = 0, adj.x.s = 0, 
    adj.y.s = 0, text.size = 2.5, segment.size = 0.1) {
    for (i in genes) {
        x1 <- exp.mat[i, 1]
        y1 <- exp.mat[i, 2]
        plot <- plot + annotate("text", x = x1 + adj.x.t, y = y1 + adj.y.t, 
            label = i, size = text.size)
        plot <- plot + annotate("segment", x = x1 + adj.x.s, xend = x1, y = y1 + 
            adj.y.s, yend = y1, size = segment.size)
    }
    return(plot)
}

LabelUR <- function(plot, genes, exp.mat, adj.u.t = 0.1, adj.r.t = 0.15, adj.u.s = 0.05, 
    adj.r.s = 0.05, ...) {
    return(LabelPoint(plot, genes, exp.mat, adj.y.t = adj.u.t, adj.x.t = adj.r.t, 
        adj.y.s = adj.u.s, adj.x.s = adj.r.s, ...))
}

LabelUL <- function(plot, genes, exp.mat, adj.u.t = 0.1, adj.l.t = 0.15, adj.u.s = 0.05, 
    adj.l.s = 0.05, ...) {
    return(LabelPoint(plot, genes, exp.mat, adj.y.t = adj.u.t, adj.x.t = -adj.l.t, 
        adj.y.s = adj.u.s, adj.x.s = -adj.l.s, ...))
}
```

Example 38 (r):
```r
LabelPoint <- function(plot, genes, exp.mat, adj.x.t = 0, adj.y.t = 0, adj.x.s = 0, 
    adj.y.s = 0, text.size = 2.5, segment.size = 0.1) {
    for (i in genes) {
        x1 <- exp.mat[i, 1]
        y1 <- exp.mat[i, 2]
        plot <- plot + annotate("text", x = x1 + adj.x.t, y = y1 + adj.y.t, 
            label = i, size = text.size)
        plot <- plot + annotate("segment", x = x1 + adj.x.s, xend = x1, y = y1 + 
            adj.y.s, yend = y1, size = segment.size)
    }
    return(plot)
}

LabelUR <- function(plot, genes, exp.mat, adj.u.t = 0.1, adj.r.t = 0.15, adj.u.s = 0.05, 
    adj.r.s = 0.05, ...) {
    return(LabelPoint(plot, genes, exp.mat, adj.y.t = adj.u.t, adj.x.t = adj.r.t, 
        adj.y.s = adj.u.s, adj.x.s = adj.r.s, ...))
}

LabelUL <- function(plot, genes, exp.mat, adj.u.t = 0.1, adj.l.t = 0.15, adj.u.s = 0.05, 
    adj.l.s = 0.05, ...) {
    return(LabelPoint(plot, genes, exp.mat, adj.y.t = adj.u.t, adj.x.t = -adj.l.t, 
        adj.y.s = adj.u.s, adj.x.s = -adj.l.s, ...))
}
```

Example 39 (r):
```r
t.cells <- SubsetData(immune.combined, ident.use = "CD4 Naive T", subset.raw = T)
t.cells <- SetAllIdent(t.cells, id = "stim")
avg.t.cells <- log1p(AverageExpression(t.cells, show.progress = FALSE))
avg.t.cells$gene <- rownames(avg.t.cells)

cd14.mono <- SubsetData(immune.combined, ident.use = "CD14 Mono", subset.raw = T)
cd14.mono <- SetAllIdent(cd14.mono, id = "stim")
avg.cd14.mono <- log1p(AverageExpression(cd14.mono, show.progress = FALSE))
avg.cd14.mono$gene <- rownames(avg.cd14.mono)

genes.to.label1 = c("ISG15", "LY6E", "IFI6", "ISG20", "MX1")
genes.to.label2 = c("IFIT2", "IFIT1")
genes.to.label3 = c("CXCL10", "CCL8")
p1 <- ggplot(avg.t.cells, aes(CTRL, STIM)) + geom_point() + ggtitle("CD4 Naive T Cells")
p1 <- LabelUR(p1, genes = c(genes.to.label1, genes.to.label2), avg.t.cells, 
    adj.u.t = 0.3, adj.u.s = 0.23)
p1 <- LabelUL(p1, genes = genes.to.label3, avg.t.cells, adj.u.t = 0.5, adj.u.s = 0.4, 
    adj.l.t = 0.25, adj.l.s = 0.25)
p2 <- ggplot(avg.cd14.mono, aes(CTRL, STIM)) + geom_point() + ggtitle("CD14 Monocytes")
p2 <- LabelUR(p2, genes = c(genes.to.label1, genes.to.label3), avg.cd14.mono, 
    adj.u.t = 0.3, adj.u.s = 0.23)
p2 <- LabelUL(p2, genes = genes.to.label2, avg.cd14.mono, adj.u.t = 0.5, adj.u.s = 0.4, 
    adj.l.t = 0.25, adj.l.s = 0.25)
plot_grid(p1, p2)
```

Example 40 (r):
```r
t.cells <- SubsetData(immune.combined, ident.use = "CD4 Naive T", subset.raw = T)
t.cells <- SetAllIdent(t.cells, id = "stim")
avg.t.cells <- log1p(AverageExpression(t.cells, show.progress = FALSE))
avg.t.cells$gene <- rownames(avg.t.cells)

cd14.mono <- SubsetData(immune.combined, ident.use = "CD14 Mono", subset.raw = T)
cd14.mono <- SetAllIdent(cd14.mono, id = "stim")
avg.cd14.mono <- log1p(AverageExpression(cd14.mono, show.progress = FALSE))
avg.cd14.mono$gene <- rownames(avg.cd14.mono)

genes.to.label1 = c("ISG15", "LY6E", "IFI6", "ISG20", "MX1")
genes.to.label2 = c("IFIT2", "IFIT1")
genes.to.label3 = c("CXCL10", "CCL8")
p1 <- ggplot(avg.t.cells, aes(CTRL, STIM)) + geom_point() + ggtitle("CD4 Naive T Cells")
p1 <- LabelUR(p1, genes = c(genes.to.label1, genes.to.label2), avg.t.cells, 
    adj.u.t = 0.3, adj.u.s = 0.23)
p1 <- LabelUL(p1, genes = genes.to.label3, avg.t.cells, adj.u.t = 0.5, adj.u.s = 0.4, 
    adj.l.t = 0.25, adj.l.s = 0.25)
p2 <- ggplot(avg.cd14.mono, aes(CTRL, STIM)) + geom_point() + ggtitle("CD14 Monocytes")
p2 <- LabelUR(p2, genes = c(genes.to.label1, genes.to.label3), avg.cd14.mono, 
    adj.u.t = 0.3, adj.u.s = 0.23)
p2 <- LabelUL(p2, genes = genes.to.label2, avg.cd14.mono, adj.u.t = 0.5, adj.u.s = 0.4, 
    adj.l.t = 0.25, adj.l.s = 0.25)
plot_grid(p1, p2)
```

Example 41 (unknown):
```unknown
FindMarkers
```

Example 42 (r):
```r
immune.combined@meta.data$celltype.stim <- paste0(immune.combined@ident, "_", 
    immune.combined@meta.data$stim)
immune.combined <- StashIdent(immune.combined, save.name = "celltype")
immune.combined <- SetAllIdent(immune.combined, id = "celltype.stim")
b.interferon.response <- FindMarkers(immune.combined, ident.1 = "B_STIM", ident.2 = "B_CTRL", 
    print.bar = FALSE)
head(b.interferon.response, 15)
```

Example 43 (r):
```r
immune.combined@meta.data$celltype.stim <- paste0(immune.combined@ident, "_", 
    immune.combined@meta.data$stim)
immune.combined <- StashIdent(immune.combined, save.name = "celltype")
immune.combined <- SetAllIdent(immune.combined, id = "celltype.stim")
b.interferon.response <- FindMarkers(immune.combined, ident.1 = "B_STIM", ident.2 = "B_CTRL", 
    print.bar = FALSE)
head(b.interferon.response, 15)
```

Example 44 (unknown):
```unknown
##                 p_val avg_logFC pct.1 pct.2     p_val_adj
## ISG15   1.507485e-166 3.2430775 0.998 0.235 2.118469e-162
## IFIT3   1.197089e-160 3.1181217 0.960 0.051 1.682269e-156
## IFI6    6.168886e-158 2.9295219 0.959 0.078 8.669135e-154
## ISG20   1.915755e-156 2.0416453 1.000 0.664 2.692210e-152
## IFIT1   5.639346e-146 2.8623180 0.905 0.030 7.924973e-142
## MX1     8.264417e-131 2.2634637 0.912 0.122 1.161398e-126
## LY6E    8.874270e-126 2.1880659 0.893 0.143 1.247101e-121
## IFIT2   3.854507e-116 2.5589116 0.793 0.037 5.416739e-112
## TNFSF10 1.053693e-113 2.6153254 0.769 0.021 1.480755e-109
## B2M     4.751051e-104 0.4375721 1.000 1.000 6.676652e-100
## IRF7    1.019016e-101 1.8399457 0.845 0.184  1.432023e-97
## PLSCR1   4.454230e-99 1.9390512 0.793 0.120  6.259529e-95
## CXCL10   9.071726e-94 3.7461707 0.663 0.007  1.274850e-89
## UBE2L6   1.293306e-86 1.4651257 0.855 0.304  1.817484e-82
## HERC5    4.014929e-82 1.9416847 0.625 0.023  5.642180e-78
```

Example 45 (unknown):
```unknown
##                 p_val avg_logFC pct.1 pct.2     p_val_adj
## ISG15   1.507485e-166 3.2430775 0.998 0.235 2.118469e-162
## IFIT3   1.197089e-160 3.1181217 0.960 0.051 1.682269e-156
## IFI6    6.168886e-158 2.9295219 0.959 0.078 8.669135e-154
## ISG20   1.915755e-156 2.0416453 1.000 0.664 2.692210e-152
## IFIT1   5.639346e-146 2.8623180 0.905 0.030 7.924973e-142
## MX1     8.264417e-131 2.2634637 0.912 0.122 1.161398e-126
## LY6E    8.874270e-126 2.1880659 0.893 0.143 1.247101e-121
## IFIT2   3.854507e-116 2.5589116 0.793 0.037 5.416739e-112
## TNFSF10 1.053693e-113 2.6153254 0.769 0.021 1.480755e-109
## B2M     4.751051e-104 0.4375721 1.000 1.000 6.676652e-100
## IRF7    1.019016e-101 1.8399457 0.845 0.184  1.432023e-97
## PLSCR1   4.454230e-99 1.9390512 0.793 0.120  6.259529e-95
## CXCL10   9.071726e-94 3.7461707 0.663 0.007  1.274850e-89
## UBE2L6   1.293306e-86 1.4651257 0.855 0.304  1.817484e-82
## HERC5    4.014929e-82 1.9416847 0.625 0.023  5.642180e-78
```

Example 46 (unknown):
```unknown
FeatureHeatmap
```

Example 47 (r):
```r
FeatureHeatmap(immune.combined, features.plot = c("CD3D", "GNLY", "IFI6", "ISG15", 
    "CD14", "CXCL10"), group.by = "stim", pt.size = 0.25, key.position = "top", 
    max.exp = 3)
```

Example 48 (r):
```r
FeatureHeatmap(immune.combined, features.plot = c("CD3D", "GNLY", "IFI6", "ISG15", 
    "CD14", "CXCL10"), group.by = "stim", pt.size = 0.25, key.position = "top", 
    max.exp = 3)
```

Example 49 (r):
```r
saveRDS(immune.combined, file = "~/Projects/datasets/immune_combined.rds")
```

Example 50 (r):
```r
saveRDS(immune.combined, file = "~/Projects/datasets/immune_combined.rds")
```

---

## Seurat - Guided Clustering Tutorial

**URL:** http://127.0.0.1:9173/seurat/archive/v3.1/pbmc3k_tutorial/index.html

**Contents:**
- Seurat - Guided Clustering Tutorial
    - Compiled: April 17, 2020
  - Setup the Seurat Object
  - Standard pre-processing workflow
    - QC and selecting cells for further analysis
  - Normalizing the data
  - Identification of highly variable features (feature selection)
  - Scaling the data
  - Perform linear dimensional reduction
  - Determine the ‘dimensionality’ of the dataset
  - Cluster the cells
  - Run non-linear dimensional reduction (UMAP/tSNE)
  - Finding differentially expressed features (cluster biomarkers)
  - Assigning cell type identity to clusters

For this tutorial, we will be analyzing the a dataset of Peripheral Blood Mononuclear Cells (PBMC) freely available from 10X Genomics. There are 2,700 single cells that were sequenced on the Illumina NextSeq 500. The raw data can be found here.

We start by reading in the data. The Read10X function reads in the output of the cellranger pipeline from 10X, returning a unique molecular identified (UMI) count matrix. The values in this matrix represent the number of molecules for each feature (i.e. gene; row) that are detected in each cell (column).

We next use the count matrix to create a Seurat object. The object serves as a container that contains both data (like the count matrix) and analysis (like PCA, or clustering results) for a single-cell dataset. For a technical discussion of the Seurat object structure, check out our GitHub Wiki. For example, the count matrix is stored in pbmc[["RNA"]]@counts.

What does data in a count matrix look like?

The . values in the matrix represent 0s (no molecules detected). Since most values in an scRNA-seq matrix are 0, Seurat uses a sparse-matrix representation whenever possible. This results in significant memory and speed savings for Drop-seq/inDrop/10x data.

The steps below encompass the standard pre-processing workflow for scRNA-seq data in Seurat. These represent the selection and filtration of cells based on QC metrics, data normalization and scaling, and the detection of highly variable features.

Seurat allows you to easily explore QC metrics and filter cells based on any user-defined criteria. A few QC metrics commonly used by the community include

Where are QC metrics stored in Seurat?

In the example below, we visualize QC metrics, and use these to filter cells.

After removing unwanted cells from the dataset, the next step is to normalize the data. By default, we employ a global-scaling normalization method “LogNormalize” that normalizes the feature expression measurements for each cell by the total expression, multiplies this by a scale factor (10,000 by default), and log-transforms the result. Normalized values are stored in pbmc[["RNA"]]@data.

For clarity, in this previous line of code (and in future commands), we provide the default values for certain parameters in the function call. However, this isn’t required and the same behavior can be achieved with:

We next calculate a subset of features that exhibit high cell-to-cell variation in the dataset (i.e, they are highly expressed in some cells, and lowly expressed in others). We and others have found that focusing on these genes in downstream analysis helps to highlight biological signal in single-cell datasets.

Our procedure in Seurat3 is described in detail here, and improves on previous versions by directly modeling the mean-variance relationship inherent in single-cell data, and is implemented in the FindVariableFeatures function. By default, we return 2,000 features per dataset. These will be used in downstream analysis, like PCA.

Next, we apply a linear transformation (‘scaling’) that is a standard pre-processing step prior to dimensional reduction techniques like PCA. The ScaleData function:

This step takes too long! Can I make it faster?

Scaling is an essential step in the Seurat workflow, but only on genes that will be used as input to PCA. Therefore, the default in ScaleData is only to perform scaling on the previously identified variable features (2,000 by default). To do this, omit the features argument in the previous function call, i.e.

Your PCA and clustering results will be unaffected. However, Seurat heatmaps (produced as shown below with DoHeatmap) require genes in the heatmap to be scaled, to make sure highly-expressed genes don’t dominate the heatmap. To make sure we don’t leave any genes out of the heatmap later, we are scaling all genes in this tutorial. How can I remove unwanted sources of variation, as in Seurat v2?

In Seurat v2 we also use the ScaleData function to remove unwanted sources of variation from a single-cell dataset. For example, we could ‘regress out’ heterogeneity associated with (for example) cell cycle stage, or mitochondrial contamination. These features are still supported in ScaleData in Seurat v3, i.e.:

However, particularly for advanced users who would like to use this functionality, we strongly recommend the use of our new normalization workflow, sctransform. The method is described in our recent preprint, with a separate vignette using Seurat v3 here. As with ScaleData, the function SCTransform also includes a vars.to.regress parameter.

Next we perform PCA on the scaled data. By default, only the previously determined variable features are used as input, but can be defined using features argument if you wish to choose a different subset.

Seurat provides several useful ways of visualizing both cells and features that define the PCA, including VizDimReduction, DimPlot, and DimHeatmap

In particular DimHeatmap allows for easy exploration of the primary sources of heterogeneity in a dataset, and can be useful when trying to decide which PCs to include for further downstream analyses. Both cells and features are ordered according to their PCA scores. Setting cells to a number plots the ‘extreme’ cells on both ends of the spectrum, which dramatically speeds plotting for large datasets. Though clearly a supervised analysis, we find this to be a valuable tool for exploring correlated feature sets.

To overcome the extensive technical noise in any single feature for scRNA-seq data, Seurat clusters cells based on their PCA scores, with each PC essentially representing a ‘metafeature’ that combines information across a correlated feature set. The top principal components therefore represent a robust compression of the dataset. However, how many componenets should we choose to include? 10? 20? 100?

In Macosko et al, we implemented a resampling test inspired by the JackStraw procedure. We randomly permute a subset of the data (1% by default) and rerun PCA, constructing a ‘null distribution’ of feature scores, and repeat this procedure. We identify ‘significant’ PCs as those who have a strong enrichment of low p-value features.

The JackStrawPlot function provides a visualization tool for comparing the distribution of p-values for each PC with a uniform distribution (dashed line). ‘Significant’ PCs will show a strong enrichment of features with low p-values (solid curve above the dashed line). In this case it appears that there is a sharp drop-off in significance after the first 10-12 PCs.

An alternative heuristic method generates an ‘Elbow plot’: a ranking of principle components based on the percentage of variance explained by each one (ElbowPlot function). In this example, we can observe an ‘elbow’ around PC9-10, suggesting that the majority of true signal is captured in the first 10 PCs.

Identifying the true dimensionality of a dataset – can be challenging/uncertain for the user. We therefore suggest these three approaches to consider. The first is more supervised, exploring PCs to determine relevant sources of heterogeneity, and could be used in conjunction with GSEA for example. The second implements a statistical test based on a random null model, but is time-consuming for large datasets, and may not return a clear PC cutoff. The third is a heuristic that is commonly used, and can be calculated instantly. In this example, all three approaches yielded similar results, but we might have been justified in choosing anything between PC 7-12 as a cutoff.

We chose 10 here, but encourage users to consider the following:

Seurat v3 applies a graph-based clustering approach, building upon initial strategies in (Macosko et al). Importantly, the distance metric which drives the clustering analysis (based on previously identified PCs) remains the same. However, our approach to partioning the cellular distance matrix into clusters has dramatically improved. Our approach was heavily inspired by recent manuscripts which applied graph-based clustering approaches to scRNA-seq data [SNN-Cliq, Xu and Su, Bioinformatics, 2015] and CyTOF data [PhenoGraph, Levine et al., Cell, 2015]. Briefly, these methods embed cells in a graph structure - for example a K-nearest neighbor (KNN) graph, with edges drawn between cells with similar feature expression patterns, and then attempt to partition this graph into highly interconnected ‘quasi-cliques’ or ‘communities’.

As in PhenoGraph, we first construct a KNN graph based on the euclidean distance in PCA space, and refine the edge weights between any two cells based on the shared overlap in their local neighborhoods (Jaccard similarity). This step is performed using the FindNeighbors function, and takes as input the previously defined dimensionality of the dataset (first 10 PCs).

To cluster the cells, we next apply modularity optimization techniques such as the Louvain algorithm (default) or SLM [SLM, Blondel et al., Journal of Statistical Mechanics], to iteratively group cells together, with the goal of optimizing the standard modularity function. The FindClusters function implements this procedure, and contains a resolution parameter that sets the ‘granularity’ of the downstream clustering, with increased values leading to a greater number of clusters. We find that setting this parameter between 0.4-1.2 typically returns good results for single-cell datasets of around 3K cells. Optimal resolution often increases for larger datasets. The clusters can be found using the Idents function.

Seurat offers several non-linear dimensional reduction techniques, such as tSNE and UMAP, to visualize and explore these datasets. The goal of these algorithms is to learn the underlying manifold of the data in order to place similar cells together in low-dimensional space. Cells within the graph-based clusters determined above should co-localize on these dimension reduction plots. As input to the UMAP and tSNE, we suggest using the same PCs as input to the clustering analysis.

You can save the object at this point so that it can easily be loaded back in without having to rerun the computationally intensive steps performed above, or easily shared with collaborators.

Seurat can help you find markers that define clusters via differential expression. By default, it identifes positive and negative markers of a single cluster (specified in ident.1), compared to all other cells. FindAllMarkers automates this process for all clusters, but you can also test groups of clusters vs. each other, or against all cells.

The min.pct argument requires a feature to be detected at a minimum percentage in either of the two groups of cells, and the thresh.test argument requires a feature to be differentially expressed (on average) by some amount between the two groups. You can set both of these to 0, but with a dramatic increase in time - since this will test a large number of features that are unlikely to be highly discriminatory. As another option to speed up these computations, max.cells.per.ident can be set. This will downsample each identity class to have no more cells than whatever this is set to. While there is generally going to be a loss in power, the speed increases can be significiant and the most highly differentially expressed features will likely still rise to the top.

Seurat has several tests for differential expression which can be set with the test.use parameter (see our DE vignette for details). For example, the ROC test returns the ‘classification power’ for any individual marker (ranging from 0 - random, to 1 - perfect).

We include several tools for visualizing marker expression. VlnPlot (shows expression probability distributions across clusters), and FeaturePlot (visualizes feature expression on a tSNE or PCA plot) are our most commonly used visualizations. We also suggest exploring RidgePlot, CellScatter, and DotPlot as additional methods to view your dataset.

DoHeatmap generates an expression heatmap for given cells and features. In this case, we are plotting the top 20 markers (or all markers if less than 20) for each cluster.

Fortunately in the case of this dataset, we can use canonical markers to easily match the unbiased clustering to known cell types:

**Examples:**

Example 1 (unknown):
```unknown
pbmc[["RNA"]]@counts
```

Example 2 (r):
```r
library(dplyr)
library(Seurat)
library(patchwork)

# Load the PBMC dataset
pbmc.data <- Read10X(data.dir = "../data/pbmc3k/filtered_gene_bc_matrices/hg19/")
# Initialize the Seurat object with the raw (non-normalized data).
pbmc <- CreateSeuratObject(counts = pbmc.data, project = "pbmc3k", min.cells = 3, min.features = 200)
pbmc
```

Example 3 (r):
```r
library(dplyr)
library(Seurat)
library(patchwork)

# Load the PBMC dataset
pbmc.data <- Read10X(data.dir = "../data/pbmc3k/filtered_gene_bc_matrices/hg19/")
# Initialize the Seurat object with the raw (non-normalized data).
pbmc <- CreateSeuratObject(counts = pbmc.data, project = "pbmc3k", min.cells = 3, min.features = 200)
pbmc
```

Example 4 (python):
```python
## An object of class Seurat 
## 13714 features across 2700 samples within 1 assay 
## Active assay: RNA (13714 features, 0 variable features)
```

Example 5 (python):
```python
## An object of class Seurat 
## 13714 features across 2700 samples within 1 assay 
## Active assay: RNA (13714 features, 0 variable features)
```

Example 6 (r):
```r
# Lets examine a few genes in the first thirty cells
pbmc.data[c("CD3D", "TCL1A", "MS4A1"), 1:30]
```

Example 7 (r):
```r
# Lets examine a few genes in the first thirty cells
pbmc.data[c("CD3D", "TCL1A", "MS4A1"), 1:30]
```

Example 8 (python):
```python
## 3 x 30 sparse Matrix of class "dgCMatrix"
##                                                                    
## CD3D  4 . 10 . . 1 2 3 1 . . 2 7 1 . . 1 3 . 2  3 . . . . . 3 4 1 5
## TCL1A . .  . . . . . . 1 . . . . . . . . . . .  . 1 . . . . . . . .
## MS4A1 . 6  . . . . . . 1 1 1 . . . . . . . . . 36 1 2 . . 2 . . . .
```

Example 9 (python):
```python
## 3 x 30 sparse Matrix of class "dgCMatrix"
##                                                                    
## CD3D  4 . 10 . . 1 2 3 1 . . 2 7 1 . . 1 3 . 2  3 . . . . . 3 4 1 5
## TCL1A . .  . . . . . . 1 . . . . . . . . . . .  . 1 . . . . . . . .
## MS4A1 . 6  . . . . . . 1 1 1 . . . . . . . . . 36 1 2 . . 2 . . . .
```

Example 10 (r):
```r
dense.size <- object.size(as.matrix(pbmc.data))
dense.size
```

Example 11 (r):
```r
dense.size <- object.size(as.matrix(pbmc.data))
dense.size
```

Example 12 (unknown):
```unknown
## 709591472 bytes
```

Example 13 (unknown):
```unknown
## 709591472 bytes
```

Example 14 (r):
```r
sparse.size <- object.size(pbmc.data)
sparse.size
```

Example 15 (r):
```r
sparse.size <- object.size(pbmc.data)
sparse.size
```

Example 16 (unknown):
```unknown
## 29905192 bytes
```

Example 17 (unknown):
```unknown
## 29905192 bytes
```

Example 18 (r):
```r
dense.size/sparse.size
```

Example 19 (r):
```r
dense.size/sparse.size
```

Example 20 (unknown):
```unknown
## 23.7 bytes
```

Example 21 (unknown):
```unknown
## 23.7 bytes
```

Example 22 (unknown):
```unknown
PercentageFeatureSet
```

Example 23 (r):
```r
# The [[ operator can add columns to object metadata. This is a great place to stash QC stats
pbmc[["percent.mt"]] <- PercentageFeatureSet(pbmc, pattern = "^MT-")
```

Example 24 (r):
```r
# The [[ operator can add columns to object metadata. This is a great place to stash QC stats
pbmc[["percent.mt"]] <- PercentageFeatureSet(pbmc, pattern = "^MT-")
```

Example 25 (unknown):
```unknown
CreateSeuratObject
```

Example 26 (r):
```r
# Show QC metrics for the first 5 cells
head(pbmc@meta.data, 5)
```

Example 27 (r):
```r
# Show QC metrics for the first 5 cells
head(pbmc@meta.data, 5)
```

Example 28 (r):
```r
# Visualize QC metrics as a violin plot
VlnPlot(pbmc, features = c("nFeature_RNA", "nCount_RNA", "percent.mt"), ncol = 3)
```

Example 29 (r):
```r
# Visualize QC metrics as a violin plot
VlnPlot(pbmc, features = c("nFeature_RNA", "nCount_RNA", "percent.mt"), ncol = 3)
```

Example 30 (r):
```r
# FeatureScatter is typically used to visualize feature-feature relationships, but can be used
# for anything calculated by the object, i.e. columns in object metadata, PC scores etc.

plot1 <- FeatureScatter(pbmc, feature1 = "nCount_RNA", feature2 = "percent.mt")
plot2 <- FeatureScatter(pbmc, feature1 = "nCount_RNA", feature2 = "nFeature_RNA")
plot1 + plot2
```

Example 31 (r):
```r
# FeatureScatter is typically used to visualize feature-feature relationships, but can be used
# for anything calculated by the object, i.e. columns in object metadata, PC scores etc.

plot1 <- FeatureScatter(pbmc, feature1 = "nCount_RNA", feature2 = "percent.mt")
plot2 <- FeatureScatter(pbmc, feature1 = "nCount_RNA", feature2 = "nFeature_RNA")
plot1 + plot2
```

Example 32 (r):
```r
pbmc <- subset(pbmc, subset = nFeature_RNA > 200 & nFeature_RNA < 2500 & percent.mt < 5)
```

Example 33 (r):
```r
pbmc <- subset(pbmc, subset = nFeature_RNA > 200 & nFeature_RNA < 2500 & percent.mt < 5)
```

Example 34 (unknown):
```unknown
pbmc[["RNA"]]@data
```

Example 35 (r):
```r
pbmc <- NormalizeData(pbmc, normalization.method = "LogNormalize", scale.factor = 10000)
```

Example 36 (r):
```r
pbmc <- NormalizeData(pbmc, normalization.method = "LogNormalize", scale.factor = 10000)
```

Example 37 (r):
```r
pbmc <- NormalizeData(pbmc)
```

Example 38 (r):
```r
pbmc <- NormalizeData(pbmc)
```

Example 39 (unknown):
```unknown
FindVariableFeatures
```

Example 40 (r):
```r
pbmc <- FindVariableFeatures(pbmc, selection.method = "vst", nfeatures = 2000)

# Identify the 10 most highly variable genes
top10 <- head(VariableFeatures(pbmc), 10)

# plot variable features with and without labels
plot1 <- VariableFeaturePlot(pbmc)
plot2 <- LabelPoints(plot = plot1, points = top10, repel = TRUE)
plot1 + plot2
```

Example 41 (r):
```r
pbmc <- FindVariableFeatures(pbmc, selection.method = "vst", nfeatures = 2000)

# Identify the 10 most highly variable genes
top10 <- head(VariableFeatures(pbmc), 10)

# plot variable features with and without labels
plot1 <- VariableFeaturePlot(pbmc)
plot2 <- LabelPoints(plot = plot1, points = top10, repel = TRUE)
plot1 + plot2
```

Example 42 (unknown):
```unknown
pbmc[["RNA"]]@scale.data
```

Example 43 (r):
```r
all.genes <- rownames(pbmc)
pbmc <- ScaleData(pbmc, features = all.genes)
```

Example 44 (r):
```r
all.genes <- rownames(pbmc)
pbmc <- ScaleData(pbmc, features = all.genes)
```

Example 45 (r):
```r
pbmc <- ScaleData(pbmc)
```

Example 46 (r):
```r
pbmc <- ScaleData(pbmc)
```

Example 47 (r):
```r
pbmc <- ScaleData(pbmc, vars.to.regress = "percent.mt")
```

Example 48 (r):
```r
pbmc <- ScaleData(pbmc, vars.to.regress = "percent.mt")
```

Example 49 (unknown):
```unknown
sctransform
```

Example 50 (unknown):
```unknown
SCTransform
```

Example 51 (unknown):
```unknown
vars.to.regress
```

Example 52 (r):
```r
pbmc <- RunPCA(pbmc, features = VariableFeatures(object = pbmc))
```

Example 53 (r):
```r
pbmc <- RunPCA(pbmc, features = VariableFeatures(object = pbmc))
```

Example 54 (unknown):
```unknown
VizDimReduction
```

Example 55 (r):
```r
# Examine and visualize PCA results a few different ways
print(pbmc[["pca"]], dims = 1:5, nfeatures = 5)
```

Example 56 (r):
```r
# Examine and visualize PCA results a few different ways
print(pbmc[["pca"]], dims = 1:5, nfeatures = 5)
```

Example 57 (unknown):
```unknown
## PC_ 1 
## Positive:  CST3, TYROBP, LST1, AIF1, FTL 
## Negative:  MALAT1, LTB, IL32, IL7R, CD2 
## PC_ 2 
## Positive:  CD79A, MS4A1, TCL1A, HLA-DQA1, HLA-DQB1 
## Negative:  NKG7, PRF1, CST7, GZMB, GZMA 
## PC_ 3 
## Positive:  HLA-DQA1, CD79A, CD79B, HLA-DQB1, HLA-DPB1 
## Negative:  PPBP, PF4, SDPR, SPARC, GNG11 
## PC_ 4 
## Positive:  HLA-DQA1, CD79B, CD79A, MS4A1, HLA-DQB1 
## Negative:  VIM, IL7R, S100A6, IL32, S100A8 
## PC_ 5 
## Positive:  GZMB, NKG7, S100A8, FGFBP2, GNLY 
## Negative:  LTB, IL7R, CKB, VIM, MS4A7
```

Example 58 (unknown):
```unknown
## PC_ 1 
## Positive:  CST3, TYROBP, LST1, AIF1, FTL 
## Negative:  MALAT1, LTB, IL32, IL7R, CD2 
## PC_ 2 
## Positive:  CD79A, MS4A1, TCL1A, HLA-DQA1, HLA-DQB1 
## Negative:  NKG7, PRF1, CST7, GZMB, GZMA 
## PC_ 3 
## Positive:  HLA-DQA1, CD79A, CD79B, HLA-DQB1, HLA-DPB1 
## Negative:  PPBP, PF4, SDPR, SPARC, GNG11 
## PC_ 4 
## Positive:  HLA-DQA1, CD79B, CD79A, MS4A1, HLA-DQB1 
## Negative:  VIM, IL7R, S100A6, IL32, S100A8 
## PC_ 5 
## Positive:  GZMB, NKG7, S100A8, FGFBP2, GNLY 
## Negative:  LTB, IL7R, CKB, VIM, MS4A7
```

Example 59 (r):
```r
VizDimLoadings(pbmc, dims = 1:2, reduction = "pca")
```

Example 60 (r):
```r
VizDimLoadings(pbmc, dims = 1:2, reduction = "pca")
```

Example 61 (r):
```r
DimPlot(pbmc, reduction = "pca")
```

Example 62 (r):
```r
DimPlot(pbmc, reduction = "pca")
```

Example 63 (r):
```r
DimHeatmap(pbmc, dims = 1, cells = 500, balanced = TRUE)
```

Example 64 (r):
```r
DimHeatmap(pbmc, dims = 1, cells = 500, balanced = TRUE)
```

Example 65 (r):
```r
DimHeatmap(pbmc, dims = 1:15, cells = 500, balanced = TRUE)
```

Example 66 (r):
```r
DimHeatmap(pbmc, dims = 1:15, cells = 500, balanced = TRUE)
```

Example 67 (r):
```r
# NOTE: This process can take a long time for big datasets, comment out for expediency. More
# approximate techniques such as those implemented in ElbowPlot() can be used to reduce
# computation time
pbmc <- JackStraw(pbmc, num.replicate = 100)
pbmc <- ScoreJackStraw(pbmc, dims = 1:20)
```

Example 68 (r):
```r
# NOTE: This process can take a long time for big datasets, comment out for expediency. More
# approximate techniques such as those implemented in ElbowPlot() can be used to reduce
# computation time
pbmc <- JackStraw(pbmc, num.replicate = 100)
pbmc <- ScoreJackStraw(pbmc, dims = 1:20)
```

Example 69 (unknown):
```unknown
JackStrawPlot
```

Example 70 (r):
```r
JackStrawPlot(pbmc, dims = 1:15)
```

Example 71 (r):
```r
JackStrawPlot(pbmc, dims = 1:15)
```

Example 72 (r):
```r
ElbowPlot(pbmc)
```

Example 73 (r):
```r
ElbowPlot(pbmc)
```

Example 74 (unknown):
```unknown
FindNeighbors
```

Example 75 (unknown):
```unknown
FindClusters
```

Example 76 (r):
```r
pbmc <- FindNeighbors(pbmc, dims = 1:10)
pbmc <- FindClusters(pbmc, resolution = 0.5)
```

Example 77 (r):
```r
pbmc <- FindNeighbors(pbmc, dims = 1:10)
pbmc <- FindClusters(pbmc, resolution = 0.5)
```

Example 78 (unknown):
```unknown
## Modularity Optimizer version 1.3.0 by Ludo Waltman and Nees Jan van Eck
## 
## Number of nodes: 2638
## Number of edges: 96033
## 
## Running Louvain algorithm...
## Maximum modularity in 10 random starts: 0.8720
## Number of communities: 9
## Elapsed time: 0 seconds
```

Example 79 (unknown):
```unknown
## Modularity Optimizer version 1.3.0 by Ludo Waltman and Nees Jan van Eck
## 
## Number of nodes: 2638
## Number of edges: 96033
## 
## Running Louvain algorithm...
## Maximum modularity in 10 random starts: 0.8720
## Number of communities: 9
## Elapsed time: 0 seconds
```

Example 80 (r):
```r
# Look at cluster IDs of the first 5 cells
head(Idents(pbmc), 5)
```

Example 81 (r):
```r
# Look at cluster IDs of the first 5 cells
head(Idents(pbmc), 5)
```

Example 82 (unknown):
```unknown
## AAACATACAACCAC-1 AAACATTGAGCTAC-1 AAACATTGATCAGC-1 AAACCGTGCTTCCG-1 
##                1                3                1                2 
## AAACCGTGTATGCG-1 
##                6 
## Levels: 0 1 2 3 4 5 6 7 8
```

Example 83 (unknown):
```unknown
## AAACATACAACCAC-1 AAACATTGAGCTAC-1 AAACATTGATCAGC-1 AAACCGTGCTTCCG-1 
##                1                3                1                2 
## AAACCGTGTATGCG-1 
##                6 
## Levels: 0 1 2 3 4 5 6 7 8
```

Example 84 (r):
```r
# If you haven't installed UMAP, you can do so via reticulate::py_install(packages =
# 'umap-learn')
pbmc <- RunUMAP(pbmc, dims = 1:10)
```

Example 85 (r):
```r
# If you haven't installed UMAP, you can do so via reticulate::py_install(packages =
# 'umap-learn')
pbmc <- RunUMAP(pbmc, dims = 1:10)
```

Example 86 (r):
```r
# note that you can set `label = TRUE` or use the LabelClusters function to help label
# individual clusters
DimPlot(pbmc, reduction = "umap")
```

Example 87 (r):
```r
# note that you can set `label = TRUE` or use the LabelClusters function to help label
# individual clusters
DimPlot(pbmc, reduction = "umap")
```

Example 88 (r):
```r
saveRDS(pbmc, file = "../output/pbmc_tutorial.rds")
```

Example 89 (r):
```r
saveRDS(pbmc, file = "../output/pbmc_tutorial.rds")
```

Example 90 (unknown):
```unknown
FindAllMarkers
```

Example 91 (unknown):
```unknown
max.cells.per.ident
```

Example 92 (r):
```r
# find all markers of cluster 1
cluster1.markers <- FindMarkers(pbmc, ident.1 = 1, min.pct = 0.25)
head(cluster1.markers, n = 5)
```

Example 93 (r):
```r
# find all markers of cluster 1
cluster1.markers <- FindMarkers(pbmc, ident.1 = 1, min.pct = 0.25)
head(cluster1.markers, n = 5)
```

Example 94 (r):
```r
# find all markers distinguishing cluster 5 from clusters 0 and 3
cluster5.markers <- FindMarkers(pbmc, ident.1 = 5, ident.2 = c(0, 3), min.pct = 0.25)
head(cluster5.markers, n = 5)
```

Example 95 (r):
```r
# find all markers distinguishing cluster 5 from clusters 0 and 3
cluster5.markers <- FindMarkers(pbmc, ident.1 = 5, ident.2 = c(0, 3), min.pct = 0.25)
head(cluster5.markers, n = 5)
```

Example 96 (r):
```r
# find markers for every cluster compared to all remaining cells, report only the positive ones
pbmc.markers <- FindAllMarkers(pbmc, only.pos = TRUE, min.pct = 0.25, logfc.threshold = 0.25)
pbmc.markers %>% group_by(cluster) %>% top_n(n = 2, wt = avg_logFC)
```

Example 97 (r):
```r
# find markers for every cluster compared to all remaining cells, report only the positive ones
pbmc.markers <- FindAllMarkers(pbmc, only.pos = TRUE, min.pct = 0.25, logfc.threshold = 0.25)
pbmc.markers %>% group_by(cluster) %>% top_n(n = 2, wt = avg_logFC)
```

Example 98 (r):
```r
cluster1.markers <- FindMarkers(pbmc, ident.1 = 0, logfc.threshold = 0.25, test.use = "roc", only.pos = TRUE)
```

Example 99 (r):
```r
cluster1.markers <- FindMarkers(pbmc, ident.1 = 0, logfc.threshold = 0.25, test.use = "roc", only.pos = TRUE)
```

Example 100 (unknown):
```unknown
FeaturePlot
```

Example 101 (unknown):
```unknown
CellScatter
```

Example 102 (r):
```r
VlnPlot(pbmc, features = c("MS4A1", "CD79A"))
```

Example 103 (r):
```r
VlnPlot(pbmc, features = c("MS4A1", "CD79A"))
```

Example 104 (r):
```r
# you can plot raw counts as well
VlnPlot(pbmc, features = c("NKG7", "PF4"), slot = "counts", log = TRUE)
```

Example 105 (r):
```r
# you can plot raw counts as well
VlnPlot(pbmc, features = c("NKG7", "PF4"), slot = "counts", log = TRUE)
```

Example 106 (r):
```r
FeaturePlot(pbmc, features = c("MS4A1", "GNLY", "CD3E", "CD14", "FCER1A", "FCGR3A", "LYZ", "PPBP", 
    "CD8A"))
```

Example 107 (r):
```r
FeaturePlot(pbmc, features = c("MS4A1", "GNLY", "CD3E", "CD14", "FCER1A", "FCGR3A", "LYZ", "PPBP", 
    "CD8A"))
```

Example 108 (r):
```r
top10 <- pbmc.markers %>% group_by(cluster) %>% top_n(n = 10, wt = avg_logFC)
DoHeatmap(pbmc, features = top10$gene) + NoLegend()
```

Example 109 (r):
```r
top10 <- pbmc.markers %>% group_by(cluster) %>% top_n(n = 10, wt = avg_logFC)
DoHeatmap(pbmc, features = top10$gene) + NoLegend()
```

Example 110 (r):
```r
new.cluster.ids <- c("Naive CD4 T", "Memory CD4 T", "CD14+ Mono", "B", "CD8 T", "FCGR3A+ Mono", 
    "NK", "DC", "Platelet")
names(new.cluster.ids) <- levels(pbmc)
pbmc <- RenameIdents(pbmc, new.cluster.ids)
DimPlot(pbmc, reduction = "umap", label = TRUE, pt.size = 0.5) + NoLegend()
```

Example 111 (r):
```r
new.cluster.ids <- c("Naive CD4 T", "Memory CD4 T", "CD14+ Mono", "B", "CD8 T", "FCGR3A+ Mono", 
    "NK", "DC", "Platelet")
names(new.cluster.ids) <- levels(pbmc)
pbmc <- RenameIdents(pbmc, new.cluster.ids)
DimPlot(pbmc, reduction = "umap", label = TRUE, pt.size = 0.5) + NoLegend()
```

Example 112 (r):
```r
saveRDS(pbmc, file = "../output/pbmc3k_final.rds")
```

Example 113 (r):
```r
saveRDS(pbmc, file = "../output/pbmc3k_final.rds")
```

---

## Seurat - Guided Clustering Tutorial

**URL:** http://127.0.0.1:9173/seurat/v3.0/pbmc3k_tutorial.html

**Contents:**
- Seurat - Guided Clustering Tutorial
    - Compiled: June 24, 2019
  - Setup the Seurat Object
  - Standard pre-processing workflow
    - QC and selecting cells for further analysis
  - Normalizing the data
  - Identification of highly variable features (feature selection)
  - Scaling the data
  - Perform linear dimensional reduction
  - Determine the ‘dimensionality’ of the dataset
  - Cluster the cells
  - Run non-linear dimensional reduction (UMAP/tSNE)
  - Finding differentially expressed features (cluster biomarkers)
  - Assigning cell type identity to clusters

For this tutorial, we will be analyzing the a dataset of Peripheral Blood Mononuclear Cells (PBMC) freely available from 10X Genomics. There are 2,700 single cells that were sequenced on the Illumina NextSeq 500. The raw data can be found here.

We start by reading in the data. The Read10X function reads in the output of the cellranger pipeline from 10X, returning a unique molecular identified (UMI) count matrix. The values in this matrix represent the number of molecules for each feature (i.e. gene; row) that are detected in each cell (column).

We next use the count matrix to create a Seurat object. The object serves as a container that contains both data (like the count matrix) and analysis (like PCA, or clustering results) for a single-cell dataset. For a technical discussion of the Seurat object structure, check out our GitHub Wiki. For example, the count matrix is stored in pbmc[["RNA"]]@counts.

What does data in a count matrix look like?

The . values in the matrix represent 0s (no molecules detected). Since most values in an scRNA-seq matrix are 0, Seurat uses a sparse-matrix representation whenever possible. This results in significant memory and speed savings for Drop-seq/inDrop/10x data.

The steps below encompass the standard pre-processing workflow for scRNA-seq data in Seurat. These represent the selection and filtration of cells based on QC metrics, data normalization and scaling, and the detection of highly variable features.

Seurat allows you to easily explore QC metrics and filter cells based on any user-defined criteria. A few QC metrics commonly used by the community include

Where are QC metrics stored in Seurat?

In the example below, we visualize QC metrics, and use these to filter cells.

After removing unwanted cells from the dataset, the next step is to normalize the data. By default, we employ a global-scaling normalization method “LogNormalize” that normalizes the feature expression measurements for each cell by the total expression, multiplies this by a scale factor (10,000 by default), and log-transforms the result. Normalized values are stored in pbmc[["RNA"]]@data.

For clarity, in this previous line of code (and in future commands), we provide the default values for certain parameters in the function call. However, this isn’t required and the same behavior can be achieved with:

We next calculate a subset of features that exhibit high cell-to-cell variation in the dataset (i.e, they are highly expressed in some cells, and lowly expressed in others). We and others have found that focusing on these genes in downstream analysis helps to highlight biological signal in single-cell datasets.

Our procedure in Seurat3 is described in detail here, and improves on previous versions by directly modeling the mean-variance relationship inherent in single-cell data, and is implemented in the FindVariableFeatures function. By default, we return 2,000 features per dataset. These will be used in downstream analysis, like PCA.

Next, we apply a linear transformation (‘scaling’) that is a standard pre-processing step prior to dimensional reduction techniques like PCA. The ScaleData function:

This step takes too long! Can I make it faster?

Scaling is an essential step in the Seurat workflow, but only on genes that will be used as input to PCA. Therefore, the default in ScaleData is only to perform scaling on the previously identified variable features (2,000 by default). To do this, omit the features argument in the previous function call, i.e.

How can I remove unwanted sources of variation, as in Seurat v2?

In Seurat v2 we also use the ScaleData function to remove unwanted sources of variation from a single-cell dataset. For example, we could ‘regress out’ heterogeneity associated with (for example) cell cycle stage, or mitochondrial contamination. These features are still supported in ScaleData in Seurat v3, i.e.:

Next we perform PCA on the scaled data. By default, only the previously determined variable features are used as input, but can be defined using features argument if you wish to choose a different subset.

Seurat provides several useful ways of visualizing both cells and features that define the PCA, including VizDimReduction, DimPlot, and DimHeatmap

In particular DimHeatmap allows for easy exploration of the primary sources of heterogeneity in a dataset, and can be useful when trying to decide which PCs to include for further downstream analyses. Both cells and features are ordered according to their PCA scores. Setting cells to a number plots the ‘extreme’ cells on both ends of the spectrum, which dramatically speeds plotting for large datasets. Though clearly a supervised analysis, we find this to be a valuable tool for exploring correlated feature sets.

To overcome the extensive technical noise in any single feature for scRNA-seq data, Seurat clusters cells based on their PCA scores, with each PC essentially representing a ‘metafeature’ that combines information across a correlated feature set. The top principal components therefore represent a robust compression of the dataset. However, how many componenets should we choose to include? 10? 20? 100?

In Macosko et al, we implemented a resampling test inspired by the JackStraw procedure. We randomly permute a subset of the data (1% by default) and rerun PCA, constructing a ‘null distribution’ of feature scores, and repeat this procedure. We identify ‘significant’ PCs as those who have a strong enrichment of low p-value features.

The JackStrawPlot function provides a visualization tool for comparing the distribution of p-values for each PC with a uniform distribution (dashed line). ‘Significant’ PCs will show a strong enrichment of features with low p-values (solid curve above the dashed line). In this case it appears that there is a sharp drop-off in significance after the first 10-12 PCs.

An alternative heuristic method generates an ‘Elbow plot’: a ranking of principle components based on the percentage of variance explained by each one (ElbowPlot function). In this example, we can observe an ‘elbow’ around PC9-10, suggesting that the majority of true signal is captured in the first 10 PCs.

Identifying the true dimensionality of a dataset – can be challenging/uncertain for the user. We therefore suggest these three approaches to consider. The first is more supervised, exploring PCs to determine relevant sources of heterogeneity, and could be used in conjunction with GSEA for example. The second implements a statistical test based on a random null model, but is time-consuming for large datasets, and may not return a clear PC cutoff. The third is a heuristic that is commonly used, and can be calculated instantly. In this example, all three approaches yielded similar results, but we might have been justified in choosing anything between PC 7-12 as a cutoff.

We chose 10 here, but encourage users to consider the following:

Seurat v3 applies a graph-based clustering approach, building upon initial strategies in (Macosko et al). Importantly, the distance metric which drives the clustering analysis (based on previously identified PCs) remains the same. However, our approach to partioning the cellular distance matrix into clusters has dramatically improved. Our approach was heavily inspired by recent manuscripts which applied graph-based clustering approaches to scRNA-seq data [SNN-Cliq, Xu and Su, Bioinformatics, 2015] and CyTOF data [PhenoGraph, Levine et al., Cell, 2015]. Briefly, these methods embed cells in a graph structure - for example a K-nearest neighbor (KNN) graph, with edges drawn between cells with similar feature expression patterns, and then attempt to partition this graph into highly interconnected ‘quasi-cliques’ or ‘communities’.

As in PhenoGraph, we first construct a KNN graph based on the euclidean distance in PCA space, and refine the edge weights between any two cells based on the shared overlap in their local neighborhoods (Jaccard similarity). This step is performed using the FindNeighbors function, and takes as input the previously defined dimensionality of the dataset (first 10 PCs).

To cluster the cells, we next apply modularity optimization techniques such as the Louvain algorithm (default) or SLM [SLM, Blondel et al., Journal of Statistical Mechanics], to iteratively group cells together, with the goal of optimizing the standard modularity function. The FindClusters function implements this procedure, and contains a resolution parameter that sets the ‘granularity’ of the downstream clustering, with increased values leading to a greater number of clusters. We find that setting this parameter between 0.4-1.2 typically returns good results for single-cell datasets of around 3K cells. Optimal resolution often increases for larger datasets. The clusters can be found using the Idents function.

Seurat offers several non-linear dimensional reduction techniques, such as tSNE and UMAP, to visualize and explore these datasets. The goal of these algorithms is to learn the underlying manifold of the data in order to place similar cells together in low-dimensional space. Cells within the graph-based clusters determined above should co-localize on these dimension reduction plots. As input to the UMAP and tSNE, we suggest using the same PCs as input to the clustering analysis.

You can save the object at this point so that it can easily be loaded back in without having to rerun the computationally intensive steps performed above, or easily shared with collaborators.

Seurat can help you find markers that define clusters via differential expression. By default, it identifes positive and negative markers of a single cluster (specified in ident.1), compared to all other cells. FindAllMarkers automates this process for all clusters, but you can also test groups of clusters vs. each other, or against all cells.

The min.pct argument requires a feature to be detected at a minimum percentage in either of the two groups of cells, and the thresh.test argument requires a feature to be differentially expressed (on average) by some amount between the two groups. You can set both of these to 0, but with a dramatic increase in time - since this will test a large number of features that are unlikely to be highly discriminatory. As another option to speed up these computations, max.cells.per.ident can be set. This will downsample each identity class to have no more cells than whatever this is set to. While there is generally going to be a loss in power, the speed increases can be significiant and the most highly differentially expressed features will likely still rise to the top.

Seurat has several tests for differential expression which can be set with the test.use parameter (see our DE vignette for details). For example, the ROC test returns the ‘classification power’ for any individual marker (ranging from 0 - random, to 1 - perfect).

We include several tools for visualizing marker expression. VlnPlot (shows expression probability distributions across clusters), and FeaturePlot (visualizes feature expression on a tSNE or PCA plot) are our most commonly used visualizations. We also suggest exploring RidgePlot, CellScatter, and DotPlot as additional methods to view your dataset.

DoHeatmap generates an expression heatmap for given cells and features. In this case, we are plotting the top 20 markers (or all markers if less than 20) for each cluster.

Fortunately in the case of this dataset, we can use canonical markers to easily match the unbiased clustering to known cell types:

**Examples:**

Example 1 (unknown):
```unknown
pbmc[["RNA"]]@counts
```

Example 2 (r):
```r
library(dplyr)
library(Seurat)

# Load the PBMC dataset
pbmc.data <- Read10X(data.dir = "../data/pbmc3k/filtered_gene_bc_matrices/hg19/")
# Initialize the Seurat object with the raw (non-normalized data).
pbmc <- CreateSeuratObject(counts = pbmc.data, project = "pbmc3k", min.cells = 3, min.features = 200)
pbmc
```

Example 3 (r):
```r
library(dplyr)
library(Seurat)

# Load the PBMC dataset
pbmc.data <- Read10X(data.dir = "../data/pbmc3k/filtered_gene_bc_matrices/hg19/")
# Initialize the Seurat object with the raw (non-normalized data).
pbmc <- CreateSeuratObject(counts = pbmc.data, project = "pbmc3k", min.cells = 3, min.features = 200)
pbmc
```

Example 4 (python):
```python
## An object of class Seurat 
## 13714 features across 2700 samples within 1 assay 
## Active assay: RNA (13714 features)
```

Example 5 (python):
```python
## An object of class Seurat 
## 13714 features across 2700 samples within 1 assay 
## Active assay: RNA (13714 features)
```

Example 6 (r):
```r
# Lets examine a few genes in the first thirty cells
pbmc.data[c("CD3D", "TCL1A", "MS4A1"), 1:30]
```

Example 7 (r):
```r
# Lets examine a few genes in the first thirty cells
pbmc.data[c("CD3D", "TCL1A", "MS4A1"), 1:30]
```

Example 8 (python):
```python
## 3 x 30 sparse Matrix of class "dgCMatrix"
##                                                                    
## CD3D  4 . 10 . . 1 2 3 1 . . 2 7 1 . . 1 3 . 2  3 . . . . . 3 4 1 5
## TCL1A . .  . . . . . . 1 . . . . . . . . . . .  . 1 . . . . . . . .
## MS4A1 . 6  . . . . . . 1 1 1 . . . . . . . . . 36 1 2 . . 2 . . . .
```

Example 9 (python):
```python
## 3 x 30 sparse Matrix of class "dgCMatrix"
##                                                                    
## CD3D  4 . 10 . . 1 2 3 1 . . 2 7 1 . . 1 3 . 2  3 . . . . . 3 4 1 5
## TCL1A . .  . . . . . . 1 . . . . . . . . . . .  . 1 . . . . . . . .
## MS4A1 . 6  . . . . . . 1 1 1 . . . . . . . . . 36 1 2 . . 2 . . . .
```

Example 10 (r):
```r
dense.size <- object.size(as.matrix(pbmc.data))
dense.size
```

Example 11 (r):
```r
dense.size <- object.size(as.matrix(pbmc.data))
dense.size
```

Example 12 (unknown):
```unknown
## 709548272 bytes
```

Example 13 (unknown):
```unknown
## 709548272 bytes
```

Example 14 (r):
```r
sparse.size <- object.size(pbmc.data)
sparse.size
```

Example 15 (r):
```r
sparse.size <- object.size(pbmc.data)
sparse.size
```

Example 16 (unknown):
```unknown
## 29861992 bytes
```

Example 17 (unknown):
```unknown
## 29861992 bytes
```

Example 18 (r):
```r
dense.size/sparse.size
```

Example 19 (r):
```r
dense.size/sparse.size
```

Example 20 (unknown):
```unknown
## 23.8 bytes
```

Example 21 (unknown):
```unknown
## 23.8 bytes
```

Example 22 (unknown):
```unknown
PercentageFeatureSet
```

Example 23 (r):
```r
# The [[ operator can add columns to object metadata. This is a great place to stash QC stats
pbmc[["percent.mt"]] <- PercentageFeatureSet(pbmc, pattern = "^MT-")
```

Example 24 (r):
```r
# The [[ operator can add columns to object metadata. This is a great place to stash QC stats
pbmc[["percent.mt"]] <- PercentageFeatureSet(pbmc, pattern = "^MT-")
```

Example 25 (unknown):
```unknown
CreateSeuratObject
```

Example 26 (r):
```r
# Show QC metrics for the first 5 cells
head(pbmc@meta.data, 5)
```

Example 27 (r):
```r
# Show QC metrics for the first 5 cells
head(pbmc@meta.data, 5)
```

Example 28 (r):
```r
# Visualize QC metrics as a violin plot
VlnPlot(pbmc, features = c("nFeature_RNA", "nCount_RNA", "percent.mt"), ncol = 3)
```

Example 29 (r):
```r
# Visualize QC metrics as a violin plot
VlnPlot(pbmc, features = c("nFeature_RNA", "nCount_RNA", "percent.mt"), ncol = 3)
```

Example 30 (r):
```r
# FeatureScatter is typically used to visualize feature-feature relationships, but can be used
# for anything calculated by the object, i.e. columns in object metadata, PC scores etc.

plot1 <- FeatureScatter(pbmc, feature1 = "nCount_RNA", feature2 = "percent.mt")
plot2 <- FeatureScatter(pbmc, feature1 = "nCount_RNA", feature2 = "nFeature_RNA")
CombinePlots(plots = list(plot1, plot2))
```

Example 31 (r):
```r
# FeatureScatter is typically used to visualize feature-feature relationships, but can be used
# for anything calculated by the object, i.e. columns in object metadata, PC scores etc.

plot1 <- FeatureScatter(pbmc, feature1 = "nCount_RNA", feature2 = "percent.mt")
plot2 <- FeatureScatter(pbmc, feature1 = "nCount_RNA", feature2 = "nFeature_RNA")
CombinePlots(plots = list(plot1, plot2))
```

Example 32 (r):
```r
pbmc <- subset(pbmc, subset = nFeature_RNA > 200 & nFeature_RNA < 2500 & percent.mt < 5)
```

Example 33 (r):
```r
pbmc <- subset(pbmc, subset = nFeature_RNA > 200 & nFeature_RNA < 2500 & percent.mt < 5)
```

Example 34 (unknown):
```unknown
pbmc[["RNA"]]@data
```

Example 35 (r):
```r
pbmc <- NormalizeData(pbmc, normalization.method = "LogNormalize", scale.factor = 10000)
```

Example 36 (r):
```r
pbmc <- NormalizeData(pbmc, normalization.method = "LogNormalize", scale.factor = 10000)
```

Example 37 (r):
```r
pbmc <- NormalizeData(pbmc)
```

Example 38 (r):
```r
pbmc <- NormalizeData(pbmc)
```

Example 39 (unknown):
```unknown
FindVariableFeatures
```

Example 40 (r):
```r
pbmc <- FindVariableFeatures(pbmc, selection.method = "vst", nfeatures = 2000)

# Identify the 10 most highly variable genes
top10 <- head(VariableFeatures(pbmc), 10)

# plot variable features with and without labels
plot1 <- VariableFeaturePlot(pbmc)
plot2 <- LabelPoints(plot = plot1, points = top10, repel = TRUE)
CombinePlots(plots = list(plot1, plot2))
```

Example 41 (r):
```r
pbmc <- FindVariableFeatures(pbmc, selection.method = "vst", nfeatures = 2000)

# Identify the 10 most highly variable genes
top10 <- head(VariableFeatures(pbmc), 10)

# plot variable features with and without labels
plot1 <- VariableFeaturePlot(pbmc)
plot2 <- LabelPoints(plot = plot1, points = top10, repel = TRUE)
CombinePlots(plots = list(plot1, plot2))
```

Example 42 (unknown):
```unknown
pbmc[["RNA"]]@scale.data
```

Example 43 (r):
```r
all.genes <- rownames(pbmc)
pbmc <- ScaleData(pbmc, features = all.genes)
```

Example 44 (r):
```r
all.genes <- rownames(pbmc)
pbmc <- ScaleData(pbmc, features = all.genes)
```

Example 45 (r):
```r
pbmc <- ScaleData(pbmc)
```

Example 46 (r):
```r
pbmc <- ScaleData(pbmc)
```

Example 47 (r):
```r
pbmc <- ScaleData(pbmc, vars.to.regress = "percent.mt")
```

Example 48 (r):
```r
pbmc <- ScaleData(pbmc, vars.to.regress = "percent.mt")
```

Example 49 (unknown):
```unknown
sctransform
```

Example 50 (unknown):
```unknown
SCTransform
```

Example 51 (unknown):
```unknown
vars.to.regress
```

Example 52 (r):
```r
pbmc <- RunPCA(pbmc, features = VariableFeatures(object = pbmc))
```

Example 53 (r):
```r
pbmc <- RunPCA(pbmc, features = VariableFeatures(object = pbmc))
```

Example 54 (unknown):
```unknown
VizDimReduction
```

Example 55 (r):
```r
# Examine and visualize PCA results a few different ways
print(pbmc[["pca"]], dims = 1:5, nfeatures = 5)
```

Example 56 (r):
```r
# Examine and visualize PCA results a few different ways
print(pbmc[["pca"]], dims = 1:5, nfeatures = 5)
```

Example 57 (unknown):
```unknown
## PC_ 1 
## Positive:  CST3, TYROBP, LST1, AIF1, FTL 
## Negative:  MALAT1, LTB, IL32, IL7R, CD2 
## PC_ 2 
## Positive:  CD79A, MS4A1, TCL1A, HLA-DQA1, HLA-DQB1 
## Negative:  NKG7, PRF1, CST7, GZMB, GZMA 
## PC_ 3 
## Positive:  HLA-DQA1, CD79A, CD79B, HLA-DQB1, HLA-DPB1 
## Negative:  PPBP, PF4, SDPR, SPARC, GNG11 
## PC_ 4 
## Positive:  HLA-DQA1, CD79B, CD79A, MS4A1, HLA-DQB1 
## Negative:  VIM, IL7R, S100A6, IL32, S100A8 
## PC_ 5 
## Positive:  GZMB, NKG7, S100A8, FGFBP2, GNLY 
## Negative:  LTB, IL7R, CKB, VIM, MS4A7
```

Example 58 (unknown):
```unknown
## PC_ 1 
## Positive:  CST3, TYROBP, LST1, AIF1, FTL 
## Negative:  MALAT1, LTB, IL32, IL7R, CD2 
## PC_ 2 
## Positive:  CD79A, MS4A1, TCL1A, HLA-DQA1, HLA-DQB1 
## Negative:  NKG7, PRF1, CST7, GZMB, GZMA 
## PC_ 3 
## Positive:  HLA-DQA1, CD79A, CD79B, HLA-DQB1, HLA-DPB1 
## Negative:  PPBP, PF4, SDPR, SPARC, GNG11 
## PC_ 4 
## Positive:  HLA-DQA1, CD79B, CD79A, MS4A1, HLA-DQB1 
## Negative:  VIM, IL7R, S100A6, IL32, S100A8 
## PC_ 5 
## Positive:  GZMB, NKG7, S100A8, FGFBP2, GNLY 
## Negative:  LTB, IL7R, CKB, VIM, MS4A7
```

Example 59 (r):
```r
VizDimLoadings(pbmc, dims = 1:2, reduction = "pca")
```

Example 60 (r):
```r
VizDimLoadings(pbmc, dims = 1:2, reduction = "pca")
```

Example 61 (r):
```r
DimPlot(pbmc, reduction = "pca")
```

Example 62 (r):
```r
DimPlot(pbmc, reduction = "pca")
```

Example 63 (r):
```r
DimHeatmap(pbmc, dims = 1, cells = 500, balanced = TRUE)
```

Example 64 (r):
```r
DimHeatmap(pbmc, dims = 1, cells = 500, balanced = TRUE)
```

Example 65 (r):
```r
DimHeatmap(pbmc, dims = 1:15, cells = 500, balanced = TRUE)
```

Example 66 (r):
```r
DimHeatmap(pbmc, dims = 1:15, cells = 500, balanced = TRUE)
```

Example 67 (r):
```r
# NOTE: This process can take a long time for big datasets, comment out for expediency. More
# approximate techniques such as those implemented in ElbowPlot() can be used to reduce
# computation time
pbmc <- JackStraw(pbmc, num.replicate = 100)
pbmc <- ScoreJackStraw(pbmc, dims = 1:20)
```

Example 68 (r):
```r
# NOTE: This process can take a long time for big datasets, comment out for expediency. More
# approximate techniques such as those implemented in ElbowPlot() can be used to reduce
# computation time
pbmc <- JackStraw(pbmc, num.replicate = 100)
pbmc <- ScoreJackStraw(pbmc, dims = 1:20)
```

Example 69 (unknown):
```unknown
JackStrawPlot
```

Example 70 (r):
```r
JackStrawPlot(pbmc, dims = 1:15)
```

Example 71 (r):
```r
JackStrawPlot(pbmc, dims = 1:15)
```

Example 72 (r):
```r
ElbowPlot(pbmc)
```

Example 73 (r):
```r
ElbowPlot(pbmc)
```

Example 74 (unknown):
```unknown
FindNeighbors
```

Example 75 (unknown):
```unknown
FindClusters
```

Example 76 (r):
```r
pbmc <- FindNeighbors(pbmc, dims = 1:10)
pbmc <- FindClusters(pbmc, resolution = 0.5)
```

Example 77 (r):
```r
pbmc <- FindNeighbors(pbmc, dims = 1:10)
pbmc <- FindClusters(pbmc, resolution = 0.5)
```

Example 78 (unknown):
```unknown
## Modularity Optimizer version 1.3.0 by Ludo Waltman and Nees Jan van Eck
## 
## Number of nodes: 2638
## Number of edges: 96033
## 
## Running Louvain algorithm...
## Maximum modularity in 10 random starts: 0.8720
## Number of communities: 9
## Elapsed time: 0 seconds
```

Example 79 (unknown):
```unknown
## Modularity Optimizer version 1.3.0 by Ludo Waltman and Nees Jan van Eck
## 
## Number of nodes: 2638
## Number of edges: 96033
## 
## Running Louvain algorithm...
## Maximum modularity in 10 random starts: 0.8720
## Number of communities: 9
## Elapsed time: 0 seconds
```

Example 80 (r):
```r
# Look at cluster IDs of the first 5 cells
head(Idents(pbmc), 5)
```

Example 81 (r):
```r
# Look at cluster IDs of the first 5 cells
head(Idents(pbmc), 5)
```

Example 82 (unknown):
```unknown
## AAACATACAACCAC AAACATTGAGCTAC AAACATTGATCAGC AAACCGTGCTTCCG AAACCGTGTATGCG 
##              1              3              1              2              6 
## Levels: 0 1 2 3 4 5 6 7 8
```

Example 83 (unknown):
```unknown
## AAACATACAACCAC AAACATTGAGCTAC AAACATTGATCAGC AAACCGTGCTTCCG AAACCGTGTATGCG 
##              1              3              1              2              6 
## Levels: 0 1 2 3 4 5 6 7 8
```

Example 84 (r):
```r
# If you haven't installed UMAP, you can do so via reticulate::py_install(packages =
# 'umap-learn')
pbmc <- RunUMAP(pbmc, dims = 1:10)
```

Example 85 (r):
```r
# If you haven't installed UMAP, you can do so via reticulate::py_install(packages =
# 'umap-learn')
pbmc <- RunUMAP(pbmc, dims = 1:10)
```

Example 86 (r):
```r
# note that you can set `label = TRUE` or use the LabelClusters function to help label
# individual clusters
DimPlot(pbmc, reduction = "umap")
```

Example 87 (r):
```r
# note that you can set `label = TRUE` or use the LabelClusters function to help label
# individual clusters
DimPlot(pbmc, reduction = "umap")
```

Example 88 (r):
```r
saveRDS(pbmc, file = "../output/pbmc_tutorial.rds")
```

Example 89 (r):
```r
saveRDS(pbmc, file = "../output/pbmc_tutorial.rds")
```

Example 90 (unknown):
```unknown
FindAllMarkers
```

Example 91 (unknown):
```unknown
max.cells.per.ident
```

Example 92 (r):
```r
# find all markers of cluster 1
cluster1.markers <- FindMarkers(pbmc, ident.1 = 1, min.pct = 0.25)
head(cluster1.markers, n = 5)
```

Example 93 (r):
```r
# find all markers of cluster 1
cluster1.markers <- FindMarkers(pbmc, ident.1 = 1, min.pct = 0.25)
head(cluster1.markers, n = 5)
```

Example 94 (r):
```r
# find all markers distinguishing cluster 5 from clusters 0 and 3
cluster5.markers <- FindMarkers(pbmc, ident.1 = 5, ident.2 = c(0, 3), min.pct = 0.25)
head(cluster5.markers, n = 5)
```

Example 95 (r):
```r
# find all markers distinguishing cluster 5 from clusters 0 and 3
cluster5.markers <- FindMarkers(pbmc, ident.1 = 5, ident.2 = c(0, 3), min.pct = 0.25)
head(cluster5.markers, n = 5)
```

Example 96 (r):
```r
# find markers for every cluster compared to all remaining cells, report only the positive ones
pbmc.markers <- FindAllMarkers(pbmc, only.pos = TRUE, min.pct = 0.25, logfc.threshold = 0.25)
pbmc.markers %>% group_by(cluster) %>% top_n(n = 2, wt = avg_logFC)
```

Example 97 (r):
```r
# find markers for every cluster compared to all remaining cells, report only the positive ones
pbmc.markers <- FindAllMarkers(pbmc, only.pos = TRUE, min.pct = 0.25, logfc.threshold = 0.25)
pbmc.markers %>% group_by(cluster) %>% top_n(n = 2, wt = avg_logFC)
```

Example 98 (r):
```r
cluster1.markers <- FindMarkers(pbmc, ident.1 = 0, logfc.threshold = 0.25, test.use = "roc", only.pos = TRUE)
```

Example 99 (r):
```r
cluster1.markers <- FindMarkers(pbmc, ident.1 = 0, logfc.threshold = 0.25, test.use = "roc", only.pos = TRUE)
```

Example 100 (unknown):
```unknown
FeaturePlot
```

Example 101 (unknown):
```unknown
CellScatter
```

Example 102 (r):
```r
VlnPlot(pbmc, features = c("MS4A1", "CD79A"))
```

Example 103 (r):
```r
VlnPlot(pbmc, features = c("MS4A1", "CD79A"))
```

Example 104 (r):
```r
# you can plot raw counts as well
VlnPlot(pbmc, features = c("NKG7", "PF4"), slot = "counts", log = TRUE)
```

Example 105 (r):
```r
# you can plot raw counts as well
VlnPlot(pbmc, features = c("NKG7", "PF4"), slot = "counts", log = TRUE)
```

Example 106 (r):
```r
FeaturePlot(pbmc, features = c("MS4A1", "GNLY", "CD3E", "CD14", "FCER1A", "FCGR3A", "LYZ", "PPBP", 
    "CD8A"))
```

Example 107 (r):
```r
FeaturePlot(pbmc, features = c("MS4A1", "GNLY", "CD3E", "CD14", "FCER1A", "FCGR3A", "LYZ", "PPBP", 
    "CD8A"))
```

Example 108 (r):
```r
top10 <- pbmc.markers %>% group_by(cluster) %>% top_n(n = 10, wt = avg_logFC)
DoHeatmap(pbmc, features = top10$gene) + NoLegend()
```

Example 109 (r):
```r
top10 <- pbmc.markers %>% group_by(cluster) %>% top_n(n = 10, wt = avg_logFC)
DoHeatmap(pbmc, features = top10$gene) + NoLegend()
```

Example 110 (r):
```r
new.cluster.ids <- c("Naive CD4 T", "Memory CD4 T", "CD14+ Mono", "B", "CD8 T", "FCGR3A+ Mono", 
    "NK", "DC", "Platelet")
names(new.cluster.ids) <- levels(pbmc)
pbmc <- RenameIdents(pbmc, new.cluster.ids)
DimPlot(pbmc, reduction = "umap", label = TRUE, pt.size = 0.5) + NoLegend()
```

Example 111 (r):
```r
new.cluster.ids <- c("Naive CD4 T", "Memory CD4 T", "CD14+ Mono", "B", "CD8 T", "FCGR3A+ Mono", 
    "NK", "DC", "Platelet")
names(new.cluster.ids) <- levels(pbmc)
pbmc <- RenameIdents(pbmc, new.cluster.ids)
DimPlot(pbmc, reduction = "umap", label = TRUE, pt.size = 0.5) + NoLegend()
```

Example 112 (r):
```r
saveRDS(pbmc, file = "../output/pbmc3k_final.rds")
```

Example 113 (r):
```r
saveRDS(pbmc, file = "../output/pbmc3k_final.rds")
```

---

## Tutorial: Integrating stimulated vs. control PBMC datasets to learn cell-type specific responses

**URL:** http://127.0.0.1:9173/seurat/archive/v3.0/immune_alignment/index.html

**Contents:**
- Tutorial: Integrating stimulated vs. control PBMC datasets to learn cell-type specific responses
    - Compiled: June 24, 2019
  - Integration goals
  - Setup the Seurat objects
  - Perform integration
  - Perform an integrated analysis
  - Identify conserved cell type markers
  - Identify differential expressed genes across conditions

This tutorial walks through an alignment of two groups of PBMCs from Kang et al, 2017. In this experiment, PBMCs were split into a stimulated and control group and the stimulated group was treated with interferon beta. The response to interferon caused cell type specific gene expression changes that makes a joint analysis of all the data difficult, with cells clustering both by stimulation condition and by cell type. Here, we demonstrate our integration strategy, as described in Stuart and Butler et al, 2018, for performing integrated analyses to promote the identification of common cell types and enable comparative analyses. While this example demonstrates the integration of two datasets (conditions), these methods have been extended to multiple datasets. This workflow provides an example of integrating four pancreatic islet datasets.

The following tutorial is designed to give you an overview of the kinds of comparative analyses on complex cell types that are possible using the Seurat integration procedure. Here, we address three main goals:

The gene expression matrices can be found here. We first read in the two count matrices and set up the Seurat objects.

We then identify anchors using the FindIntegrationAnchors function, which takes a list of Seurat objects as input, and use these anchors to integrate the two datasets together with IntegrateData.

Now we can run a single integrated analysis on all cells!

To visualize the two conditions side-by-side, we can use the split.by argument to show each condition colored by cluster.

To identify canonical cell type marker genes that are conserved across conditions, we provide the FindConservedMarkers function. This function performs differential gene expression testing for each dataset/group and combines the p-values using meta-analysis methods from the MetaDE R package. For example, we can calculated the genes that are conserved markers irrespective of stimulation condition in cluster 7 (NK cells).

We can explore these marker genes for each cluster and use them to annotate our clusters as specific cell types.

The DotPlot function with the split.by parameter can be useful for viewing conserved cell type markers across conditions, showing both the expression level and the percentage of cells in a cluster expressing any given gene. Here we plot 2-3 strong marker genes for each of our 13 clusters.

Now that we’ve aligned the stimulated and control cells, we can start to do comparative analyses and look at the differences induced by stimulation. One way to look broadly at these changes is to plot the average expression of both the stimulated and control cells and look for genes that are visual outliers on a scatter plot. Here, we take the average expression of both the stimulated and control naive T cells and CD14 monocyte populations and generate the scatter plots, highlighting genes that exhibit dramatic responses to interferon stimulation.

As you can see, many of the same genes are upregulated in both of these cell types and likely represent a conserved interferon response pathway.

Because we are confident in having identified common cell types across condition, we can ask what genes change in different conditions for cells of the same type. First, we create a column in the meta.data slot to hold both the cell type and stimulation information and switch the current ident to that column. Then we use FindMarkers to find the genes that are different between stimulated and control B cells. Notice that many of the top genes that show up here are the same as the ones we plotted earlier as core interferon response genes. Additionally, genes like CXCL10 which we saw were specific to monocyte and B cell interferon response show up as highly significant in this list as well.

Another useful way to visualize these changes in gene expression is with the split.by option to the FeaturePlot or VlnPlot function. This will display FeaturePlots of the list of given genes, split by a grouping variable (stimulation condition here). Genes such as CD3D and GNLY are canonical cell type markers (for T cells and NK/CD8 T cells) that are virtually unaffected by interferon stimulation and display similar gene expression patterns in the control and stimulated group. IFI6 and ISG15, on the other hand, are core interferon response genes and are upregulated accordingly in all cell types. Finally, CD14 and CXCL10 are genes that show a cell type specific interferon response. CD14 expression decreases after stimulation in CD14 monocytes, which could lead to misclassification in a supervised analysis framework, underscoring the value of integrated analysis. CXCL10 shows a distinct upregulation in monocytes and B cells after interferon stimulation but not in other cell types.

**Examples:**

Example 1 (r):
```r
library(Seurat)
library(cowplot)
ctrl.data <- read.table(file = "../data/immune_control_expression_matrix.txt.gz", sep = "\t")
stim.data <- read.table(file = "../data/immune_stimulated_expression_matrix.txt.gz", sep = "\t")

# Set up control object
ctrl <- CreateSeuratObject(counts = ctrl.data, project = "IMMUNE_CTRL", min.cells = 5)
ctrl$stim <- "CTRL"
ctrl <- subset(ctrl, subset = nFeature_RNA > 500)
ctrl <- NormalizeData(ctrl, verbose = FALSE)
ctrl <- FindVariableFeatures(ctrl, selection.method = "vst", nfeatures = 2000)

# Set up stimulated object
stim <- CreateSeuratObject(counts = stim.data, project = "IMMUNE_STIM", min.cells = 5)
stim$stim <- "STIM"
stim <- subset(stim, subset = nFeature_RNA > 500)
stim <- NormalizeData(stim, verbose = FALSE)
stim <- FindVariableFeatures(stim, selection.method = "vst", nfeatures = 2000)
```

Example 2 (r):
```r
library(Seurat)
library(cowplot)
ctrl.data <- read.table(file = "../data/immune_control_expression_matrix.txt.gz", sep = "\t")
stim.data <- read.table(file = "../data/immune_stimulated_expression_matrix.txt.gz", sep = "\t")

# Set up control object
ctrl <- CreateSeuratObject(counts = ctrl.data, project = "IMMUNE_CTRL", min.cells = 5)
ctrl$stim <- "CTRL"
ctrl <- subset(ctrl, subset = nFeature_RNA > 500)
ctrl <- NormalizeData(ctrl, verbose = FALSE)
ctrl <- FindVariableFeatures(ctrl, selection.method = "vst", nfeatures = 2000)

# Set up stimulated object
stim <- CreateSeuratObject(counts = stim.data, project = "IMMUNE_STIM", min.cells = 5)
stim$stim <- "STIM"
stim <- subset(stim, subset = nFeature_RNA > 500)
stim <- NormalizeData(stim, verbose = FALSE)
stim <- FindVariableFeatures(stim, selection.method = "vst", nfeatures = 2000)
```

Example 3 (unknown):
```unknown
FindIntegrationAnchors
```

Example 4 (unknown):
```unknown
IntegrateData
```

Example 5 (r):
```r
immune.anchors <- FindIntegrationAnchors(object.list = list(ctrl, stim), dims = 1:20)
```

Example 6 (r):
```r
immune.anchors <- FindIntegrationAnchors(object.list = list(ctrl, stim), dims = 1:20)
```

Example 7 (r):
```r
immune.combined <- IntegrateData(anchorset = immune.anchors, dims = 1:20)
```

Example 8 (r):
```r
immune.combined <- IntegrateData(anchorset = immune.anchors, dims = 1:20)
```

Example 9 (r):
```r
DefaultAssay(immune.combined) <- "integrated"

# Run the standard workflow for visualization and clustering
immune.combined <- ScaleData(immune.combined, verbose = FALSE)
immune.combined <- RunPCA(immune.combined, npcs = 30, verbose = FALSE)
# t-SNE and Clustering
immune.combined <- RunUMAP(immune.combined, reduction = "pca", dims = 1:20)
immune.combined <- FindNeighbors(immune.combined, reduction = "pca", dims = 1:20)
immune.combined <- FindClusters(immune.combined, resolution = 0.5)
```

Example 10 (r):
```r
DefaultAssay(immune.combined) <- "integrated"

# Run the standard workflow for visualization and clustering
immune.combined <- ScaleData(immune.combined, verbose = FALSE)
immune.combined <- RunPCA(immune.combined, npcs = 30, verbose = FALSE)
# t-SNE and Clustering
immune.combined <- RunUMAP(immune.combined, reduction = "pca", dims = 1:20)
immune.combined <- FindNeighbors(immune.combined, reduction = "pca", dims = 1:20)
immune.combined <- FindClusters(immune.combined, resolution = 0.5)
```

Example 11 (r):
```r
# Visualization
p1 <- DimPlot(immune.combined, reduction = "umap", group.by = "stim")
p2 <- DimPlot(immune.combined, reduction = "umap", label = TRUE)
plot_grid(p1, p2)
```

Example 12 (r):
```r
# Visualization
p1 <- DimPlot(immune.combined, reduction = "umap", group.by = "stim")
p2 <- DimPlot(immune.combined, reduction = "umap", label = TRUE)
plot_grid(p1, p2)
```

Example 13 (r):
```r
DimPlot(immune.combined, reduction = "umap", split.by = "stim")
```

Example 14 (r):
```r
DimPlot(immune.combined, reduction = "umap", split.by = "stim")
```

Example 15 (unknown):
```unknown
FindConservedMarkers
```

Example 16 (r):
```r
DefaultAssay(immune.combined) <- "RNA"
nk.markers <- FindConservedMarkers(immune.combined, ident.1 = 7, grouping.var = "stim", verbose = FALSE)
head(nk.markers)
```

Example 17 (r):
```r
DefaultAssay(immune.combined) <- "RNA"
nk.markers <- FindConservedMarkers(immune.combined, ident.1 = 7, grouping.var = "stim", verbose = FALSE)
head(nk.markers)
```

Example 18 (unknown):
```unknown
##        CTRL_p_val CTRL_avg_logFC CTRL_pct.1 CTRL_pct.2 CTRL_p_val_adj
## GNLY            0       4.186117      0.943      0.046              0
## NKG7            0       3.164712      0.953      0.085              0
## GZMB            0       2.915692      0.839      0.044              0
## CLIC3           0       2.407695      0.601      0.024              0
## FGFBP2          0       2.241968      0.500      0.021              0
## CTSW            0       2.088278      0.537      0.030              0
##           STIM_p_val STIM_avg_logFC STIM_pct.1 STIM_pct.2 STIM_p_val_adj
## GNLY    0.000000e+00       4.033650      0.955      0.061   0.000000e+00
## NKG7    0.000000e+00       2.914724      0.952      0.082   0.000000e+00
## GZMB    0.000000e+00       3.142391      0.898      0.061   0.000000e+00
## CLIC3   0.000000e+00       2.470769      0.629      0.031   0.000000e+00
## FGFBP2 9.524349e-156       1.483922      0.259      0.016  1.338457e-151
## CTSW    0.000000e+00       2.196390      0.604      0.035   0.000000e+00
##             max_pval minimump_p_val
## GNLY    0.000000e+00              0
## NKG7    0.000000e+00              0
## GZMB    0.000000e+00              0
## CLIC3   0.000000e+00              0
## FGFBP2 9.524349e-156              0
## CTSW    0.000000e+00              0
```

Example 19 (unknown):
```unknown
##        CTRL_p_val CTRL_avg_logFC CTRL_pct.1 CTRL_pct.2 CTRL_p_val_adj
## GNLY            0       4.186117      0.943      0.046              0
## NKG7            0       3.164712      0.953      0.085              0
## GZMB            0       2.915692      0.839      0.044              0
## CLIC3           0       2.407695      0.601      0.024              0
## FGFBP2          0       2.241968      0.500      0.021              0
## CTSW            0       2.088278      0.537      0.030              0
##           STIM_p_val STIM_avg_logFC STIM_pct.1 STIM_pct.2 STIM_p_val_adj
## GNLY    0.000000e+00       4.033650      0.955      0.061   0.000000e+00
## NKG7    0.000000e+00       2.914724      0.952      0.082   0.000000e+00
## GZMB    0.000000e+00       3.142391      0.898      0.061   0.000000e+00
## CLIC3   0.000000e+00       2.470769      0.629      0.031   0.000000e+00
## FGFBP2 9.524349e-156       1.483922      0.259      0.016  1.338457e-151
## CTSW    0.000000e+00       2.196390      0.604      0.035   0.000000e+00
##             max_pval minimump_p_val
## GNLY    0.000000e+00              0
## NKG7    0.000000e+00              0
## GZMB    0.000000e+00              0
## CLIC3   0.000000e+00              0
## FGFBP2 9.524349e-156              0
## CTSW    0.000000e+00              0
```

Example 20 (r):
```r
FeaturePlot(immune.combined, features = c("CD3D", "SELL", "CREM", "CD8A", "GNLY", "CD79A", "FCGR3A", 
    "CCL2", "PPBP"), min.cutoff = "q9")
```

Example 21 (r):
```r
FeaturePlot(immune.combined, features = c("CD3D", "SELL", "CREM", "CD8A", "GNLY", "CD79A", "FCGR3A", 
    "CCL2", "PPBP"), min.cutoff = "q9")
```

Example 22 (r):
```r
immune.combined <- RenameIdents(immune.combined, `0` = "CD14 Mono", `1` = "CD4 Naive T", `2` = "CD4 Memory T", 
    `3` = "CD16 Mono", `4` = "B", `5` = "CD8 T", `6` = "T activated", `7` = "NK", `8` = "DC", `9` = "B Activated", 
    `10` = "Mk", `11` = "pDC", `12` = "Eryth", `13` = "Mono/Mk Doublets")

DimPlot(immune.combined, label = TRUE)
```

Example 23 (r):
```r
immune.combined <- RenameIdents(immune.combined, `0` = "CD14 Mono", `1` = "CD4 Naive T", `2` = "CD4 Memory T", 
    `3` = "CD16 Mono", `4` = "B", `5` = "CD8 T", `6` = "T activated", `7` = "NK", `8` = "DC", `9` = "B Activated", 
    `10` = "Mk", `11` = "pDC", `12` = "Eryth", `13` = "Mono/Mk Doublets")

DimPlot(immune.combined, label = TRUE)
```

Example 24 (r):
```r
Idents(immune.combined) <- factor(Idents(immune.combined), levels = c("Mono/Mk Doublets", "pDC", 
    "Eryth", "Mk", "DC", "CD14 Mono", "CD16 Mono", "B Activated", "B", "CD8 T", "NK", "T activated", 
    "CD4 Naive T", "CD4 Memory T"))
markers.to.plot <- c("CD3D", "CREM", "HSPH1", "SELL", "GIMAP5", "CACYBP", "GNLY", "NKG7", "CCL5", 
    "CD8A", "MS4A1", "CD79A", "MIR155HG", "NME1", "FCGR3A", "VMO1", "CCL2", "S100A9", "HLA-DQA1", 
    "GPR183", "PPBP", "GNG11", "HBA2", "HBB", "TSPAN13", "IL3RA", "IGJ")
DotPlot(immune.combined, features = rev(markers.to.plot), cols = c("blue", "red"), dot.scale = 8, 
    split.by = "stim") + RotatedAxis()
```

Example 25 (r):
```r
Idents(immune.combined) <- factor(Idents(immune.combined), levels = c("Mono/Mk Doublets", "pDC", 
    "Eryth", "Mk", "DC", "CD14 Mono", "CD16 Mono", "B Activated", "B", "CD8 T", "NK", "T activated", 
    "CD4 Naive T", "CD4 Memory T"))
markers.to.plot <- c("CD3D", "CREM", "HSPH1", "SELL", "GIMAP5", "CACYBP", "GNLY", "NKG7", "CCL5", 
    "CD8A", "MS4A1", "CD79A", "MIR155HG", "NME1", "FCGR3A", "VMO1", "CCL2", "S100A9", "HLA-DQA1", 
    "GPR183", "PPBP", "GNG11", "HBA2", "HBB", "TSPAN13", "IL3RA", "IGJ")
DotPlot(immune.combined, features = rev(markers.to.plot), cols = c("blue", "red"), dot.scale = 8, 
    split.by = "stim") + RotatedAxis()
```

Example 26 (r):
```r
t.cells <- subset(immune.combined, idents = "CD4 Naive T")
Idents(t.cells) <- "stim"
avg.t.cells <- log1p(AverageExpression(t.cells, verbose = FALSE)$RNA)
avg.t.cells$gene <- rownames(avg.t.cells)

cd14.mono <- subset(immune.combined, idents = "CD14 Mono")
Idents(cd14.mono) <- "stim"
avg.cd14.mono <- log1p(AverageExpression(cd14.mono, verbose = FALSE)$RNA)
avg.cd14.mono$gene <- rownames(avg.cd14.mono)

genes.to.label = c("ISG15", "LY6E", "IFI6", "ISG20", "MX1", "IFIT2", "IFIT1", "CXCL10", "CCL8")
p1 <- ggplot(avg.t.cells, aes(CTRL, STIM)) + geom_point() + ggtitle("CD4 Naive T Cells")
p1 <- LabelPoints(plot = p1, points = genes.to.label, repel = TRUE)
p2 <- ggplot(avg.cd14.mono, aes(CTRL, STIM)) + geom_point() + ggtitle("CD14 Monocytes")
p2 <- LabelPoints(plot = p2, points = genes.to.label, repel = TRUE)
plot_grid(p1, p2)
```

Example 27 (r):
```r
t.cells <- subset(immune.combined, idents = "CD4 Naive T")
Idents(t.cells) <- "stim"
avg.t.cells <- log1p(AverageExpression(t.cells, verbose = FALSE)$RNA)
avg.t.cells$gene <- rownames(avg.t.cells)

cd14.mono <- subset(immune.combined, idents = "CD14 Mono")
Idents(cd14.mono) <- "stim"
avg.cd14.mono <- log1p(AverageExpression(cd14.mono, verbose = FALSE)$RNA)
avg.cd14.mono$gene <- rownames(avg.cd14.mono)

genes.to.label = c("ISG15", "LY6E", "IFI6", "ISG20", "MX1", "IFIT2", "IFIT1", "CXCL10", "CCL8")
p1 <- ggplot(avg.t.cells, aes(CTRL, STIM)) + geom_point() + ggtitle("CD4 Naive T Cells")
p1 <- LabelPoints(plot = p1, points = genes.to.label, repel = TRUE)
p2 <- ggplot(avg.cd14.mono, aes(CTRL, STIM)) + geom_point() + ggtitle("CD14 Monocytes")
p2 <- LabelPoints(plot = p2, points = genes.to.label, repel = TRUE)
plot_grid(p1, p2)
```

Example 28 (unknown):
```unknown
FindMarkers
```

Example 29 (r):
```r
immune.combined$celltype.stim <- paste(Idents(immune.combined), immune.combined$stim, sep = "_")
immune.combined$celltype <- Idents(immune.combined)
Idents(immune.combined) <- "celltype.stim"
b.interferon.response <- FindMarkers(immune.combined, ident.1 = "B_STIM", ident.2 = "B_CTRL", verbose = FALSE)
head(b.interferon.response, n = 15)
```

Example 30 (r):
```r
immune.combined$celltype.stim <- paste(Idents(immune.combined), immune.combined$stim, sep = "_")
immune.combined$celltype <- Idents(immune.combined)
Idents(immune.combined) <- "celltype.stim"
b.interferon.response <- FindMarkers(immune.combined, ident.1 = "B_STIM", ident.2 = "B_CTRL", verbose = FALSE)
head(b.interferon.response, n = 15)
```

Example 31 (unknown):
```unknown
##                 p_val avg_logFC pct.1 pct.2     p_val_adj
## ISG15   8.611499e-155 3.1934171 0.998 0.236 1.210174e-150
## IFIT3   1.319470e-150 3.1195144 0.965 0.053 1.854251e-146
## IFI6    4.716672e-148 2.9264004 0.964 0.078 6.628339e-144
## ISG20   1.061563e-145 2.0390802 1.000 0.664 1.491814e-141
## IFIT1   1.830963e-136 2.8706318 0.909 0.030 2.573053e-132
## MX1     1.775606e-120 2.2540787 0.909 0.118 2.495259e-116
## LY6E    2.824749e-116 2.1460522 0.896 0.153 3.969620e-112
## TNFSF10 4.227184e-109 2.6372382 0.785 0.020 5.940461e-105
## IFIT2   4.627440e-106 2.5102230 0.789 0.038 6.502941e-102
## B2M      1.344345e-94 0.4193618 1.000 1.000  1.889208e-90
## PLSCR1   5.170871e-94 1.9769476 0.794 0.113  7.266624e-90
## IRF7     1.451494e-92 1.7994058 0.838 0.190  2.039785e-88
## CXCL10   6.201621e-84 3.6906104 0.650 0.010  8.715138e-80
## UBE2L6   1.324818e-81 1.4879509 0.854 0.301  1.861767e-77
## PSMB9    1.098134e-76 1.1378896 0.940 0.571  1.543208e-72
```

Example 32 (unknown):
```unknown
##                 p_val avg_logFC pct.1 pct.2     p_val_adj
## ISG15   8.611499e-155 3.1934171 0.998 0.236 1.210174e-150
## IFIT3   1.319470e-150 3.1195144 0.965 0.053 1.854251e-146
## IFI6    4.716672e-148 2.9264004 0.964 0.078 6.628339e-144
## ISG20   1.061563e-145 2.0390802 1.000 0.664 1.491814e-141
## IFIT1   1.830963e-136 2.8706318 0.909 0.030 2.573053e-132
## MX1     1.775606e-120 2.2540787 0.909 0.118 2.495259e-116
## LY6E    2.824749e-116 2.1460522 0.896 0.153 3.969620e-112
## TNFSF10 4.227184e-109 2.6372382 0.785 0.020 5.940461e-105
## IFIT2   4.627440e-106 2.5102230 0.789 0.038 6.502941e-102
## B2M      1.344345e-94 0.4193618 1.000 1.000  1.889208e-90
## PLSCR1   5.170871e-94 1.9769476 0.794 0.113  7.266624e-90
## IRF7     1.451494e-92 1.7994058 0.838 0.190  2.039785e-88
## CXCL10   6.201621e-84 3.6906104 0.650 0.010  8.715138e-80
## UBE2L6   1.324818e-81 1.4879509 0.854 0.301  1.861767e-77
## PSMB9    1.098134e-76 1.1378896 0.940 0.571  1.543208e-72
```

Example 33 (unknown):
```unknown
FeaturePlot
```

Example 34 (r):
```r
FeaturePlot(immune.combined, features = c("CD3D", "GNLY", "IFI6"), split.by = "stim", max.cutoff = 3, 
    cols = c("grey", "red"))
```

Example 35 (r):
```r
FeaturePlot(immune.combined, features = c("CD3D", "GNLY", "IFI6"), split.by = "stim", max.cutoff = 3, 
    cols = c("grey", "red"))
```

Example 36 (r):
```r
plots <- VlnPlot(immune.combined, features = c("LYZ", "ISG15", "CXCL10"), split.by = "stim", group.by = "celltype", 
    pt.size = 0, combine = FALSE)
CombinePlots(plots = plots, ncol = 1)
```

Example 37 (r):
```r
plots <- VlnPlot(immune.combined, features = c("LYZ", "ISG15", "CXCL10"), split.by = "stim", group.by = "celltype", 
    pt.size = 0, combine = FALSE)
CombinePlots(plots = plots, ncol = 1)
```

---

## Seurat Command List • Seurat

**URL:** http://127.0.0.1:9173/seurat/archive/v4.3/essential_commands/index.html

**Contents:**
- Seurat Command List
    - Compiled: 2023-03-27
- Seurat Standard Worflow
- Seurat Object Interaction
- Data Access
- Visualization in Seurat
- Multi-Assay Features
- Seurat v2.X vs v3.X
- Contents

The standard Seurat workflow takes raw single-cell expression data and aims to find clusters within the data. For full details, please read our tutorial. This process consists of data normalization and variable feature selection, data scaling, a PCA on variable features, construction of a shared-nearest-neighbors graph, and clustering using a modularity optimizer. Finally, we use a t-SNE to visualize our clusters in a two-dimensional space. pbmc.counts <- Read10X(data.dir = "~/Downloads/pbmc3k/filtered_gene_bc_matrices/hg19/") pbmc <- CreateSeuratObject(counts = pbmc.counts) pbmc <- NormalizeData(object = pbmc) pbmc <- FindVariableFeatures(object = pbmc) pbmc <- ScaleData(object = pbmc) pbmc <- RunPCA(object = pbmc) pbmc <- FindNeighbors(object = pbmc) pbmc <- FindClusters(object = pbmc) pbmc <- RunTSNE(object = pbmc) DimPlot(object = pbmc, reduction = "tsne")

Since Seurat v3.0, we’ve made improvements to the Seurat object, and added new methods for user interaction. We also introduce simple functions for common tasks, like subsetting and merging, that mirror standard R functions. # Get cell and feature names, and total numbers colnames(x = pbmc) Cells(object = pbmc) rownames(x = pbmc) ncol(x = pbmc) nrow(x = pbmc) # Get cell identity classes Idents(object = pbmc) levels(x = pbmc) # Stash cell identity classes pbmc[["old.ident"]] <- Idents(object = pbmc) pbmc <- StashIdent(object = pbmc, save.name = "old.ident") # Set identity classes Idents(object = pbmc) <- "CD4 T cells" Idents(object = pbmc, cells = 1:10) <- "CD4 T cells" # Set identity classes to an existing column in meta data Idents(object = pbmc, cells = 1:10) <- "orig.ident" Idents(object = pbmc) <- "orig.ident" # Rename identity classes pbmc <- RenameIdents(object = pbmc, `CD4 T cells` = "T Helper cells") # Subset Seurat object based on identity class, also see ?SubsetData subset(x = pbmc, idents = "B cells") subset(x = pbmc, idents = c("CD4 T cells", "CD8 T cells"), invert = TRUE) # Subset on the expression level of a gene/feature subset(x = pbmc, subset = MS4A1 > 3) # Subset on a combination of criteria subset(x = pbmc, subset = MS4A1 > 3 & PC1 > 5) subset(x = pbmc, subset = MS4A1 > 3, idents = "B cells") # Subset on a value in the object meta data subset(x = pbmc, subset = orig.ident == "Replicate1") # Downsample the number of cells per identity class subset(x = pbmc, downsample = 100) # Merge two Seurat objects merge(x = pbmc1, y = pbmc2) # Merge more than two Seurat objects merge(x = pbmc1, y = list(pbmc2, pbmc3))

Accessing data in Seurat is simple, using clearly defined accessors and setters to quickly find the data needed. # View metadata data frame, stored in object@meta.data pbmc[[]] # Retrieve specific values from the metadata pbmc$nCount_RNA pbmc[[c("percent.mito", "nFeature_RNA")]] # Add metadata, see ?AddMetaData random_group_labels <- sample(x = c("g1", "g2"), size = ncol(x = pbmc), replace = TRUE) pbmc$groups <- random_group_labels # Retrieve or set data in an expression matrix ('counts', 'data', and 'scale.data') GetAssayData(object = pbmc, slot = "counts") pbmc <- SetAssayData(object = pbmc, slot = "scale.data", new.data = new.data) # Get cell embeddings and feature loadings Embeddings(object = pbmc, reduction = "pca") Loadings(object = pbmc, reduction = "pca") Loadings(object = pbmc, reduction = "pca", projected = TRUE) # FetchData can pull anything from expression matrices, cell embeddings, or metadata FetchData(object = pbmc, vars = c("PC_1", "percent.mito", "MS4A1"))

Seurat has a vast, ggplot2-based plotting library. All plotting functions will return a ggplot2 plot by default, allowing easy customization with ggplot2. # Dimensional reduction plot for PCA or tSNE DimPlot(object = pbmc, reduction = "tsne") DimPlot(object = pbmc, reduction = "pca") # Dimensional reduction plot, with cells colored by a quantitative feature FeaturePlot(object = pbmc, features = "MS4A1") # Scatter plot across single cells, replaces GenePlot FeatureScatter(object = pbmc, feature1 = "MS4A1", feature2 = "PC_1") FeatureScatter(object = pbmc, feature1 = "MS4A1", feature2 = "CD3D") # Scatter plot across individual features, repleaces CellPlot CellScatter(object = pbmc, cell1 = "AGTCTACTAGGGTG", cell2 = "CACAGATGGTTTCT") VariableFeaturePlot(object = pbmc) # Violin and Ridge plots VlnPlot(object = pbmc, features = c("LYZ", "CCL5", "IL32")) RidgePlot(object = pbmc, feature = c("LYZ", "CCL5", "IL32")) # Heatmaps DoHeatmap(object = pbmc, features = heatmap_markers) DimHeatmap(object = pbmc, reduction = "pca", cells = 200) # New things to try! Note that plotting functions now return ggplot2 objects, so you can add themes, titles, and # options onto them VlnPlot(object = pbmc, features = "MS4A1", split.by = "groups") DotPlot(object = pbmc, features = c("LYZ", "CCL5", "IL32"), split.by = "groups") FeaturePlot(object = pbmc, features = c("MS4A1", "CD79A"), blend = TRUE) DimPlot(object = pbmc) + DarkTheme() DimPlot(object = pbmc) + labs(title = "2,700 PBMCs clustered using Seurat and viewed\non a two-dimensional tSNE")Seurat provides many prebuilt themes that can be added to ggplot2 plots for quick customizationThemeFunctionDarkThemeSet a black background with white textFontSizeSet font sizes for various elements of a plotNoAxesRemove axes and axis textNoLegendRemove all legend elementsRestoreLegendRestores a legend after removalRotatedAxisRotates x-axis labels # Plotting helper functions work with ggplot2-based scatter plots, such as DimPlot, FeaturePlot, CellScatter, and # FeatureScatter plot <- DimPlot(object = pbmc) + NoLegend() # HoverLocator replaces the former `do.hover` argument It can also show extra data throught the `information` argument, # designed to work smoothly with FetchData HoverLocator(plot = plot, information = FetchData(object = pbmc, vars = c("ident", "PC_1", "nFeature_RNA"))) # FeatureLocator replaces the former `do.identify` select.cells <- FeatureLocator(plot = plot) # Label points on a ggplot object LabelPoints(plot = plot, points = TopCells(object = pbmc[["pca"]]), repel = TRUE)

Seurat provides many prebuilt themes that can be added to ggplot2 plots for quick customizationThemeFunctionDarkThemeSet a black background with white textFontSizeSet font sizes for various elements of a plotNoAxesRemove axes and axis textNoLegendRemove all legend elementsRestoreLegendRestores a legend after removalRotatedAxisRotates x-axis labels # Plotting helper functions work with ggplot2-based scatter plots, such as DimPlot, FeaturePlot, CellScatter, and # FeatureScatter plot <- DimPlot(object = pbmc) + NoLegend() # HoverLocator replaces the former `do.hover` argument It can also show extra data throught the `information` argument, # designed to work smoothly with FetchData HoverLocator(plot = plot, information = FetchData(object = pbmc, vars = c("ident", "PC_1", "nFeature_RNA"))) # FeatureLocator replaces the former `do.identify` select.cells <- FeatureLocator(plot = plot) # Label points on a ggplot object LabelPoints(plot = plot, points = TopCells(object = pbmc[["pca"]]), repel = TRUE)

With Seurat, you can easily switch between different assays at the single cell level (such as ADT counts from CITE-seq, or integrated/batch-corrected data). Most functions now take an assay parameter, but you can set a Default Assay to avoid repetitive statements. cbmc <- CreateSeuratObject(counts = cbmc.rna) # Add ADT data cbmc[["ADT"]] <- CreateAssayObject(counts = cbmc.adt) # Run analyses by specifying the assay to use NormalizeData(object = cbmc, assay = "RNA") NormalizeData(object = cbmc, assay = "ADT", method = "CLR") # Retrieve and set the default assay DefaultAssay(object = cbmc) DefaultAssay(object = cbmc) <- "ADT" DefaultAssay(object = cbmc) # Pull feature expression from both assays by using keys FetchData(object = cbmc, vars = c("rna_CD3E", "adt_CD3")) # Plot data from multiple assays using keys FeatureScatter(object = cbmc, feature1 = "rna_CD3E", feature2 = "adt_CD3")

Developed by Paul Hoffman, Satija Lab and Collaborators.

Developed by Paul Hoffman, Satija Lab and Collaborators.

Site built with pkgdown 2.0.7.

Site built with pkgdown 2.0.7.

**Examples:**

Example 1 (unknown):
```unknown
vignettes/essential_commands.Rmd
```

Example 2 (unknown):
```unknown
essential_commands.Rmd
```

Example 3 (unknown):
```unknown
pbmc.counts <- Read10X(data.dir = "~/Downloads/pbmc3k/filtered_gene_bc_matrices/hg19/")
pbmc <- CreateSeuratObject(counts = pbmc.counts)
pbmc <- NormalizeData(object = pbmc)
pbmc <- FindVariableFeatures(object = pbmc)
pbmc <- ScaleData(object = pbmc)
pbmc <- RunPCA(object = pbmc)
pbmc <- FindNeighbors(object = pbmc)
pbmc <- FindClusters(object = pbmc)
pbmc <- RunTSNE(object = pbmc)
DimPlot(object = pbmc, reduction = "tsne")
```

Example 4 (r):
```r
pbmc.counts <- Read10X(data.dir = "~/Downloads/pbmc3k/filtered_gene_bc_matrices/hg19/")
pbmc <- CreateSeuratObject(counts = pbmc.counts)
pbmc <- NormalizeData(object = pbmc)
pbmc <- FindVariableFeatures(object = pbmc)
pbmc <- ScaleData(object = pbmc)
pbmc <- RunPCA(object = pbmc)
pbmc <- FindNeighbors(object = pbmc)
pbmc <- FindClusters(object = pbmc)
pbmc <- RunTSNE(object = pbmc)
DimPlot(object = pbmc, reduction = "tsne")
```

Example 5 (r):
```r
pbmc.counts <- Read10X(data.dir = "~/Downloads/pbmc3k/filtered_gene_bc_matrices/hg19/")
pbmc <- CreateSeuratObject(counts = pbmc.counts)
pbmc <- NormalizeData(object = pbmc)
pbmc <- FindVariableFeatures(object = pbmc)
pbmc <- ScaleData(object = pbmc)
pbmc <- RunPCA(object = pbmc)
pbmc <- FindNeighbors(object = pbmc)
pbmc <- FindClusters(object = pbmc)
pbmc <- RunTSNE(object = pbmc)
DimPlot(object = pbmc, reduction = "tsne")
```

Example 6 (unknown):
```unknown
# Get cell and feature names, and total numbers
colnames(x = pbmc)
Cells(object = pbmc)
rownames(x = pbmc)
ncol(x = pbmc)
nrow(x = pbmc)
```

Example 7 (r):
```r
# Get cell and feature names, and total numbers
colnames(x = pbmc)
Cells(object = pbmc)
rownames(x = pbmc)
ncol(x = pbmc)
nrow(x = pbmc)
```

Example 8 (r):
```r
# Get cell and feature names, and total numbers
colnames(x = pbmc)
Cells(object = pbmc)
rownames(x = pbmc)
ncol(x = pbmc)
nrow(x = pbmc)
```

Example 9 (unknown):
```unknown
# Get cell identity classes
Idents(object = pbmc)
levels(x = pbmc)

# Stash cell identity classes
pbmc[["old.ident"]] <- Idents(object = pbmc)
pbmc <- StashIdent(object = pbmc, save.name = "old.ident")

# Set identity classes
Idents(object = pbmc) <- "CD4 T cells"
Idents(object = pbmc, cells = 1:10) <- "CD4 T cells"

# Set identity classes to an existing column in meta data
Idents(object = pbmc, cells = 1:10) <- "orig.ident"
Idents(object = pbmc) <- "orig.ident"

# Rename identity classes
pbmc <- RenameIdents(object = pbmc, `CD4 T cells` = "T Helper cells")
```

Example 10 (r):
```r
# Get cell identity classes
Idents(object = pbmc)
levels(x = pbmc)

# Stash cell identity classes
pbmc[["old.ident"]] <- Idents(object = pbmc)
pbmc <- StashIdent(object = pbmc, save.name = "old.ident")

# Set identity classes
Idents(object = pbmc) <- "CD4 T cells"
Idents(object = pbmc, cells = 1:10) <- "CD4 T cells"

# Set identity classes to an existing column in meta data
Idents(object = pbmc, cells = 1:10) <- "orig.ident"
Idents(object = pbmc) <- "orig.ident"

# Rename identity classes
pbmc <- RenameIdents(object = pbmc, `CD4 T cells` = "T Helper cells")
```

Example 11 (r):
```r
# Get cell identity classes
Idents(object = pbmc)
levels(x = pbmc)

# Stash cell identity classes
pbmc[["old.ident"]] <- Idents(object = pbmc)
pbmc <- StashIdent(object = pbmc, save.name = "old.ident")

# Set identity classes
Idents(object = pbmc) <- "CD4 T cells"
Idents(object = pbmc, cells = 1:10) <- "CD4 T cells"

# Set identity classes to an existing column in meta data
Idents(object = pbmc, cells = 1:10) <- "orig.ident"
Idents(object = pbmc) <- "orig.ident"

# Rename identity classes
pbmc <- RenameIdents(object = pbmc, `CD4 T cells` = "T Helper cells")
```

Example 12 (unknown):
```unknown
# Subset Seurat object based on identity class, also see ?SubsetData
subset(x = pbmc, idents = "B cells")
subset(x = pbmc, idents = c("CD4 T cells", "CD8 T cells"), invert = TRUE)

# Subset on the expression level of a gene/feature
subset(x = pbmc, subset = MS4A1 > 3)

# Subset on a combination of criteria
subset(x = pbmc, subset = MS4A1 > 3 & PC1 > 5)
subset(x = pbmc, subset = MS4A1 > 3, idents = "B cells")

# Subset on a value in the object meta data
subset(x = pbmc, subset = orig.ident == "Replicate1")

# Downsample the number of cells per identity class
subset(x = pbmc, downsample = 100)
```

Example 13 (r):
```r
# Subset Seurat object based on identity class, also see ?SubsetData
subset(x = pbmc, idents = "B cells")
subset(x = pbmc, idents = c("CD4 T cells", "CD8 T cells"), invert = TRUE)

# Subset on the expression level of a gene/feature
subset(x = pbmc, subset = MS4A1 > 3)

# Subset on a combination of criteria
subset(x = pbmc, subset = MS4A1 > 3 & PC1 > 5)
subset(x = pbmc, subset = MS4A1 > 3, idents = "B cells")

# Subset on a value in the object meta data
subset(x = pbmc, subset = orig.ident == "Replicate1")

# Downsample the number of cells per identity class
subset(x = pbmc, downsample = 100)
```

Example 14 (r):
```r
# Subset Seurat object based on identity class, also see ?SubsetData
subset(x = pbmc, idents = "B cells")
subset(x = pbmc, idents = c("CD4 T cells", "CD8 T cells"), invert = TRUE)

# Subset on the expression level of a gene/feature
subset(x = pbmc, subset = MS4A1 > 3)

# Subset on a combination of criteria
subset(x = pbmc, subset = MS4A1 > 3 & PC1 > 5)
subset(x = pbmc, subset = MS4A1 > 3, idents = "B cells")

# Subset on a value in the object meta data
subset(x = pbmc, subset = orig.ident == "Replicate1")

# Downsample the number of cells per identity class
subset(x = pbmc, downsample = 100)
```

Example 15 (unknown):
```unknown
# Merge two Seurat objects
merge(x = pbmc1, y = pbmc2)
# Merge more than two Seurat objects
merge(x = pbmc1, y = list(pbmc2, pbmc3))
```

Example 16 (r):
```r
# Merge two Seurat objects
merge(x = pbmc1, y = pbmc2)
# Merge more than two Seurat objects
merge(x = pbmc1, y = list(pbmc2, pbmc3))
```

Example 17 (r):
```r
# Merge two Seurat objects
merge(x = pbmc1, y = pbmc2)
# Merge more than two Seurat objects
merge(x = pbmc1, y = list(pbmc2, pbmc3))
```

Example 18 (python):
```python
# View metadata data frame, stored in object@meta.data
pbmc[[]]

# Retrieve specific values from the metadata
pbmc$nCount_RNA
pbmc[[c("percent.mito", "nFeature_RNA")]]

# Add metadata, see ?AddMetaData
random_group_labels <- sample(x = c("g1", "g2"), size = ncol(x = pbmc), replace = TRUE)
pbmc$groups <- random_group_labels
```

Example 19 (r):
```r
# View metadata data frame, stored in object@meta.data
pbmc[[]]

# Retrieve specific values from the metadata
pbmc$nCount_RNA
pbmc[[c("percent.mito", "nFeature_RNA")]]

# Add metadata, see ?AddMetaData
random_group_labels <- sample(x = c("g1", "g2"), size = ncol(x = pbmc), replace = TRUE)
pbmc$groups <- random_group_labels
```

Example 20 (r):
```r
# View metadata data frame, stored in object@meta.data
pbmc[[]]

# Retrieve specific values from the metadata
pbmc$nCount_RNA
pbmc[[c("percent.mito", "nFeature_RNA")]]

# Add metadata, see ?AddMetaData
random_group_labels <- sample(x = c("g1", "g2"), size = ncol(x = pbmc), replace = TRUE)
pbmc$groups <- random_group_labels
```

Example 21 (unknown):
```unknown
# Retrieve or set data in an expression matrix ('counts', 'data', and 'scale.data')
GetAssayData(object = pbmc, slot = "counts")
pbmc <- SetAssayData(object = pbmc, slot = "scale.data", new.data = new.data)
```

Example 22 (r):
```r
# Retrieve or set data in an expression matrix ('counts', 'data', and 'scale.data')
GetAssayData(object = pbmc, slot = "counts")
pbmc <- SetAssayData(object = pbmc, slot = "scale.data", new.data = new.data)
```

Example 23 (r):
```r
# Retrieve or set data in an expression matrix ('counts', 'data', and 'scale.data')
GetAssayData(object = pbmc, slot = "counts")
pbmc <- SetAssayData(object = pbmc, slot = "scale.data", new.data = new.data)
```

Example 24 (unknown):
```unknown
# Get cell embeddings and feature loadings
Embeddings(object = pbmc, reduction = "pca")
Loadings(object = pbmc, reduction = "pca")
Loadings(object = pbmc, reduction = "pca", projected = TRUE)
```

Example 25 (r):
```r
# Get cell embeddings and feature loadings
Embeddings(object = pbmc, reduction = "pca")
Loadings(object = pbmc, reduction = "pca")
Loadings(object = pbmc, reduction = "pca", projected = TRUE)
```

Example 26 (r):
```r
# Get cell embeddings and feature loadings
Embeddings(object = pbmc, reduction = "pca")
Loadings(object = pbmc, reduction = "pca")
Loadings(object = pbmc, reduction = "pca", projected = TRUE)
```

Example 27 (python):
```python
# FetchData can pull anything from expression matrices, cell embeddings, or metadata
FetchData(object = pbmc, vars = c("PC_1", "percent.mito", "MS4A1"))
```

Example 28 (r):
```r
# FetchData can pull anything from expression matrices, cell embeddings, or metadata
FetchData(object = pbmc, vars = c("PC_1", "percent.mito", "MS4A1"))
```

Example 29 (r):
```r
# FetchData can pull anything from expression matrices, cell embeddings, or metadata
FetchData(object = pbmc, vars = c("PC_1", "percent.mito", "MS4A1"))
```

Example 30 (unknown):
```unknown
# Dimensional reduction plot for PCA or tSNE
DimPlot(object = pbmc, reduction = "tsne")
DimPlot(object = pbmc, reduction = "pca")

# Dimensional reduction plot, with cells colored by a quantitative feature
FeaturePlot(object = pbmc, features = "MS4A1")

# Scatter plot across single cells, replaces GenePlot
FeatureScatter(object = pbmc, feature1 = "MS4A1", feature2 = "PC_1")
FeatureScatter(object = pbmc, feature1 = "MS4A1", feature2 = "CD3D")

# Scatter plot across individual features, repleaces CellPlot
CellScatter(object = pbmc, cell1 = "AGTCTACTAGGGTG", cell2 = "CACAGATGGTTTCT")

VariableFeaturePlot(object = pbmc)

# Violin and Ridge plots
VlnPlot(object = pbmc, features = c("LYZ", "CCL5", "IL32"))
RidgePlot(object = pbmc, feature = c("LYZ", "CCL5", "IL32"))

# Heatmaps
DoHeatmap(object = pbmc, features = heatmap_markers)
DimHeatmap(object = pbmc, reduction = "pca", cells = 200)

# New things to try!  Note that plotting functions now return ggplot2 objects, so you can add themes, titles, and
# options onto them
VlnPlot(object = pbmc, features = "MS4A1", split.by = "groups")
DotPlot(object = pbmc, features = c("LYZ", "CCL5", "IL32"), split.by = "groups")
FeaturePlot(object = pbmc, features = c("MS4A1", "CD79A"), blend = TRUE)
DimPlot(object = pbmc) + DarkTheme()
DimPlot(object = pbmc) + labs(title = "2,700 PBMCs clustered using Seurat and viewed\non a two-dimensional tSNE")
```

Example 31 (r):
```r
# Dimensional reduction plot for PCA or tSNE
DimPlot(object = pbmc, reduction = "tsne")
DimPlot(object = pbmc, reduction = "pca")

# Dimensional reduction plot, with cells colored by a quantitative feature
FeaturePlot(object = pbmc, features = "MS4A1")

# Scatter plot across single cells, replaces GenePlot
FeatureScatter(object = pbmc, feature1 = "MS4A1", feature2 = "PC_1")
FeatureScatter(object = pbmc, feature1 = "MS4A1", feature2 = "CD3D")

# Scatter plot across individual features, repleaces CellPlot
CellScatter(object = pbmc, cell1 = "AGTCTACTAGGGTG", cell2 = "CACAGATGGTTTCT")

VariableFeaturePlot(object = pbmc)

# Violin and Ridge plots
VlnPlot(object = pbmc, features = c("LYZ", "CCL5", "IL32"))
RidgePlot(object = pbmc, feature = c("LYZ", "CCL5", "IL32"))

# Heatmaps
DoHeatmap(object = pbmc, features = heatmap_markers)
DimHeatmap(object = pbmc, reduction = "pca", cells = 200)

# New things to try!  Note that plotting functions now return ggplot2 objects, so you can add themes, titles, and
# options onto them
VlnPlot(object = pbmc, features = "MS4A1", split.by = "groups")
DotPlot(object = pbmc, features = c("LYZ", "CCL5", "IL32"), split.by = "groups")
FeaturePlot(object = pbmc, features = c("MS4A1", "CD79A"), blend = TRUE)
DimPlot(object = pbmc) + DarkTheme()
DimPlot(object = pbmc) + labs(title = "2,700 PBMCs clustered using Seurat and viewed\non a two-dimensional tSNE")
```

Example 32 (r):
```r
# Dimensional reduction plot for PCA or tSNE
DimPlot(object = pbmc, reduction = "tsne")
DimPlot(object = pbmc, reduction = "pca")

# Dimensional reduction plot, with cells colored by a quantitative feature
FeaturePlot(object = pbmc, features = "MS4A1")

# Scatter plot across single cells, replaces GenePlot
FeatureScatter(object = pbmc, feature1 = "MS4A1", feature2 = "PC_1")
FeatureScatter(object = pbmc, feature1 = "MS4A1", feature2 = "CD3D")

# Scatter plot across individual features, repleaces CellPlot
CellScatter(object = pbmc, cell1 = "AGTCTACTAGGGTG", cell2 = "CACAGATGGTTTCT")

VariableFeaturePlot(object = pbmc)

# Violin and Ridge plots
VlnPlot(object = pbmc, features = c("LYZ", "CCL5", "IL32"))
RidgePlot(object = pbmc, feature = c("LYZ", "CCL5", "IL32"))

# Heatmaps
DoHeatmap(object = pbmc, features = heatmap_markers)
DimHeatmap(object = pbmc, reduction = "pca", cells = 200)

# New things to try!  Note that plotting functions now return ggplot2 objects, so you can add themes, titles, and
# options onto them
VlnPlot(object = pbmc, features = "MS4A1", split.by = "groups")
DotPlot(object = pbmc, features = c("LYZ", "CCL5", "IL32"), split.by = "groups")
FeaturePlot(object = pbmc, features = c("MS4A1", "CD79A"), blend = TRUE)
DimPlot(object = pbmc) + DarkTheme()
DimPlot(object = pbmc) + labs(title = "2,700 PBMCs clustered using Seurat and viewed\non a two-dimensional tSNE")
```

Example 33 (unknown):
```unknown
RestoreLegend
```

Example 34 (unknown):
```unknown
RotatedAxis
```

Example 35 (unknown):
```unknown
# Plotting helper functions work with ggplot2-based scatter plots, such as DimPlot, FeaturePlot, CellScatter, and
# FeatureScatter
plot <- DimPlot(object = pbmc) + NoLegend()

# HoverLocator replaces the former `do.hover` argument It can also show extra data throught the `information` argument,
# designed to work smoothly with FetchData
HoverLocator(plot = plot, information = FetchData(object = pbmc, vars = c("ident", "PC_1", "nFeature_RNA")))

# FeatureLocator replaces the former `do.identify`
select.cells <- FeatureLocator(plot = plot)

# Label points on a ggplot object
LabelPoints(plot = plot, points = TopCells(object = pbmc[["pca"]]), repel = TRUE)
```

Example 36 (r):
```r
# Plotting helper functions work with ggplot2-based scatter plots, such as DimPlot, FeaturePlot, CellScatter, and
# FeatureScatter
plot <- DimPlot(object = pbmc) + NoLegend()

# HoverLocator replaces the former `do.hover` argument It can also show extra data throught the `information` argument,
# designed to work smoothly with FetchData
HoverLocator(plot = plot, information = FetchData(object = pbmc, vars = c("ident", "PC_1", "nFeature_RNA")))

# FeatureLocator replaces the former `do.identify`
select.cells <- FeatureLocator(plot = plot)

# Label points on a ggplot object
LabelPoints(plot = plot, points = TopCells(object = pbmc[["pca"]]), repel = TRUE)
```

Example 37 (r):
```r
# Plotting helper functions work with ggplot2-based scatter plots, such as DimPlot, FeaturePlot, CellScatter, and
# FeatureScatter
plot <- DimPlot(object = pbmc) + NoLegend()

# HoverLocator replaces the former `do.hover` argument It can also show extra data throught the `information` argument,
# designed to work smoothly with FetchData
HoverLocator(plot = plot, information = FetchData(object = pbmc, vars = c("ident", "PC_1", "nFeature_RNA")))

# FeatureLocator replaces the former `do.identify`
select.cells <- FeatureLocator(plot = plot)

# Label points on a ggplot object
LabelPoints(plot = plot, points = TopCells(object = pbmc[["pca"]]), repel = TRUE)
```

Example 38 (python):
```python
cbmc <- CreateSeuratObject(counts = cbmc.rna)
# Add ADT data
cbmc[["ADT"]] <- CreateAssayObject(counts = cbmc.adt)
# Run analyses by specifying the assay to use
NormalizeData(object = cbmc, assay = "RNA")
NormalizeData(object = cbmc, assay = "ADT", method = "CLR")

# Retrieve and set the default assay
DefaultAssay(object = cbmc)
DefaultAssay(object = cbmc) <- "ADT"
DefaultAssay(object = cbmc)

# Pull feature expression from both assays by using keys
FetchData(object = cbmc, vars = c("rna_CD3E", "adt_CD3"))

# Plot data from multiple assays using keys
FeatureScatter(object = cbmc, feature1 = "rna_CD3E", feature2 = "adt_CD3")
```

Example 39 (r):
```r
cbmc <- CreateSeuratObject(counts = cbmc.rna)
# Add ADT data
cbmc[["ADT"]] <- CreateAssayObject(counts = cbmc.adt)
# Run analyses by specifying the assay to use
NormalizeData(object = cbmc, assay = "RNA")
NormalizeData(object = cbmc, assay = "ADT", method = "CLR")

# Retrieve and set the default assay
DefaultAssay(object = cbmc)
DefaultAssay(object = cbmc) <- "ADT"
DefaultAssay(object = cbmc)

# Pull feature expression from both assays by using keys
FetchData(object = cbmc, vars = c("rna_CD3E", "adt_CD3"))

# Plot data from multiple assays using keys
FeatureScatter(object = cbmc, feature1 = "rna_CD3E", feature2 = "adt_CD3")
```

Example 40 (r):
```r
cbmc <- CreateSeuratObject(counts = cbmc.rna)
# Add ADT data
cbmc[["ADT"]] <- CreateAssayObject(counts = cbmc.adt)
# Run analyses by specifying the assay to use
NormalizeData(object = cbmc, assay = "RNA")
NormalizeData(object = cbmc, assay = "ADT", method = "CLR")

# Retrieve and set the default assay
DefaultAssay(object = cbmc)
DefaultAssay(object = cbmc) <- "ADT"
DefaultAssay(object = cbmc)

# Pull feature expression from both assays by using keys
FetchData(object = cbmc, vars = c("rna_CD3E", "adt_CD3"))

# Plot data from multiple assays using keys
FeatureScatter(object = cbmc, feature1 = "rna_CD3E", feature2 = "adt_CD3")
```

Example 41 (unknown):
```unknown
object@data
```

Example 42 (unknown):
```unknown
GetAssayData(object = object)
```

Example 43 (unknown):
```unknown
object@raw.data
```

Example 44 (unknown):
```unknown
GetAssayData(object = object, slot = "counts")
```

Example 45 (unknown):
```unknown
object@scale.data
```

Example 46 (unknown):
```unknown
GetAssayData(object = object, slot = "scale.data")
```

Example 47 (unknown):
```unknown
object@cell.names
```

Example 48 (unknown):
```unknown
colnames(x = object)
```

Example 49 (unknown):
```unknown
rownames(x = object@data)
```

Example 50 (unknown):
```unknown
rownames(x = object)
```

Example 51 (unknown):
```unknown
object@var.genes
```

Example 52 (unknown):
```unknown
VariableFeatures(object = object)
```

Example 53 (unknown):
```unknown
object@hvg.info
```

Example 54 (unknown):
```unknown
HVFInfo(object = object)
```

Example 55 (unknown):
```unknown
object@assays$assay.name
```

Example 56 (unknown):
```unknown
object[["assay.name"]]
```

Example 57 (unknown):
```unknown
object@dr$pca
```

Example 58 (unknown):
```unknown
object[["pca"]]
```

Example 59 (unknown):
```unknown
GetCellEmbeddings(object = object, reduction.type = "pca")
```

Example 60 (unknown):
```unknown
Embeddings(object = object, reduction = "pca")
```

Example 61 (unknown):
```unknown
GetGeneLoadings(object = object, reduction.type = "pca")
```

Example 62 (unknown):
```unknown
Loadings(object = object, reduction = "pca")
```

Example 63 (python):
```python
AddMetaData(object = object, metadata = vector, col.name = "name")
```

Example 64 (unknown):
```unknown
object$name <- vector
```

Example 65 (unknown):
```unknown
object@meta.data$name
```

Example 66 (unknown):
```unknown
object$name
```

Example 67 (unknown):
```unknown
object@idents
```

Example 68 (unknown):
```unknown
Idents(object = object)
```

Example 69 (unknown):
```unknown
SetIdent(object = object, ident.use = "new.idents")
```

Example 70 (unknown):
```unknown
Idents(object = object) <- "new.idents"
```

Example 71 (unknown):
```unknown
SetIdent(object = object, cells.use = 1:10, ident.use = "new.idents")
```

Example 72 (unknown):
```unknown
Idents(object = object, cells = 1:10) <- "new.idents"
```

Example 73 (unknown):
```unknown
StashIdent(object = object, save.name = "saved.idents")
```

Example 74 (unknown):
```unknown
object$saved.idents <- Idents(object = object)
```

Example 75 (unknown):
```unknown
levels(x = object@idents)
```

Example 76 (unknown):
```unknown
levels(x = object)
```

Example 77 (unknown):
```unknown
RenameIdent(object = object, old.ident.name = "old.ident", new.ident.name = "new.ident")
```

Example 78 (unknown):
```unknown
RenameIdents(object = object, "old.ident" = "new.ident")
```

Example 79 (unknown):
```unknown
WhichCells(object = object, ident = "ident.keep")
```

Example 80 (unknown):
```unknown
WhichCells(object = object, idents = "ident.keep")
```

Example 81 (unknown):
```unknown
WhichCells(object = object, ident.remove = "ident.remove")
```

Example 82 (unknown):
```unknown
WhichCells(object = object, idents = "ident.remove", invert = TRUE)
```

Example 83 (unknown):
```unknown
WhichCells(object = object, max.cells.per.ident = 500)
```

Example 84 (unknown):
```unknown
WhichCells(object = object, downsample = 500)
```

Example 85 (unknown):
```unknown
WhichCells(object = object, subset.name = "name", low.threshold = low, high.threshold = high)
```

Example 86 (unknown):
```unknown
WhichCells(object = object, expression = name > low & name < high)
```

Example 87 (unknown):
```unknown
FilterCells(object = object, subset.names = "name", low.threshold = low, high.threshold = high)
```

Example 88 (unknown):
```unknown
subset(x = object, subset = name > low & name < high)
```

Example 89 (unknown):
```unknown
SubsetData(object = object, subset.name = "name", low.threshold = low, high.threshold = high)
```

Example 90 (unknown):
```unknown
subset(x = object, subset = name > low & name < high)
```

Example 91 (unknown):
```unknown
MergeSeurat(object1 = object1, object2 = object2)
```

Example 92 (unknown):
```unknown
merge(x = object1, y = object2)
```

Example 93 (unknown):
```unknown
sessionInfo()
```

Example 94 (r):
```r
sessionInfo()
```

Example 95 (r):
```r
sessionInfo()
```

---

## Seurat - Guided Clustering Tutorial

**URL:** http://127.0.0.1:9173/seurat/archive/v2.4/pbmc3k_tutorial/index.html

**Contents:**
- Seurat - Guided Clustering Tutorial
    - Compiled: March 22, 2018
  - Setup the Seurat Object
  - Standard pre-processing workflow
  - QC and selecting cells for further analysis
  - Normalizing the data
  - Detection of variable genes across the single cells
  - Scaling the data and removing unwanted sources of variation
  - Perform linear dimensional reduction
  - Determine statistically significant principal components
  - Cluster the cells
  - Run Non-linear dimensional reduction (tSNE)
  - Finding differentially expressed genes (cluster biomarkers)
  - Assigning cell type identity to clusters
  - Further subdivisions within cell types

For this tutorial, we will be analyzing the a dataset of Peripheral Blood Mononuclear Cells (PBMC) freely available from 10X Genomics. There are 2,700 single cells that were sequenced on the Illumina NextSeq 500. The raw data can be found here.

We start by reading in the data. All features in Seurat have been configured to work with sparse matrices which results in significant memory and speed savings for Drop-seq/inDrop/10x data.

The steps below encompass the standard pre-processing workflow for scRNA-seq data in Seurat. These represent the creation of a Seurat object, the selection and filtration of cells based on QC metrics, data normalization and scaling, and the detection of highly variable genes. In previous versions, we grouped many of these steps together in the Setup function, but in v2, we separate these steps into a clear and sequential workflow.

While the CreateSeuratObject imposes a basic minimum gene-cutoff, you may want to filter out cells at this stage based on technical or biological parameters. Seurat allows you to easily explore QC metrics and filter cells based on any user-defined criteria. In the example below, we visualize gene and molecule counts, plot their relationship, and exclude cells with a clear outlier number of genes detected as potential multiplets. Of course this is not a guaranteed method to exclude cell doublets, but we include this as an example of filtering user-defined outlier cells. We also filter cells based on the percentage of mitochondrial genes present.

After removing unwanted cells from the dataset, the next step is to normalize the data. By default, we employ a global-scaling normalization method “LogNormalize” that normalizes the gene expression measurements for each cell by the total expression, multiplies this by a scale factor (10,000 by default), and log-transforms the result.

Seurat calculates highly variable genes and focuses on these for downstream analysis. FindVariableGenes calculates the average expression and dispersion for each gene, places these genes into bins, and then calculates a z-score for dispersion within each bin. This helps control for the relationship between variability and average expression. This function is unchanged from (Macosko et al.), but new methods for variable gene expression identification are coming soon. We suggest that users set these parameters to mark visual outliers on the dispersion plot, but the exact parameter settings may vary based on the data type, heterogeneity in the sample, and normalization strategy. The parameters here identify ~2,000 variable genes, and represent typical parameter settings for UMI data that is normalized to a total of 1e4 molecules.

Your single cell dataset likely contains ‘uninteresting’ sources of variation. This could include not only technical noise, but batch effects, or even biological sources of variation (cell cycle stage). As suggested in Buettner et al, NBT, 2015, regressing these signals out of the analysis can improve downstream dimensionality reduction and clustering. To mitigate the effect of these signals, Seurat constructs linear models to predict gene expression based on user-defined variables. The scaled z-scored residuals of these models are stored in the scale.data slot, and are used for dimensionality reduction and clustering.

We can regress out cell-cell variation in gene expression driven by batch (if applicable), cell alignment rate (as provided by Drop-seq tools for Drop-seq data), the number of detected molecules, and mitochondrial gene expression. For cycling cells, we can also learn a ‘cell-cycle’ score (see example here) and regress this out as well. In this simple example here for post-mitotic blood cells, we regress on the number of detected molecules per cell as well as the percentage mitochondrial gene content.

Seurat v2.0 implements this regression as part of the data scaling process. Therefore, the RegressOut function has been deprecated, and replaced with the vars.to.regress argument in ScaleData.

Next we perform PCA on the scaled data. By default, the genes in object@var.genes are used as input, but can be defined using pc.genes. We have typically found that running dimensionality reduction on highly variable genes can improve performance. However, with UMI data - particularly after regressing out technical variables, we often see that PCA returns similar (albeit slower) results when run on much larger subsets of genes, including the whole transcriptome.

Seurat provides several useful ways of visualizing both cells and genes that define the PCA, including PrintPCA, VizPCA, PCAPlot, and PCHeatmap

In particular PCHeatmap allows for easy exploration of the primary sources of heterogeneity in a dataset, and can be useful when trying to decide which PCs to include for further downstream analyses. Both cells and genes are ordered according to their PCA scores. Setting cells.use to a number plots the ‘extreme’ cells on both ends of the spectrum, which dramatically speeds plotting for large datasets. Though clearly a supervised analysis, we find this to be a valuable tool for exploring correlated gene sets.

To overcome the extensive technical noise in any single gene for scRNA-seq data, Seurat clusters cells based on their PCA scores, with each PC essentially representing a ‘metagene’ that combines information across a correlated gene set. Determining how many PCs to include downstream is therefore an important step.

In Macosko et al, we implemented a resampling test inspired by the jackStraw procedure. We randomly permute a subset of the data (1% by default) and rerun PCA, constructing a ‘null distribution’ of gene scores, and repeat this procedure. We identify ‘significant’ PCs as those who have a strong enrichment of low p-value genes.

The JackStrawPlot function provides a visualization tool for comparing the distribution of p-values for each PC with a uniform distribution (dashed line). ‘Significant’ PCs will show a strong enrichment of genes with low p-values (solid curve above the dashed line). In this case it appears that PCs 1-10 are significant.

A more ad hoc method for determining which PCs to use is to look at a plot of the standard deviations of the principle components and draw your cutoff where there is a clear elbow in the graph. This can be done with PCElbowPlot. In this example, it looks like the elbow would fall around PC 9.

PC selection – identifying the true dimensionality of a dataset – is an important step for Seurat, but can be challenging/uncertain for the user. We therefore suggest these three approaches to consider. The first is more supervised, exploring PCs to determine relevant sources of heterogeneity, and could be used in conjunction with GSEA for example. The second implements a statistical test based on a random null model, but is time-consuming for large datasets, and may not return a clear PC cutoff. The third is a heuristic that is commonly used, and can be calculated instantly. In this example, all three approaches yielded similar results, but we might have been justified in choosing anything between PC 7-10 as a cutoff. We followed the jackStraw here, admittedly buoyed by seeing the PCHeatmap returning interpretable signals (including canonical dendritic cell markers) throughout these PCs. Though the results are only subtly affected by small shifts in this cutoff (you can test below), we strongly suggest always explore the PCs they choose to include downstream.

Seurat now includes an graph-based clustering approach compared to (Macosko et al.). Importantly, the distance metric which drives the clustering analysis (based on previously identified PCs) remains the same. However, our approach to partioning the cellular distance matrix into clusters has dramatically improved. Our approach was heavily inspired by recent manuscripts which applied graph-based clustering approaches to scRNA-seq data [SNN-Cliq, Xu and Su, Bioinformatics, 2015] and CyTOF data [PhenoGraph, Levine et al., Cell, 2015]. Briefly, these methods embed cells in a graph structure - for example a K-nearest neighbor (KNN) graph, with edges drawn between cells with similar gene expression patterns, and then attempt to partition this graph into highly interconnected ‘quasi-cliques’ or ‘communities’. As in PhenoGraph, we first construct a KNN graph based on the euclidean distance in PCA space, and refine the edge weights between any two cells based on the shared overlap in their local neighborhoods (Jaccard similarity). To cluster the cells, we apply modularity optimization techniques such as the Louvain algorithm (default) or SLM [SLM, Blondel et al., Journal of Statistical Mechanics], to iteratively group cells together, with the goal of optimizing the standard modularity function.

The FindClusters function implements the procedure, and contains a resolution parameter that sets the ‘granularity’ of the downstream clustering, with increased values leading to a greater number of clusters. We find that setting this parameter between 0.6-1.2 typically returns good results for single cell datasets of around 3K cells. Optimal resolution often increases for larger datasets. The clusters are saved in the object@ident slot.

A useful feature in Seurat v2.0 is the ability to recall the parameters that were used in the latest function calls for commonly used functions. For FindClusters, we provide the function PrintFindClustersParams to print a nicely formatted formatted summary of the parameters that were chosen.

Seurat continues to use tSNE as a powerful tool to visualize and explore these datasets. While we no longer advise clustering directly on tSNE components, cells within the graph-based clusters determined above should co-localize on the tSNE plot. This is because the tSNE aims to place cells with similar local neighborhoods in high-dimensional space together in low-dimensional space. As input to the tSNE, we suggest using the same PCs as input to the clustering analysis, although computing the tSNE based on scaled gene expression is also supported using the genes.use argument.

You can save the object at this point so that it can easily be loaded back in without having to rerun the computationally intensive steps performed above, or easily shared with collaborators.

Seurat can help you find markers that define clusters via differential expression. By default, it identifes positive and negative markers of a single cluster (specified in ident.1), compared to all other cells. FindAllMarkers automates this process for all clusters, but you can also test groups of clusters vs. each other, or against all cells.

The min.pct argument requires a gene to be detected at a minimum percentage in either of the two groups of cells, and the thresh.test argument requires a gene to be differentially expressed (on average) by some amount between the two groups. You can set both of these to 0, but with a dramatic increase in time - since this will test a large number of genes that are unlikely to be highly discriminatory. As another option to speed up these computations, max.cells.per.ident can be set. This will downsample each identity class to have no more cells than whatever this is set to. While there is generally going to be a loss in power, the speed increases can be significiant and the most highly differentially expressed genes will likely still rise to the top.

Seurat has several tests for differential expression which can be set with the test.use parameter (see our DE vignette for details). For example, the ROC test returns the ‘classification power’ for any individual marker (ranging from 0 - random, to 1 - perfect).

We include several tools for visualizing marker expression. VlnPlot (shows expression probability distributions across clusters), and FeaturePlot (visualizes gene expression on a tSNE or PCA plot) are our most commonly used visualizations. We also suggest exploring RidgePlot, CellPlot, and DotPlot as additional methods to view your dataset.

DoHeatmap generates an expression heatmap for given cells and genes. In this case, we are plotting the top 10 markers (or all markers if less than 10) for each cluster.

Fortunately in the case of this dataset, we can use canonical markers to easily match the unbiased clustering to known cell types:

If you perturb some of our parameter choices above (for example, setting resolution=0.8 or changing the number of PCs), you might see the CD4 T cells subdivide into two groups. You can explore this subdivision to find markers separating the two T cell subsets. However, before reclustering (which will overwrite object@ident), we can stash our renamed identities to be easily recovered later.

The memory/naive split is bit weak, and we would probably benefit from looking at more cells to see if this becomes more convincing. In the meantime, we can restore our old cluster identities for downstream processing.

**Examples:**

Example 1 (r):
```r
library(Seurat)
library(dplyr)

# Load the PBMC dataset
pbmc.data <- Read10X(data.dir = "~/Downloads/filtered_gene_bc_matrices/hg19/")

# Examine the memory savings between regular and sparse matrices
dense.size <- object.size(x = as.matrix(x = pbmc.data))
dense.size
```

Example 2 (r):
```r
library(Seurat)
library(dplyr)

# Load the PBMC dataset
pbmc.data <- Read10X(data.dir = "~/Downloads/filtered_gene_bc_matrices/hg19/")

# Examine the memory savings between regular and sparse matrices
dense.size <- object.size(x = as.matrix(x = pbmc.data))
dense.size
```

Example 3 (unknown):
```unknown
## 709264728 bytes
```

Example 4 (unknown):
```unknown
## 709264728 bytes
```

Example 5 (r):
```r
sparse.size <- object.size(x = pbmc.data)
sparse.size
```

Example 6 (r):
```r
sparse.size <- object.size(x = pbmc.data)
sparse.size
```

Example 7 (unknown):
```unknown
## 38715120 bytes
```

Example 8 (unknown):
```unknown
## 38715120 bytes
```

Example 9 (r):
```r
dense.size/sparse.size
```

Example 10 (r):
```r
dense.size/sparse.size
```

Example 11 (unknown):
```unknown
## 18.3 bytes
```

Example 12 (unknown):
```unknown
## 18.3 bytes
```

Example 13 (r):
```r
# Initialize the Seurat object with the raw (non-normalized data).  Keep all
# genes expressed in >= 3 cells (~0.1% of the data). Keep all cells with at
# least 200 detected genes
pbmc <- CreateSeuratObject(raw.data = pbmc.data, min.cells = 3, min.genes = 200, 
    project = "10X_PBMC")
```

Example 14 (r):
```r
# Initialize the Seurat object with the raw (non-normalized data).  Keep all
# genes expressed in >= 3 cells (~0.1% of the data). Keep all cells with at
# least 200 detected genes
pbmc <- CreateSeuratObject(raw.data = pbmc.data, min.cells = 3, min.genes = 200, 
    project = "10X_PBMC")
```

Example 15 (unknown):
```unknown
CreateSeuratObject
```

Example 16 (r):
```r
# The number of genes and UMIs (nGene and nUMI) are automatically calculated
# for every object by Seurat.  For non-UMI data, nUMI represents the sum of
# the non-normalized values within a cell We calculate the percentage of
# mitochondrial genes here and store it in percent.mito using AddMetaData.
# We use object@raw.data since this represents non-transformed and
# non-log-normalized counts The % of UMI mapping to MT-genes is a common
# scRNA-seq QC metric.
mito.genes <- grep(pattern = "^MT-", x = rownames(x = pbmc@data), value = TRUE)
percent.mito <- Matrix::colSums(pbmc@raw.data[mito.genes, ])/Matrix::colSums(pbmc@raw.data)

# AddMetaData adds columns to object@meta.data, and is a great place to
# stash QC stats
pbmc <- AddMetaData(object = pbmc, metadata = percent.mito, col.name = "percent.mito")
VlnPlot(object = pbmc, features.plot = c("nGene", "nUMI", "percent.mito"), nCol = 3)
```

Example 17 (r):
```r
# The number of genes and UMIs (nGene and nUMI) are automatically calculated
# for every object by Seurat.  For non-UMI data, nUMI represents the sum of
# the non-normalized values within a cell We calculate the percentage of
# mitochondrial genes here and store it in percent.mito using AddMetaData.
# We use object@raw.data since this represents non-transformed and
# non-log-normalized counts The % of UMI mapping to MT-genes is a common
# scRNA-seq QC metric.
mito.genes <- grep(pattern = "^MT-", x = rownames(x = pbmc@data), value = TRUE)
percent.mito <- Matrix::colSums(pbmc@raw.data[mito.genes, ])/Matrix::colSums(pbmc@raw.data)

# AddMetaData adds columns to object@meta.data, and is a great place to
# stash QC stats
pbmc <- AddMetaData(object = pbmc, metadata = percent.mito, col.name = "percent.mito")
VlnPlot(object = pbmc, features.plot = c("nGene", "nUMI", "percent.mito"), nCol = 3)
```

Example 18 (r):
```r
# GenePlot is typically used to visualize gene-gene relationships, but can
# be used for anything calculated by the object, i.e. columns in
# object@meta.data, PC scores etc.  Since there is a rare subset of cells
# with an outlier level of high mitochondrial percentage and also low UMI
# content, we filter these as well
par(mfrow = c(1, 2))
GenePlot(object = pbmc, gene1 = "nUMI", gene2 = "percent.mito")
GenePlot(object = pbmc, gene1 = "nUMI", gene2 = "nGene")
```

Example 19 (r):
```r
# GenePlot is typically used to visualize gene-gene relationships, but can
# be used for anything calculated by the object, i.e. columns in
# object@meta.data, PC scores etc.  Since there is a rare subset of cells
# with an outlier level of high mitochondrial percentage and also low UMI
# content, we filter these as well
par(mfrow = c(1, 2))
GenePlot(object = pbmc, gene1 = "nUMI", gene2 = "percent.mito")
GenePlot(object = pbmc, gene1 = "nUMI", gene2 = "nGene")
```

Example 20 (r):
```r
# We filter out cells that have unique gene counts over 2,500 or less than
# 200 Note that low.thresholds and high.thresholds are used to define a
# 'gate'.  -Inf and Inf should be used if you don't want a lower or upper
# threshold.
pbmc <- FilterCells(object = pbmc, subset.names = c("nGene", "percent.mito"), 
    low.thresholds = c(200, -Inf), high.thresholds = c(2500, 0.05))
```

Example 21 (r):
```r
# We filter out cells that have unique gene counts over 2,500 or less than
# 200 Note that low.thresholds and high.thresholds are used to define a
# 'gate'.  -Inf and Inf should be used if you don't want a lower or upper
# threshold.
pbmc <- FilterCells(object = pbmc, subset.names = c("nGene", "percent.mito"), 
    low.thresholds = c(200, -Inf), high.thresholds = c(2500, 0.05))
```

Example 22 (r):
```r
pbmc <- NormalizeData(object = pbmc, normalization.method = "LogNormalize", 
    scale.factor = 10000)
```

Example 23 (r):
```r
pbmc <- NormalizeData(object = pbmc, normalization.method = "LogNormalize", 
    scale.factor = 10000)
```

Example 24 (unknown):
```unknown
FindVariableGenes
```

Example 25 (r):
```r
pbmc <- FindVariableGenes(object = pbmc, mean.function = ExpMean, dispersion.function = LogVMR, 
    x.low.cutoff = 0.0125, x.high.cutoff = 3, y.cutoff = 0.5)
```

Example 26 (r):
```r
pbmc <- FindVariableGenes(object = pbmc, mean.function = ExpMean, dispersion.function = LogVMR, 
    x.low.cutoff = 0.0125, x.high.cutoff = 3, y.cutoff = 0.5)
```

Example 27 (r):
```r
length(x = pbmc@var.genes)
```

Example 28 (r):
```r
length(x = pbmc@var.genes)
```

Example 29 (unknown):
```unknown
## [1] 1838
```

Example 30 (unknown):
```unknown
## [1] 1838
```

Example 31 (r):
```r
pbmc <- ScaleData(object = pbmc, vars.to.regress = c("nUMI", "percent.mito"))
```

Example 32 (r):
```r
pbmc <- ScaleData(object = pbmc, vars.to.regress = c("nUMI", "percent.mito"))
```

Example 33 (unknown):
```unknown
object@var.genes
```

Example 34 (r):
```r
pbmc <- RunPCA(object = pbmc, pc.genes = pbmc@var.genes, do.print = TRUE, pcs.print = 1:5, 
    genes.print = 5)
```

Example 35 (r):
```r
pbmc <- RunPCA(object = pbmc, pc.genes = pbmc@var.genes, do.print = TRUE, pcs.print = 1:5, 
    genes.print = 5)
```

Example 36 (unknown):
```unknown
## [1] "PC1"
## [1] "CST3"   "TYROBP" "FCN1"   "LST1"   "AIF1"  
## [1] ""
## [1] "PTPRCAP" "IL32"    "LTB"     "CD2"     "CTSW"   
## [1] ""
## [1] ""
## [1] "PC2"
## [1] "CD79A"    "MS4A1"    "HLA-DQA1" "TCL1A"    "HLA-DQB1"
## [1] ""
## [1] "NKG7" "GZMB" "PRF1" "CST7" "GZMA"
## [1] ""
## [1] ""
## [1] "PC3"
## [1] "CYBA"     "HLA-DPA1" "HLA-DPB1" "HLA-DRB1" "CD37"    
## [1] ""
## [1] "PF4"   "PPBP"  "SDPR"  "SPARC" "GNG11"
## [1] ""
## [1] ""
## [1] "PC4"
## [1] "CD79A"    "HLA-DQA1" "CD79B"    "MS4A1"    "HLA-DQB1"
## [1] ""
## [1] "IL32"   "GIMAP7" "AQP3"   "FYB"    "MAL"   
## [1] ""
## [1] ""
## [1] "PC5"
## [1] "FCGR3A"        "CTD-2006K23.1" "IFITM3"        "ABI3"         
## [5] "CEBPB"        
## [1] ""
## [1] "FCER1A"  "LGALS2"  "MS4A6A"  "S100A8"  "CLEC10A"
## [1] ""
## [1] ""
```

Example 37 (unknown):
```unknown
## [1] "PC1"
## [1] "CST3"   "TYROBP" "FCN1"   "LST1"   "AIF1"  
## [1] ""
## [1] "PTPRCAP" "IL32"    "LTB"     "CD2"     "CTSW"   
## [1] ""
## [1] ""
## [1] "PC2"
## [1] "CD79A"    "MS4A1"    "HLA-DQA1" "TCL1A"    "HLA-DQB1"
## [1] ""
## [1] "NKG7" "GZMB" "PRF1" "CST7" "GZMA"
## [1] ""
## [1] ""
## [1] "PC3"
## [1] "CYBA"     "HLA-DPA1" "HLA-DPB1" "HLA-DRB1" "CD37"    
## [1] ""
## [1] "PF4"   "PPBP"  "SDPR"  "SPARC" "GNG11"
## [1] ""
## [1] ""
## [1] "PC4"
## [1] "CD79A"    "HLA-DQA1" "CD79B"    "MS4A1"    "HLA-DQB1"
## [1] ""
## [1] "IL32"   "GIMAP7" "AQP3"   "FYB"    "MAL"   
## [1] ""
## [1] ""
## [1] "PC5"
## [1] "FCGR3A"        "CTD-2006K23.1" "IFITM3"        "ABI3"         
## [5] "CEBPB"        
## [1] ""
## [1] "FCER1A"  "LGALS2"  "MS4A6A"  "S100A8"  "CLEC10A"
## [1] ""
## [1] ""
```

Example 38 (r):
```r
# Examine and visualize PCA results a few different ways
PrintPCA(object = pbmc, pcs.print = 1:5, genes.print = 5, use.full = FALSE)
```

Example 39 (r):
```r
# Examine and visualize PCA results a few different ways
PrintPCA(object = pbmc, pcs.print = 1:5, genes.print = 5, use.full = FALSE)
```

Example 40 (unknown):
```unknown
## [1] "PC1"
## [1] "CST3"   "TYROBP" "FCN1"   "LST1"   "AIF1"  
## [1] ""
## [1] "PTPRCAP" "IL32"    "LTB"     "CD2"     "CTSW"   
## [1] ""
## [1] ""
## [1] "PC2"
## [1] "CD79A"    "MS4A1"    "HLA-DQA1" "TCL1A"    "HLA-DQB1"
## [1] ""
## [1] "NKG7" "GZMB" "PRF1" "CST7" "GZMA"
## [1] ""
## [1] ""
## [1] "PC3"
## [1] "CYBA"     "HLA-DPA1" "HLA-DPB1" "HLA-DRB1" "CD37"    
## [1] ""
## [1] "PF4"   "PPBP"  "SDPR"  "SPARC" "GNG11"
## [1] ""
## [1] ""
## [1] "PC4"
## [1] "CD79A"    "HLA-DQA1" "CD79B"    "MS4A1"    "HLA-DQB1"
## [1] ""
## [1] "IL32"   "GIMAP7" "AQP3"   "FYB"    "MAL"   
## [1] ""
## [1] ""
## [1] "PC5"
## [1] "FCGR3A"        "CTD-2006K23.1" "IFITM3"        "ABI3"         
## [5] "CEBPB"        
## [1] ""
## [1] "FCER1A"  "LGALS2"  "MS4A6A"  "S100A8"  "CLEC10A"
## [1] ""
## [1] ""
```

Example 41 (unknown):
```unknown
## [1] "PC1"
## [1] "CST3"   "TYROBP" "FCN1"   "LST1"   "AIF1"  
## [1] ""
## [1] "PTPRCAP" "IL32"    "LTB"     "CD2"     "CTSW"   
## [1] ""
## [1] ""
## [1] "PC2"
## [1] "CD79A"    "MS4A1"    "HLA-DQA1" "TCL1A"    "HLA-DQB1"
## [1] ""
## [1] "NKG7" "GZMB" "PRF1" "CST7" "GZMA"
## [1] ""
## [1] ""
## [1] "PC3"
## [1] "CYBA"     "HLA-DPA1" "HLA-DPB1" "HLA-DRB1" "CD37"    
## [1] ""
## [1] "PF4"   "PPBP"  "SDPR"  "SPARC" "GNG11"
## [1] ""
## [1] ""
## [1] "PC4"
## [1] "CD79A"    "HLA-DQA1" "CD79B"    "MS4A1"    "HLA-DQB1"
## [1] ""
## [1] "IL32"   "GIMAP7" "AQP3"   "FYB"    "MAL"   
## [1] ""
## [1] ""
## [1] "PC5"
## [1] "FCGR3A"        "CTD-2006K23.1" "IFITM3"        "ABI3"         
## [5] "CEBPB"        
## [1] ""
## [1] "FCER1A"  "LGALS2"  "MS4A6A"  "S100A8"  "CLEC10A"
## [1] ""
## [1] ""
```

Example 42 (r):
```r
VizPCA(object = pbmc, pcs.use = 1:2)
```

Example 43 (r):
```r
VizPCA(object = pbmc, pcs.use = 1:2)
```

Example 44 (r):
```r
PCAPlot(object = pbmc, dim.1 = 1, dim.2 = 2)
```

Example 45 (r):
```r
PCAPlot(object = pbmc, dim.1 = 1, dim.2 = 2)
```

Example 46 (r):
```r
# ProjectPCA scores each gene in the dataset (including genes not included
# in the PCA) based on their correlation with the calculated components.
# Though we don't use this further here, it can be used to identify markers
# that are strongly correlated with cellular heterogeneity, but may not have
# passed through variable gene selection.  The results of the projected PCA
# can be explored by setting use.full=T in the functions above
pbmc <- ProjectPCA(object = pbmc, do.print = FALSE)
```

Example 47 (r):
```r
# ProjectPCA scores each gene in the dataset (including genes not included
# in the PCA) based on their correlation with the calculated components.
# Though we don't use this further here, it can be used to identify markers
# that are strongly correlated with cellular heterogeneity, but may not have
# passed through variable gene selection.  The results of the projected PCA
# can be explored by setting use.full=T in the functions above
pbmc <- ProjectPCA(object = pbmc, do.print = FALSE)
```

Example 48 (r):
```r
PCHeatmap(object = pbmc, pc.use = 1, cells.use = 500, do.balanced = TRUE, label.columns = FALSE)
```

Example 49 (r):
```r
PCHeatmap(object = pbmc, pc.use = 1, cells.use = 500, do.balanced = TRUE, label.columns = FALSE)
```

Example 50 (r):
```r
PCHeatmap(object = pbmc, pc.use = 1:12, cells.use = 500, do.balanced = TRUE, 
    label.columns = FALSE, use.full = FALSE)
```

Example 51 (r):
```r
PCHeatmap(object = pbmc, pc.use = 1:12, cells.use = 500, do.balanced = TRUE, 
    label.columns = FALSE, use.full = FALSE)
```

Example 52 (r):
```r
# NOTE: This process can take a long time for big datasets, comment out for
# expediency.  More approximate techniques such as those implemented in
# PCElbowPlot() can be used to reduce computation time
pbmc <- JackStraw(object = pbmc, num.replicate = 100, display.progress = FALSE)
```

Example 53 (r):
```r
# NOTE: This process can take a long time for big datasets, comment out for
# expediency.  More approximate techniques such as those implemented in
# PCElbowPlot() can be used to reduce computation time
pbmc <- JackStraw(object = pbmc, num.replicate = 100, display.progress = FALSE)
```

Example 54 (unknown):
```unknown
JackStrawPlot
```

Example 55 (r):
```r
JackStrawPlot(object = pbmc, PCs = 1:12)
```

Example 56 (r):
```r
JackStrawPlot(object = pbmc, PCs = 1:12)
```

Example 57 (unknown):
```unknown
PCElbowPlot
```

Example 58 (r):
```r
PCElbowPlot(object = pbmc)
```

Example 59 (r):
```r
PCElbowPlot(object = pbmc)
```

Example 60 (unknown):
```unknown
FindClusters
```

Example 61 (unknown):
```unknown
object@ident
```

Example 62 (r):
```r
# save.SNN = T saves the SNN so that the clustering algorithm can be rerun
# using the same graph but with a different resolution value (see docs for
# full details)
pbmc <- FindClusters(object = pbmc, reduction.type = "pca", dims.use = 1:10, 
    resolution = 0.6, print.output = 0, save.SNN = TRUE)
```

Example 63 (r):
```r
# save.SNN = T saves the SNN so that the clustering algorithm can be rerun
# using the same graph but with a different resolution value (see docs for
# full details)
pbmc <- FindClusters(object = pbmc, reduction.type = "pca", dims.use = 1:10, 
    resolution = 0.6, print.output = 0, save.SNN = TRUE)
```

Example 64 (unknown):
```unknown
PrintFindClustersParams
```

Example 65 (r):
```r
PrintFindClustersParams(object = pbmc)
```

Example 66 (r):
```r
PrintFindClustersParams(object = pbmc)
```

Example 67 (unknown):
```unknown
## Parameters used in latest FindClusters calculation run on: 2018-03-22 20:02:17
## =============================================================================
## Resolution: 0.6
## -----------------------------------------------------------------------------
## Modularity Function    Algorithm         n.start         n.iter
##      1                   1                 100             10
## -----------------------------------------------------------------------------
## Reduction used          k.param          prune.SNN
##      pca                 30                0.0667
## -----------------------------------------------------------------------------
## Dims used in calculation
## =============================================================================
## 1 2 3 4 5 6 7 8 9 10
```

Example 68 (unknown):
```unknown
## Parameters used in latest FindClusters calculation run on: 2018-03-22 20:02:17
## =============================================================================
## Resolution: 0.6
## -----------------------------------------------------------------------------
## Modularity Function    Algorithm         n.start         n.iter
##      1                   1                 100             10
## -----------------------------------------------------------------------------
## Reduction used          k.param          prune.SNN
##      pca                 30                0.0667
## -----------------------------------------------------------------------------
## Dims used in calculation
## =============================================================================
## 1 2 3 4 5 6 7 8 9 10
```

Example 69 (r):
```r
# While we do provide function-specific printing functions, the more general
# function to print calculation parameters is PrintCalcParams().
```

Example 70 (r):
```r
# While we do provide function-specific printing functions, the more general
# function to print calculation parameters is PrintCalcParams().
```

Example 71 (r):
```r
pbmc <- RunTSNE(object = pbmc, dims.use = 1:10, do.fast = TRUE)
```

Example 72 (r):
```r
pbmc <- RunTSNE(object = pbmc, dims.use = 1:10, do.fast = TRUE)
```

Example 73 (r):
```r
# note that you can set do.label=T to help label individual clusters
TSNEPlot(object = pbmc)
```

Example 74 (r):
```r
# note that you can set do.label=T to help label individual clusters
TSNEPlot(object = pbmc)
```

Example 75 (r):
```r
saveRDS(pbmc, file = "~/Projects/datasets/pbmc3k/pbmc_tutorial.rds")
```

Example 76 (r):
```r
saveRDS(pbmc, file = "~/Projects/datasets/pbmc3k/pbmc_tutorial.rds")
```

Example 77 (unknown):
```unknown
FindAllMarkers
```

Example 78 (unknown):
```unknown
max.cells.per.ident
```

Example 79 (r):
```r
# find all markers of cluster 1
cluster1.markers <- FindMarkers(object = pbmc, ident.1 = 1, min.pct = 0.25)
print(x = head(x = cluster1.markers, n = 5))
```

Example 80 (r):
```r
# find all markers of cluster 1
cluster1.markers <- FindMarkers(object = pbmc, ident.1 = 1, min.pct = 0.25)
print(x = head(x = cluster1.markers, n = 5))
```

Example 81 (unknown):
```unknown
##               p_val avg_logFC pct.1 pct.2     p_val_adj
## S100A9  0.00000e+00  3.830954 0.996 0.216  0.000000e+00
## S100A8  0.00000e+00  3.786963 0.973 0.122  0.000000e+00
## LGALS2  0.00000e+00  2.639056 0.908 0.060  0.000000e+00
## FCN1    0.00000e+00  2.367232 0.954 0.151  0.000000e+00
## CD14   5.05283e-289  1.947447 0.662 0.029 6.929451e-285
```

Example 82 (unknown):
```unknown
##               p_val avg_logFC pct.1 pct.2     p_val_adj
## S100A9  0.00000e+00  3.830954 0.996 0.216  0.000000e+00
## S100A8  0.00000e+00  3.786963 0.973 0.122  0.000000e+00
## LGALS2  0.00000e+00  2.639056 0.908 0.060  0.000000e+00
## FCN1    0.00000e+00  2.367232 0.954 0.151  0.000000e+00
## CD14   5.05283e-289  1.947447 0.662 0.029 6.929451e-285
```

Example 83 (r):
```r
# find all markers distinguishing cluster 5 from clusters 0 and 3
cluster5.markers <- FindMarkers(object = pbmc, ident.1 = 5, ident.2 = c(0, 3), 
    min.pct = 0.25)
print(x = head(x = cluster5.markers, n = 5))
```

Example 84 (r):
```r
# find all markers distinguishing cluster 5 from clusters 0 and 3
cluster5.markers <- FindMarkers(object = pbmc, ident.1 = 5, ident.2 = c(0, 3), 
    min.pct = 0.25)
print(x = head(x = cluster5.markers, n = 5))
```

Example 85 (unknown):
```unknown
##                p_val avg_logFC pct.1 pct.2     p_val_adj
## GZMB   2.280513e-190  3.195731 0.955 0.084 3.127496e-186
## IGFBP7 1.859718e-155  2.175973 0.542 0.010 2.550417e-151
## GNLY   5.014639e-155  3.515681 0.961 0.143 6.877075e-151
## FGFBP2 5.082837e-150  2.558487 0.852 0.086 6.970603e-146
## SPON2  4.814899e-141  2.191047 0.716 0.053 6.603153e-137
```

Example 86 (unknown):
```unknown
##                p_val avg_logFC pct.1 pct.2     p_val_adj
## GZMB   2.280513e-190  3.195731 0.955 0.084 3.127496e-186
## IGFBP7 1.859718e-155  2.175973 0.542 0.010 2.550417e-151
## GNLY   5.014639e-155  3.515681 0.961 0.143 6.877075e-151
## FGFBP2 5.082837e-150  2.558487 0.852 0.086 6.970603e-146
## SPON2  4.814899e-141  2.191047 0.716 0.053 6.603153e-137
```

Example 87 (r):
```r
# find markers for every cluster compared to all remaining cells, report
# only the positive ones
pbmc.markers <- FindAllMarkers(object = pbmc, only.pos = TRUE, min.pct = 0.25, 
    thresh.use = 0.25)
pbmc.markers %>% group_by(cluster) %>% top_n(2, avg_logFC)
```

Example 88 (r):
```r
# find markers for every cluster compared to all remaining cells, report
# only the positive ones
pbmc.markers <- FindAllMarkers(object = pbmc, only.pos = TRUE, min.pct = 0.25, 
    thresh.use = 0.25)
pbmc.markers %>% group_by(cluster) %>% top_n(2, avg_logFC)
```

Example 89 (unknown):
```unknown
## # A tibble: 16 x 7
## # Groups:   cluster [8]
##                p_val avg_logFC pct.1  pct.2        p_val_adj cluster gene 
##                <dbl>     <dbl> <dbl>  <dbl>            <dbl> <fct>   <chr>
##  1         1.47e⁻²³⁴      1.15 0.924 0.482         2.01e⁻²³⁰ 0       LDHB 
##  2         3.09e⁻¹²⁹      1.07 0.662 0.202         4.24e⁻¹²⁵ 0       IL7R 
##  3         0              3.83 0.996 0.216         0         1       S100…
##  4         0              3.79 0.973 0.122         0         1       S100…
##  5         0              2.98 0.936 0.0420        0         2       CD79A
##  6         1.06e⁻²⁶⁹      2.49 0.623 0.0220        1.45e⁻²⁶⁵ 2       TCL1A
##  7         8.03e⁻²⁰⁷      2.16 0.974 0.230         1.10e⁻²⁰² 3       CCL5 
##  8         1.12e⁻¹⁸¹      2.11 0.588 0.0500        1.53e⁻¹⁷⁷ 3       GZMK 
##  9         1.04e⁻¹⁷²      2.28 0.962 0.137         1.42e⁻¹⁶⁸ 4       FCGR…
## 10         7.13e⁻¹²³      2.15 1.00  0.316         9.78e⁻¹¹⁹ 4       LST1 
## 11         9.12e⁻²⁶⁵      3.33 0.955 0.0680        1.25e⁻²⁶⁰ 5       GZMB 
## 12         6.25e⁻¹⁹²      3.76 0.961 0.131         8.57e⁻¹⁸⁸ 5       GNLY 
## 13         2.51e⁻²³⁸      2.73 0.844 0.0110        3.44e⁻²³⁴ 6       FCER…
## 14         7.04e⁻ ²¹      1.97 1.00  0.513         9.65e⁻ ¹⁷ 6       HLA-…
## 15         7.73e⁻²⁰⁰      5.02 1.00  0.0100        1.06e⁻¹⁹⁵ 7       PF4  
## 16         3.68e⁻¹¹⁰      5.94 1.00  0.0240        5.05e⁻¹⁰⁶ 7       PPBP
```

Example 90 (unknown):
```unknown
## # A tibble: 16 x 7
## # Groups:   cluster [8]
##                p_val avg_logFC pct.1  pct.2        p_val_adj cluster gene 
##                <dbl>     <dbl> <dbl>  <dbl>            <dbl> <fct>   <chr>
##  1         1.47e⁻²³⁴      1.15 0.924 0.482         2.01e⁻²³⁰ 0       LDHB 
##  2         3.09e⁻¹²⁹      1.07 0.662 0.202         4.24e⁻¹²⁵ 0       IL7R 
##  3         0              3.83 0.996 0.216         0         1       S100…
##  4         0              3.79 0.973 0.122         0         1       S100…
##  5         0              2.98 0.936 0.0420        0         2       CD79A
##  6         1.06e⁻²⁶⁹      2.49 0.623 0.0220        1.45e⁻²⁶⁵ 2       TCL1A
##  7         8.03e⁻²⁰⁷      2.16 0.974 0.230         1.10e⁻²⁰² 3       CCL5 
##  8         1.12e⁻¹⁸¹      2.11 0.588 0.0500        1.53e⁻¹⁷⁷ 3       GZMK 
##  9         1.04e⁻¹⁷²      2.28 0.962 0.137         1.42e⁻¹⁶⁸ 4       FCGR…
## 10         7.13e⁻¹²³      2.15 1.00  0.316         9.78e⁻¹¹⁹ 4       LST1 
## 11         9.12e⁻²⁶⁵      3.33 0.955 0.0680        1.25e⁻²⁶⁰ 5       GZMB 
## 12         6.25e⁻¹⁹²      3.76 0.961 0.131         8.57e⁻¹⁸⁸ 5       GNLY 
## 13         2.51e⁻²³⁸      2.73 0.844 0.0110        3.44e⁻²³⁴ 6       FCER…
## 14         7.04e⁻ ²¹      1.97 1.00  0.513         9.65e⁻ ¹⁷ 6       HLA-…
## 15         7.73e⁻²⁰⁰      5.02 1.00  0.0100        1.06e⁻¹⁹⁵ 7       PF4  
## 16         3.68e⁻¹¹⁰      5.94 1.00  0.0240        5.05e⁻¹⁰⁶ 7       PPBP
```

Example 91 (r):
```r
cluster1.markers <- FindMarkers(object = pbmc, ident.1 = 0, thresh.use = 0.25, 
    test.use = "roc", only.pos = TRUE)
```

Example 92 (r):
```r
cluster1.markers <- FindMarkers(object = pbmc, ident.1 = 0, thresh.use = 0.25, 
    test.use = "roc", only.pos = TRUE)
```

Example 93 (unknown):
```unknown
FeaturePlot
```

Example 94 (r):
```r
VlnPlot(object = pbmc, features.plot = c("MS4A1", "CD79A"))
```

Example 95 (r):
```r
VlnPlot(object = pbmc, features.plot = c("MS4A1", "CD79A"))
```

Example 96 (r):
```r
# you can plot raw UMI counts as well
VlnPlot(object = pbmc, features.plot = c("NKG7", "PF4"), use.raw = TRUE, y.log = TRUE)
```

Example 97 (r):
```r
# you can plot raw UMI counts as well
VlnPlot(object = pbmc, features.plot = c("NKG7", "PF4"), use.raw = TRUE, y.log = TRUE)
```

Example 98 (r):
```r
FeaturePlot(object = pbmc, features.plot = c("MS4A1", "GNLY", "CD3E", "CD14", 
    "FCER1A", "FCGR3A", "LYZ", "PPBP", "CD8A"), cols.use = c("grey", "blue"), 
    reduction.use = "tsne")
```

Example 99 (r):
```r
FeaturePlot(object = pbmc, features.plot = c("MS4A1", "GNLY", "CD3E", "CD14", 
    "FCER1A", "FCGR3A", "LYZ", "PPBP", "CD8A"), cols.use = c("grey", "blue"), 
    reduction.use = "tsne")
```

Example 100 (r):
```r
top10 <- pbmc.markers %>% group_by(cluster) %>% top_n(10, avg_logFC)
# setting slim.col.label to TRUE will print just the cluster IDS instead of
# every cell name
DoHeatmap(object = pbmc, genes.use = top10$gene, slim.col.label = TRUE, remove.key = TRUE)
```

Example 101 (r):
```r
top10 <- pbmc.markers %>% group_by(cluster) %>% top_n(10, avg_logFC)
# setting slim.col.label to TRUE will print just the cluster IDS instead of
# every cell name
DoHeatmap(object = pbmc, genes.use = top10$gene, slim.col.label = TRUE, remove.key = TRUE)
```

Example 102 (r):
```r
current.cluster.ids <- c(0, 1, 2, 3, 4, 5, 6, 7)
new.cluster.ids <- c("CD4 T cells", "CD14+ Monocytes", "B cells", "CD8 T cells", 
    "FCGR3A+ Monocytes", "NK cells", "Dendritic cells", "Megakaryocytes")
pbmc@ident <- plyr::mapvalues(x = pbmc@ident, from = current.cluster.ids, to = new.cluster.ids)
TSNEPlot(object = pbmc, do.label = TRUE, pt.size = 0.5)
```

Example 103 (r):
```r
current.cluster.ids <- c(0, 1, 2, 3, 4, 5, 6, 7)
new.cluster.ids <- c("CD4 T cells", "CD14+ Monocytes", "B cells", "CD8 T cells", 
    "FCGR3A+ Monocytes", "NK cells", "Dendritic cells", "Megakaryocytes")
pbmc@ident <- plyr::mapvalues(x = pbmc@ident, from = current.cluster.ids, to = new.cluster.ids)
TSNEPlot(object = pbmc, do.label = TRUE, pt.size = 0.5)
```

Example 104 (unknown):
```unknown
resolution=0.8
```

Example 105 (unknown):
```unknown
object@ident
```

Example 106 (r):
```r
# First lets stash our identities for later
pbmc <- StashIdent(object = pbmc, save.name = "ClusterNames_0.6")

# Note that if you set save.snn=T above, you don't need to recalculate the
# SNN, and can simply put: pbmc <- FindClusters(pbmc,resolution = 0.8)
pbmc <- FindClusters(object = pbmc, reduction.type = "pca", dims.use = 1:10, 
    resolution = 0.8, print.output = FALSE)
```

Example 107 (r):
```r
# First lets stash our identities for later
pbmc <- StashIdent(object = pbmc, save.name = "ClusterNames_0.6")

# Note that if you set save.snn=T above, you don't need to recalculate the
# SNN, and can simply put: pbmc <- FindClusters(pbmc,resolution = 0.8)
pbmc <- FindClusters(object = pbmc, reduction.type = "pca", dims.use = 1:10, 
    resolution = 0.8, print.output = FALSE)
```

Example 108 (unknown):
```unknown
## Warning in BuildSNN(object = object, genes.use = genes.use, reduction.type
## = reduction.type, : Build parameters exactly match those of already
## computed and stored SNN. To force recalculation, set force.recalc to TRUE.
```

Example 109 (unknown):
```unknown
## Warning in BuildSNN(object = object, genes.use = genes.use, reduction.type
## = reduction.type, : Build parameters exactly match those of already
## computed and stored SNN. To force recalculation, set force.recalc to TRUE.
```

Example 110 (r):
```r
# Demonstration of how to plot two tSNE plots side by side, and how to color
# points based on different criteria
plot1 <- TSNEPlot(object = pbmc, do.return = TRUE, no.legend = TRUE, do.label = TRUE)
plot2 <- TSNEPlot(object = pbmc, do.return = TRUE, group.by = "ClusterNames_0.6", 
    no.legend = TRUE, do.label = TRUE)
plot_grid(plot1, plot2)
```

Example 111 (r):
```r
# Demonstration of how to plot two tSNE plots side by side, and how to color
# points based on different criteria
plot1 <- TSNEPlot(object = pbmc, do.return = TRUE, no.legend = TRUE, do.label = TRUE)
plot2 <- TSNEPlot(object = pbmc, do.return = TRUE, group.by = "ClusterNames_0.6", 
    no.legend = TRUE, do.label = TRUE)
plot_grid(plot1, plot2)
```

Example 112 (r):
```r
# Find discriminating markers
tcell.markers <- FindMarkers(object = pbmc, ident.1 = 0, ident.2 = 1)

# Most of the markers tend to be expressed in C1 (i.e. S100A4). However, we
# can see that CCR7 is upregulated in C0, strongly indicating that we can
# differentiate memory from naive CD4 cells.  cols.use demarcates the color
# palette from low to high expression
FeaturePlot(object = pbmc, features.plot = c("S100A4", "CCR7"), cols.use = c("green", 
    "blue"))
```

Example 113 (r):
```r
# Find discriminating markers
tcell.markers <- FindMarkers(object = pbmc, ident.1 = 0, ident.2 = 1)

# Most of the markers tend to be expressed in C1 (i.e. S100A4). However, we
# can see that CCR7 is upregulated in C0, strongly indicating that we can
# differentiate memory from naive CD4 cells.  cols.use demarcates the color
# palette from low to high expression
FeaturePlot(object = pbmc, features.plot = c("S100A4", "CCR7"), cols.use = c("green", 
    "blue"))
```

Example 114 (r):
```r
pbmc <- SetAllIdent(object = pbmc, id = "ClusterNames_0.6")
saveRDS(pbmc, file = "~/Projects/datasets/pbmc3k_final.rds")
```

Example 115 (r):
```r
pbmc <- SetAllIdent(object = pbmc, id = "ClusterNames_0.6")
saveRDS(pbmc, file = "~/Projects/datasets/pbmc3k_final.rds")
```

---

## Guided Clustering of the Microwell-seq Mouse Cell Atlas

**URL:** http://127.0.0.1:9173/seurat/archive/v2.4/mca/index.html

**Contents:**
- Guided Clustering of the Microwell-seq Mouse Cell Atlas
    - Compiled: May 09, 2018
  - Setup the Seurat Object
  - Data Preprocessing
  - Dimensional Reduction (PCA)
  - Graph-based clustering
  - Visualization (t-SNE/UMAP)
  - Elapsed time for key steps

In the following tutorial, we examine the recently published Microwell-seq “Mouse Cell Atlas”, composed of hundreds of thousands of cells derived from all major mouse organs. For those that are getting started using Seurat, we recommend first working through our 3k PBMC tutorial, which introduces the basic functionality of the package.

Our goal is to demonstrate a workflow for handling very large datasets in Seurat, emphasizing recent improvements we have made for speed and memory efficiency. We do not perform downstream biological analyses on the resulting clusters, but encourage users to explore this dataset and interpret this exciting resource. All analyses here are performed in memory, but we also now support storage on-disk (using the HDF5-based loom framework). See this vignette for a workflow of the same MCA dataset using loomR.

The original data for the MCA is available here. For ease of getting started, we provide a sparse matrix R data file (.rds) file containing the combined expression matrix and the published metadata file here.

We will analyze ~242,000 cells that were assigned a cluster ID in the original study. As a result, we don’t do perform additional QC steps or filtration steps here.

We perform standard log-normalization.

FindVariableGenes calculates the variance and mean for each gene in the dataset in the dataset (storing this in object@hvg.info), and sorts genes by their variance/mean ratio (VMR). We have observed that for large-cell datasets with unique molecular identifiers, selecting highly variable genes (HVG) simply based on VMR is an efficient and robust strategy. Here, we select the top 1,000 HVG for downstream analysis.

We calculate and regress out mitochondrial expression per cell.

We now cluster the data in lower-dimensional space. Our approach was heavily inspired by recent manuscripts which applied graph-based clustering approaches to scRNA-seq data [SNN-Cliq, Xu and Su, Bioinformatics, 2015] and CyTOF data [PhenoGraph, Levine et al., Cell, 2015].

We use the same principal components that were input for clustering, for two-dimensional visualization with t-SNE or UMAP.

These tests were performed on a desktop computer running Ubuntu 16.04.4 LTS with an Intel(R) Core(TM) i5-6500 CPU @ 3.20GHz and 32GB of RAM.

**Examples:**

Example 1 (r):
```r
library(Matrix)
library(Seurat)
mca.matrix <- readRDS(file = "~/Downloads/MCA/MCA_merged_mat.rds")
mca.metadata <- read.csv("~/Downloads/MCA/MCA_All-batch-removed-assignments.csv", 
    row.names = 1)
```

Example 2 (r):
```r
library(Matrix)
library(Seurat)
mca.matrix <- readRDS(file = "~/Downloads/MCA/MCA_merged_mat.rds")
mca.metadata <- read.csv("~/Downloads/MCA/MCA_All-batch-removed-assignments.csv", 
    row.names = 1)
```

Example 3 (r):
```r
mca <- CreateSeuratObject(raw.data = mca.matrix, meta.data = mca.metadata, project = "MouseCellAtlas")
# Only keep annotated cells
mca <- SubsetData(mca, cells.use = rownames(mca@meta.data[!is.na(mca@meta.data$ClusterID), 
    ]), do.clean = TRUE)
# Leaves us with 242k cells
mca
```

Example 4 (r):
```r
mca <- CreateSeuratObject(raw.data = mca.matrix, meta.data = mca.metadata, project = "MouseCellAtlas")
# Only keep annotated cells
mca <- SubsetData(mca, cells.use = rownames(mca@meta.data[!is.na(mca@meta.data$ClusterID), 
    ]), do.clean = TRUE)
# Leaves us with 242k cells
mca
```

Example 5 (python):
```python
## An object of class seurat in project MouseCellAtlas 
##  39855 genes across 242533 samples.
```

Example 6 (python):
```python
## An object of class seurat in project MouseCellAtlas 
##  39855 genes across 242533 samples.
```

Example 7 (r):
```r
mca <- NormalizeData(object = mca, normalization.method = "LogNormalize", scale.factor = 10000)
```

Example 8 (r):
```r
mca <- NormalizeData(object = mca, normalization.method = "LogNormalize", scale.factor = 10000)
```

Example 9 (unknown):
```unknown
FindVariableGenes
```

Example 10 (unknown):
```unknown
object@hvg.info
```

Example 11 (r):
```r
mca <- FindVariableGenes(object = mca, mean.function = ExpMean, dispersion.function = LogVMR, 
    do.plot = FALSE)
hv.genes <- head(rownames(mca@hvg.info), 1000)
```

Example 12 (r):
```r
mca <- FindVariableGenes(object = mca, mean.function = ExpMean, dispersion.function = LogVMR, 
    do.plot = FALSE)
hv.genes <- head(rownames(mca@hvg.info), 1000)
```

Example 13 (r):
```r
mito.genes <- grep(pattern = "^mt-", x = rownames(x = mca@data), value = TRUE)
percent.mito <- Matrix::colSums(mca@raw.data[mito.genes, ])/Matrix::colSums(mca@raw.data)
mca <- AddMetaData(object = mca, metadata = percent.mito, col.name = "percent.mito")
mca <- ScaleData(object = mca, genes.use = hv.genes, display.progress = FALSE, 
    vars.to.regress = "percent.mito", do.par = TRUE, num.cores = 4)
```

Example 14 (r):
```r
mito.genes <- grep(pattern = "^mt-", x = rownames(x = mca@data), value = TRUE)
percent.mito <- Matrix::colSums(mca@raw.data[mito.genes, ])/Matrix::colSums(mca@raw.data)
mca <- AddMetaData(object = mca, metadata = percent.mito, col.name = "percent.mito")
mca <- ScaleData(object = mca, genes.use = hv.genes, display.progress = FALSE, 
    vars.to.regress = "percent.mito", do.par = TRUE, num.cores = 4)
```

Example 15 (r):
```r
mca <- RunPCA(object = mca, pc.genes = hv.genes, pcs.compute = 100, do.print = TRUE, 
    pcs.print = 1:5, genes.print = 5)
```

Example 16 (r):
```r
mca <- RunPCA(object = mca, pc.genes = hv.genes, pcs.compute = 100, do.print = TRUE, 
    pcs.print = 1:5, genes.print = 5)
```

Example 17 (unknown):
```unknown
## [1] "PC1"
## [1] "Prm1"  "Prm2"  "Meig1" "Fabp9" "Ldhc" 
## [1] ""
## [1] "Tmsb4x" "B2m"    "Fth1"   "Ftl1"   "Rpl18a"
## [1] ""
## [1] ""
## [1] "PC2"
## [1] "Sparc"  "Col2a1" "Col9a2" "Col9a1" "Col9a3"
## [1] ""
## [1] "Defa24" "Reg3b"  "Defa30" "Igkc"   "Reg3g" 
## [1] ""
## [1] ""
## [1] "PC3"
## [1] "Camp"   "Ngp"    "S100a9" "S100a8" "Chil3" 
## [1] ""
## [1] "Defa24" "Reg3b"  "Defa30" "Reg3g"  "Defa17"
## [1] ""
## [1] ""
## [1] "PC4"
## [1] "Csn1s2b" "Wap"     "Trf"     "Lalba"   "Glycam1"
## [1] ""
## [1] "S100a8" "S100a9" "Lyz2"   "Tyrobp" "Srgn"  
## [1] ""
## [1] ""
## [1] "PC5"
## [1] "Wap"     "Csn1s2b" "Lalba"   "Glycam1" "Csn1s2a"
## [1] ""
## [1] "Tmsb10" "Rplp1"  "Rpl13"  "Rps27"  "Rps15a"
## [1] ""
## [1] ""
```

Example 18 (unknown):
```unknown
## [1] "PC1"
## [1] "Prm1"  "Prm2"  "Meig1" "Fabp9" "Ldhc" 
## [1] ""
## [1] "Tmsb4x" "B2m"    "Fth1"   "Ftl1"   "Rpl18a"
## [1] ""
## [1] ""
## [1] "PC2"
## [1] "Sparc"  "Col2a1" "Col9a2" "Col9a1" "Col9a3"
## [1] ""
## [1] "Defa24" "Reg3b"  "Defa30" "Igkc"   "Reg3g" 
## [1] ""
## [1] ""
## [1] "PC3"
## [1] "Camp"   "Ngp"    "S100a9" "S100a8" "Chil3" 
## [1] ""
## [1] "Defa24" "Reg3b"  "Defa30" "Reg3g"  "Defa17"
## [1] ""
## [1] ""
## [1] "PC4"
## [1] "Csn1s2b" "Wap"     "Trf"     "Lalba"   "Glycam1"
## [1] ""
## [1] "S100a8" "S100a9" "Lyz2"   "Tyrobp" "Srgn"  
## [1] ""
## [1] ""
## [1] "PC5"
## [1] "Wap"     "Csn1s2b" "Lalba"   "Glycam1" "Csn1s2a"
## [1] ""
## [1] "Tmsb10" "Rplp1"  "Rpl13"  "Rps27"  "Rps15a"
## [1] ""
## [1] ""
```

Example 19 (r):
```r
PCElbowPlot(object = mca, num.pc = 100)
```

Example 20 (r):
```r
PCElbowPlot(object = mca, num.pc = 100)
```

Example 21 (r):
```r
PCHeatmap(mca, pc.use = c(1:3, 70:75), cells.use = 500, do.balanced = TRUE)
```

Example 22 (r):
```r
PCHeatmap(mca, pc.use = c(1:3, 70:75), cells.use = 500, do.balanced = TRUE)
```

Example 23 (r):
```r
mca <- FindClusters(object = mca, reduction.type = "pca", dims.use = 1:75, resolution = 3, 
    save.SNN = TRUE, n.start = 10, nn.eps = 0.5, print.output = FALSE)
```

Example 24 (r):
```r
mca <- FindClusters(object = mca, reduction.type = "pca", dims.use = 1:75, resolution = 3, 
    save.SNN = TRUE, n.start = 10, nn.eps = 0.5, print.output = FALSE)
```

Example 25 (unknown):
```unknown
n_neighbors
```

Example 26 (unknown):
```unknown
vector.friendly = TRUE
```

Example 27 (r):
```r
mca <- RunTSNE(object = mca, reduction.use = "pca", dims.use = 1:75, tsne.method = "FIt-SNE", 
    nthreads = 4, reduction.name = "FItSNE", reduction.key = "FItSNE_", fast_tsne_path = "/home/andrew/Software/FIt-SNE/bin/fast_tsne", 
    max_iter = 2000)
mca <- RunUMAP(object = mca, reduction.use = "pca", dims.use = 1:75, min_dist = 0.75)
```

Example 28 (r):
```r
mca <- RunTSNE(object = mca, reduction.use = "pca", dims.use = 1:75, tsne.method = "FIt-SNE", 
    nthreads = 4, reduction.name = "FItSNE", reduction.key = "FItSNE_", fast_tsne_path = "/home/andrew/Software/FIt-SNE/bin/fast_tsne", 
    max_iter = 2000)
mca <- RunUMAP(object = mca, reduction.use = "pca", dims.use = 1:75, min_dist = 0.75)
```

Example 29 (r):
```r
library(cowplot)
p1 <- DimPlot(object = mca, reduction.use = "FItSNE", no.legend = TRUE, do.return = TRUE, 
    vector.friendly = TRUE, pt.size = 0.1) + ggtitle("FIt-SNE") + theme(plot.title = element_text(hjust = 0.5))
p2 <- DimPlot(object = mca, reduction.use = "umap", no.legend = TRUE, do.return = TRUE, 
    vector.friendly = TRUE, pt.size = 0.1) + ggtitle("UMAP") + theme(plot.title = element_text(hjust = 0.5))
plot_grid(p1, p2)
```

Example 30 (r):
```r
library(cowplot)
p1 <- DimPlot(object = mca, reduction.use = "FItSNE", no.legend = TRUE, do.return = TRUE, 
    vector.friendly = TRUE, pt.size = 0.1) + ggtitle("FIt-SNE") + theme(plot.title = element_text(hjust = 0.5))
p2 <- DimPlot(object = mca, reduction.use = "umap", no.legend = TRUE, do.return = TRUE, 
    vector.friendly = TRUE, pt.size = 0.1) + ggtitle("UMAP") + theme(plot.title = element_text(hjust = 0.5))
plot_grid(p1, p2)
```

Example 31 (r):
```r
FeaturePlot(mca, c("S100a9", "Sftpc"), reduction.use = "FItSNE", dark.theme = TRUE, 
    pt.size = 0.1, vector.friendly = TRUE)
```

Example 32 (r):
```r
FeaturePlot(mca, c("S100a9", "Sftpc"), reduction.use = "FItSNE", dark.theme = TRUE, 
    pt.size = 0.1, vector.friendly = TRUE)
```

---

## Seurat - Guided Clustering Tutorial

**URL:** http://127.0.0.1:9173/seurat/archive/v1.4/pbmc3k_tutorial/index.html

**Contents:**
- Seurat - Guided Clustering Tutorial
    - Compiled: March 30, 2017
  - Setup the Seurat Object
  - Basic QC and selecting cells for further analysis
  - Regress out unwanted sources of variation
  - Detection of variable genes across the single cells
  - Perform linear dimensional reduction
  - Determine statistically significant principal components
  - Cluster the cells
  - Run Non-linear dimensional reduction (tSNE)
  - Finding differentially expressed genes (cluster biomarkers)
  - Assigning cell type identity to clusters
  - Further subdivisions within cell types

For this tutorial, we will be analyzing the a dataset of Peripheral Blood Mononuclear Cells (PBMC) freely available from 10X Genomics. There are 2,700 single cells that were sequenced on the Illumina NextSeq 500. The raw data can be found here.

We start by reading in the data. All features in Seurat have been configured to work with both regular and sparse matrices, but sparse matrices result in significant memory and speed savings for Drop-seq/inDrop/10x data.

While the setup function imposes a basic minimum gene-cutoff, you may want to filter out cells at this stage based on technical or biological parameters. Seurat allows you to easily explore QC metrics and filter cells based on any user-defined criteria. In the example below, we visualize gene and molecule counts, plot their relationship, and exclude cells with a clear outlier number of genes detected as potential multiplets. Of course this is not a guarenteed method to exclude cell doublets, but we include this as an example of filtering user-defined outlier cells. We also filter cells based on the percentage of mitochondrial genes present.

Your single cell dataset likely contains ‘uninteresting’ sources of variation. This could include not only technical noise, but batch effects, or even biological sources of variation (cell cycle stage). As suggested in Buettner et al, NBT, 2015, regressing these signals out of the analysis can improve downstream dimensionality reduction and clustering. Seurat implements a basic version of this by constructing linear models to predict gene expression based on user-defined variables. Seurat stores the z-scored residuals of these models in the scale.data slot, and they are used for dimensionality reduction and clustering.

We typically regress out cell-cell variation in gene expression driven by batch (if applicable), cell alignment rate (as provided by Drop-seq tools for Drop-seq data), the number of detected molecules, and mitochondrial gene expression. For cycling cells, we can also learn a ‘cell-cycle’ score (as in Macosko et al) and Regress this out as well. In this simple example here for post-mitotic blood cells, we simply regress on the number of detected molecules per cell as well as the percentage mitochondrial gene content an example.

Seurat calculates highly variable genes and focuses on these for downstream analysis. MeanVarPlot(), which works by calculating the average expression and dispersion for each gene, placing these genes into bins, and then calculating a z-score for dispersion within each bin. This helps control for the relationship between variability and average expression. This function is unchanged from (Macosko et al.), but new methods for variable gene expression identification are coming soon. We suggest that users set these parameters to mark visual outliers on the dispersion plot, but the exact parameter settings may vary based on the data type, heterogeneity in the sample, and normalization strategy. The parameters here identify ~2,000 variable genes, and represent typical parameter settings for UMI data that is normalized to a total of 1e4 molecules.

Perform PCA on the scaled data. By default, the genes in object@var.genes are used as input, but can be defined using pc.genes. We have typically found that running dimensionality reduction on genes with high-dispersion can improve performance. However, with UMI data - particularly after using RegressOut, we often see that PCA returns similar (albeit slower) results when run on much larger subsets of genes, including the whole transcriptome.

ProjectPCA scores each gene in the dataset (including genes not included in the PCA) based on their correlation with the calculated components. Though we don’t use this further here, it can be used to identify markers that are strongly correlated with cellular heterogeneity, but may not have passed through variable gene selection. The results of the projected PCA can be explored by setting use.full=T in the functions below.

Seurat provides several useful ways of visualizing both cells and genes that define the PCA, including PrintPCA(), VizPCA(), PCAPlot(), and PCHeatmap()

In particular PCHeatmap() allows for easy exploration of the primary sources of heterogeneity in a dataset, and can be useful when trying to decide which PCs to include for further downstream analyses. Both cells and genes are ordered according to their PCA scores. Setting cells.use to a number plots the ‘extreme’ cells on both ends of the spectrum, which dramatically speeds plotting for large datasets. Though clearly a supervised analysis, we find this to be a valuable tool for exploring correlated gene sets.

To overcome the extensive technical noise in any single gene for scRNA-seq data, Seurat clusters cells based on their PCA scores, with each PC essentially representing a ‘metagene’ that combines information across a correlated gene set. Determining how many PCs to include downstream is therefore an important step.

In Macosko et al, we implemented a resampling test inspired by the jackStraw procedure. We randomly permute a subset of the data (1% by default) and rerun PCA, constructing a ‘null distribution’ of gene scores, and repeat this procedure. We identify ‘significant’ PCs as those who have a strong enrichment of low p-value genes.

The JackStrawPlot() function provides a visualization tool for comparing the distribution of p-values for each PC with a uniform distribution (dashed line). ‘Significant’ PCs will show a strong enrichment of genes with low p-values (solid curve above the dashed line). In this case it appears that PCs 1-10 are significant.

A more ad hoc method for determining which PCs to use is to look at a plot of the standard deviations of the principle components and draw your cutoff where there is a clear elbow in the graph. This can be done with PCElbowPlot(). In this example, it looks like the elbow would fall around PC 9.

PC selection – identifying the true dimensionality of a dataset – is an important step for Seurat, but can be challenging/uncertain for the user. We therefore suggest these three approaches to consider. The first is more supervised, exploring PCs to determine relevant sources of heterogeneity, and could be used in conjunction with GSEA for example. The second implements a statistical test based on a random null model, but is time-consuming for large datasets, and may not return a clear PC cutoff. The third is a heuristic that is commonly used, and can be calculated instantly. In this example all three approaches yielded similar results, but we might have been justified in choosing anything between PC 7-10 as a cutoff. We followed the jackStraw here, admittedly buoyed by seeing the PCHeatmap returning interpretable signals (including canonical dendritic cell markers) throughout these PCs. Though the results are only subtly affected by small shifts in this cutoff (you can test below), we strongly suggest always explore the PCs they choose to include downstream.

Seurat now includes an graph-based clustering approach compared to (Macosko et al.). Importantly, the distance metric which drives the clustering analysis (based on previously identified PCs) remains the same. However, our approach to partioning the cellular distance matrix into clusters has dramatically improved. Our approach was heavily inspired by recent manuscripts which applied graph-based clustering approaches to scRNA-seq data [SNN-Cliq, Xu and Su, Bioinformatics, 2015] and CyTOF data [PhenoGraph, Levine et al., Cell, 2015]. Briefly, these methods embed cells in a graph structure - for example a K-nearest neighbor (KNN) graph, with edges drawn between cells with similar gene expression patterns, and then attempt to partition this graph into highly interconnected ‘quasi-cliques’ or ‘communities’. As in PhenoGraph, we first construct a KNN graph based on the euclidean distance in PCA space, and refine the edge weights between any two cells based on the shared overlap in their local neighborhoods (Jaccard distance). To cluster the cells, we apply the smart local moving algorithm [SLM, Blondel et al., Journal of Statistical Mechanics], to iteratively group cell groupings together with the goal of optimizing the standard modularity function.

The FindClusters() function implements the procedure, and contains a resolution parameter that sets the ‘granularity’ of the downstream clustering, with increased values leading to a greater number of clusters. We find that setting this parameter between 0.6-1.2 typically returns good results for single cell datasets of around 3K cells. Optimal resolution often increases for larger datasets. The clusters are saved in the object@ident slot.

Seurat continues to use tSNE as a powerful tool to visualize and explore these datasets. While we no longer advise clustering directly on tSNE components, cells within the graph-based clusters determined above should co-localize on the tSNE plot. This is because the tSNE aims to place cells with similar local neighborhoods in high-dimensional space together in low-dimensional space. As input to the tSNE, we suggest using the same PCs as input to the clustering analysis, although computing the tSNE based on scaled gene expression is also supported using the genes.use argument.

You can save the object at this point so that it can easily be loaded back in without having to rerun the computationally intensive steps performed above, or easily shared with collaborators.

Seurat can help you find markers that define clusters via differential expression. By default, it identifes positive and negative markers of a single cluster (specified in ident.1), compared to all other cells. FindAllMarkers() automates this process for all clusters, but you can also test groups of clusters vs. each other, or against all cells.

The min.pct argument requires a gene to be detected at a minimum percentage in either of the two groups of cells, and the thresh.test argument requires a gene to be differentially expressed (on average) by some amount between the two groups. You can set both of these to 0, but with a dramatic increase in time - since this will test a large number of genes that are unlikely to be highly discriminatory. As another option to speed up these computations, max.cells.per.ident can be set. This will downsample each identity class to have no more cells than whatever this is set to. While there is generally going to be a loss in power, the speed increases can be signficiant and the most highly differentially expressed genes will likely still rise to the top.

Seurat has four tests for differential expression which can be set with the test.use parameter: ROC test (“roc”), t-test (“t”), LRT test based on zero-inflated data (“bimod”, default), LRT test based on tobit-censoring models (“tobit”) The ROC test returns the ‘classification power’ for any individual marker (ranging from 0 - random, to 1 - perfect).

There are several tools for visualizing marker expression. VlnPlot() generates a violin plot which shows the probability density at different expression levels of the gene for each cluster. As seen below, good marker genes will show strongly in a single cluster. It can also be useful to look at gene/gene correlation with GenePlot() which returns a plot similar to a ‘FACS’ plot with cells colored by cluster identity. Also, the FeaturePlot() function is useful for viewing the expression of the gene in the context of all the cells and helps validate the specificity of the marker or the quality of the clustering.

Heatmaps can also be a good way to examine heterogeneity within/between clusters. The DoHeatmap() function will generate a heatmap for given cells and genes. In this case, we are plotting the top 20 markers (or all markers if less than 20) for each cluster.

Fortunately in the case of this dataset, we can use canonical markers to easily match the unbiased clustering to known cell types:

If you perturb some of our parameter choices above (for example, setting resolution=0.8 or changing the number of PCs), you might see the CD4 T cells subdivide into two groups. You can explore this subdivision to find markers separating the two T cell subsets. However, before reclustering (which will overwrite object@ident), we can stash our renamed identities to be easily recovered later.

The memory/naive split is bit weak, and we would probably benefit from looking at more cells to see if this becomes more convincing (stay tuned!). In the meantime, we can restore our old cluster identities for downstream processing.

**Examples:**

Example 1 (r):
```r
library(Seurat)
library(dplyr)
library(Matrix)

# Load the PBMC dataset
pbmc.data <- Read10X("~/Downloads/filtered_gene_bc_matrices/hg19/")

#Examine the memory savings between regular and sparse matrices
dense.size <- object.size(as.matrix(pbmc.data))
dense.size
```

Example 2 (r):
```r
library(Seurat)
library(dplyr)
library(Matrix)

# Load the PBMC dataset
pbmc.data <- Read10X("~/Downloads/filtered_gene_bc_matrices/hg19/")

#Examine the memory savings between regular and sparse matrices
dense.size <- object.size(as.matrix(pbmc.data))
dense.size
```

Example 3 (unknown):
```unknown
## 709264728 bytes
```

Example 4 (unknown):
```unknown
## 709264728 bytes
```

Example 5 (r):
```r
sparse.size <- object.size(pbmc.data)
sparse.size
```

Example 6 (r):
```r
sparse.size <- object.size(pbmc.data)
sparse.size
```

Example 7 (unknown):
```unknown
## 38715120 bytes
```

Example 8 (unknown):
```unknown
## 38715120 bytes
```

Example 9 (r):
```r
dense.size/sparse.size
```

Example 10 (r):
```r
dense.size/sparse.size
```

Example 11 (unknown):
```unknown
## 18.3200963344554 bytes
```

Example 12 (unknown):
```unknown
## 18.3200963344554 bytes
```

Example 13 (r):
```r
# Initialize the Seurat object with the raw (non-normalized data)
# Note that this is slightly different than the older Seurat workflow, where log-normalized values were passed in directly.
# You can continue to pass in log-normalized values, just set do.logNormalize=F in the next step.
pbmc <- new("seurat", raw.data = pbmc.data)

# Keep all genes expressed in >= 3 cells, keep all cells with >= 200 genes
# Perform log-normalization, first scaling each cell to a total of 1e4 molecules (as in Macosko et al. Cell 2015)
pbmc <- Setup(pbmc, min.cells = 3, min.genes = 200, do.logNormalize = T, total.expr = 1e4, project = "10X_PBMC")
```

Example 14 (r):
```r
# Initialize the Seurat object with the raw (non-normalized data)
# Note that this is slightly different than the older Seurat workflow, where log-normalized values were passed in directly.
# You can continue to pass in log-normalized values, just set do.logNormalize=F in the next step.
pbmc <- new("seurat", raw.data = pbmc.data)

# Keep all genes expressed in >= 3 cells, keep all cells with >= 200 genes
# Perform log-normalization, first scaling each cell to a total of 1e4 molecules (as in Macosko et al. Cell 2015)
pbmc <- Setup(pbmc, min.cells = 3, min.genes = 200, do.logNormalize = T, total.expr = 1e4, project = "10X_PBMC")
```

Example 15 (r):
```r
# The number of genes and UMIs (nGene and nUMI) are automatically calculated for every object by Seurat. 
# For non-UMI data, nUMI represents the sum of the non-normalized values within a cell
# We calculate the percentage of mitochondrial genes here and store it in percent.mito using the AddMetaData. 
# The % of UMI mapping to MT-genes is a common scRNA-seq QC metric.
# NOTE: You must have the Matrix package loaded to calculate the percent.mito values. 
mito.genes <- grep("^MT-", rownames(pbmc@data), value = T)
percent.mito <- colSums(expm1(pbmc@data[mito.genes, ]))/colSums(expm1(pbmc@data))

#AddMetaData adds columns to object@data.info, and is a great place to stash QC stats
pbmc <- AddMetaData(pbmc, percent.mito, "percent.mito")
VlnPlot(pbmc, c("nGene", "nUMI", "percent.mito"), nCol = 3)
```

Example 16 (r):
```r
# The number of genes and UMIs (nGene and nUMI) are automatically calculated for every object by Seurat. 
# For non-UMI data, nUMI represents the sum of the non-normalized values within a cell
# We calculate the percentage of mitochondrial genes here and store it in percent.mito using the AddMetaData. 
# The % of UMI mapping to MT-genes is a common scRNA-seq QC metric.
# NOTE: You must have the Matrix package loaded to calculate the percent.mito values. 
mito.genes <- grep("^MT-", rownames(pbmc@data), value = T)
percent.mito <- colSums(expm1(pbmc@data[mito.genes, ]))/colSums(expm1(pbmc@data))

#AddMetaData adds columns to object@data.info, and is a great place to stash QC stats
pbmc <- AddMetaData(pbmc, percent.mito, "percent.mito")
VlnPlot(pbmc, c("nGene", "nUMI", "percent.mito"), nCol = 3)
```

Example 17 (r):
```r
#GenePlot is typically used to visualize gene-gene relationships, but can be used for anything calculated by the object, i.e. columns in object@data.info, PC scores etc.
#Since there is a rare subset of cells with an outlier level of high mitochondrial percentage, and also low UMI content, we filter these as well
par(mfrow = c(1, 2))
GenePlot(pbmc, "nUMI", "percent.mito")
GenePlot(pbmc, "nUMI", "nGene")
```

Example 18 (r):
```r
#GenePlot is typically used to visualize gene-gene relationships, but can be used for anything calculated by the object, i.e. columns in object@data.info, PC scores etc.
#Since there is a rare subset of cells with an outlier level of high mitochondrial percentage, and also low UMI content, we filter these as well
par(mfrow = c(1, 2))
GenePlot(pbmc, "nUMI", "percent.mito")
GenePlot(pbmc, "nUMI", "nGene")
```

Example 19 (r):
```r
#We filter out cells that have unique gene counts over 2,500
#Note that accept.high and accept.low can be used to define a 'gate', and can filter cells not only based on nGene but on anything in the object (as in GenePlot above)
pbmc <- SubsetData(pbmc, subset.name = "nGene", accept.high = 2500)
pbmc <- SubsetData(pbmc, subset.name = "percent.mito", accept.high = 0.05)
```

Example 20 (r):
```r
#We filter out cells that have unique gene counts over 2,500
#Note that accept.high and accept.low can be used to define a 'gate', and can filter cells not only based on nGene but on anything in the object (as in GenePlot above)
pbmc <- SubsetData(pbmc, subset.name = "nGene", accept.high = 2500)
pbmc <- SubsetData(pbmc, subset.name = "percent.mito", accept.high = 0.05)
```

Example 21 (r):
```r
#note that this overwrites pbmc@scale.data. Therefore, if you intend to use RegressOut, you can set do.scale=F and do.center=F in the original object to save some time.
pbmc <- RegressOut(pbmc, latent.vars = c("nUMI", "percent.mito"))
```

Example 22 (r):
```r
#note that this overwrites pbmc@scale.data. Therefore, if you intend to use RegressOut, you can set do.scale=F and do.center=F in the original object to save some time.
pbmc <- RegressOut(pbmc, latent.vars = c("nUMI", "percent.mito"))
```

Example 23 (r):
```r
pbmc <- MeanVarPlot(pbmc ,fxn.x = expMean, fxn.y = logVarDivMean, x.low.cutoff = 0.0125, x.high.cutoff = 3, y.cutoff = 0.5, do.contour = F)
```

Example 24 (r):
```r
pbmc <- MeanVarPlot(pbmc ,fxn.x = expMean, fxn.y = logVarDivMean, x.low.cutoff = 0.0125, x.high.cutoff = 3, y.cutoff = 0.5, do.contour = F)
```

Example 25 (r):
```r
length(pbmc@var.genes)
```

Example 26 (r):
```r
length(pbmc@var.genes)
```

Example 27 (unknown):
```unknown
## [1] 1838
```

Example 28 (unknown):
```unknown
## [1] 1838
```

Example 29 (r):
```r
pbmc <- PCA(pbmc, pc.genes = pbmc@var.genes, do.print = TRUE, pcs.print = 5, genes.print = 5)
```

Example 30 (r):
```r
pbmc <- PCA(pbmc, pc.genes = pbmc@var.genes, do.print = TRUE, pcs.print = 5, genes.print = 5)
```

Example 31 (unknown):
```unknown
## [1] "PC1"
## [1] "CST3"   "TYROBP" "FCN1"   "LST1"   "AIF1"  
## [1] ""
## [1] "PTPRCAP" "IL32"    "LTB"     "CD2"     "CTSW"   
## [1] ""
## [1] ""
## [1] "PC2"
## [1] "NKG7" "GZMB" "PRF1" "CST7" "GZMA"
## [1] ""
## [1] "CD79A"    "MS4A1"    "HLA-DQA1" "TCL1A"    "HLA-DQB1"
## [1] ""
## [1] ""
## [1] "PC3"
## [1] "CYBA"     "HLA-DPA1" "HLA-DPB1" "HLA-DRB1" "CD37"    
## [1] ""
## [1] "PF4"   "PPBP"  "SDPR"  "SPARC" "GNG11"
## [1] ""
## [1] ""
## [1] "PC4"
## [1] "IL32"   "GIMAP7" "AQP3"   "FYB"    "MAL"   
## [1] ""
## [1] "CD79A"    "HLA-DQA1" "CD79B"    "MS4A1"    "HLA-DQB1"
## [1] ""
## [1] ""
## [1] "PC5"
## [1] "FCER1A"  "LGALS2"  "MS4A6A"  "S100A8"  "CLEC10A"
## [1] ""
## [1] "FCGR3A"        "CTD-2006K23.1" "IFITM3"        "ABI3"         
## [5] "CEBPB"        
## [1] ""
## [1] ""
```

Example 32 (unknown):
```unknown
## [1] "PC1"
## [1] "CST3"   "TYROBP" "FCN1"   "LST1"   "AIF1"  
## [1] ""
## [1] "PTPRCAP" "IL32"    "LTB"     "CD2"     "CTSW"   
## [1] ""
## [1] ""
## [1] "PC2"
## [1] "NKG7" "GZMB" "PRF1" "CST7" "GZMA"
## [1] ""
## [1] "CD79A"    "MS4A1"    "HLA-DQA1" "TCL1A"    "HLA-DQB1"
## [1] ""
## [1] ""
## [1] "PC3"
## [1] "CYBA"     "HLA-DPA1" "HLA-DPB1" "HLA-DRB1" "CD37"    
## [1] ""
## [1] "PF4"   "PPBP"  "SDPR"  "SPARC" "GNG11"
## [1] ""
## [1] ""
## [1] "PC4"
## [1] "IL32"   "GIMAP7" "AQP3"   "FYB"    "MAL"   
## [1] ""
## [1] "CD79A"    "HLA-DQA1" "CD79B"    "MS4A1"    "HLA-DQB1"
## [1] ""
## [1] ""
## [1] "PC5"
## [1] "FCER1A"  "LGALS2"  "MS4A6A"  "S100A8"  "CLEC10A"
## [1] ""
## [1] "FCGR3A"        "CTD-2006K23.1" "IFITM3"        "ABI3"         
## [5] "CEBPB"        
## [1] ""
## [1] ""
```

Example 33 (r):
```r
pbmc <- ProjectPCA(pbmc)
```

Example 34 (r):
```r
pbmc <- ProjectPCA(pbmc)
```

Example 35 (r):
```r
# Examine  and visualize PCA results a few different ways
PrintPCA(pbmc, pcs.print = 1:5, genes.print = 5, use.full = TRUE)
```

Example 36 (r):
```r
# Examine  and visualize PCA results a few different ways
PrintPCA(pbmc, pcs.print = 1:5, genes.print = 5, use.full = TRUE)
```

Example 37 (unknown):
```unknown
## [1] "PC1"
## [1] "CST3"   "S100A9" "FTL"    "TYROBP" "FCN1"  
## [1] ""
## [1] "MALAT1"  "RPS27A"  "PTPRCAP" "RPSA"    "RPS3A"  
## [1] ""
## [1] ""
## [1] "PC2"
## [1] "NKG7" "GZMB" "PRF1" "CST7" "GZMA"
## [1] ""
## [1] "CD79A"    "MS4A1"    "RPL18A"   "HLA-DQA1" "TCL1A"   
## [1] ""
## [1] ""
## [1] "PC3"
## [1] "RPL10" "RPS2"  "RPL11" "RPL28" "RPL32"
## [1] ""
## [1] "PF4"   "PPBP"  "SDPR"  "SPARC" "GNG11"
## [1] ""
## [1] ""
## [1] "PC4"
## [1] "CD3D"  "LDHB"  "IL7R"  "RPS14" "CD3E" 
## [1] ""
## [1] "CD79A"    "HLA-DQA1" "CD79B"    "MS4A1"    "CD74"    
## [1] ""
## [1] ""
## [1] "PC5"
## [1] "FCER1A"  "LGALS2"  "MS4A6A"  "S100A8"  "CLEC10A"
## [1] ""
## [1] "FCGR3A" "CDKN1C" "MS4A7"  "HES4"   "CKB"   
## [1] ""
## [1] ""
```

Example 38 (unknown):
```unknown
## [1] "PC1"
## [1] "CST3"   "S100A9" "FTL"    "TYROBP" "FCN1"  
## [1] ""
## [1] "MALAT1"  "RPS27A"  "PTPRCAP" "RPSA"    "RPS3A"  
## [1] ""
## [1] ""
## [1] "PC2"
## [1] "NKG7" "GZMB" "PRF1" "CST7" "GZMA"
## [1] ""
## [1] "CD79A"    "MS4A1"    "RPL18A"   "HLA-DQA1" "TCL1A"   
## [1] ""
## [1] ""
## [1] "PC3"
## [1] "RPL10" "RPS2"  "RPL11" "RPL28" "RPL32"
## [1] ""
## [1] "PF4"   "PPBP"  "SDPR"  "SPARC" "GNG11"
## [1] ""
## [1] ""
## [1] "PC4"
## [1] "CD3D"  "LDHB"  "IL7R"  "RPS14" "CD3E" 
## [1] ""
## [1] "CD79A"    "HLA-DQA1" "CD79B"    "MS4A1"    "CD74"    
## [1] ""
## [1] ""
## [1] "PC5"
## [1] "FCER1A"  "LGALS2"  "MS4A6A"  "S100A8"  "CLEC10A"
## [1] ""
## [1] "FCGR3A" "CDKN1C" "MS4A7"  "HES4"   "CKB"   
## [1] ""
## [1] ""
```

Example 39 (r):
```r
VizPCA(pbmc, 1:2)
```

Example 40 (r):
```r
VizPCA(pbmc, 1:2)
```

Example 41 (r):
```r
PCAPlot(pbmc, 1, 2)
```

Example 42 (r):
```r
PCAPlot(pbmc, 1, 2)
```

Example 43 (r):
```r
PCHeatmap(pbmc, pc.use = 1, cells.use = 100, do.balanced = TRUE)
```

Example 44 (r):
```r
PCHeatmap(pbmc, pc.use = 1, cells.use = 100, do.balanced = TRUE)
```

Example 45 (r):
```r
PCHeatmap(pbmc, pc.use = 1:12, cells.use = 500, do.balanced = TRUE, label.columns = FALSE, use.full = FALSE)
```

Example 46 (r):
```r
PCHeatmap(pbmc, pc.use = 1:12, cells.use = 500, do.balanced = TRUE, label.columns = FALSE, use.full = FALSE)
```

Example 47 (r):
```r
# NOTE: This process can take a long time for big datasets, comment out for expediency.
# More approximate techniques such as those implemented in PCElbowPlot() can be used to reduce computation time
pbmc <- JackStraw(pbmc, num.replicate = 100, do.print = FALSE)
```

Example 48 (r):
```r
# NOTE: This process can take a long time for big datasets, comment out for expediency.
# More approximate techniques such as those implemented in PCElbowPlot() can be used to reduce computation time
pbmc <- JackStraw(pbmc, num.replicate = 100, do.print = FALSE)
```

Example 49 (r):
```r
JackStrawPlot(pbmc, PCs = 1:12)
```

Example 50 (r):
```r
JackStrawPlot(pbmc, PCs = 1:12)
```

Example 51 (r):
```r
PCElbowPlot(pbmc)
```

Example 52 (r):
```r
PCElbowPlot(pbmc)
```

Example 53 (r):
```r
#save.SNN=T saves the SNN so that the  SLM algorithm can be rerun using the same graph, but with a different resolution value (see docs for full details)
pbmc <- FindClusters(pbmc, pc.use = 1:10, resolution = 0.6, print.output = 0, save.SNN = T)
```

Example 54 (r):
```r
#save.SNN=T saves the SNN so that the  SLM algorithm can be rerun using the same graph, but with a different resolution value (see docs for full details)
pbmc <- FindClusters(pbmc, pc.use = 1:10, resolution = 0.6, print.output = 0, save.SNN = T)
```

Example 55 (r):
```r
pbmc <- RunTSNE(pbmc, dims.use = 1:10, do.fast = T)
```

Example 56 (r):
```r
pbmc <- RunTSNE(pbmc, dims.use = 1:10, do.fast = T)
```

Example 57 (r):
```r
#note that you can set do.label=T to help label individual clusters
TSNEPlot(pbmc)
```

Example 58 (r):
```r
#note that you can set do.label=T to help label individual clusters
TSNEPlot(pbmc)
```

Example 59 (r):
```r
save(pbmc, file = "~/Projects/datasets/pbmc3k/pbmc_tutorial.Robj")
```

Example 60 (r):
```r
save(pbmc, file = "~/Projects/datasets/pbmc3k/pbmc_tutorial.Robj")
```

Example 61 (r):
```r
# find all markers of cluster 1
cluster1.markers <- FindMarkers(pbmc, ident.1 = 1, min.pct = 0.25)
print(head(cluster1.markers, 5))
```

Example 62 (r):
```r
# find all markers of cluster 1
cluster1.markers <- FindMarkers(pbmc, ident.1 = 1, min.pct = 0.25)
print(head(cluster1.markers, 5))
```

Example 63 (unknown):
```unknown
##        p_val avg_diff pct.1 pct.2
## S100A9     0 3.827593 0.996 0.216
## S100A8     0 3.786535 0.973 0.123
## LYZ        0 3.116197 1.000 0.517
## LGALS2     0 2.634722 0.908 0.060
## FCN1       0 2.369524 0.956 0.150
```

Example 64 (unknown):
```unknown
##        p_val avg_diff pct.1 pct.2
## S100A9     0 3.827593 0.996 0.216
## S100A8     0 3.786535 0.973 0.123
## LYZ        0 3.116197 1.000 0.517
## LGALS2     0 2.634722 0.908 0.060
## FCN1       0 2.369524 0.956 0.150
```

Example 65 (r):
```r
# find all markers distinguishing cluster 5 from clusters 0 and 3
cluster5.markers <- FindMarkers(pbmc, 5, c(0,3), min.pct = 0.25)
print(head(cluster5.markers, 5))
```

Example 66 (r):
```r
# find all markers distinguishing cluster 5 from clusters 0 and 3
cluster5.markers <- FindMarkers(pbmc, 5, c(0,3), min.pct = 0.25)
print(head(cluster5.markers, 5))
```

Example 67 (unknown):
```unknown
##               p_val   avg_diff pct.1 pct.2
## GNLY  3.466387e-171  3.5147178 0.961 0.143
## RPS12 4.191523e-170 -1.0195287 0.994 1.000
## NKG7  1.266864e-159  2.3523369 1.000 0.307
## GZMB  8.416814e-158  3.1950212 0.955 0.084
## RPS27 5.655551e-157 -0.9156105 0.987 0.999
```

Example 68 (unknown):
```unknown
##               p_val   avg_diff pct.1 pct.2
## GNLY  3.466387e-171  3.5147178 0.961 0.143
## RPS12 4.191523e-170 -1.0195287 0.994 1.000
## NKG7  1.266864e-159  2.3523369 1.000 0.307
## GZMB  8.416814e-158  3.1950212 0.955 0.084
## RPS27 5.655551e-157 -0.9156105 0.987 0.999
```

Example 69 (r):
```r
# find markers for every cluster compared to all remaining cells, report only the positive ones
pbmc.markers <- FindAllMarkers(pbmc, only.pos = TRUE, min.pct = 0.25, thresh.use = 0.25)
pbmc.markers %>% group_by(cluster) %>% top_n(2, avg_diff)
```

Example 70 (r):
```r
# find markers for every cluster compared to all remaining cells, report only the positive ones
pbmc.markers <- FindAllMarkers(pbmc, only.pos = TRUE, min.pct = 0.25, thresh.use = 0.25)
pbmc.markers %>% group_by(cluster) %>% top_n(2, avg_diff)
```

Example 71 (unknown):
```unknown
## Source: local data frame [16 x 6]
## Groups: cluster [8]
## 
##            p_val avg_diff pct.1 pct.2 cluster     gene
##            <dbl>    <dbl> <dbl> <dbl>  <fctr>    <chr>
## 1  1.382491e-268 1.150398 0.925 0.483       0     LDHB
## 2  1.625949e-132 1.064122 0.662 0.203       0     IL7R
## 3   0.000000e+00 3.827593 0.996 0.216       1   S100A9
## 4   0.000000e+00 3.786535 0.973 0.123       1   S100A8
## 5   0.000000e+00 2.977399 0.936 0.042       2    CD79A
## 6  1.030004e-191 2.492236 0.624 0.022       2    TCL1A
## 7  1.404612e-232 2.172409 0.974 0.229       3     CCL5
## 8  9.415562e-125 2.110316 0.586 0.050       3     GZMK
## 9  1.304430e-165 2.151881 1.000 0.316       4     LST1
## 10 1.420369e-138 2.275509 0.962 0.137       4   FCGR3A
## 11 1.127318e-215 3.763928 0.961 0.131       5     GNLY
## 12 8.182907e-187 3.334634 0.955 0.068       5     GZMB
## 13  3.261141e-48 2.729243 0.844 0.011       6   FCER1A
## 14  7.655042e-30 1.965168 1.000 0.513       6 HLA-DPB1
## 15  1.165274e-56 5.889503 1.000 0.023       7     PPBP
## 16  3.238887e-44 4.952160 0.933 0.010       7      PF4
```

Example 72 (unknown):
```unknown
## Source: local data frame [16 x 6]
## Groups: cluster [8]
## 
##            p_val avg_diff pct.1 pct.2 cluster     gene
##            <dbl>    <dbl> <dbl> <dbl>  <fctr>    <chr>
## 1  1.382491e-268 1.150398 0.925 0.483       0     LDHB
## 2  1.625949e-132 1.064122 0.662 0.203       0     IL7R
## 3   0.000000e+00 3.827593 0.996 0.216       1   S100A9
## 4   0.000000e+00 3.786535 0.973 0.123       1   S100A8
## 5   0.000000e+00 2.977399 0.936 0.042       2    CD79A
## 6  1.030004e-191 2.492236 0.624 0.022       2    TCL1A
## 7  1.404612e-232 2.172409 0.974 0.229       3     CCL5
## 8  9.415562e-125 2.110316 0.586 0.050       3     GZMK
## 9  1.304430e-165 2.151881 1.000 0.316       4     LST1
## 10 1.420369e-138 2.275509 0.962 0.137       4   FCGR3A
## 11 1.127318e-215 3.763928 0.961 0.131       5     GNLY
## 12 8.182907e-187 3.334634 0.955 0.068       5     GZMB
## 13  3.261141e-48 2.729243 0.844 0.011       6   FCER1A
## 14  7.655042e-30 1.965168 1.000 0.513       6 HLA-DPB1
## 15  1.165274e-56 5.889503 1.000 0.023       7     PPBP
## 16  3.238887e-44 4.952160 0.933 0.010       7      PF4
```

Example 73 (r):
```r
cluster1.markers <- FindMarkers(pbmc, ident.1 = 0, thresh.use = 0.25, test.use = "roc",only.pos = T)
```

Example 74 (r):
```r
cluster1.markers <- FindMarkers(pbmc, ident.1 = 0, thresh.use = 0.25, test.use = "roc",only.pos = T)
```

Example 75 (r):
```r
VlnPlot(pbmc, c("MS4A1","CD79A"))
```

Example 76 (r):
```r
VlnPlot(pbmc, c("MS4A1","CD79A"))
```

Example 77 (r):
```r
#you can plot raw UMI counts as well
VlnPlot(pbmc, c("NKG7","PF4"),use.raw = T,y.log = T)
```

Example 78 (r):
```r
#you can plot raw UMI counts as well
VlnPlot(pbmc, c("NKG7","PF4"),use.raw = T,y.log = T)
```

Example 79 (r):
```r
FeaturePlot(pbmc, c("MS4A1", "GNLY","CD3E","CD14","FCER1A","FCGR3A", "LYZ", "PPBP", "CD8A"),cols.use = c("grey","blue"))
```

Example 80 (r):
```r
FeaturePlot(pbmc, c("MS4A1", "GNLY","CD3E","CD14","FCER1A","FCGR3A", "LYZ", "PPBP", "CD8A"),cols.use = c("grey","blue"))
```

Example 81 (r):
```r
pbmc.markers %>% group_by(cluster) %>% top_n(10, avg_diff) -> top10
# setting slim.col.label to TRUE will print just the cluster IDS instead of every cell name
DoHeatmap(pbmc, genes.use = top10$gene, order.by.ident = TRUE, slim.col.label = TRUE, remove.key = TRUE)
```

Example 82 (r):
```r
pbmc.markers %>% group_by(cluster) %>% top_n(10, avg_diff) -> top10
# setting slim.col.label to TRUE will print just the cluster IDS instead of every cell name
DoHeatmap(pbmc, genes.use = top10$gene, order.by.ident = TRUE, slim.col.label = TRUE, remove.key = TRUE)
```

Example 83 (r):
```r
current.cluster.ids <- c(0, 1, 2, 3, 4, 5, 6, 7)
new.cluster.ids <- c("CD4 T cells", "CD14+ Monocytes", "B cells", "CD8 T cells", "FCGR3A+ Monocytes", "NK cells", "Dendritic cells", "Megakaryocytes")
pbmc@ident <- plyr::mapvalues(pbmc@ident, from = current.cluster.ids, to = new.cluster.ids)
TSNEPlot(pbmc, do.label = T, pt.size = 0.5)
```

Example 84 (r):
```r
current.cluster.ids <- c(0, 1, 2, 3, 4, 5, 6, 7)
new.cluster.ids <- c("CD4 T cells", "CD14+ Monocytes", "B cells", "CD8 T cells", "FCGR3A+ Monocytes", "NK cells", "Dendritic cells", "Megakaryocytes")
pbmc@ident <- plyr::mapvalues(pbmc@ident, from = current.cluster.ids, to = new.cluster.ids)
TSNEPlot(pbmc, do.label = T, pt.size = 0.5)
```

Example 85 (unknown):
```unknown
resolution=0.8
```

Example 86 (unknown):
```unknown
object@ident
```

Example 87 (r):
```r
#First lets stash our identities for later
pbmc <- StashIdent(pbmc, save.name = "ClusterNames_0.6")

#Note that if you set save.snn=T above, you don't need to recalculate the SNN, and can simply put : pbmc=FindClusters(pbmc,resolution = 0.8)
pbmc <- FindClusters(pbmc, pc.use = 1:10, resolution = 0.8, print.output = F)

#Demonstration of how to plot two tSNE plots side by side, and how to color points based on different criteria
plot1 <- TSNEPlot(pbmc, do.return = T, no.legend = TRUE, do.label = T)
plot2 <- TSNEPlot(pbmc, do.return = T, group.by = "ClusterNames_0.6", no.legend = TRUE, do.label = T)
MultiPlotList(list(plot1, plot2), cols = 2)
```

Example 88 (r):
```r
#First lets stash our identities for later
pbmc <- StashIdent(pbmc, save.name = "ClusterNames_0.6")

#Note that if you set save.snn=T above, you don't need to recalculate the SNN, and can simply put : pbmc=FindClusters(pbmc,resolution = 0.8)
pbmc <- FindClusters(pbmc, pc.use = 1:10, resolution = 0.8, print.output = F)

#Demonstration of how to plot two tSNE plots side by side, and how to color points based on different criteria
plot1 <- TSNEPlot(pbmc, do.return = T, no.legend = TRUE, do.label = T)
plot2 <- TSNEPlot(pbmc, do.return = T, group.by = "ClusterNames_0.6", no.legend = TRUE, do.label = T)
MultiPlotList(list(plot1, plot2), cols = 2)
```

Example 89 (r):
```r
#Find discriminating markers
tcell.markers <- FindMarkers(pbmc, 0, 1)

#Most of the markers tend to be expressed in C1 (i.e. S100A4). However, we can see that CCR7 is upregulated in C0, strongly indicating that we can differentiate memory from naive CD4 cells.
#cols.use demarcates the color palette from low to high expression
FeaturePlot(pbmc, c("S100A4", "CCR7"), cols.use = c("green", "blue"))
```

Example 90 (r):
```r
#Find discriminating markers
tcell.markers <- FindMarkers(pbmc, 0, 1)

#Most of the markers tend to be expressed in C1 (i.e. S100A4). However, we can see that CCR7 is upregulated in C0, strongly indicating that we can differentiate memory from naive CD4 cells.
#cols.use demarcates the color palette from low to high expression
FeaturePlot(pbmc, c("S100A4", "CCR7"), cols.use = c("green", "blue"))
```

Example 91 (r):
```r
pbmc <- SetAllIdent(pbmc, id = "ClusterNames_0.6")
```

Example 92 (r):
```r
pbmc <- SetAllIdent(pbmc, id = "ClusterNames_0.6")
```

---

## Get Started - V1.3-1.4

**URL:** http://127.0.0.1:9173/seurat/archive/v1.4/get_started_v1_4/index.html

---

## Seurat - Guided Clustering Tutorial

**URL:** http://127.0.0.1:9173/seurat/archive/v3.2/pbmc3k_tutorial/index.html

**Contents:**
- Seurat - Guided Clustering Tutorial
    - Compiled: October 02, 2020
  - Setup the Seurat Object
  - Standard pre-processing workflow
    - QC and selecting cells for further analysis
  - Normalizing the data
  - Identification of highly variable features (feature selection)
  - Scaling the data
  - Perform linear dimensional reduction
  - Determine the 'dimensionality' of the dataset
  - Cluster the cells
  - Run non-linear dimensional reduction (UMAP/tSNE)
  - Finding differentially expressed features (cluster biomarkers)
  - Assigning cell type identity to clusters

For this tutorial, we will be analyzing the a dataset of Peripheral Blood Mononuclear Cells (PBMC) freely available from 10X Genomics. There are 2,700 single cells that were sequenced on the Illumina NextSeq 500. The raw data can be found here.

We start by reading in the data. The Read10X function reads in the output of the cellranger pipeline from 10X, returning a unique molecular identified (UMI) count matrix. The values in this matrix represent the number of molecules for each feature (i.e. gene; row) that are detected in each cell (column).

We next use the count matrix to create a Seurat object. The object serves as a container that contains both data (like the count matrix) and analysis (like PCA, or clustering results) for a single-cell dataset. For a technical discussion of the Seurat object structure, check out our GitHub Wiki. For example, the count matrix is stored in pbmc[["RNA"]]@counts.

What does data in a count matrix look like?

The . values in the matrix represent 0s (no molecules detected). Since most values in an scRNA-seq matrix are 0, Seurat uses a sparse-matrix representation whenever possible. This results in significant memory and speed savings for Drop-seq/inDrop/10x data.

The steps below encompass the standard pre-processing workflow for scRNA-seq data in Seurat. These represent the selection and filtration of cells based on QC metrics, data normalization and scaling, and the detection of highly variable features.

Seurat allows you to easily explore QC metrics and filter cells based on any user-defined criteria. A few QC metrics commonly used by the community include

Where are QC metrics stored in Seurat?

In the example below, we visualize QC metrics, and use these to filter cells.

After removing unwanted cells from the dataset, the next step is to normalize the data. By default, we employ a global-scaling normalization method "LogNormalize" that normalizes the feature expression measurements for each cell by the total expression, multiplies this by a scale factor (10,000 by default), and log-transforms the result. Normalized values are stored in pbmc[["RNA"]]@data.

For clarity, in this previous line of code (and in future commands), we provide the default values for certain parameters in the function call. However, this isn't required and the same behavior can be achieved with:

We next calculate a subset of features that exhibit high cell-to-cell variation in the dataset (i.e, they are highly expressed in some cells, and lowly expressed in others). We and others have found that focusing on these genes in downstream analysis helps to highlight biological signal in single-cell datasets.

Our procedure in Seurat3 is described in detail here, and improves on previous versions by directly modeling the mean-variance relationship inherent in single-cell data, and is implemented in the FindVariableFeatures function. By default, we return 2,000 features per dataset. These will be used in downstream analysis, like PCA.

Next, we apply a linear transformation ('scaling') that is a standard pre-processing step prior to dimensional reduction techniques like PCA. The ScaleData function:

This step takes too long! Can I make it faster?

Scaling is an essential step in the Seurat workflow, but only on genes that will be used as input to PCA. Therefore, the default in ScaleData is only to perform scaling on the previously identified variable features (2,000 by default). To do this, omit the features argument in the previous function call, i.e.

Your PCA and clustering results will be unaffected. However, Seurat heatmaps (produced as shown below with DoHeatmap) require genes in the heatmap to be scaled, to make sure highly-expressed genes don't dominate the heatmap. To make sure we don't leave any genes out of the heatmap later, we are scaling all genes in this tutorial. How can I remove unwanted sources of variation, as in Seurat v2?

In Seurat v2 we also use the ScaleData function to remove unwanted sources of variation from a single-cell dataset. For example, we could 'regress out' heterogeneity associated with (for example) cell cycle stage, or mitochondrial contamination. These features are still supported in ScaleData in Seurat v3, i.e.:

However, particularly for advanced users who would like to use this functionality, we strongly recommend the use of our new normalization workflow, sctransform. The method is described in our recent preprint, with a separate vignette using Seurat v3 here. As with ScaleData, the function SCTransform also includes a vars.to.regress parameter.

Next we perform PCA on the scaled data. By default, only the previously determined variable features are used as input, but can be defined using features argument if you wish to choose a different subset.

Seurat provides several useful ways of visualizing both cells and features that define the PCA, including VizDimReduction, DimPlot, and DimHeatmap

In particular DimHeatmap allows for easy exploration of the primary sources of heterogeneity in a dataset, and can be useful when trying to decide which PCs to include for further downstream analyses. Both cells and features are ordered according to their PCA scores. Setting cells to a number plots the 'extreme' cells on both ends of the spectrum, which dramatically speeds plotting for large datasets. Though clearly a supervised analysis, we find this to be a valuable tool for exploring correlated feature sets.

To overcome the extensive technical noise in any single feature for scRNA-seq data, Seurat clusters cells based on their PCA scores, with each PC essentially representing a 'metafeature' that combines information across a correlated feature set. The top principal components therefore represent a robust compression of the dataset. However, how many componenets should we choose to include? 10? 20? 100?

In Macosko et al, we implemented a resampling test inspired by the JackStraw procedure. We randomly permute a subset of the data (1% by default) and rerun PCA, constructing a 'null distribution' of feature scores, and repeat this procedure. We identify 'significant' PCs as those who have a strong enrichment of low p-value features.

The JackStrawPlot function provides a visualization tool for comparing the distribution of p-values for each PC with a uniform distribution (dashed line). 'Significant' PCs will show a strong enrichment of features with low p-values (solid curve above the dashed line). In this case it appears that there is a sharp drop-off in significance after the first 10-12 PCs.

An alternative heuristic method generates an 'Elbow plot': a ranking of principle components based on the percentage of variance explained by each one (ElbowPlot function). In this example, we can observe an 'elbow' around PC9-10, suggesting that the majority of true signal is captured in the first 10 PCs.

Identifying the true dimensionality of a dataset -- can be challenging/uncertain for the user. We therefore suggest these three approaches to consider. The first is more supervised, exploring PCs to determine relevant sources of heterogeneity, and could be used in conjunction with GSEA for example. The second implements a statistical test based on a random null model, but is time-consuming for large datasets, and may not return a clear PC cutoff. The third is a heuristic that is commonly used, and can be calculated instantly. In this example, all three approaches yielded similar results, but we might have been justified in choosing anything between PC 7-12 as a cutoff.

We chose 10 here, but encourage users to consider the following:

Seurat v3 applies a graph-based clustering approach, building upon initial strategies in (Macosko et al). Importantly, the distance metric which drives the clustering analysis (based on previously identified PCs) remains the same. However, our approach to partioning the cellular distance matrix into clusters has dramatically improved. Our approach was heavily inspired by recent manuscripts which applied graph-based clustering approaches to scRNA-seq data [SNN-Cliq, Xu and Su, Bioinformatics, 2015] and CyTOF data [PhenoGraph, Levine et al., Cell, 2015]. Briefly, these methods embed cells in a graph structure - for example a K-nearest neighbor (KNN) graph, with edges drawn between cells with similar feature expression patterns, and then attempt to partition this graph into highly interconnected 'quasi-cliques' or 'communities'.

As in PhenoGraph, we first construct a KNN graph based on the euclidean distance in PCA space, and refine the edge weights between any two cells based on the shared overlap in their local neighborhoods (Jaccard similarity). This step is performed using the FindNeighbors function, and takes as input the previously defined dimensionality of the dataset (first 10 PCs).

To cluster the cells, we next apply modularity optimization techniques such as the Louvain algorithm (default) or SLM [SLM, Blondel et al., Journal of Statistical Mechanics], to iteratively group cells together, with the goal of optimizing the standard modularity function. The FindClusters function implements this procedure, and contains a resolution parameter that sets the 'granularity' of the downstream clustering, with increased values leading to a greater number of clusters. We find that setting this parameter between 0.4-1.2 typically returns good results for single-cell datasets of around 3K cells. Optimal resolution often increases for larger datasets. The clusters can be found using the Idents function.

Seurat offers several non-linear dimensional reduction techniques, such as tSNE and UMAP, to visualize and explore these datasets. The goal of these algorithms is to learn the underlying manifold of the data in order to place similar cells together in low-dimensional space. Cells within the graph-based clusters determined above should co-localize on these dimension reduction plots. As input to the UMAP and tSNE, we suggest using the same PCs as input to the clustering analysis.

You can save the object at this point so that it can easily be loaded back in without having to rerun the computationally intensive steps performed above, or easily shared with collaborators.

Seurat can help you find markers that define clusters via differential expression. By default, it identifes positive and negative markers of a single cluster (specified in ident.1), compared to all other cells. FindAllMarkers automates this process for all clusters, but you can also test groups of clusters vs. each other, or against all cells.

The min.pct argument requires a feature to be detected at a minimum percentage in either of the two groups of cells, and the thresh.test argument requires a feature to be differentially expressed (on average) by some amount between the two groups. You can set both of these to 0, but with a dramatic increase in time - since this will test a large number of features that are unlikely to be highly discriminatory. As another option to speed up these computations, max.cells.per.ident can be set. This will downsample each identity class to have no more cells than whatever this is set to. While there is generally going to be a loss in power, the speed increases can be significiant and the most highly differentially expressed features will likely still rise to the top.

Seurat has several tests for differential expression which can be set with the test.use parameter (see our DE vignette for details). For example, the ROC test returns the 'classification power' for any individual marker (ranging from 0 - random, to 1 - perfect).

We include several tools for visualizing marker expression. VlnPlot (shows expression probability distributions across clusters), and FeaturePlot (visualizes feature expression on a tSNE or PCA plot) are our most commonly used visualizations. We also suggest exploring RidgePlot, CellScatter, and DotPlot as additional methods to view your dataset.

DoHeatmap generates an expression heatmap for given cells and features. In this case, we are plotting the top 20 markers (or all markers if less than 20) for each cluster.

Fortunately in the case of this dataset, we can use canonical markers to easily match the unbiased clustering to known cell types:

**Examples:**

Example 1 (unknown):
```unknown
pbmc[["RNA"]]@counts
```

Example 2 (r):
```r
library(dplyr)
library(Seurat)
library(patchwork)

# Load the PBMC dataset
pbmc.data <- Read10X(data.dir = "../data/pbmc3k/filtered_gene_bc_matrices/hg19/")
# Initialize the Seurat object with the raw (non-normalized data).
pbmc <- CreateSeuratObject(counts = pbmc.data, project = "pbmc3k", min.cells = 3, min.features = 200)
pbmc
```

Example 3 (r):
```r
library(dplyr)
library(Seurat)
library(patchwork)

# Load the PBMC dataset
pbmc.data <- Read10X(data.dir = "../data/pbmc3k/filtered_gene_bc_matrices/hg19/")
# Initialize the Seurat object with the raw (non-normalized data).
pbmc <- CreateSeuratObject(counts = pbmc.data, project = "pbmc3k", min.cells = 3, min.features = 200)
pbmc
```

Example 4 (python):
```python
## An object of class Seurat 
## 13714 features across 2700 samples within 1 assay 
## Active assay: RNA (13714 features, 0 variable features)
```

Example 5 (python):
```python
## An object of class Seurat 
## 13714 features across 2700 samples within 1 assay 
## Active assay: RNA (13714 features, 0 variable features)
```

Example 6 (r):
```r
# Lets examine a few genes in the first thirty cells
pbmc.data[c("CD3D", "TCL1A", "MS4A1"), 1:30]
```

Example 7 (r):
```r
# Lets examine a few genes in the first thirty cells
pbmc.data[c("CD3D", "TCL1A", "MS4A1"), 1:30]
```

Example 8 (python):
```python
## 3 x 30 sparse Matrix of class "dgCMatrix"
##                                                                    
## CD3D  4 . 10 . . 1 2 3 1 . . 2 7 1 . . 1 3 . 2  3 . . . . . 3 4 1 5
## TCL1A . .  . . . . . . 1 . . . . . . . . . . .  . 1 . . . . . . . .
## MS4A1 . 6  . . . . . . 1 1 1 . . . . . . . . . 36 1 2 . . 2 . . . .
```

Example 9 (python):
```python
## 3 x 30 sparse Matrix of class "dgCMatrix"
##                                                                    
## CD3D  4 . 10 . . 1 2 3 1 . . 2 7 1 . . 1 3 . 2  3 . . . . . 3 4 1 5
## TCL1A . .  . . . . . . 1 . . . . . . . . . . .  . 1 . . . . . . . .
## MS4A1 . 6  . . . . . . 1 1 1 . . . . . . . . . 36 1 2 . . 2 . . . .
```

Example 10 (r):
```r
dense.size <- object.size(as.matrix(pbmc.data))
dense.size
```

Example 11 (r):
```r
dense.size <- object.size(as.matrix(pbmc.data))
dense.size
```

Example 12 (unknown):
```unknown
## 709591472 bytes
```

Example 13 (unknown):
```unknown
## 709591472 bytes
```

Example 14 (r):
```r
sparse.size <- object.size(pbmc.data)
sparse.size
```

Example 15 (r):
```r
sparse.size <- object.size(pbmc.data)
sparse.size
```

Example 16 (unknown):
```unknown
## 29905192 bytes
```

Example 17 (unknown):
```unknown
## 29905192 bytes
```

Example 18 (r):
```r
dense.size/sparse.size
```

Example 19 (r):
```r
dense.size/sparse.size
```

Example 20 (unknown):
```unknown
## 23.7 bytes
```

Example 21 (unknown):
```unknown
## 23.7 bytes
```

Example 22 (unknown):
```unknown
PercentageFeatureSet
```

Example 23 (r):
```r
# The [[ operator can add columns to object metadata. This is a great place to stash QC stats
pbmc[["percent.mt"]] <- PercentageFeatureSet(pbmc, pattern = "^MT-")
```

Example 24 (r):
```r
# The [[ operator can add columns to object metadata. This is a great place to stash QC stats
pbmc[["percent.mt"]] <- PercentageFeatureSet(pbmc, pattern = "^MT-")
```

Example 25 (unknown):
```unknown
CreateSeuratObject
```

Example 26 (r):
```r
# Show QC metrics for the first 5 cells
head(pbmc@meta.data, 5)
```

Example 27 (r):
```r
# Show QC metrics for the first 5 cells
head(pbmc@meta.data, 5)
```

Example 28 (r):
```r
# Visualize QC metrics as a violin plot
VlnPlot(pbmc, features = c("nFeature_RNA", "nCount_RNA", "percent.mt"), ncol = 3)
```

Example 29 (r):
```r
# Visualize QC metrics as a violin plot
VlnPlot(pbmc, features = c("nFeature_RNA", "nCount_RNA", "percent.mt"), ncol = 3)
```

Example 30 (r):
```r
# FeatureScatter is typically used to visualize feature-feature relationships, but can be used
# for anything calculated by the object, i.e. columns in object metadata, PC scores etc.

plot1 <- FeatureScatter(pbmc, feature1 = "nCount_RNA", feature2 = "percent.mt")
plot2 <- FeatureScatter(pbmc, feature1 = "nCount_RNA", feature2 = "nFeature_RNA")
plot1 + plot2
```

Example 31 (r):
```r
# FeatureScatter is typically used to visualize feature-feature relationships, but can be used
# for anything calculated by the object, i.e. columns in object metadata, PC scores etc.

plot1 <- FeatureScatter(pbmc, feature1 = "nCount_RNA", feature2 = "percent.mt")
plot2 <- FeatureScatter(pbmc, feature1 = "nCount_RNA", feature2 = "nFeature_RNA")
plot1 + plot2
```

Example 32 (r):
```r
pbmc <- subset(pbmc, subset = nFeature_RNA > 200 & nFeature_RNA < 2500 & percent.mt < 5)
```

Example 33 (r):
```r
pbmc <- subset(pbmc, subset = nFeature_RNA > 200 & nFeature_RNA < 2500 & percent.mt < 5)
```

Example 34 (unknown):
```unknown
pbmc[["RNA"]]@data
```

Example 35 (r):
```r
pbmc <- NormalizeData(pbmc, normalization.method = "LogNormalize", scale.factor = 10000)
```

Example 36 (r):
```r
pbmc <- NormalizeData(pbmc, normalization.method = "LogNormalize", scale.factor = 10000)
```

Example 37 (r):
```r
pbmc <- NormalizeData(pbmc)
```

Example 38 (r):
```r
pbmc <- NormalizeData(pbmc)
```

Example 39 (unknown):
```unknown
FindVariableFeatures
```

Example 40 (r):
```r
pbmc <- FindVariableFeatures(pbmc, selection.method = "vst", nfeatures = 2000)

# Identify the 10 most highly variable genes
top10 <- head(VariableFeatures(pbmc), 10)

# plot variable features with and without labels
plot1 <- VariableFeaturePlot(pbmc)
plot2 <- LabelPoints(plot = plot1, points = top10, repel = TRUE)
plot1 + plot2
```

Example 41 (r):
```r
pbmc <- FindVariableFeatures(pbmc, selection.method = "vst", nfeatures = 2000)

# Identify the 10 most highly variable genes
top10 <- head(VariableFeatures(pbmc), 10)

# plot variable features with and without labels
plot1 <- VariableFeaturePlot(pbmc)
plot2 <- LabelPoints(plot = plot1, points = top10, repel = TRUE)
plot1 + plot2
```

Example 42 (unknown):
```unknown
pbmc[["RNA"]]@scale.data
```

Example 43 (r):
```r
all.genes <- rownames(pbmc)
pbmc <- ScaleData(pbmc, features = all.genes)
```

Example 44 (r):
```r
all.genes <- rownames(pbmc)
pbmc <- ScaleData(pbmc, features = all.genes)
```

Example 45 (r):
```r
pbmc <- ScaleData(pbmc)
```

Example 46 (r):
```r
pbmc <- ScaleData(pbmc)
```

Example 47 (r):
```r
pbmc <- ScaleData(pbmc, vars.to.regress = "percent.mt")
```

Example 48 (r):
```r
pbmc <- ScaleData(pbmc, vars.to.regress = "percent.mt")
```

Example 49 (unknown):
```unknown
sctransform
```

Example 50 (unknown):
```unknown
SCTransform
```

Example 51 (unknown):
```unknown
vars.to.regress
```

Example 52 (r):
```r
pbmc <- RunPCA(pbmc, features = VariableFeatures(object = pbmc))
```

Example 53 (r):
```r
pbmc <- RunPCA(pbmc, features = VariableFeatures(object = pbmc))
```

Example 54 (unknown):
```unknown
VizDimReduction
```

Example 55 (r):
```r
# Examine and visualize PCA results a few different ways
print(pbmc[["pca"]], dims = 1:5, nfeatures = 5)
```

Example 56 (r):
```r
# Examine and visualize PCA results a few different ways
print(pbmc[["pca"]], dims = 1:5, nfeatures = 5)
```

Example 57 (unknown):
```unknown
## PC_ 1 
## Positive:  CST3, TYROBP, LST1, AIF1, FTL 
## Negative:  MALAT1, LTB, IL32, IL7R, CD2 
## PC_ 2 
## Positive:  CD79A, MS4A1, TCL1A, HLA-DQA1, HLA-DQB1 
## Negative:  NKG7, PRF1, CST7, GZMB, GZMA 
## PC_ 3 
## Positive:  HLA-DQA1, CD79A, CD79B, HLA-DQB1, HLA-DPB1 
## Negative:  PPBP, PF4, SDPR, SPARC, GNG11 
## PC_ 4 
## Positive:  HLA-DQA1, CD79B, CD79A, MS4A1, HLA-DQB1 
## Negative:  VIM, IL7R, S100A6, IL32, S100A8 
## PC_ 5 
## Positive:  GZMB, NKG7, S100A8, FGFBP2, GNLY 
## Negative:  LTB, IL7R, CKB, VIM, MS4A7
```

Example 58 (unknown):
```unknown
## PC_ 1 
## Positive:  CST3, TYROBP, LST1, AIF1, FTL 
## Negative:  MALAT1, LTB, IL32, IL7R, CD2 
## PC_ 2 
## Positive:  CD79A, MS4A1, TCL1A, HLA-DQA1, HLA-DQB1 
## Negative:  NKG7, PRF1, CST7, GZMB, GZMA 
## PC_ 3 
## Positive:  HLA-DQA1, CD79A, CD79B, HLA-DQB1, HLA-DPB1 
## Negative:  PPBP, PF4, SDPR, SPARC, GNG11 
## PC_ 4 
## Positive:  HLA-DQA1, CD79B, CD79A, MS4A1, HLA-DQB1 
## Negative:  VIM, IL7R, S100A6, IL32, S100A8 
## PC_ 5 
## Positive:  GZMB, NKG7, S100A8, FGFBP2, GNLY 
## Negative:  LTB, IL7R, CKB, VIM, MS4A7
```

Example 59 (r):
```r
VizDimLoadings(pbmc, dims = 1:2, reduction = "pca")
```

Example 60 (r):
```r
VizDimLoadings(pbmc, dims = 1:2, reduction = "pca")
```

Example 61 (r):
```r
DimPlot(pbmc, reduction = "pca")
```

Example 62 (r):
```r
DimPlot(pbmc, reduction = "pca")
```

Example 63 (r):
```r
DimHeatmap(pbmc, dims = 1, cells = 500, balanced = TRUE)
```

Example 64 (r):
```r
DimHeatmap(pbmc, dims = 1, cells = 500, balanced = TRUE)
```

Example 65 (r):
```r
DimHeatmap(pbmc, dims = 1:15, cells = 500, balanced = TRUE)
```

Example 66 (r):
```r
DimHeatmap(pbmc, dims = 1:15, cells = 500, balanced = TRUE)
```

Example 67 (r):
```r
# NOTE: This process can take a long time for big datasets, comment out for expediency. More
# approximate techniques such as those implemented in ElbowPlot() can be used to reduce
# computation time
pbmc <- JackStraw(pbmc, num.replicate = 100)
pbmc <- ScoreJackStraw(pbmc, dims = 1:20)
```

Example 68 (r):
```r
# NOTE: This process can take a long time for big datasets, comment out for expediency. More
# approximate techniques such as those implemented in ElbowPlot() can be used to reduce
# computation time
pbmc <- JackStraw(pbmc, num.replicate = 100)
pbmc <- ScoreJackStraw(pbmc, dims = 1:20)
```

Example 69 (unknown):
```unknown
JackStrawPlot
```

Example 70 (r):
```r
JackStrawPlot(pbmc, dims = 1:15)
```

Example 71 (r):
```r
JackStrawPlot(pbmc, dims = 1:15)
```

Example 72 (r):
```r
ElbowPlot(pbmc)
```

Example 73 (r):
```r
ElbowPlot(pbmc)
```

Example 74 (unknown):
```unknown
FindNeighbors
```

Example 75 (unknown):
```unknown
FindClusters
```

Example 76 (r):
```r
pbmc <- FindNeighbors(pbmc, dims = 1:10)
pbmc <- FindClusters(pbmc, resolution = 0.5)
```

Example 77 (r):
```r
pbmc <- FindNeighbors(pbmc, dims = 1:10)
pbmc <- FindClusters(pbmc, resolution = 0.5)
```

Example 78 (unknown):
```unknown
## Modularity Optimizer version 1.3.0 by Ludo Waltman and Nees Jan van Eck
## 
## Number of nodes: 2638
## Number of edges: 96033
## 
## Running Louvain algorithm...
## Maximum modularity in 10 random starts: 0.8720
## Number of communities: 9
## Elapsed time: 0 seconds
```

Example 79 (unknown):
```unknown
## Modularity Optimizer version 1.3.0 by Ludo Waltman and Nees Jan van Eck
## 
## Number of nodes: 2638
## Number of edges: 96033
## 
## Running Louvain algorithm...
## Maximum modularity in 10 random starts: 0.8720
## Number of communities: 9
## Elapsed time: 0 seconds
```

Example 80 (r):
```r
# Look at cluster IDs of the first 5 cells
head(Idents(pbmc), 5)
```

Example 81 (r):
```r
# Look at cluster IDs of the first 5 cells
head(Idents(pbmc), 5)
```

Example 82 (unknown):
```unknown
## AAACATACAACCAC-1 AAACATTGAGCTAC-1 AAACATTGATCAGC-1 AAACCGTGCTTCCG-1 
##                1                3                1                2 
## AAACCGTGTATGCG-1 
##                6 
## Levels: 0 1 2 3 4 5 6 7 8
```

Example 83 (unknown):
```unknown
## AAACATACAACCAC-1 AAACATTGAGCTAC-1 AAACATTGATCAGC-1 AAACCGTGCTTCCG-1 
##                1                3                1                2 
## AAACCGTGTATGCG-1 
##                6 
## Levels: 0 1 2 3 4 5 6 7 8
```

Example 84 (r):
```r
# If you haven't installed UMAP, you can do so via reticulate::py_install(packages =
# 'umap-learn')
pbmc <- RunUMAP(pbmc, dims = 1:10)
```

Example 85 (r):
```r
# If you haven't installed UMAP, you can do so via reticulate::py_install(packages =
# 'umap-learn')
pbmc <- RunUMAP(pbmc, dims = 1:10)
```

Example 86 (r):
```r
# note that you can set `label = TRUE` or use the LabelClusters function to help label
# individual clusters
DimPlot(pbmc, reduction = "umap")
```

Example 87 (r):
```r
# note that you can set `label = TRUE` or use the LabelClusters function to help label
# individual clusters
DimPlot(pbmc, reduction = "umap")
```

Example 88 (r):
```r
saveRDS(pbmc, file = "../output/pbmc_tutorial.rds")
```

Example 89 (r):
```r
saveRDS(pbmc, file = "../output/pbmc_tutorial.rds")
```

Example 90 (unknown):
```unknown
FindAllMarkers
```

Example 91 (unknown):
```unknown
max.cells.per.ident
```

Example 92 (r):
```r
# find all markers of cluster 1
cluster1.markers <- FindMarkers(pbmc, ident.1 = 1, min.pct = 0.25)
head(cluster1.markers, n = 5)
```

Example 93 (r):
```r
# find all markers of cluster 1
cluster1.markers <- FindMarkers(pbmc, ident.1 = 1, min.pct = 0.25)
head(cluster1.markers, n = 5)
```

Example 94 (r):
```r
# find all markers distinguishing cluster 5 from clusters 0 and 3
cluster5.markers <- FindMarkers(pbmc, ident.1 = 5, ident.2 = c(0, 3), min.pct = 0.25)
head(cluster5.markers, n = 5)
```

Example 95 (r):
```r
# find all markers distinguishing cluster 5 from clusters 0 and 3
cluster5.markers <- FindMarkers(pbmc, ident.1 = 5, ident.2 = c(0, 3), min.pct = 0.25)
head(cluster5.markers, n = 5)
```

Example 96 (r):
```r
# find markers for every cluster compared to all remaining cells, report only the positive ones
pbmc.markers <- FindAllMarkers(pbmc, only.pos = TRUE, min.pct = 0.25, logfc.threshold = 0.25)
pbmc.markers %>% group_by(cluster) %>% top_n(n = 2, wt = avg_logFC)
```

Example 97 (r):
```r
# find markers for every cluster compared to all remaining cells, report only the positive ones
pbmc.markers <- FindAllMarkers(pbmc, only.pos = TRUE, min.pct = 0.25, logfc.threshold = 0.25)
pbmc.markers %>% group_by(cluster) %>% top_n(n = 2, wt = avg_logFC)
```

Example 98 (r):
```r
cluster1.markers <- FindMarkers(pbmc, ident.1 = 0, logfc.threshold = 0.25, test.use = "roc", only.pos = TRUE)
```

Example 99 (r):
```r
cluster1.markers <- FindMarkers(pbmc, ident.1 = 0, logfc.threshold = 0.25, test.use = "roc", only.pos = TRUE)
```

Example 100 (unknown):
```unknown
FeaturePlot
```

Example 101 (unknown):
```unknown
CellScatter
```

Example 102 (r):
```r
VlnPlot(pbmc, features = c("MS4A1", "CD79A"))
```

Example 103 (r):
```r
VlnPlot(pbmc, features = c("MS4A1", "CD79A"))
```

Example 104 (r):
```r
# you can plot raw counts as well
VlnPlot(pbmc, features = c("NKG7", "PF4"), slot = "counts", log = TRUE)
```

Example 105 (r):
```r
# you can plot raw counts as well
VlnPlot(pbmc, features = c("NKG7", "PF4"), slot = "counts", log = TRUE)
```

Example 106 (r):
```r
FeaturePlot(pbmc, features = c("MS4A1", "GNLY", "CD3E", "CD14", "FCER1A", "FCGR3A", "LYZ", "PPBP", 
    "CD8A"))
```

Example 107 (r):
```r
FeaturePlot(pbmc, features = c("MS4A1", "GNLY", "CD3E", "CD14", "FCER1A", "FCGR3A", "LYZ", "PPBP", 
    "CD8A"))
```

Example 108 (r):
```r
top10 <- pbmc.markers %>% group_by(cluster) %>% top_n(n = 10, wt = avg_logFC)
DoHeatmap(pbmc, features = top10$gene) + NoLegend()
```

Example 109 (r):
```r
top10 <- pbmc.markers %>% group_by(cluster) %>% top_n(n = 10, wt = avg_logFC)
DoHeatmap(pbmc, features = top10$gene) + NoLegend()
```

Example 110 (r):
```r
new.cluster.ids <- c("Naive CD4 T", "Memory CD4 T", "CD14+ Mono", "B", "CD8 T", "FCGR3A+ Mono", 
    "NK", "DC", "Platelet")
names(new.cluster.ids) <- levels(pbmc)
pbmc <- RenameIdents(pbmc, new.cluster.ids)
DimPlot(pbmc, reduction = "umap", label = TRUE, pt.size = 0.5) + NoLegend()
```

Example 111 (r):
```r
new.cluster.ids <- c("Naive CD4 T", "Memory CD4 T", "CD14+ Mono", "B", "CD8 T", "FCGR3A+ Mono", 
    "NK", "DC", "Platelet")
names(new.cluster.ids) <- levels(pbmc)
pbmc <- RenameIdents(pbmc, new.cluster.ids)
DimPlot(pbmc, reduction = "umap", label = TRUE, pt.size = 0.5) + NoLegend()
```

Example 112 (r):
```r
saveRDS(pbmc, file = "../output/pbmc3k_final.rds")
```

Example 113 (r):
```r
saveRDS(pbmc, file = "../output/pbmc3k_final.rds")
```

---

## Guided Clustering of the Microwell-seq Mouse Cell Atlas

**URL:** http://127.0.0.1:9173/seurat/archive/v3.2/mca/index.html

**Contents:**
- Guided Clustering of the Microwell-seq Mouse Cell Atlas
    - Compiled: October 02, 2020
  - Setup the Seurat Object
  - Data Preprocessing
  - Dimensional Reduction (PCA)
  - Graph-based clustering
  - Visualization (t-SNE/UMAP)
  - Elapsed time for key steps

In the following tutorial, we examine the recently published Microwell-seq “Mouse Cell Atlas”, composed of hundreds of thousands of cells derived from all major mouse organs. For those that are getting started using Seurat, we recommend first working through our 3k PBMC tutorial, which introduces the basic functionality of the package.

Our goal is to demonstrate a workflow for handling very large datasets in Seurat, emphasizing recent improvements we have made for speed and memory efficiency. We do not perform downstream biological analyses on the resulting clusters, but encourage users to explore this dataset and interpret this exciting resource. All analyses here are performed in memory, but we also now support storage on-disk (using the HDF5-based loom framework). See this vignette for a workflow of the same MCA dataset using loomR.

The original data for the MCA is available here. For ease of getting started, we provide a sparse matrix R data file (.rds) file containing the combined expression matrix and the published metadata file here.

We will analyze ~242,000 cells that were assigned a cluster ID in the original study. As a result, we don’t do perform additional QC steps or filtration steps here.

We perform standard log-normalization.

FindVariableGenes calculates the variance and mean for each gene in the dataset in the dataset (storing this in object[[assay]]@meta.features). We have observed that for large-cell datasets with unique molecular identifiers, selecting highly variable genes (HVG) simply based on variance mean ratio (VMR) is an efficient and robust strategy. Here, we select the top 1,000 HVG for downstream analysis.

We calculate and regress out mitochondrial expression per cell.

We now cluster the data in lower-dimensional space. Our approach was heavily inspired by recent manuscripts which applied graph-based clustering approaches to scRNA-seq data [SNN-Cliq, Xu and Su, Bioinformatics, 2015] and CyTOF data [PhenoGraph, Levine et al., Cell, 2015].

We use the same principal components that were input for clustering, for two-dimensional visualization with t-SNE or UMAP.

These tests were performed on a desktop computer running Ubuntu 16.04.5 LTS with an Intel(R) Core(TM) i7-6800K CPU @ 3.40GHz and 96 GB of RAM.

**Examples:**

Example 1 (r):
```r
library(Seurat)
library(patchwork)
mca.matrix <- readRDS(file = "../data/MCA_merged_mat.rds")
mca.metadata <- read.csv(file = "../data/MCA_All-batch-removed-assignments.csv", row.names = 1)
```

Example 2 (r):
```r
library(Seurat)
library(patchwork)
mca.matrix <- readRDS(file = "../data/MCA_merged_mat.rds")
mca.metadata <- read.csv(file = "../data/MCA_All-batch-removed-assignments.csv", row.names = 1)
```

Example 3 (r):
```r
mca <- CreateSeuratObject(counts = mca.matrix, meta.data = mca.metadata, project = "MouseCellAtlas")
# Only keep annotated cells
mca <- subset(mca, cells = names(which(!is.na(mca$ClusterID))))
# Leaves us with 242k cells
mca
```

Example 4 (r):
```r
mca <- CreateSeuratObject(counts = mca.matrix, meta.data = mca.metadata, project = "MouseCellAtlas")
# Only keep annotated cells
mca <- subset(mca, cells = names(which(!is.na(mca$ClusterID))))
# Leaves us with 242k cells
mca
```

Example 5 (python):
```python
## An object of class Seurat 
## 39855 features across 242533 samples within 1 assay 
## Active assay: RNA (39855 features, 0 variable features)
```

Example 6 (python):
```python
## An object of class Seurat 
## 39855 features across 242533 samples within 1 assay 
## Active assay: RNA (39855 features, 0 variable features)
```

Example 7 (r):
```r
mca <- NormalizeData(mca, normalization.method = "LogNormalize", scale.factor = 10000)
```

Example 8 (r):
```r
mca <- NormalizeData(mca, normalization.method = "LogNormalize", scale.factor = 10000)
```

Example 9 (unknown):
```unknown
FindVariableGenes
```

Example 10 (unknown):
```unknown
object[[assay]]@meta.features
```

Example 11 (r):
```r
mca <- FindVariableFeatures(mca)
```

Example 12 (r):
```r
mca <- FindVariableFeatures(mca)
```

Example 13 (r):
```r
mca[["percent.mt"]] <- PercentageFeatureSet(mca, pattern = "^mt-")
mca <- ScaleData(mca, vars.to.regress = "percent.mt")
```

Example 14 (r):
```r
mca[["percent.mt"]] <- PercentageFeatureSet(mca, pattern = "^mt-")
mca <- ScaleData(mca, vars.to.regress = "percent.mt")
```

Example 15 (r):
```r
mca <- RunPCA(mca, npcs = 100, ndims.print = 1:5, nfeatures.print = 5)
```

Example 16 (r):
```r
mca <- RunPCA(mca, npcs = 100, ndims.print = 1:5, nfeatures.print = 5)
```

Example 17 (unknown):
```unknown
## PC_ 1 
## Positive:  Lyz2, S100a8, S100a6, S100a9, Igkc 
## Negative:  Fabp9, Meig1, Prm1, Ldhc, Prm2 
## PC_ 2 
## Positive:  Lypd8, Reg3b, Lgals2, Reg3g, Lgals4 
## Negative:  Sparc, Col2a1, Col9a2, Col9a1, Col9a3 
## PC_ 3 
## Positive:  Plp1, Mobp, Mag, Ermn, Cldn11 
## Negative:  Sparc, Mgp, Col2a1, Col9a2, Col9a1 
## PC_ 4 
## Positive:  Zpbp2, Hdgfl1, Pabpc6, Tmbim7, Tuba3a 
## Negative:  1700031M16Rik, 1700042G07Rik, 4930570D08Rik, 1700016P04Rik, H1fnt 
## PC_ 5 
## Positive:  Plp1, Mobp, Mag, Ermn, Cldn11 
## Negative:  S100a8, S100a9, Camp, Ngp, Ly6c2
```

Example 18 (unknown):
```unknown
## PC_ 1 
## Positive:  Lyz2, S100a8, S100a6, S100a9, Igkc 
## Negative:  Fabp9, Meig1, Prm1, Ldhc, Prm2 
## PC_ 2 
## Positive:  Lypd8, Reg3b, Lgals2, Reg3g, Lgals4 
## Negative:  Sparc, Col2a1, Col9a2, Col9a1, Col9a3 
## PC_ 3 
## Positive:  Plp1, Mobp, Mag, Ermn, Cldn11 
## Negative:  Sparc, Mgp, Col2a1, Col9a2, Col9a1 
## PC_ 4 
## Positive:  Zpbp2, Hdgfl1, Pabpc6, Tmbim7, Tuba3a 
## Negative:  1700031M16Rik, 1700042G07Rik, 4930570D08Rik, 1700016P04Rik, H1fnt 
## PC_ 5 
## Positive:  Plp1, Mobp, Mag, Ermn, Cldn11 
## Negative:  S100a8, S100a9, Camp, Ngp, Ly6c2
```

Example 19 (r):
```r
ElbowPlot(mca, ndims = 100)
```

Example 20 (r):
```r
ElbowPlot(mca, ndims = 100)
```

Example 21 (r):
```r
DimHeatmap(mca, dims = c(1:3, 70:75), cells = 500, balanced = TRUE)
```

Example 22 (r):
```r
DimHeatmap(mca, dims = c(1:3, 70:75), cells = 500, balanced = TRUE)
```

Example 23 (r):
```r
mca <- FindNeighbors(mca, reduction = "pca", dims = 1:75, nn.eps = 0.5)
mca <- FindClusters(mca, resolution = 3, n.start = 10)
```

Example 24 (r):
```r
mca <- FindNeighbors(mca, reduction = "pca", dims = 1:75, nn.eps = 0.5)
mca <- FindClusters(mca, resolution = 3, n.start = 10)
```

Example 25 (unknown):
```unknown
## Modularity Optimizer version 1.3.0 by Ludo Waltman and Nees Jan van Eck
## 
## Number of nodes: 242533
## Number of edges: 11218977
## 
## Running Louvain algorithm...
## Maximum modularity in 10 random starts: 0.9232
## Number of communities: 148
## Elapsed time: 284 seconds
```

Example 26 (unknown):
```unknown
## Modularity Optimizer version 1.3.0 by Ludo Waltman and Nees Jan van Eck
## 
## Number of nodes: 242533
## Number of edges: 11218977
## 
## Running Louvain algorithm...
## Maximum modularity in 10 random starts: 0.9232
## Number of communities: 148
## Elapsed time: 284 seconds
```

Example 27 (unknown):
```unknown
n_neighbors
```

Example 28 (unknown):
```unknown
AugmentPlot
```

Example 29 (r):
```r
mca <- RunTSNE(mca, dims = 1:75, tsne.method = "FIt-SNE", nthreads = 4, max_iter = 2000)
mca <- RunUMAP(mca, dims = 1:75, min.dist = 0.75)
```

Example 30 (r):
```r
mca <- RunTSNE(mca, dims = 1:75, tsne.method = "FIt-SNE", nthreads = 4, max_iter = 2000)
mca <- RunUMAP(mca, dims = 1:75, min.dist = 0.75)
```

Example 31 (r):
```r
library(ggplot2)
p1 <- DimPlot(mca, reduction = "tsne", pt.size = 0.1) + ggtitle(label = "FIt-SNE")
p2 <- DimPlot(mca, reduction = "umap", pt.size = 0.1) + ggtitle(label = "UMAP")
p1 <- AugmentPlot(plot = p1)
p2 <- AugmentPlot(plot = p2)
(p1 + p2) & NoLegend()
```

Example 32 (r):
```r
library(ggplot2)
p1 <- DimPlot(mca, reduction = "tsne", pt.size = 0.1) + ggtitle(label = "FIt-SNE")
p2 <- DimPlot(mca, reduction = "umap", pt.size = 0.1) + ggtitle(label = "UMAP")
p1 <- AugmentPlot(plot = p1)
p2 <- AugmentPlot(plot = p2)
(p1 + p2) & NoLegend()
```

Example 33 (r):
```r
p3 <- FeaturePlot(mca, features = c("S100a9", "Sftpc"), reduction = "tsne", pt.size = 0.1, combine = FALSE)
p3 <- lapply(X = p3, FUN = function(x) AugmentPlot(x + DarkTheme() + NoLegend()))
wrap_plots(p3)
```

Example 34 (r):
```r
p3 <- FeaturePlot(mca, features = c("S100a9", "Sftpc"), reduction = "tsne", pt.size = 0.1, combine = FALSE)
p3 <- lapply(X = p3, FUN = function(x) AugmentPlot(x + DarkTheme() + NoLegend()))
wrap_plots(p3)
```

---

## NOTE: These tutorials are for older versions of Seurat <= v1.2

**URL:** http://127.0.0.1:9173/seurat/archive/v1.2/get_started_v1_2/index.html

---

## Seurat - Combining Two 10X Runs • Seurat

**URL:** http://127.0.0.1:9173/seurat/archive/v4.3/merge/index.html

**Contents:**
- Seurat - Combining Two 10X Runs
    - Compiled: 2023-11-10
- Merging Two Seurat Objects
- Merging More Than Two Seurat Objects
- Merge Based on Normalized Data
- Contents

In this vignette, we will combine two 10X PBMC datasets: one containing 4K cells and one containing 8K cells. The datasets can be found here.

To start, we read in the data and create two Seurat objects.

merge() merges the raw count matrices of two Seurat objects and creates a new Seurat object with the resulting combined raw count matrix. To easily tell which original object any particular cell came from, you can set the add.cell.ids parameter with an c(x, y) vector, which will prepend the given identifier to the beginning of each cell name. The original project ID will remain stored in object meta data under orig.ident

To merge more than two Seurat objects, simply pass a vector of multiple Seurat objects to the y parameter for merge; we’ll demonstrate this using the 4K and 8K PBMC datasets as well as our previously computed Seurat object from the 2,700 PBMC tutorial (loaded via the SeuratData package).

By default, merge() will combine the Seurat objects based on the raw count matrices, erasing any previously normalized and scaled data matrices. If you want to merge the normalized data matrices as well as the raw count matrices, simply pass merge.data = TRUE. This should be done if the same normalization approach was applied to all objects.

Developed by Rahul Satija, Satija Lab and Collaborators.

Site built with pkgdown 2.0.7.

**Examples:**

Example 1 (unknown):
```unknown
vignettes/merge_vignette.Rmd
```

Example 2 (unknown):
```unknown
merge_vignette.Rmd
```

Example 3 (unknown):
```unknown
options(SeuratData.repo.use = "http://satijalab04.nygenome.org")
```

Example 4 (r):
```r
options(SeuratData.repo.use = "http://satijalab04.nygenome.org")
```

Example 5 (r):
```r
options(SeuratData.repo.use = "http://satijalab04.nygenome.org")
```

Example 6 (unknown):
```unknown
library(Seurat)
pbmc4k.data <- Read10X(data.dir = "../data/pbmc4k/filtered_gene_bc_matrices/GRCh38/")
pbmc4k <- CreateSeuratObject(counts = pbmc4k.data, project = "PBMC4K")
pbmc4k
```

Example 7 (r):
```r
library(Seurat)
pbmc4k.data <- Read10X(data.dir = "../data/pbmc4k/filtered_gene_bc_matrices/GRCh38/")
pbmc4k <- CreateSeuratObject(counts = pbmc4k.data, project = "PBMC4K")
pbmc4k
```

Example 8 (r):
```r
library(Seurat)
pbmc4k.data <- Read10X(data.dir = "../data/pbmc4k/filtered_gene_bc_matrices/GRCh38/")
pbmc4k <- CreateSeuratObject(counts = pbmc4k.data, project = "PBMC4K")
pbmc4k
```

Example 9 (python):
```python
## An object of class Seurat 
## 33694 features across 4340 samples within 1 assay 
## Active assay: RNA (33694 features, 0 variable features)
##  1 layer present: counts
```

Example 10 (python):
```python
## An object of class Seurat 
## 33694 features across 4340 samples within 1 assay 
## Active assay: RNA (33694 features, 0 variable features)
##  1 layer present: counts
```

Example 11 (unknown):
```unknown
pbmc8k.data <- Read10X(data.dir = "../data/pbmc8k/filtered_gene_bc_matrices/GRCh38/")
pbmc8k <- CreateSeuratObject(counts = pbmc8k.data, project = "PBMC8K")
pbmc8k
```

Example 12 (r):
```r
pbmc8k.data <- Read10X(data.dir = "../data/pbmc8k/filtered_gene_bc_matrices/GRCh38/")
pbmc8k <- CreateSeuratObject(counts = pbmc8k.data, project = "PBMC8K")
pbmc8k
```

Example 13 (r):
```r
pbmc8k.data <- Read10X(data.dir = "../data/pbmc8k/filtered_gene_bc_matrices/GRCh38/")
pbmc8k <- CreateSeuratObject(counts = pbmc8k.data, project = "PBMC8K")
pbmc8k
```

Example 14 (python):
```python
## An object of class Seurat 
## 33694 features across 8381 samples within 1 assay 
## Active assay: RNA (33694 features, 0 variable features)
##  1 layer present: counts
```

Example 15 (python):
```python
## An object of class Seurat 
## 33694 features across 8381 samples within 1 assay 
## Active assay: RNA (33694 features, 0 variable features)
##  1 layer present: counts
```

Example 16 (unknown):
```unknown
add.cell.ids
```

Example 17 (unknown):
```unknown
pbmc.combined <- merge(pbmc4k, y = pbmc8k, add.cell.ids = c("4K", "8K"), project = "PBMC12K")
pbmc.combined
```

Example 18 (r):
```r
pbmc.combined <- merge(pbmc4k, y = pbmc8k, add.cell.ids = c("4K", "8K"), project = "PBMC12K")
pbmc.combined
```

Example 19 (r):
```r
pbmc.combined <- merge(pbmc4k, y = pbmc8k, add.cell.ids = c("4K", "8K"), project = "PBMC12K")
pbmc.combined
```

Example 20 (python):
```python
## An object of class Seurat 
## 33694 features across 12721 samples within 1 assay 
## Active assay: RNA (33694 features, 0 variable features)
##  2 layers present: counts.PBMC4K, counts.PBMC8K
```

Example 21 (python):
```python
## An object of class Seurat 
## 33694 features across 12721 samples within 1 assay 
## Active assay: RNA (33694 features, 0 variable features)
##  2 layers present: counts.PBMC4K, counts.PBMC8K
```

Example 22 (unknown):
```unknown
# notice the cell names now have an added identifier
head(colnames(pbmc.combined))
```

Example 23 (r):
```r
# notice the cell names now have an added identifier
head(colnames(pbmc.combined))
```

Example 24 (r):
```r
# notice the cell names now have an added identifier
head(colnames(pbmc.combined))
```

Example 25 (unknown):
```unknown
## [1] "4K_AAACCTGAGAAGGCCT-1" "4K_AAACCTGAGACAGACC-1" "4K_AAACCTGAGATAGTCA-1"
## [4] "4K_AAACCTGAGCGCCTCA-1" "4K_AAACCTGAGGCATGGT-1" "4K_AAACCTGCAAGGTTCT-1"
```

Example 26 (unknown):
```unknown
## [1] "4K_AAACCTGAGAAGGCCT-1" "4K_AAACCTGAGACAGACC-1" "4K_AAACCTGAGATAGTCA-1"
## [4] "4K_AAACCTGAGCGCCTCA-1" "4K_AAACCTGAGGCATGGT-1" "4K_AAACCTGCAAGGTTCT-1"
```

Example 27 (unknown):
```unknown
table(pbmc.combined$orig.ident)
```

Example 28 (r):
```r
table(pbmc.combined$orig.ident)
```

Example 29 (r):
```r
table(pbmc.combined$orig.ident)
```

Example 30 (unknown):
```unknown
## 
## PBMC4K PBMC8K 
##   4340   8381
```

Example 31 (unknown):
```unknown
## 
## PBMC4K PBMC8K 
##   4340   8381
```

Example 32 (unknown):
```unknown
library(SeuratData)
InstallData("pbmc3k")
pbmc3k <- LoadData("pbmc3k", type = "pbmc3k.final")
pbmc3k
```

Example 33 (r):
```r
library(SeuratData)
InstallData("pbmc3k")
pbmc3k <- LoadData("pbmc3k", type = "pbmc3k.final")
pbmc3k
```

Example 34 (r):
```r
library(SeuratData)
InstallData("pbmc3k")
pbmc3k <- LoadData("pbmc3k", type = "pbmc3k.final")
pbmc3k
```

Example 35 (python):
```python
## An object of class Seurat 
## 13714 features across 2638 samples within 1 assay 
## Active assay: RNA (13714 features, 2000 variable features)
##  3 layers present: data, counts, scale.data
##  2 dimensional reductions calculated: pca, umap
```

Example 36 (python):
```python
## An object of class Seurat 
## 13714 features across 2638 samples within 1 assay 
## Active assay: RNA (13714 features, 2000 variable features)
##  3 layers present: data, counts, scale.data
##  2 dimensional reductions calculated: pca, umap
```

Example 37 (unknown):
```unknown
pbmc.big <- merge(pbmc3k, y = c(pbmc4k, pbmc8k), add.cell.ids = c("3K", "4K", "8K"), project = "PBMC15K")
pbmc.big
```

Example 38 (r):
```r
pbmc.big <- merge(pbmc3k, y = c(pbmc4k, pbmc8k), add.cell.ids = c("3K", "4K", "8K"), project = "PBMC15K")
pbmc.big
```

Example 39 (r):
```r
pbmc.big <- merge(pbmc3k, y = c(pbmc4k, pbmc8k), add.cell.ids = c("3K", "4K", "8K"), project = "PBMC15K")
pbmc.big
```

Example 40 (python):
```python
## An object of class Seurat 
## 34230 features across 15359 samples within 1 assay 
## Active assay: RNA (34230 features, 2000 variable features)
##  5 layers present: data.pbmc3k, counts.pbmc3k, scale.data.pbmc3k, counts.PBMC4K, counts.PBMC8K
```

Example 41 (python):
```python
## An object of class Seurat 
## 34230 features across 15359 samples within 1 assay 
## Active assay: RNA (34230 features, 2000 variable features)
##  5 layers present: data.pbmc3k, counts.pbmc3k, scale.data.pbmc3k, counts.PBMC4K, counts.PBMC8K
```

Example 42 (unknown):
```unknown
head(colnames(pbmc.big))
```

Example 43 (r):
```r
head(colnames(pbmc.big))
```

Example 44 (r):
```r
head(colnames(pbmc.big))
```

Example 45 (unknown):
```unknown
## [1] "3K_AAACATACAACCAC" "3K_AAACATTGAGCTAC" "3K_AAACATTGATCAGC"
## [4] "3K_AAACCGTGCTTCCG" "3K_AAACCGTGTATGCG" "3K_AAACGCACTGGTAC"
```

Example 46 (unknown):
```unknown
## [1] "3K_AAACATACAACCAC" "3K_AAACATTGAGCTAC" "3K_AAACATTGATCAGC"
## [4] "3K_AAACCGTGCTTCCG" "3K_AAACCGTGTATGCG" "3K_AAACGCACTGGTAC"
```

Example 47 (unknown):
```unknown
tail(colnames(pbmc.big))
```

Example 48 (r):
```r
tail(colnames(pbmc.big))
```

Example 49 (r):
```r
tail(colnames(pbmc.big))
```

Example 50 (unknown):
```unknown
## [1] "8K_TTTGTCAGTTACCGAT-1" "8K_TTTGTCATCATGTCCC-1" "8K_TTTGTCATCCGATATG-1"
## [4] "8K_TTTGTCATCGTCTGAA-1" "8K_TTTGTCATCTCGAGTA-1" "8K_TTTGTCATCTGCTTGC-1"
```

Example 51 (unknown):
```unknown
## [1] "8K_TTTGTCAGTTACCGAT-1" "8K_TTTGTCATCATGTCCC-1" "8K_TTTGTCATCCGATATG-1"
## [4] "8K_TTTGTCATCGTCTGAA-1" "8K_TTTGTCATCTCGAGTA-1" "8K_TTTGTCATCTGCTTGC-1"
```

Example 52 (unknown):
```unknown
unique(sapply(X = strsplit(colnames(pbmc.big), split = "_"), FUN = "[", 1))
```

Example 53 (r):
```r
unique(sapply(X = strsplit(colnames(pbmc.big), split = "_"), FUN = "[", 1))
```

Example 54 (r):
```r
unique(sapply(X = strsplit(colnames(pbmc.big), split = "_"), FUN = "[", 1))
```

Example 55 (unknown):
```unknown
## [1] "3K" "4K" "8K"
```

Example 56 (unknown):
```unknown
## [1] "3K" "4K" "8K"
```

Example 57 (unknown):
```unknown
table(pbmc.big$orig.ident)
```

Example 58 (r):
```r
table(pbmc.big$orig.ident)
```

Example 59 (r):
```r
table(pbmc.big$orig.ident)
```

Example 60 (unknown):
```unknown
## 
## pbmc3k PBMC4K PBMC8K 
##   2638   4340   8381
```

Example 61 (unknown):
```unknown
## 
## pbmc3k PBMC4K PBMC8K 
##   2638   4340   8381
```

Example 62 (unknown):
```unknown
merge.data = TRUE
```

Example 63 (unknown):
```unknown
pbmc4k <- NormalizeData(pbmc4k)
pbmc8k <- NormalizeData(pbmc8k)
pbmc.normalized <- merge(pbmc4k, y = pbmc8k, add.cell.ids = c("4K", "8K"), project = "PBMC12K",
    merge.data = TRUE)
LayerData(pbmc.combined)[1:10, 1:15]
```

Example 64 (r):
```r
pbmc4k <- NormalizeData(pbmc4k)
pbmc8k <- NormalizeData(pbmc8k)
pbmc.normalized <- merge(pbmc4k, y = pbmc8k, add.cell.ids = c("4K", "8K"), project = "PBMC12K",
    merge.data = TRUE)
LayerData(pbmc.combined)[1:10, 1:15]
```

Example 65 (r):
```r
pbmc4k <- NormalizeData(pbmc4k)
pbmc8k <- NormalizeData(pbmc8k)
pbmc.normalized <- merge(pbmc4k, y = pbmc8k, add.cell.ids = c("4K", "8K"), project = "PBMC12K",
    merge.data = TRUE)
LayerData(pbmc.combined)[1:10, 1:15]
```

Example 66 (python):
```python
## 10 x 15 sparse Matrix of class "dgCMatrix"
##                                            
## RP11-34P13.3  . . . . . . . . . . . . . . .
## FAM138A       . . . . . . . . . . . . . . .
## OR4F5         . . . . . . . . . . . . . . .
## RP11-34P13.7  . . . . . . . . . . . . . . .
## RP11-34P13.8  . . . . . . . . . . . . . . .
## RP11-34P13.14 . . . . . . . . . . . . . . .
## RP11-34P13.9  . . . . . . . . . . . . . . .
## FO538757.3    . . . . . . . . . . . . . . .
## FO538757.2    . . . . . . . . . 1 . . . . .
## AP006222.2    . . . . . . . . . . . 1 . . .
```

Example 67 (python):
```python
## 10 x 15 sparse Matrix of class "dgCMatrix"
##                                            
## RP11-34P13.3  . . . . . . . . . . . . . . .
## FAM138A       . . . . . . . . . . . . . . .
## OR4F5         . . . . . . . . . . . . . . .
## RP11-34P13.7  . . . . . . . . . . . . . . .
## RP11-34P13.8  . . . . . . . . . . . . . . .
## RP11-34P13.14 . . . . . . . . . . . . . . .
## RP11-34P13.9  . . . . . . . . . . . . . . .
## FO538757.3    . . . . . . . . . . . . . . .
## FO538757.2    . . . . . . . . . 1 . . . . .
## AP006222.2    . . . . . . . . . . . 1 . . .
```

Example 68 (unknown):
```unknown
LayerData(pbmc.normalized)[1:10, 1:15]
```

Example 69 (r):
```r
LayerData(pbmc.normalized)[1:10, 1:15]
```

Example 70 (r):
```r
LayerData(pbmc.normalized)[1:10, 1:15]
```

Example 71 (python):
```python
## 10 x 15 sparse Matrix of class "dgCMatrix"
##                                                           
## RP11-34P13.3  . . . . . . . . . .         . .        . . .
## FAM138A       . . . . . . . . . .         . .        . . .
## OR4F5         . . . . . . . . . .         . .        . . .
## RP11-34P13.7  . . . . . . . . . .         . .        . . .
## RP11-34P13.8  . . . . . . . . . .         . .        . . .
## RP11-34P13.14 . . . . . . . . . .         . .        . . .
## RP11-34P13.9  . . . . . . . . . .         . .        . . .
## FO538757.3    . . . . . . . . . .         . .        . . .
## FO538757.2    . . . . . . . . . 0.7721503 . .        . . .
## AP006222.2    . . . . . . . . . .         . 1.087928 . . .
```

Example 72 (python):
```python
## 10 x 15 sparse Matrix of class "dgCMatrix"
##                                                           
## RP11-34P13.3  . . . . . . . . . .         . .        . . .
## FAM138A       . . . . . . . . . .         . .        . . .
## OR4F5         . . . . . . . . . .         . .        . . .
## RP11-34P13.7  . . . . . . . . . .         . .        . . .
## RP11-34P13.8  . . . . . . . . . .         . .        . . .
## RP11-34P13.14 . . . . . . . . . .         . .        . . .
## RP11-34P13.9  . . . . . . . . . .         . .        . . .
## FO538757.3    . . . . . . . . . .         . .        . . .
## FO538757.2    . . . . . . . . . 0.7721503 . .        . . .
## AP006222.2    . . . . . . . . . .         . 1.087928 . . .
```

Example 73 (unknown):
```unknown
write.csv(x = t(as.data.frame(all_times)), file = "../output/timings/merge_vignette_times.csv")
```

Example 74 (r):
```r
write.csv(x = t(as.data.frame(all_times)), file = "../output/timings/merge_vignette_times.csv")
```

Example 75 (r):
```r
write.csv(x = t(as.data.frame(all_times)), file = "../output/timings/merge_vignette_times.csv")
```

Example 76 (unknown):
```unknown
sessionInfo()
```

Example 77 (r):
```r
sessionInfo()
```

Example 78 (r):
```r
sessionInfo()
```

Example 79 (unknown):
```unknown
## R version 4.2.2 Patched (2022-11-10 r83330)
## Platform: x86_64-pc-linux-gnu (64-bit)
## Running under: Ubuntu 20.04.6 LTS
## 
## Matrix products: default
## BLAS:   /usr/lib/x86_64-linux-gnu/blas/libblas.so.3.9.0
## LAPACK: /usr/lib/x86_64-linux-gnu/lapack/liblapack.so.3.9.0
## 
## locale:
##  [1] LC_CTYPE=en_US.UTF-8       LC_NUMERIC=C              
##  [3] LC_TIME=en_US.UTF-8        LC_COLLATE=en_US.UTF-8    
##  [5] LC_MONETARY=en_US.UTF-8    LC_MESSAGES=en_US.UTF-8   
##  [7] LC_PAPER=en_US.UTF-8       LC_NAME=C                 
##  [9] LC_ADDRESS=C               LC_TELEPHONE=C            
## [11] LC_MEASUREMENT=en_US.UTF-8 LC_IDENTIFICATION=C       
## 
## attached base packages:
## [1] stats     graphics  grDevices utils     datasets  methods   base     
## 
## other attached packages:
##  [1] thp1.eccite.SeuratData_3.1.5  stxBrain.SeuratData_0.1.1    
##  [3] ssHippo.SeuratData_3.1.4      pbmcsca.SeuratData_3.0.0     
##  [5] pbmcMultiome.SeuratData_0.1.4 pbmc3k.SeuratData_3.1.4      
##  [7] panc8.SeuratData_3.0.2        ifnb.SeuratData_3.0.0        
##  [9] hcabm40k.SeuratData_3.0.0     cbmc.SeuratData_3.1.4        
## [11] bmcite.SeuratData_0.3.0       SeuratData_0.2.2.9001        
## [13] Seurat_5.0.0                  SeuratObject_5.0.0           
## [15] sp_2.1-1                     
## 
## loaded via a namespace (and not attached):
##   [1] spam_2.10-0            systemfonts_1.0.4      plyr_1.8.9            
##   [4] igraph_1.5.1           lazyeval_0.2.2         splines_4.2.2         
##   [7] RcppHNSW_0.5.0         listenv_0.9.0          scattermore_1.2       
##  [10] ggplot2_3.4.4          digest_0.6.33          htmltools_0.5.6.1     
##  [13] fansi_1.0.5            magrittr_2.0.3         memoise_2.0.1         
##  [16] tensor_1.5             cluster_2.1.4          ROCR_1.0-11           
##  [19] globals_0.16.2         matrixStats_1.0.0      R.utils_2.12.2        
##  [22] pkgdown_2.0.7          spatstat.sparse_3.0-3  colorspace_2.1-0      
##  [25] rappdirs_0.3.3         ggrepel_0.9.4          textshaping_0.3.6     
##  [28] xfun_0.40              dplyr_1.1.3            crayon_1.5.2          
##  [31] jsonlite_1.8.7         progressr_0.14.0       spatstat.data_3.0-3   
##  [34] survival_3.5-7         zoo_1.8-12             glue_1.6.2            
##  [37] polyclip_1.10-6        gtable_0.3.4           leiden_0.4.3          
##  [40] future.apply_1.11.0    abind_1.4-5            scales_1.2.1          
##  [43] spatstat.random_3.2-1  miniUI_0.1.1.1         Rcpp_1.0.11           
##  [46] viridisLite_0.4.2      xtable_1.8-4           reticulate_1.34.0     
##  [49] dotCall64_1.1-0        htmlwidgets_1.6.2      httr_1.4.7            
##  [52] RColorBrewer_1.1-3     ellipsis_0.3.2         ica_1.0-3             
##  [55] pkgconfig_2.0.3        R.methodsS3_1.8.2      sass_0.4.7            
##  [58] uwot_0.1.16            deldir_1.0-9           utf8_1.2.4            
##  [61] tidyselect_1.2.0       rlang_1.1.1            reshape2_1.4.4        
##  [64] later_1.3.1            munsell_0.5.0          tools_4.2.2           
##  [67] cachem_1.0.8           cli_3.6.1              generics_0.1.3        
##  [70] ggridges_0.5.4         evaluate_0.22          stringr_1.5.0         
##  [73] fastmap_1.1.1          yaml_2.3.7             ragg_1.2.5            
##  [76] goftest_1.2-3          knitr_1.45             fs_1.6.3              
##  [79] fitdistrplus_1.1-11    purrr_1.0.2            RANN_2.6.1            
##  [82] pbapply_1.7-2          future_1.33.0          nlme_3.1-162          
##  [85] mime_0.12              formatR_1.14           R.oo_1.25.0           
##  [88] compiler_4.2.2         plotly_4.10.3          png_0.1-8             
##  [91] spatstat.utils_3.0-4   tibble_3.2.1           bslib_0.5.1           
##  [94] stringi_1.7.12         desc_1.4.2             RSpectra_0.16-1       
##  [97] lattice_0.21-9         Matrix_1.6-1.1         vctrs_0.6.4           
## [100] pillar_1.9.0           lifecycle_1.0.4        spatstat.geom_3.2-7   
## [103] lmtest_0.9-40          jquerylib_0.1.4        RcppAnnoy_0.0.21      
## [106] data.table_1.14.8      cowplot_1.1.1          irlba_2.3.5.1         
## [109] httpuv_1.6.12          patchwork_1.1.3        R6_2.5.1              
## [112] promises_1.2.1         KernSmooth_2.23-22     gridExtra_2.3         
## [115] parallelly_1.36.0      codetools_0.2-19       fastDummies_1.7.3     
## [118] MASS_7.3-58.2          rprojroot_2.0.4        sctransform_0.4.1     
## [121] parallel_4.2.2         grid_4.2.2             tidyr_1.3.0           
## [124] rmarkdown_2.25         Rtsne_0.16             spatstat.explore_3.2-5
## [127] shiny_1.7.5.1
```

Example 80 (unknown):
```unknown
## R version 4.2.2 Patched (2022-11-10 r83330)
## Platform: x86_64-pc-linux-gnu (64-bit)
## Running under: Ubuntu 20.04.6 LTS
## 
## Matrix products: default
## BLAS:   /usr/lib/x86_64-linux-gnu/blas/libblas.so.3.9.0
## LAPACK: /usr/lib/x86_64-linux-gnu/lapack/liblapack.so.3.9.0
## 
## locale:
##  [1] LC_CTYPE=en_US.UTF-8       LC_NUMERIC=C              
##  [3] LC_TIME=en_US.UTF-8        LC_COLLATE=en_US.UTF-8    
##  [5] LC_MONETARY=en_US.UTF-8    LC_MESSAGES=en_US.UTF-8   
##  [7] LC_PAPER=en_US.UTF-8       LC_NAME=C                 
##  [9] LC_ADDRESS=C               LC_TELEPHONE=C            
## [11] LC_MEASUREMENT=en_US.UTF-8 LC_IDENTIFICATION=C       
## 
## attached base packages:
## [1] stats     graphics  grDevices utils     datasets  methods   base     
## 
## other attached packages:
##  [1] thp1.eccite.SeuratData_3.1.5  stxBrain.SeuratData_0.1.1    
##  [3] ssHippo.SeuratData_3.1.4      pbmcsca.SeuratData_3.0.0     
##  [5] pbmcMultiome.SeuratData_0.1.4 pbmc3k.SeuratData_3.1.4      
##  [7] panc8.SeuratData_3.0.2        ifnb.SeuratData_3.0.0        
##  [9] hcabm40k.SeuratData_3.0.0     cbmc.SeuratData_3.1.4        
## [11] bmcite.SeuratData_0.3.0       SeuratData_0.2.2.9001        
## [13] Seurat_5.0.0                  SeuratObject_5.0.0           
## [15] sp_2.1-1                     
## 
## loaded via a namespace (and not attached):
##   [1] spam_2.10-0            systemfonts_1.0.4      plyr_1.8.9            
##   [4] igraph_1.5.1           lazyeval_0.2.2         splines_4.2.2         
##   [7] RcppHNSW_0.5.0         listenv_0.9.0          scattermore_1.2       
##  [10] ggplot2_3.4.4          digest_0.6.33          htmltools_0.5.6.1     
##  [13] fansi_1.0.5            magrittr_2.0.3         memoise_2.0.1         
##  [16] tensor_1.5             cluster_2.1.4          ROCR_1.0-11           
##  [19] globals_0.16.2         matrixStats_1.0.0      R.utils_2.12.2        
##  [22] pkgdown_2.0.7          spatstat.sparse_3.0-3  colorspace_2.1-0      
##  [25] rappdirs_0.3.3         ggrepel_0.9.4          textshaping_0.3.6     
##  [28] xfun_0.40              dplyr_1.1.3            crayon_1.5.2          
##  [31] jsonlite_1.8.7         progressr_0.14.0       spatstat.data_3.0-3   
##  [34] survival_3.5-7         zoo_1.8-12             glue_1.6.2            
##  [37] polyclip_1.10-6        gtable_0.3.4           leiden_0.4.3          
##  [40] future.apply_1.11.0    abind_1.4-5            scales_1.2.1          
##  [43] spatstat.random_3.2-1  miniUI_0.1.1.1         Rcpp_1.0.11           
##  [46] viridisLite_0.4.2      xtable_1.8-4           reticulate_1.34.0     
##  [49] dotCall64_1.1-0        htmlwidgets_1.6.2      httr_1.4.7            
##  [52] RColorBrewer_1.1-3     ellipsis_0.3.2         ica_1.0-3             
##  [55] pkgconfig_2.0.3        R.methodsS3_1.8.2      sass_0.4.7            
##  [58] uwot_0.1.16            deldir_1.0-9           utf8_1.2.4            
##  [61] tidyselect_1.2.0       rlang_1.1.1            reshape2_1.4.4        
##  [64] later_1.3.1            munsell_0.5.0          tools_4.2.2           
##  [67] cachem_1.0.8           cli_3.6.1              generics_0.1.3        
##  [70] ggridges_0.5.4         evaluate_0.22          stringr_1.5.0         
##  [73] fastmap_1.1.1          yaml_2.3.7             ragg_1.2.5            
##  [76] goftest_1.2-3          knitr_1.45             fs_1.6.3              
##  [79] fitdistrplus_1.1-11    purrr_1.0.2            RANN_2.6.1            
##  [82] pbapply_1.7-2          future_1.33.0          nlme_3.1-162          
##  [85] mime_0.12              formatR_1.14           R.oo_1.25.0           
##  [88] compiler_4.2.2         plotly_4.10.3          png_0.1-8             
##  [91] spatstat.utils_3.0-4   tibble_3.2.1           bslib_0.5.1           
##  [94] stringi_1.7.12         desc_1.4.2             RSpectra_0.16-1       
##  [97] lattice_0.21-9         Matrix_1.6-1.1         vctrs_0.6.4           
## [100] pillar_1.9.0           lifecycle_1.0.4        spatstat.geom_3.2-7   
## [103] lmtest_0.9-40          jquerylib_0.1.4        RcppAnnoy_0.0.21      
## [106] data.table_1.14.8      cowplot_1.1.1          irlba_2.3.5.1         
## [109] httpuv_1.6.12          patchwork_1.1.3        R6_2.5.1              
## [112] promises_1.2.1         KernSmooth_2.23-22     gridExtra_2.3         
## [115] parallelly_1.36.0      codetools_0.2-19       fastDummies_1.7.3     
## [118] MASS_7.3-58.2          rprojroot_2.0.4        sctransform_0.4.1     
## [121] parallel_4.2.2         grid_4.2.2             tidyr_1.3.0           
## [124] rmarkdown_2.25         Rtsne_0.16             spatstat.explore_3.2-5
## [127] shiny_1.7.5.1
```

---

## Guided Clustering of the Microwell-seq Mouse Cell Atlas

**URL:** http://127.0.0.1:9173/seurat/archive/v3.1/mca/index.html

**Contents:**
- Guided Clustering of the Microwell-seq Mouse Cell Atlas
    - Compiled: April 17, 2020
  - Setup the Seurat Object
  - Data Preprocessing
  - Dimensional Reduction (PCA)
  - Graph-based clustering
  - Visualization (t-SNE/UMAP)
  - Elapsed time for key steps

In the following tutorial, we examine the recently published Microwell-seq “Mouse Cell Atlas”, composed of hundreds of thousands of cells derived from all major mouse organs. For those that are getting started using Seurat, we recommend first working through our 3k PBMC tutorial, which introduces the basic functionality of the package.

Our goal is to demonstrate a workflow for handling very large datasets in Seurat, emphasizing recent improvements we have made for speed and memory efficiency. We do not perform downstream biological analyses on the resulting clusters, but encourage users to explore this dataset and interpret this exciting resource. All analyses here are performed in memory, but we also now support storage on-disk (using the HDF5-based loom framework). See this vignette for a workflow of the same MCA dataset using loomR.

The original data for the MCA is available here. For ease of getting started, we provide a sparse matrix R data file (.rds) file containing the combined expression matrix and the published metadata file here.

We will analyze ~242,000 cells that were assigned a cluster ID in the original study. As a result, we don’t do perform additional QC steps or filtration steps here.

We perform standard log-normalization.

FindVariableGenes calculates the variance and mean for each gene in the dataset in the dataset (storing this in object[[assay]]@meta.features). We have observed that for large-cell datasets with unique molecular identifiers, selecting highly variable genes (HVG) simply based on variance mean ratio (VMR) is an efficient and robust strategy. Here, we select the top 1,000 HVG for downstream analysis.

We calculate and regress out mitochondrial expression per cell.

We now cluster the data in lower-dimensional space. Our approach was heavily inspired by recent manuscripts which applied graph-based clustering approaches to scRNA-seq data [SNN-Cliq, Xu and Su, Bioinformatics, 2015] and CyTOF data [PhenoGraph, Levine et al., Cell, 2015].

We use the same principal components that were input for clustering, for two-dimensional visualization with t-SNE or UMAP.

These tests were performed on a desktop computer running Ubuntu 16.04.5 LTS with an Intel(R) Core(TM) i7-6800K CPU @ 3.40GHz and 96 GB of RAM.

**Examples:**

Example 1 (r):
```r
library(Seurat)
library(patchwork)
mca.matrix <- readRDS(file = "../data/MCA_merged_mat.rds")
mca.metadata <- read.csv(file = "../data/MCA_All-batch-removed-assignments.csv", row.names = 1)
```

Example 2 (r):
```r
library(Seurat)
library(patchwork)
mca.matrix <- readRDS(file = "../data/MCA_merged_mat.rds")
mca.metadata <- read.csv(file = "../data/MCA_All-batch-removed-assignments.csv", row.names = 1)
```

Example 3 (r):
```r
mca <- CreateSeuratObject(counts = mca.matrix, meta.data = mca.metadata, project = "MouseCellAtlas")
# Only keep annotated cells
mca <- subset(mca, cells = names(which(!is.na(mca$ClusterID))))
# Leaves us with 242k cells
mca
```

Example 4 (r):
```r
mca <- CreateSeuratObject(counts = mca.matrix, meta.data = mca.metadata, project = "MouseCellAtlas")
# Only keep annotated cells
mca <- subset(mca, cells = names(which(!is.na(mca$ClusterID))))
# Leaves us with 242k cells
mca
```

Example 5 (python):
```python
## An object of class Seurat 
## 39855 features across 242533 samples within 1 assay 
## Active assay: RNA (39855 features, 0 variable features)
```

Example 6 (python):
```python
## An object of class Seurat 
## 39855 features across 242533 samples within 1 assay 
## Active assay: RNA (39855 features, 0 variable features)
```

Example 7 (r):
```r
mca <- NormalizeData(mca, normalization.method = "LogNormalize", scale.factor = 10000)
```

Example 8 (r):
```r
mca <- NormalizeData(mca, normalization.method = "LogNormalize", scale.factor = 10000)
```

Example 9 (unknown):
```unknown
FindVariableGenes
```

Example 10 (unknown):
```unknown
object[[assay]]@meta.features
```

Example 11 (r):
```r
mca <- FindVariableFeatures(mca)
```

Example 12 (r):
```r
mca <- FindVariableFeatures(mca)
```

Example 13 (r):
```r
mca[["percent.mt"]] <- PercentageFeatureSet(mca, pattern = "^mt-")
mca <- ScaleData(mca, vars.to.regress = "percent.mt")
```

Example 14 (r):
```r
mca[["percent.mt"]] <- PercentageFeatureSet(mca, pattern = "^mt-")
mca <- ScaleData(mca, vars.to.regress = "percent.mt")
```

Example 15 (r):
```r
mca <- RunPCA(mca, npcs = 100, ndims.print = 1:5, nfeatures.print = 5)
```

Example 16 (r):
```r
mca <- RunPCA(mca, npcs = 100, ndims.print = 1:5, nfeatures.print = 5)
```

Example 17 (unknown):
```unknown
## PC_ 1 
## Positive:  Lyz2, S100a8, S100a6, S100a9, Igkc 
## Negative:  Fabp9, Meig1, Prm1, Ldhc, Prm2 
## PC_ 2 
## Positive:  Lypd8, Reg3b, Lgals2, Reg3g, Lgals4 
## Negative:  Sparc, Col2a1, Col9a2, Col9a1, Col9a3 
## PC_ 3 
## Positive:  Plp1, Mobp, Mag, Ermn, Cldn11 
## Negative:  Sparc, Mgp, Col2a1, Col9a2, Col9a1 
## PC_ 4 
## Positive:  Zpbp2, Hdgfl1, Pabpc6, Tmbim7, Tuba3a 
## Negative:  1700031M16Rik, 1700042G07Rik, 4930570D08Rik, 1700016P04Rik, H1fnt 
## PC_ 5 
## Positive:  Plp1, Mobp, Mag, Ermn, Cldn11 
## Negative:  S100a8, S100a9, Camp, Ngp, Ly6c2
```

Example 18 (unknown):
```unknown
## PC_ 1 
## Positive:  Lyz2, S100a8, S100a6, S100a9, Igkc 
## Negative:  Fabp9, Meig1, Prm1, Ldhc, Prm2 
## PC_ 2 
## Positive:  Lypd8, Reg3b, Lgals2, Reg3g, Lgals4 
## Negative:  Sparc, Col2a1, Col9a2, Col9a1, Col9a3 
## PC_ 3 
## Positive:  Plp1, Mobp, Mag, Ermn, Cldn11 
## Negative:  Sparc, Mgp, Col2a1, Col9a2, Col9a1 
## PC_ 4 
## Positive:  Zpbp2, Hdgfl1, Pabpc6, Tmbim7, Tuba3a 
## Negative:  1700031M16Rik, 1700042G07Rik, 4930570D08Rik, 1700016P04Rik, H1fnt 
## PC_ 5 
## Positive:  Plp1, Mobp, Mag, Ermn, Cldn11 
## Negative:  S100a8, S100a9, Camp, Ngp, Ly6c2
```

Example 19 (r):
```r
ElbowPlot(mca, ndims = 100)
```

Example 20 (r):
```r
ElbowPlot(mca, ndims = 100)
```

Example 21 (r):
```r
DimHeatmap(mca, dims = c(1:3, 70:75), cells = 500, balanced = TRUE)
```

Example 22 (r):
```r
DimHeatmap(mca, dims = c(1:3, 70:75), cells = 500, balanced = TRUE)
```

Example 23 (r):
```r
mca <- FindNeighbors(mca, reduction = "pca", dims = 1:75, nn.eps = 0.5)
mca <- FindClusters(mca, resolution = 3, n.start = 10)
```

Example 24 (r):
```r
mca <- FindNeighbors(mca, reduction = "pca", dims = 1:75, nn.eps = 0.5)
mca <- FindClusters(mca, resolution = 3, n.start = 10)
```

Example 25 (unknown):
```unknown
## Modularity Optimizer version 1.3.0 by Ludo Waltman and Nees Jan van Eck
## 
## Number of nodes: 242533
## Number of edges: 11218977
## 
## Running Louvain algorithm...
## Maximum modularity in 10 random starts: 0.9232
## Number of communities: 148
## Elapsed time: 267 seconds
```

Example 26 (unknown):
```unknown
## Modularity Optimizer version 1.3.0 by Ludo Waltman and Nees Jan van Eck
## 
## Number of nodes: 242533
## Number of edges: 11218977
## 
## Running Louvain algorithm...
## Maximum modularity in 10 random starts: 0.9232
## Number of communities: 148
## Elapsed time: 267 seconds
```

Example 27 (unknown):
```unknown
n_neighbors
```

Example 28 (unknown):
```unknown
AugmentPlot
```

Example 29 (r):
```r
mca <- RunTSNE(mca, dims = 1:75, tsne.method = "FIt-SNE", nthreads = 4, max_iter = 2000)
mca <- RunUMAP(mca, dims = 1:75, min.dist = 0.75)
```

Example 30 (r):
```r
mca <- RunTSNE(mca, dims = 1:75, tsne.method = "FIt-SNE", nthreads = 4, max_iter = 2000)
mca <- RunUMAP(mca, dims = 1:75, min.dist = 0.75)
```

Example 31 (r):
```r
library(ggplot2)
p1 <- DimPlot(mca, reduction = "tsne", pt.size = 0.1) + ggtitle(label = "FIt-SNE")
p2 <- DimPlot(mca, reduction = "umap", pt.size = 0.1) + ggtitle(label = "UMAP")
p1 <- AugmentPlot(plot = p1)
p2 <- AugmentPlot(plot = p2)
(p1 + p2) & NoLegend()
```

Example 32 (r):
```r
library(ggplot2)
p1 <- DimPlot(mca, reduction = "tsne", pt.size = 0.1) + ggtitle(label = "FIt-SNE")
p2 <- DimPlot(mca, reduction = "umap", pt.size = 0.1) + ggtitle(label = "UMAP")
p1 <- AugmentPlot(plot = p1)
p2 <- AugmentPlot(plot = p2)
(p1 + p2) & NoLegend()
```

Example 33 (r):
```r
p3 <- FeaturePlot(mca, features = c("S100a9", "Sftpc"), reduction = "tsne", pt.size = 0.1, combine = FALSE)
p3 <- lapply(X = p3, FUN = function(x) AugmentPlot(x + DarkTheme() + NoLegend()))
wrap_plots(p3)
```

Example 34 (r):
```r
p3 <- FeaturePlot(mca, features = c("S100a9", "Sftpc"), reduction = "tsne", pt.size = 0.1, combine = FALSE)
p3 <- lapply(X = p3, FUN = function(x) AugmentPlot(x + DarkTheme() + NoLegend()))
wrap_plots(p3)
```

---

## Guided Clustering of the Microwell-seq Mouse Cell Atlas

**URL:** http://127.0.0.1:9173/seurat/archive/v3.0/mca/index.html

**Contents:**
- Guided Clustering of the Microwell-seq Mouse Cell Atlas
    - Compiled: June 24, 2019
  - Setup the Seurat Object
  - Data Preprocessing
  - Dimensional Reduction (PCA)
  - Graph-based clustering
  - Visualization (t-SNE/UMAP)
  - Elapsed time for key steps

In the following tutorial, we examine the recently published Microwell-seq “Mouse Cell Atlas”, composed of hundreds of thousands of cells derived from all major mouse organs. For those that are getting started using Seurat, we recommend first working through our 3k PBMC tutorial, which introduces the basic functionality of the package.

Our goal is to demonstrate a workflow for handling very large datasets in Seurat, emphasizing recent improvements we have made for speed and memory efficiency. We do not perform downstream biological analyses on the resulting clusters, but encourage users to explore this dataset and interpret this exciting resource. All analyses here are performed in memory, but we also now support storage on-disk (using the HDF5-based loom framework). See this vignette for a workflow of the same MCA dataset using loomR.

The original data for the MCA is available here. For ease of getting started, we provide a sparse matrix R data file (.rds) file containing the combined expression matrix and the published metadata file here.

We will analyze ~242,000 cells that were assigned a cluster ID in the original study. As a result, we don’t do perform additional QC steps or filtration steps here.

We perform standard log-normalization.

FindVariableGenes calculates the variance and mean for each gene in the dataset in the dataset (storing this in object[[assay]]@meta.features). We have observed that for large-cell datasets with unique molecular identifiers, selecting highly variable genes (HVG) simply based on variance mean ratio (VMR) is an efficient and robust strategy. Here, we select the top 1,000 HVG for downstream analysis.

We calculate and regress out mitochondrial expression per cell.

We now cluster the data in lower-dimensional space. Our approach was heavily inspired by recent manuscripts which applied graph-based clustering approaches to scRNA-seq data [SNN-Cliq, Xu and Su, Bioinformatics, 2015] and CyTOF data [PhenoGraph, Levine et al., Cell, 2015].

We use the same principal components that were input for clustering, for two-dimensional visualization with t-SNE or UMAP.

These tests were performed on a desktop computer running Ubuntu 16.04.5 LTS with an Intel(R) Core(TM) i7-6800K CPU @ 3.40GHz and 96 GB of RAM.

**Examples:**

Example 1 (r):
```r
library(Seurat)
mca.matrix <- readRDS(file = "../data/MCA_merged_mat.rds")
mca.metadata <- read.csv(file = "../data/MCA_All-batch-removed-assignments.csv", row.names = 1)
```

Example 2 (r):
```r
library(Seurat)
mca.matrix <- readRDS(file = "../data/MCA_merged_mat.rds")
mca.metadata <- read.csv(file = "../data/MCA_All-batch-removed-assignments.csv", row.names = 1)
```

Example 3 (r):
```r
mca <- CreateSeuratObject(counts = mca.matrix, meta.data = mca.metadata, project = "MouseCellAtlas")
# Only keep annotated cells
mca <- subset(mca, cells = names(which(!is.na(mca$ClusterID))))
# Leaves us with 242k cells
mca
```

Example 4 (r):
```r
mca <- CreateSeuratObject(counts = mca.matrix, meta.data = mca.metadata, project = "MouseCellAtlas")
# Only keep annotated cells
mca <- subset(mca, cells = names(which(!is.na(mca$ClusterID))))
# Leaves us with 242k cells
mca
```

Example 5 (python):
```python
## An object of class Seurat 
## 39855 features across 242533 samples within 1 assay 
## Active assay: RNA (39855 features)
```

Example 6 (python):
```python
## An object of class Seurat 
## 39855 features across 242533 samples within 1 assay 
## Active assay: RNA (39855 features)
```

Example 7 (r):
```r
mca <- NormalizeData(mca, normalization.method = "LogNormalize", scale.factor = 10000)
```

Example 8 (r):
```r
mca <- NormalizeData(mca, normalization.method = "LogNormalize", scale.factor = 10000)
```

Example 9 (unknown):
```unknown
FindVariableGenes
```

Example 10 (unknown):
```unknown
object[[assay]]@meta.features
```

Example 11 (r):
```r
mca <- FindVariableFeatures(mca)
```

Example 12 (r):
```r
mca <- FindVariableFeatures(mca)
```

Example 13 (r):
```r
mca[["percent.mt"]] <- PercentageFeatureSet(mca, pattern = "^mt-")
mca <- ScaleData(mca, vars.to.regress = "percent.mt")
```

Example 14 (r):
```r
mca[["percent.mt"]] <- PercentageFeatureSet(mca, pattern = "^mt-")
mca <- ScaleData(mca, vars.to.regress = "percent.mt")
```

Example 15 (r):
```r
mca <- RunPCA(mca, npcs = 100, ndims.print = 1:5, nfeatures.print = 5)
```

Example 16 (r):
```r
mca <- RunPCA(mca, npcs = 100, ndims.print = 1:5, nfeatures.print = 5)
```

Example 17 (unknown):
```unknown
## PC_ 1 
## Positive:  Lyz2, S100a8, S100a6, S100a9, Igkc 
## Negative:  Fabp9, Meig1, Prm1, Ldhc, Prm2 
## PC_ 2 
## Positive:  Lypd8, Reg3b, Lgals2, Reg3g, Lgals4 
## Negative:  Sparc, Col2a1, Col9a2, Col9a1, Col9a3 
## PC_ 3 
## Positive:  Plp1, Mobp, Mag, Ermn, Cldn11 
## Negative:  Sparc, Mgp, Col2a1, Col9a2, Col9a1 
## PC_ 4 
## Positive:  Zpbp2, Hdgfl1, Pabpc6, Tmbim7, Tuba3a 
## Negative:  1700031M16Rik, 1700042G07Rik, 4930570D08Rik, 1700016P04Rik, H1fnt 
## PC_ 5 
## Positive:  Plp1, Mobp, Mag, Ermn, Cldn11 
## Negative:  S100a8, S100a9, Camp, Ngp, Ly6c2
```

Example 18 (unknown):
```unknown
## PC_ 1 
## Positive:  Lyz2, S100a8, S100a6, S100a9, Igkc 
## Negative:  Fabp9, Meig1, Prm1, Ldhc, Prm2 
## PC_ 2 
## Positive:  Lypd8, Reg3b, Lgals2, Reg3g, Lgals4 
## Negative:  Sparc, Col2a1, Col9a2, Col9a1, Col9a3 
## PC_ 3 
## Positive:  Plp1, Mobp, Mag, Ermn, Cldn11 
## Negative:  Sparc, Mgp, Col2a1, Col9a2, Col9a1 
## PC_ 4 
## Positive:  Zpbp2, Hdgfl1, Pabpc6, Tmbim7, Tuba3a 
## Negative:  1700031M16Rik, 1700042G07Rik, 4930570D08Rik, 1700016P04Rik, H1fnt 
## PC_ 5 
## Positive:  Plp1, Mobp, Mag, Ermn, Cldn11 
## Negative:  S100a8, S100a9, Camp, Ngp, Ly6c2
```

Example 19 (r):
```r
ElbowPlot(mca, ndims = 100)
```

Example 20 (r):
```r
ElbowPlot(mca, ndims = 100)
```

Example 21 (r):
```r
DimHeatmap(mca, dims = c(1:3, 70:75), cells = 500, balanced = TRUE)
```

Example 22 (r):
```r
DimHeatmap(mca, dims = c(1:3, 70:75), cells = 500, balanced = TRUE)
```

Example 23 (r):
```r
mca <- FindNeighbors(mca, reduction = "pca", dims = 1:75, nn.eps = 0.5)
mca <- FindClusters(mca, resolution = 3, n.start = 10)
```

Example 24 (r):
```r
mca <- FindNeighbors(mca, reduction = "pca", dims = 1:75, nn.eps = 0.5)
mca <- FindClusters(mca, resolution = 3, n.start = 10)
```

Example 25 (unknown):
```unknown
## Modularity Optimizer version 1.3.0 by Ludo Waltman and Nees Jan van Eck
## 
## Number of nodes: 242533
## Number of edges: 11218977
## 
## Running Louvain algorithm...
## Maximum modularity in 10 random starts: 0.9232
## Number of communities: 148
## Elapsed time: 138 seconds
```

Example 26 (unknown):
```unknown
## Modularity Optimizer version 1.3.0 by Ludo Waltman and Nees Jan van Eck
## 
## Number of nodes: 242533
## Number of edges: 11218977
## 
## Running Louvain algorithm...
## Maximum modularity in 10 random starts: 0.9232
## Number of communities: 148
## Elapsed time: 138 seconds
```

Example 27 (unknown):
```unknown
n_neighbors
```

Example 28 (unknown):
```unknown
AugmentPlot
```

Example 29 (r):
```r
mca <- RunTSNE(mca, dims = 1:75, tsne.method = "FIt-SNE", nthreads = 4, max_iter = 2000)
mca <- RunUMAP(mca, dims = 1:75, min.dist = 0.75)
```

Example 30 (r):
```r
mca <- RunTSNE(mca, dims = 1:75, tsne.method = "FIt-SNE", nthreads = 4, max_iter = 2000)
mca <- RunUMAP(mca, dims = 1:75, min.dist = 0.75)
```

Example 31 (r):
```r
library(ggplot2)
p1 <- DimPlot(mca, reduction = "tsne", pt.size = 0.1) + ggtitle(label = "FIt-SNE")
p2 <- DimPlot(mca, reduction = "umap", pt.size = 0.1) + ggtitle(label = "UMAP")
p1 <- AugmentPlot(plot = p1)
p2 <- AugmentPlot(plot = p2)
CombinePlots(plots = list(p1, p2), legend = "none")
```

Example 32 (r):
```r
library(ggplot2)
p1 <- DimPlot(mca, reduction = "tsne", pt.size = 0.1) + ggtitle(label = "FIt-SNE")
p2 <- DimPlot(mca, reduction = "umap", pt.size = 0.1) + ggtitle(label = "UMAP")
p1 <- AugmentPlot(plot = p1)
p2 <- AugmentPlot(plot = p2)
CombinePlots(plots = list(p1, p2), legend = "none")
```

Example 33 (r):
```r
p3 <- FeaturePlot(mca, features = c("S100a9", "Sftpc"), reduction = "tsne", pt.size = 0.1, combine = FALSE)
p3 <- lapply(X = p3, FUN = function(x) AugmentPlot(x + DarkTheme() + NoLegend()))
CombinePlots(plots = p3)
```

Example 34 (r):
```r
p3 <- FeaturePlot(mca, features = c("S100a9", "Sftpc"), reduction = "tsne", pt.size = 0.1, combine = FALSE)
p3 <- lapply(X = p3, FUN = function(x) AugmentPlot(x + DarkTheme() + NoLegend()))
CombinePlots(plots = p3)
```

---

## Tutorial: Integrating stimulated vs. control PBMC datasets to learn cell-type specific responses

**URL:** http://127.0.0.1:9173/seurat/archive/v3.2/immune_alignment/index.html

**Contents:**
- Tutorial: Integrating stimulated vs. control PBMC datasets to learn cell-type specific responses
    - Compiled: October 02, 2020
  - Integration goals
  - Setup the Seurat objects
  - Perform integration
  - Perform an integrated analysis
  - Identify conserved cell type markers
  - Identify differential expressed genes across conditions

This tutorial walks through an alignment of two groups of PBMCs from Kang et al, 2017. In this experiment, PBMCs were split into a stimulated and control group and the stimulated group was treated with interferon beta. The response to interferon caused cell type specific gene expression changes that makes a joint analysis of all the data difficult, with cells clustering both by stimulation condition and by cell type. Here, we demonstrate our integration strategy, as described in Stuart and Butler et al, 2018, for performing integrated analyses to promote the identification of common cell types and enable comparative analyses. While this example demonstrates the integration of two datasets (conditions), these methods have been extended to multiple datasets. This workflow provides an example of integrating four pancreatic islet datasets.

The following tutorial is designed to give you an overview of the kinds of comparative analyses on complex cell types that are possible using the Seurat integration procedure. Here, we address three main goals:

For convienence, we distribute this dataset through our SeuratData package.

We then identify anchors using the FindIntegrationAnchors function, which takes a list of Seurat objects as input, and use these anchors to integrate the two datasets together with IntegrateData.

Now we can run a single integrated analysis on all cells!

To visualize the two conditions side-by-side, we can use the split.by argument to show each condition colored by cluster.

To identify canonical cell type marker genes that are conserved across conditions, we provide the FindConservedMarkers function. This function performs differential gene expression testing for each dataset/group and combines the p-values using meta-analysis methods from the MetaDE R package. For example, we can calculated the genes that are conserved markers irrespective of stimulation condition in cluster 6 (NK cells).

We can explore these marker genes for each cluster and use them to annotate our clusters as specific cell types.

The DotPlot function with the split.by parameter can be useful for viewing conserved cell type markers across conditions, showing both the expression level and the percentage of cells in a cluster expressing any given gene. Here we plot 2-3 strong marker genes for each of our 13 clusters.

Now that we've aligned the stimulated and control cells, we can start to do comparative analyses and look at the differences induced by stimulation. One way to look broadly at these changes is to plot the average expression of both the stimulated and control cells and look for genes that are visual outliers on a scatter plot. Here, we take the average expression of both the stimulated and control naive T cells and CD14 monocyte populations and generate the scatter plots, highlighting genes that exhibit dramatic responses to interferon stimulation.

As you can see, many of the same genes are upregulated in both of these cell types and likely represent a conserved interferon response pathway.

Because we are confident in having identified common cell types across condition, we can ask what genes change in different conditions for cells of the same type. First, we create a column in the meta.data slot to hold both the cell type and stimulation information and switch the current ident to that column. Then we use FindMarkers to find the genes that are different between stimulated and control B cells. Notice that many of the top genes that show up here are the same as the ones we plotted earlier as core interferon response genes. Additionally, genes like CXCL10 which we saw were specific to monocyte and B cell interferon response show up as highly significant in this list as well.

Another useful way to visualize these changes in gene expression is with the split.by option to the FeaturePlot or VlnPlot function. This will display FeaturePlots of the list of given genes, split by a grouping variable (stimulation condition here). Genes such as CD3D and GNLY are canonical cell type markers (for T cells and NK/CD8 T cells) that are virtually unaffected by interferon stimulation and display similar gene expression patterns in the control and stimulated group. IFI6 and ISG15, on the other hand, are core interferon response genes and are upregulated accordingly in all cell types. Finally, CD14 and CXCL10 are genes that show a cell type specific interferon response. CD14 expression decreases after stimulation in CD14 monocytes, which could lead to misclassification in a supervised analysis framework, underscoring the value of integrated analysis. CXCL10 shows a distinct upregulation in monocytes and B cells after interferon stimulation but not in other cell types.

**Examples:**

Example 1 (r):
```r
library(Seurat)
library(SeuratData)
library(cowplot)
library(patchwork)
```

Example 2 (r):
```r
library(Seurat)
library(SeuratData)
library(cowplot)
library(patchwork)
```

Example 3 (r):
```r
InstallData("ifnb")
```

Example 4 (r):
```r
InstallData("ifnb")
```

Example 5 (r):
```r
data("ifnb")
ifnb.list <- SplitObject(ifnb, split.by = "stim")

ifnb.list <- lapply(X = ifnb.list, FUN = function(x) {
    x <- NormalizeData(x)
    x <- FindVariableFeatures(x, selection.method = "vst", nfeatures = 2000)
})
```

Example 6 (r):
```r
data("ifnb")
ifnb.list <- SplitObject(ifnb, split.by = "stim")

ifnb.list <- lapply(X = ifnb.list, FUN = function(x) {
    x <- NormalizeData(x)
    x <- FindVariableFeatures(x, selection.method = "vst", nfeatures = 2000)
})
```

Example 7 (unknown):
```unknown
FindIntegrationAnchors
```

Example 8 (unknown):
```unknown
IntegrateData
```

Example 9 (r):
```r
immune.anchors <- FindIntegrationAnchors(object.list = ifnb.list, dims = 1:20)
```

Example 10 (r):
```r
immune.anchors <- FindIntegrationAnchors(object.list = ifnb.list, dims = 1:20)
```

Example 11 (r):
```r
immune.combined <- IntegrateData(anchorset = immune.anchors, dims = 1:20)
```

Example 12 (r):
```r
immune.combined <- IntegrateData(anchorset = immune.anchors, dims = 1:20)
```

Example 13 (r):
```r
DefaultAssay(immune.combined) <- "integrated"

# Run the standard workflow for visualization and clustering
immune.combined <- ScaleData(immune.combined, verbose = FALSE)
immune.combined <- RunPCA(immune.combined, npcs = 30, verbose = FALSE)
# t-SNE and Clustering
immune.combined <- RunUMAP(immune.combined, reduction = "pca", dims = 1:20)
immune.combined <- FindNeighbors(immune.combined, reduction = "pca", dims = 1:20)
immune.combined <- FindClusters(immune.combined, resolution = 0.5)
```

Example 14 (r):
```r
DefaultAssay(immune.combined) <- "integrated"

# Run the standard workflow for visualization and clustering
immune.combined <- ScaleData(immune.combined, verbose = FALSE)
immune.combined <- RunPCA(immune.combined, npcs = 30, verbose = FALSE)
# t-SNE and Clustering
immune.combined <- RunUMAP(immune.combined, reduction = "pca", dims = 1:20)
immune.combined <- FindNeighbors(immune.combined, reduction = "pca", dims = 1:20)
immune.combined <- FindClusters(immune.combined, resolution = 0.5)
```

Example 15 (r):
```r
# Visualization
p1 <- DimPlot(immune.combined, reduction = "umap", group.by = "stim")
p2 <- DimPlot(immune.combined, reduction = "umap", label = TRUE)
plot_grid(p1, p2)
```

Example 16 (r):
```r
# Visualization
p1 <- DimPlot(immune.combined, reduction = "umap", group.by = "stim")
p2 <- DimPlot(immune.combined, reduction = "umap", label = TRUE)
plot_grid(p1, p2)
```

Example 17 (r):
```r
DimPlot(immune.combined, reduction = "umap", split.by = "stim")
```

Example 18 (r):
```r
DimPlot(immune.combined, reduction = "umap", split.by = "stim")
```

Example 19 (unknown):
```unknown
FindConservedMarkers
```

Example 20 (r):
```r
DefaultAssay(immune.combined) <- "RNA"
nk.markers <- FindConservedMarkers(immune.combined, ident.1 = 6, grouping.var = "stim", verbose = FALSE)
head(nk.markers)
```

Example 21 (r):
```r
DefaultAssay(immune.combined) <- "RNA"
nk.markers <- FindConservedMarkers(immune.combined, ident.1 = 6, grouping.var = "stim", verbose = FALSE)
head(nk.markers)
```

Example 22 (unknown):
```unknown
##        CTRL_p_val CTRL_avg_logFC CTRL_pct.1 CTRL_pct.2 CTRL_p_val_adj
## GNLY            0       4.179377      0.944      0.045              0
## NKG7            0       3.163193      0.954      0.084              0
## GZMB            0       2.926436      0.841      0.043              0
## CLIC3           0       2.400545      0.599      0.024              0
## FGFBP2          0       2.242469      0.503      0.020              0
## CTSW            0       2.077683      0.533      0.029              0
##           STIM_p_val STIM_avg_logFC STIM_pct.1 STIM_pct.2 STIM_p_val_adj
## GNLY    0.000000e+00       4.077669      0.951      0.059    0.00000e+00
## NKG7    0.000000e+00       2.901784      0.957      0.080    0.00000e+00
## GZMB    0.000000e+00       3.124419      0.895      0.060    0.00000e+00
## CLIC3   0.000000e+00       2.446643      0.620      0.031    0.00000e+00
## FGFBP2 9.638295e-158       1.476625      0.256      0.016   1.35447e-153
## CTSW    0.000000e+00       2.180716      0.596      0.035    0.00000e+00
##             max_pval minimump_p_val
## GNLY    0.000000e+00              0
## NKG7    0.000000e+00              0
## GZMB    0.000000e+00              0
## CLIC3   0.000000e+00              0
## FGFBP2 9.638295e-158              0
## CTSW    0.000000e+00              0
```

Example 23 (unknown):
```unknown
##        CTRL_p_val CTRL_avg_logFC CTRL_pct.1 CTRL_pct.2 CTRL_p_val_adj
## GNLY            0       4.179377      0.944      0.045              0
## NKG7            0       3.163193      0.954      0.084              0
## GZMB            0       2.926436      0.841      0.043              0
## CLIC3           0       2.400545      0.599      0.024              0
## FGFBP2          0       2.242469      0.503      0.020              0
## CTSW            0       2.077683      0.533      0.029              0
##           STIM_p_val STIM_avg_logFC STIM_pct.1 STIM_pct.2 STIM_p_val_adj
## GNLY    0.000000e+00       4.077669      0.951      0.059    0.00000e+00
## NKG7    0.000000e+00       2.901784      0.957      0.080    0.00000e+00
## GZMB    0.000000e+00       3.124419      0.895      0.060    0.00000e+00
## CLIC3   0.000000e+00       2.446643      0.620      0.031    0.00000e+00
## FGFBP2 9.638295e-158       1.476625      0.256      0.016   1.35447e-153
## CTSW    0.000000e+00       2.180716      0.596      0.035    0.00000e+00
##             max_pval minimump_p_val
## GNLY    0.000000e+00              0
## NKG7    0.000000e+00              0
## GZMB    0.000000e+00              0
## CLIC3   0.000000e+00              0
## FGFBP2 9.638295e-158              0
## CTSW    0.000000e+00              0
```

Example 24 (r):
```r
FeaturePlot(immune.combined, features = c("CD3D", "SELL", "CREM", "CD8A", "GNLY", "CD79A", "FCGR3A", 
    "CCL2", "PPBP"), min.cutoff = "q9")
```

Example 25 (r):
```r
FeaturePlot(immune.combined, features = c("CD3D", "SELL", "CREM", "CD8A", "GNLY", "CD79A", "FCGR3A", 
    "CCL2", "PPBP"), min.cutoff = "q9")
```

Example 26 (r):
```r
immune.combined <- RenameIdents(immune.combined, `0` = "CD14 Mono", `1` = "CD4 Naive T", `2` = "CD4 Memory T", 
    `3` = "CD16 Mono", `4` = "B", `5` = "CD8 T", `6` = "NK", `7` = "T activated", `8` = "DC", `9` = "B Activated", 
    `10` = "Mk", `11` = "pDC", `12` = "Eryth")

DimPlot(immune.combined, label = TRUE)
```

Example 27 (r):
```r
immune.combined <- RenameIdents(immune.combined, `0` = "CD14 Mono", `1` = "CD4 Naive T", `2` = "CD4 Memory T", 
    `3` = "CD16 Mono", `4` = "B", `5` = "CD8 T", `6` = "NK", `7` = "T activated", `8` = "DC", `9` = "B Activated", 
    `10` = "Mk", `11` = "pDC", `12` = "Eryth")

DimPlot(immune.combined, label = TRUE)
```

Example 28 (r):
```r
Idents(immune.combined) <- factor(Idents(immune.combined), levels = c("pDC", "Eryth", "Mk", "DC", 
    "CD14 Mono", "CD16 Mono", "B Activated", "B", "CD8 T", "NK", "T activated", "CD4 Naive T", "CD4 Memory T"))
markers.to.plot <- c("CD3D", "CREM", "HSPH1", "SELL", "GIMAP5", "CACYBP", "GNLY", "NKG7", "CCL5", 
    "CD8A", "MS4A1", "CD79A", "MIR155HG", "NME1", "FCGR3A", "VMO1", "CCL2", "S100A9", "HLA-DQA1", 
    "GPR183", "PPBP", "GNG11", "HBA2", "HBB", "TSPAN13", "IL3RA", "IGJ")
DotPlot(immune.combined, features = markers.to.plot, cols = c("blue", "red"), dot.scale = 8, split.by = "stim") + 
    RotatedAxis()
```

Example 29 (r):
```r
Idents(immune.combined) <- factor(Idents(immune.combined), levels = c("pDC", "Eryth", "Mk", "DC", 
    "CD14 Mono", "CD16 Mono", "B Activated", "B", "CD8 T", "NK", "T activated", "CD4 Naive T", "CD4 Memory T"))
markers.to.plot <- c("CD3D", "CREM", "HSPH1", "SELL", "GIMAP5", "CACYBP", "GNLY", "NKG7", "CCL5", 
    "CD8A", "MS4A1", "CD79A", "MIR155HG", "NME1", "FCGR3A", "VMO1", "CCL2", "S100A9", "HLA-DQA1", 
    "GPR183", "PPBP", "GNG11", "HBA2", "HBB", "TSPAN13", "IL3RA", "IGJ")
DotPlot(immune.combined, features = markers.to.plot, cols = c("blue", "red"), dot.scale = 8, split.by = "stim") + 
    RotatedAxis()
```

Example 30 (r):
```r
library(ggplot2)
library(cowplot)
theme_set(theme_cowplot())
t.cells <- subset(immune.combined, idents = "CD4 Naive T")
Idents(t.cells) <- "stim"
avg.t.cells <- log1p(AverageExpression(t.cells, verbose = FALSE)$RNA)
avg.t.cells$gene <- rownames(avg.t.cells)

cd14.mono <- subset(immune.combined, idents = "CD14 Mono")
Idents(cd14.mono) <- "stim"
avg.cd14.mono <- log1p(AverageExpression(cd14.mono, verbose = FALSE)$RNA)
avg.cd14.mono$gene <- rownames(avg.cd14.mono)

genes.to.label = c("ISG15", "LY6E", "IFI6", "ISG20", "MX1", "IFIT2", "IFIT1", "CXCL10", "CCL8")
p1 <- ggplot(avg.t.cells, aes(CTRL, STIM)) + geom_point() + ggtitle("CD4 Naive T Cells")
p1 <- LabelPoints(plot = p1, points = genes.to.label, repel = TRUE)
p2 <- ggplot(avg.cd14.mono, aes(CTRL, STIM)) + geom_point() + ggtitle("CD14 Monocytes")
p2 <- LabelPoints(plot = p2, points = genes.to.label, repel = TRUE)
plot_grid(p1, p2)
```

Example 31 (r):
```r
library(ggplot2)
library(cowplot)
theme_set(theme_cowplot())
t.cells <- subset(immune.combined, idents = "CD4 Naive T")
Idents(t.cells) <- "stim"
avg.t.cells <- log1p(AverageExpression(t.cells, verbose = FALSE)$RNA)
avg.t.cells$gene <- rownames(avg.t.cells)

cd14.mono <- subset(immune.combined, idents = "CD14 Mono")
Idents(cd14.mono) <- "stim"
avg.cd14.mono <- log1p(AverageExpression(cd14.mono, verbose = FALSE)$RNA)
avg.cd14.mono$gene <- rownames(avg.cd14.mono)

genes.to.label = c("ISG15", "LY6E", "IFI6", "ISG20", "MX1", "IFIT2", "IFIT1", "CXCL10", "CCL8")
p1 <- ggplot(avg.t.cells, aes(CTRL, STIM)) + geom_point() + ggtitle("CD4 Naive T Cells")
p1 <- LabelPoints(plot = p1, points = genes.to.label, repel = TRUE)
p2 <- ggplot(avg.cd14.mono, aes(CTRL, STIM)) + geom_point() + ggtitle("CD14 Monocytes")
p2 <- LabelPoints(plot = p2, points = genes.to.label, repel = TRUE)
plot_grid(p1, p2)
```

Example 32 (unknown):
```unknown
FindMarkers
```

Example 33 (r):
```r
immune.combined$celltype.stim <- paste(Idents(immune.combined), immune.combined$stim, sep = "_")
immune.combined$celltype <- Idents(immune.combined)
Idents(immune.combined) <- "celltype.stim"
b.interferon.response <- FindMarkers(immune.combined, ident.1 = "B_STIM", ident.2 = "B_CTRL", verbose = FALSE)
head(b.interferon.response, n = 15)
```

Example 34 (r):
```r
immune.combined$celltype.stim <- paste(Idents(immune.combined), immune.combined$stim, sep = "_")
immune.combined$celltype <- Idents(immune.combined)
Idents(immune.combined) <- "celltype.stim"
b.interferon.response <- FindMarkers(immune.combined, ident.1 = "B_STIM", ident.2 = "B_CTRL", verbose = FALSE)
head(b.interferon.response, n = 15)
```

Example 35 (unknown):
```unknown
##                 p_val avg_logFC pct.1 pct.2     p_val_adj
## ISG15   9.008631e-168 3.2061225 0.998 0.235 1.265983e-163
## IFIT3   1.566158e-161 3.1240285 0.961 0.049 2.200921e-157
## ISG20   1.206176e-158 2.0549983 1.000 0.662 1.695038e-154
## IFI6    1.544804e-158 2.9139826 0.959 0.077 2.170914e-154
## IFIT1   1.531805e-144 2.8529052 0.899 0.031 2.152645e-140
## MX1     3.490304e-129 2.2712525 0.902 0.113 4.904924e-125
## LY6E    3.320706e-127 2.1767293 0.897 0.146 4.666588e-123
## TNFSF10 2.108526e-114 2.5996223 0.773 0.021 2.963111e-110
## IFIT2   7.373988e-113 2.5114519 0.781 0.035 1.036267e-108
## B2M     1.570724e-101 0.4194467 1.000 1.000  2.207338e-97
## PLSCR1  8.204551e-101 1.9635626 0.792 0.115  1.152986e-96
## IRF7    1.517587e-100 1.8203577 0.837 0.181  2.132665e-96
## CXCL10   7.783861e-92 3.6869595 0.660 0.012  1.093866e-87
## UBE2L6   1.659777e-88 1.4951634 0.855 0.296  2.332484e-84
## EPSTI1   1.324448e-82 1.7540298 0.717 0.103  1.861247e-78
```

Example 36 (unknown):
```unknown
##                 p_val avg_logFC pct.1 pct.2     p_val_adj
## ISG15   9.008631e-168 3.2061225 0.998 0.235 1.265983e-163
## IFIT3   1.566158e-161 3.1240285 0.961 0.049 2.200921e-157
## ISG20   1.206176e-158 2.0549983 1.000 0.662 1.695038e-154
## IFI6    1.544804e-158 2.9139826 0.959 0.077 2.170914e-154
## IFIT1   1.531805e-144 2.8529052 0.899 0.031 2.152645e-140
## MX1     3.490304e-129 2.2712525 0.902 0.113 4.904924e-125
## LY6E    3.320706e-127 2.1767293 0.897 0.146 4.666588e-123
## TNFSF10 2.108526e-114 2.5996223 0.773 0.021 2.963111e-110
## IFIT2   7.373988e-113 2.5114519 0.781 0.035 1.036267e-108
## B2M     1.570724e-101 0.4194467 1.000 1.000  2.207338e-97
## PLSCR1  8.204551e-101 1.9635626 0.792 0.115  1.152986e-96
## IRF7    1.517587e-100 1.8203577 0.837 0.181  2.132665e-96
## CXCL10   7.783861e-92 3.6869595 0.660 0.012  1.093866e-87
## UBE2L6   1.659777e-88 1.4951634 0.855 0.296  2.332484e-84
## EPSTI1   1.324448e-82 1.7540298 0.717 0.103  1.861247e-78
```

Example 37 (unknown):
```unknown
FeaturePlot
```

Example 38 (r):
```r
FeaturePlot(immune.combined, features = c("CD3D", "GNLY", "IFI6"), split.by = "stim", max.cutoff = 3, 
    cols = c("grey", "red"))
```

Example 39 (r):
```r
FeaturePlot(immune.combined, features = c("CD3D", "GNLY", "IFI6"), split.by = "stim", max.cutoff = 3, 
    cols = c("grey", "red"))
```

Example 40 (r):
```r
plots <- VlnPlot(immune.combined, features = c("LYZ", "ISG15", "CXCL10"), split.by = "stim", group.by = "celltype", 
    pt.size = 0, combine = FALSE)
wrap_plots(plots = plots, ncol = 1)
```

Example 41 (r):
```r
plots <- VlnPlot(immune.combined, features = c("LYZ", "ISG15", "CXCL10"), split.by = "stim", group.by = "celltype", 
    pt.size = 0, combine = FALSE)
wrap_plots(plots = plots, ncol = 1)
```

---

## Seurat - Guided Clustering Tutorial

**URL:** http://127.0.0.1:9173/seurat/archive/v3.0/pbmc3k_tutorial/index.html

**Contents:**
- Seurat - Guided Clustering Tutorial
    - Compiled: June 24, 2019
  - Setup the Seurat Object
  - Standard pre-processing workflow
    - QC and selecting cells for further analysis
  - Normalizing the data
  - Identification of highly variable features (feature selection)
  - Scaling the data
  - Perform linear dimensional reduction
  - Determine the ‘dimensionality’ of the dataset
  - Cluster the cells
  - Run non-linear dimensional reduction (UMAP/tSNE)
  - Finding differentially expressed features (cluster biomarkers)
  - Assigning cell type identity to clusters

For this tutorial, we will be analyzing the a dataset of Peripheral Blood Mononuclear Cells (PBMC) freely available from 10X Genomics. There are 2,700 single cells that were sequenced on the Illumina NextSeq 500. The raw data can be found here.

We start by reading in the data. The Read10X function reads in the output of the cellranger pipeline from 10X, returning a unique molecular identified (UMI) count matrix. The values in this matrix represent the number of molecules for each feature (i.e. gene; row) that are detected in each cell (column).

We next use the count matrix to create a Seurat object. The object serves as a container that contains both data (like the count matrix) and analysis (like PCA, or clustering results) for a single-cell dataset. For a technical discussion of the Seurat object structure, check out our GitHub Wiki. For example, the count matrix is stored in pbmc[["RNA"]]@counts.

What does data in a count matrix look like?

The . values in the matrix represent 0s (no molecules detected). Since most values in an scRNA-seq matrix are 0, Seurat uses a sparse-matrix representation whenever possible. This results in significant memory and speed savings for Drop-seq/inDrop/10x data.

The steps below encompass the standard pre-processing workflow for scRNA-seq data in Seurat. These represent the selection and filtration of cells based on QC metrics, data normalization and scaling, and the detection of highly variable features.

Seurat allows you to easily explore QC metrics and filter cells based on any user-defined criteria. A few QC metrics commonly used by the community include

Where are QC metrics stored in Seurat?

In the example below, we visualize QC metrics, and use these to filter cells.

After removing unwanted cells from the dataset, the next step is to normalize the data. By default, we employ a global-scaling normalization method “LogNormalize” that normalizes the feature expression measurements for each cell by the total expression, multiplies this by a scale factor (10,000 by default), and log-transforms the result. Normalized values are stored in pbmc[["RNA"]]@data.

For clarity, in this previous line of code (and in future commands), we provide the default values for certain parameters in the function call. However, this isn’t required and the same behavior can be achieved with:

We next calculate a subset of features that exhibit high cell-to-cell variation in the dataset (i.e, they are highly expressed in some cells, and lowly expressed in others). We and others have found that focusing on these genes in downstream analysis helps to highlight biological signal in single-cell datasets.

Our procedure in Seurat3 is described in detail here, and improves on previous versions by directly modeling the mean-variance relationship inherent in single-cell data, and is implemented in the FindVariableFeatures function. By default, we return 2,000 features per dataset. These will be used in downstream analysis, like PCA.

Next, we apply a linear transformation (‘scaling’) that is a standard pre-processing step prior to dimensional reduction techniques like PCA. The ScaleData function:

This step takes too long! Can I make it faster?

Scaling is an essential step in the Seurat workflow, but only on genes that will be used as input to PCA. Therefore, the default in ScaleData is only to perform scaling on the previously identified variable features (2,000 by default). To do this, omit the features argument in the previous function call, i.e.

How can I remove unwanted sources of variation, as in Seurat v2?

In Seurat v2 we also use the ScaleData function to remove unwanted sources of variation from a single-cell dataset. For example, we could ‘regress out’ heterogeneity associated with (for example) cell cycle stage, or mitochondrial contamination. These features are still supported in ScaleData in Seurat v3, i.e.:

Next we perform PCA on the scaled data. By default, only the previously determined variable features are used as input, but can be defined using features argument if you wish to choose a different subset.

Seurat provides several useful ways of visualizing both cells and features that define the PCA, including VizDimReduction, DimPlot, and DimHeatmap

In particular DimHeatmap allows for easy exploration of the primary sources of heterogeneity in a dataset, and can be useful when trying to decide which PCs to include for further downstream analyses. Both cells and features are ordered according to their PCA scores. Setting cells to a number plots the ‘extreme’ cells on both ends of the spectrum, which dramatically speeds plotting for large datasets. Though clearly a supervised analysis, we find this to be a valuable tool for exploring correlated feature sets.

To overcome the extensive technical noise in any single feature for scRNA-seq data, Seurat clusters cells based on their PCA scores, with each PC essentially representing a ‘metafeature’ that combines information across a correlated feature set. The top principal components therefore represent a robust compression of the dataset. However, how many componenets should we choose to include? 10? 20? 100?

In Macosko et al, we implemented a resampling test inspired by the JackStraw procedure. We randomly permute a subset of the data (1% by default) and rerun PCA, constructing a ‘null distribution’ of feature scores, and repeat this procedure. We identify ‘significant’ PCs as those who have a strong enrichment of low p-value features.

The JackStrawPlot function provides a visualization tool for comparing the distribution of p-values for each PC with a uniform distribution (dashed line). ‘Significant’ PCs will show a strong enrichment of features with low p-values (solid curve above the dashed line). In this case it appears that there is a sharp drop-off in significance after the first 10-12 PCs.

An alternative heuristic method generates an ‘Elbow plot’: a ranking of principle components based on the percentage of variance explained by each one (ElbowPlot function). In this example, we can observe an ‘elbow’ around PC9-10, suggesting that the majority of true signal is captured in the first 10 PCs.

Identifying the true dimensionality of a dataset – can be challenging/uncertain for the user. We therefore suggest these three approaches to consider. The first is more supervised, exploring PCs to determine relevant sources of heterogeneity, and could be used in conjunction with GSEA for example. The second implements a statistical test based on a random null model, but is time-consuming for large datasets, and may not return a clear PC cutoff. The third is a heuristic that is commonly used, and can be calculated instantly. In this example, all three approaches yielded similar results, but we might have been justified in choosing anything between PC 7-12 as a cutoff.

We chose 10 here, but encourage users to consider the following:

Seurat v3 applies a graph-based clustering approach, building upon initial strategies in (Macosko et al). Importantly, the distance metric which drives the clustering analysis (based on previously identified PCs) remains the same. However, our approach to partioning the cellular distance matrix into clusters has dramatically improved. Our approach was heavily inspired by recent manuscripts which applied graph-based clustering approaches to scRNA-seq data [SNN-Cliq, Xu and Su, Bioinformatics, 2015] and CyTOF data [PhenoGraph, Levine et al., Cell, 2015]. Briefly, these methods embed cells in a graph structure - for example a K-nearest neighbor (KNN) graph, with edges drawn between cells with similar feature expression patterns, and then attempt to partition this graph into highly interconnected ‘quasi-cliques’ or ‘communities’.

As in PhenoGraph, we first construct a KNN graph based on the euclidean distance in PCA space, and refine the edge weights between any two cells based on the shared overlap in their local neighborhoods (Jaccard similarity). This step is performed using the FindNeighbors function, and takes as input the previously defined dimensionality of the dataset (first 10 PCs).

To cluster the cells, we next apply modularity optimization techniques such as the Louvain algorithm (default) or SLM [SLM, Blondel et al., Journal of Statistical Mechanics], to iteratively group cells together, with the goal of optimizing the standard modularity function. The FindClusters function implements this procedure, and contains a resolution parameter that sets the ‘granularity’ of the downstream clustering, with increased values leading to a greater number of clusters. We find that setting this parameter between 0.4-1.2 typically returns good results for single-cell datasets of around 3K cells. Optimal resolution often increases for larger datasets. The clusters can be found using the Idents function.

Seurat offers several non-linear dimensional reduction techniques, such as tSNE and UMAP, to visualize and explore these datasets. The goal of these algorithms is to learn the underlying manifold of the data in order to place similar cells together in low-dimensional space. Cells within the graph-based clusters determined above should co-localize on these dimension reduction plots. As input to the UMAP and tSNE, we suggest using the same PCs as input to the clustering analysis.

You can save the object at this point so that it can easily be loaded back in without having to rerun the computationally intensive steps performed above, or easily shared with collaborators.

Seurat can help you find markers that define clusters via differential expression. By default, it identifes positive and negative markers of a single cluster (specified in ident.1), compared to all other cells. FindAllMarkers automates this process for all clusters, but you can also test groups of clusters vs. each other, or against all cells.

The min.pct argument requires a feature to be detected at a minimum percentage in either of the two groups of cells, and the thresh.test argument requires a feature to be differentially expressed (on average) by some amount between the two groups. You can set both of these to 0, but with a dramatic increase in time - since this will test a large number of features that are unlikely to be highly discriminatory. As another option to speed up these computations, max.cells.per.ident can be set. This will downsample each identity class to have no more cells than whatever this is set to. While there is generally going to be a loss in power, the speed increases can be significiant and the most highly differentially expressed features will likely still rise to the top.

Seurat has several tests for differential expression which can be set with the test.use parameter (see our DE vignette for details). For example, the ROC test returns the ‘classification power’ for any individual marker (ranging from 0 - random, to 1 - perfect).

We include several tools for visualizing marker expression. VlnPlot (shows expression probability distributions across clusters), and FeaturePlot (visualizes feature expression on a tSNE or PCA plot) are our most commonly used visualizations. We also suggest exploring RidgePlot, CellScatter, and DotPlot as additional methods to view your dataset.

DoHeatmap generates an expression heatmap for given cells and features. In this case, we are plotting the top 20 markers (or all markers if less than 20) for each cluster.

Fortunately in the case of this dataset, we can use canonical markers to easily match the unbiased clustering to known cell types:

**Examples:**

Example 1 (unknown):
```unknown
pbmc[["RNA"]]@counts
```

Example 2 (r):
```r
library(dplyr)
library(Seurat)

# Load the PBMC dataset
pbmc.data <- Read10X(data.dir = "../data/pbmc3k/filtered_gene_bc_matrices/hg19/")
# Initialize the Seurat object with the raw (non-normalized data).
pbmc <- CreateSeuratObject(counts = pbmc.data, project = "pbmc3k", min.cells = 3, min.features = 200)
pbmc
```

Example 3 (r):
```r
library(dplyr)
library(Seurat)

# Load the PBMC dataset
pbmc.data <- Read10X(data.dir = "../data/pbmc3k/filtered_gene_bc_matrices/hg19/")
# Initialize the Seurat object with the raw (non-normalized data).
pbmc <- CreateSeuratObject(counts = pbmc.data, project = "pbmc3k", min.cells = 3, min.features = 200)
pbmc
```

Example 4 (python):
```python
## An object of class Seurat 
## 13714 features across 2700 samples within 1 assay 
## Active assay: RNA (13714 features)
```

Example 5 (python):
```python
## An object of class Seurat 
## 13714 features across 2700 samples within 1 assay 
## Active assay: RNA (13714 features)
```

Example 6 (r):
```r
# Lets examine a few genes in the first thirty cells
pbmc.data[c("CD3D", "TCL1A", "MS4A1"), 1:30]
```

Example 7 (r):
```r
# Lets examine a few genes in the first thirty cells
pbmc.data[c("CD3D", "TCL1A", "MS4A1"), 1:30]
```

Example 8 (python):
```python
## 3 x 30 sparse Matrix of class "dgCMatrix"
##                                                                    
## CD3D  4 . 10 . . 1 2 3 1 . . 2 7 1 . . 1 3 . 2  3 . . . . . 3 4 1 5
## TCL1A . .  . . . . . . 1 . . . . . . . . . . .  . 1 . . . . . . . .
## MS4A1 . 6  . . . . . . 1 1 1 . . . . . . . . . 36 1 2 . . 2 . . . .
```

Example 9 (python):
```python
## 3 x 30 sparse Matrix of class "dgCMatrix"
##                                                                    
## CD3D  4 . 10 . . 1 2 3 1 . . 2 7 1 . . 1 3 . 2  3 . . . . . 3 4 1 5
## TCL1A . .  . . . . . . 1 . . . . . . . . . . .  . 1 . . . . . . . .
## MS4A1 . 6  . . . . . . 1 1 1 . . . . . . . . . 36 1 2 . . 2 . . . .
```

Example 10 (r):
```r
dense.size <- object.size(as.matrix(pbmc.data))
dense.size
```

Example 11 (r):
```r
dense.size <- object.size(as.matrix(pbmc.data))
dense.size
```

Example 12 (unknown):
```unknown
## 709548272 bytes
```

Example 13 (unknown):
```unknown
## 709548272 bytes
```

Example 14 (r):
```r
sparse.size <- object.size(pbmc.data)
sparse.size
```

Example 15 (r):
```r
sparse.size <- object.size(pbmc.data)
sparse.size
```

Example 16 (unknown):
```unknown
## 29861992 bytes
```

Example 17 (unknown):
```unknown
## 29861992 bytes
```

Example 18 (r):
```r
dense.size/sparse.size
```

Example 19 (r):
```r
dense.size/sparse.size
```

Example 20 (unknown):
```unknown
## 23.8 bytes
```

Example 21 (unknown):
```unknown
## 23.8 bytes
```

Example 22 (unknown):
```unknown
PercentageFeatureSet
```

Example 23 (r):
```r
# The [[ operator can add columns to object metadata. This is a great place to stash QC stats
pbmc[["percent.mt"]] <- PercentageFeatureSet(pbmc, pattern = "^MT-")
```

Example 24 (r):
```r
# The [[ operator can add columns to object metadata. This is a great place to stash QC stats
pbmc[["percent.mt"]] <- PercentageFeatureSet(pbmc, pattern = "^MT-")
```

Example 25 (unknown):
```unknown
CreateSeuratObject
```

Example 26 (r):
```r
# Show QC metrics for the first 5 cells
head(pbmc@meta.data, 5)
```

Example 27 (r):
```r
# Show QC metrics for the first 5 cells
head(pbmc@meta.data, 5)
```

Example 28 (r):
```r
# Visualize QC metrics as a violin plot
VlnPlot(pbmc, features = c("nFeature_RNA", "nCount_RNA", "percent.mt"), ncol = 3)
```

Example 29 (r):
```r
# Visualize QC metrics as a violin plot
VlnPlot(pbmc, features = c("nFeature_RNA", "nCount_RNA", "percent.mt"), ncol = 3)
```

Example 30 (r):
```r
# FeatureScatter is typically used to visualize feature-feature relationships, but can be used
# for anything calculated by the object, i.e. columns in object metadata, PC scores etc.

plot1 <- FeatureScatter(pbmc, feature1 = "nCount_RNA", feature2 = "percent.mt")
plot2 <- FeatureScatter(pbmc, feature1 = "nCount_RNA", feature2 = "nFeature_RNA")
CombinePlots(plots = list(plot1, plot2))
```

Example 31 (r):
```r
# FeatureScatter is typically used to visualize feature-feature relationships, but can be used
# for anything calculated by the object, i.e. columns in object metadata, PC scores etc.

plot1 <- FeatureScatter(pbmc, feature1 = "nCount_RNA", feature2 = "percent.mt")
plot2 <- FeatureScatter(pbmc, feature1 = "nCount_RNA", feature2 = "nFeature_RNA")
CombinePlots(plots = list(plot1, plot2))
```

Example 32 (r):
```r
pbmc <- subset(pbmc, subset = nFeature_RNA > 200 & nFeature_RNA < 2500 & percent.mt < 5)
```

Example 33 (r):
```r
pbmc <- subset(pbmc, subset = nFeature_RNA > 200 & nFeature_RNA < 2500 & percent.mt < 5)
```

Example 34 (unknown):
```unknown
pbmc[["RNA"]]@data
```

Example 35 (r):
```r
pbmc <- NormalizeData(pbmc, normalization.method = "LogNormalize", scale.factor = 10000)
```

Example 36 (r):
```r
pbmc <- NormalizeData(pbmc, normalization.method = "LogNormalize", scale.factor = 10000)
```

Example 37 (r):
```r
pbmc <- NormalizeData(pbmc)
```

Example 38 (r):
```r
pbmc <- NormalizeData(pbmc)
```

Example 39 (unknown):
```unknown
FindVariableFeatures
```

Example 40 (r):
```r
pbmc <- FindVariableFeatures(pbmc, selection.method = "vst", nfeatures = 2000)

# Identify the 10 most highly variable genes
top10 <- head(VariableFeatures(pbmc), 10)

# plot variable features with and without labels
plot1 <- VariableFeaturePlot(pbmc)
plot2 <- LabelPoints(plot = plot1, points = top10, repel = TRUE)
CombinePlots(plots = list(plot1, plot2))
```

Example 41 (r):
```r
pbmc <- FindVariableFeatures(pbmc, selection.method = "vst", nfeatures = 2000)

# Identify the 10 most highly variable genes
top10 <- head(VariableFeatures(pbmc), 10)

# plot variable features with and without labels
plot1 <- VariableFeaturePlot(pbmc)
plot2 <- LabelPoints(plot = plot1, points = top10, repel = TRUE)
CombinePlots(plots = list(plot1, plot2))
```

Example 42 (unknown):
```unknown
pbmc[["RNA"]]@scale.data
```

Example 43 (r):
```r
all.genes <- rownames(pbmc)
pbmc <- ScaleData(pbmc, features = all.genes)
```

Example 44 (r):
```r
all.genes <- rownames(pbmc)
pbmc <- ScaleData(pbmc, features = all.genes)
```

Example 45 (r):
```r
pbmc <- ScaleData(pbmc)
```

Example 46 (r):
```r
pbmc <- ScaleData(pbmc)
```

Example 47 (r):
```r
pbmc <- ScaleData(pbmc, vars.to.regress = "percent.mt")
```

Example 48 (r):
```r
pbmc <- ScaleData(pbmc, vars.to.regress = "percent.mt")
```

Example 49 (unknown):
```unknown
sctransform
```

Example 50 (unknown):
```unknown
SCTransform
```

Example 51 (unknown):
```unknown
vars.to.regress
```

Example 52 (r):
```r
pbmc <- RunPCA(pbmc, features = VariableFeatures(object = pbmc))
```

Example 53 (r):
```r
pbmc <- RunPCA(pbmc, features = VariableFeatures(object = pbmc))
```

Example 54 (unknown):
```unknown
VizDimReduction
```

Example 55 (r):
```r
# Examine and visualize PCA results a few different ways
print(pbmc[["pca"]], dims = 1:5, nfeatures = 5)
```

Example 56 (r):
```r
# Examine and visualize PCA results a few different ways
print(pbmc[["pca"]], dims = 1:5, nfeatures = 5)
```

Example 57 (unknown):
```unknown
## PC_ 1 
## Positive:  CST3, TYROBP, LST1, AIF1, FTL 
## Negative:  MALAT1, LTB, IL32, IL7R, CD2 
## PC_ 2 
## Positive:  CD79A, MS4A1, TCL1A, HLA-DQA1, HLA-DQB1 
## Negative:  NKG7, PRF1, CST7, GZMB, GZMA 
## PC_ 3 
## Positive:  HLA-DQA1, CD79A, CD79B, HLA-DQB1, HLA-DPB1 
## Negative:  PPBP, PF4, SDPR, SPARC, GNG11 
## PC_ 4 
## Positive:  HLA-DQA1, CD79B, CD79A, MS4A1, HLA-DQB1 
## Negative:  VIM, IL7R, S100A6, IL32, S100A8 
## PC_ 5 
## Positive:  GZMB, NKG7, S100A8, FGFBP2, GNLY 
## Negative:  LTB, IL7R, CKB, VIM, MS4A7
```

Example 58 (unknown):
```unknown
## PC_ 1 
## Positive:  CST3, TYROBP, LST1, AIF1, FTL 
## Negative:  MALAT1, LTB, IL32, IL7R, CD2 
## PC_ 2 
## Positive:  CD79A, MS4A1, TCL1A, HLA-DQA1, HLA-DQB1 
## Negative:  NKG7, PRF1, CST7, GZMB, GZMA 
## PC_ 3 
## Positive:  HLA-DQA1, CD79A, CD79B, HLA-DQB1, HLA-DPB1 
## Negative:  PPBP, PF4, SDPR, SPARC, GNG11 
## PC_ 4 
## Positive:  HLA-DQA1, CD79B, CD79A, MS4A1, HLA-DQB1 
## Negative:  VIM, IL7R, S100A6, IL32, S100A8 
## PC_ 5 
## Positive:  GZMB, NKG7, S100A8, FGFBP2, GNLY 
## Negative:  LTB, IL7R, CKB, VIM, MS4A7
```

Example 59 (r):
```r
VizDimLoadings(pbmc, dims = 1:2, reduction = "pca")
```

Example 60 (r):
```r
VizDimLoadings(pbmc, dims = 1:2, reduction = "pca")
```

Example 61 (r):
```r
DimPlot(pbmc, reduction = "pca")
```

Example 62 (r):
```r
DimPlot(pbmc, reduction = "pca")
```

Example 63 (r):
```r
DimHeatmap(pbmc, dims = 1, cells = 500, balanced = TRUE)
```

Example 64 (r):
```r
DimHeatmap(pbmc, dims = 1, cells = 500, balanced = TRUE)
```

Example 65 (r):
```r
DimHeatmap(pbmc, dims = 1:15, cells = 500, balanced = TRUE)
```

Example 66 (r):
```r
DimHeatmap(pbmc, dims = 1:15, cells = 500, balanced = TRUE)
```

Example 67 (r):
```r
# NOTE: This process can take a long time for big datasets, comment out for expediency. More
# approximate techniques such as those implemented in ElbowPlot() can be used to reduce
# computation time
pbmc <- JackStraw(pbmc, num.replicate = 100)
pbmc <- ScoreJackStraw(pbmc, dims = 1:20)
```

Example 68 (r):
```r
# NOTE: This process can take a long time for big datasets, comment out for expediency. More
# approximate techniques such as those implemented in ElbowPlot() can be used to reduce
# computation time
pbmc <- JackStraw(pbmc, num.replicate = 100)
pbmc <- ScoreJackStraw(pbmc, dims = 1:20)
```

Example 69 (unknown):
```unknown
JackStrawPlot
```

Example 70 (r):
```r
JackStrawPlot(pbmc, dims = 1:15)
```

Example 71 (r):
```r
JackStrawPlot(pbmc, dims = 1:15)
```

Example 72 (r):
```r
ElbowPlot(pbmc)
```

Example 73 (r):
```r
ElbowPlot(pbmc)
```

Example 74 (unknown):
```unknown
FindNeighbors
```

Example 75 (unknown):
```unknown
FindClusters
```

Example 76 (r):
```r
pbmc <- FindNeighbors(pbmc, dims = 1:10)
pbmc <- FindClusters(pbmc, resolution = 0.5)
```

Example 77 (r):
```r
pbmc <- FindNeighbors(pbmc, dims = 1:10)
pbmc <- FindClusters(pbmc, resolution = 0.5)
```

Example 78 (unknown):
```unknown
## Modularity Optimizer version 1.3.0 by Ludo Waltman and Nees Jan van Eck
## 
## Number of nodes: 2638
## Number of edges: 96033
## 
## Running Louvain algorithm...
## Maximum modularity in 10 random starts: 0.8720
## Number of communities: 9
## Elapsed time: 0 seconds
```

Example 79 (unknown):
```unknown
## Modularity Optimizer version 1.3.0 by Ludo Waltman and Nees Jan van Eck
## 
## Number of nodes: 2638
## Number of edges: 96033
## 
## Running Louvain algorithm...
## Maximum modularity in 10 random starts: 0.8720
## Number of communities: 9
## Elapsed time: 0 seconds
```

Example 80 (r):
```r
# Look at cluster IDs of the first 5 cells
head(Idents(pbmc), 5)
```

Example 81 (r):
```r
# Look at cluster IDs of the first 5 cells
head(Idents(pbmc), 5)
```

Example 82 (unknown):
```unknown
## AAACATACAACCAC AAACATTGAGCTAC AAACATTGATCAGC AAACCGTGCTTCCG AAACCGTGTATGCG 
##              1              3              1              2              6 
## Levels: 0 1 2 3 4 5 6 7 8
```

Example 83 (unknown):
```unknown
## AAACATACAACCAC AAACATTGAGCTAC AAACATTGATCAGC AAACCGTGCTTCCG AAACCGTGTATGCG 
##              1              3              1              2              6 
## Levels: 0 1 2 3 4 5 6 7 8
```

Example 84 (r):
```r
# If you haven't installed UMAP, you can do so via reticulate::py_install(packages =
# 'umap-learn')
pbmc <- RunUMAP(pbmc, dims = 1:10)
```

Example 85 (r):
```r
# If you haven't installed UMAP, you can do so via reticulate::py_install(packages =
# 'umap-learn')
pbmc <- RunUMAP(pbmc, dims = 1:10)
```

Example 86 (r):
```r
# note that you can set `label = TRUE` or use the LabelClusters function to help label
# individual clusters
DimPlot(pbmc, reduction = "umap")
```

Example 87 (r):
```r
# note that you can set `label = TRUE` or use the LabelClusters function to help label
# individual clusters
DimPlot(pbmc, reduction = "umap")
```

Example 88 (r):
```r
saveRDS(pbmc, file = "../output/pbmc_tutorial.rds")
```

Example 89 (r):
```r
saveRDS(pbmc, file = "../output/pbmc_tutorial.rds")
```

Example 90 (unknown):
```unknown
FindAllMarkers
```

Example 91 (unknown):
```unknown
max.cells.per.ident
```

Example 92 (r):
```r
# find all markers of cluster 1
cluster1.markers <- FindMarkers(pbmc, ident.1 = 1, min.pct = 0.25)
head(cluster1.markers, n = 5)
```

Example 93 (r):
```r
# find all markers of cluster 1
cluster1.markers <- FindMarkers(pbmc, ident.1 = 1, min.pct = 0.25)
head(cluster1.markers, n = 5)
```

Example 94 (r):
```r
# find all markers distinguishing cluster 5 from clusters 0 and 3
cluster5.markers <- FindMarkers(pbmc, ident.1 = 5, ident.2 = c(0, 3), min.pct = 0.25)
head(cluster5.markers, n = 5)
```

Example 95 (r):
```r
# find all markers distinguishing cluster 5 from clusters 0 and 3
cluster5.markers <- FindMarkers(pbmc, ident.1 = 5, ident.2 = c(0, 3), min.pct = 0.25)
head(cluster5.markers, n = 5)
```

Example 96 (r):
```r
# find markers for every cluster compared to all remaining cells, report only the positive ones
pbmc.markers <- FindAllMarkers(pbmc, only.pos = TRUE, min.pct = 0.25, logfc.threshold = 0.25)
pbmc.markers %>% group_by(cluster) %>% top_n(n = 2, wt = avg_logFC)
```

Example 97 (r):
```r
# find markers for every cluster compared to all remaining cells, report only the positive ones
pbmc.markers <- FindAllMarkers(pbmc, only.pos = TRUE, min.pct = 0.25, logfc.threshold = 0.25)
pbmc.markers %>% group_by(cluster) %>% top_n(n = 2, wt = avg_logFC)
```

Example 98 (r):
```r
cluster1.markers <- FindMarkers(pbmc, ident.1 = 0, logfc.threshold = 0.25, test.use = "roc", only.pos = TRUE)
```

Example 99 (r):
```r
cluster1.markers <- FindMarkers(pbmc, ident.1 = 0, logfc.threshold = 0.25, test.use = "roc", only.pos = TRUE)
```

Example 100 (unknown):
```unknown
FeaturePlot
```

Example 101 (unknown):
```unknown
CellScatter
```

Example 102 (r):
```r
VlnPlot(pbmc, features = c("MS4A1", "CD79A"))
```

Example 103 (r):
```r
VlnPlot(pbmc, features = c("MS4A1", "CD79A"))
```

Example 104 (r):
```r
# you can plot raw counts as well
VlnPlot(pbmc, features = c("NKG7", "PF4"), slot = "counts", log = TRUE)
```

Example 105 (r):
```r
# you can plot raw counts as well
VlnPlot(pbmc, features = c("NKG7", "PF4"), slot = "counts", log = TRUE)
```

Example 106 (r):
```r
FeaturePlot(pbmc, features = c("MS4A1", "GNLY", "CD3E", "CD14", "FCER1A", "FCGR3A", "LYZ", "PPBP", 
    "CD8A"))
```

Example 107 (r):
```r
FeaturePlot(pbmc, features = c("MS4A1", "GNLY", "CD3E", "CD14", "FCER1A", "FCGR3A", "LYZ", "PPBP", 
    "CD8A"))
```

Example 108 (r):
```r
top10 <- pbmc.markers %>% group_by(cluster) %>% top_n(n = 10, wt = avg_logFC)
DoHeatmap(pbmc, features = top10$gene) + NoLegend()
```

Example 109 (r):
```r
top10 <- pbmc.markers %>% group_by(cluster) %>% top_n(n = 10, wt = avg_logFC)
DoHeatmap(pbmc, features = top10$gene) + NoLegend()
```

Example 110 (r):
```r
new.cluster.ids <- c("Naive CD4 T", "Memory CD4 T", "CD14+ Mono", "B", "CD8 T", "FCGR3A+ Mono", 
    "NK", "DC", "Platelet")
names(new.cluster.ids) <- levels(pbmc)
pbmc <- RenameIdents(pbmc, new.cluster.ids)
DimPlot(pbmc, reduction = "umap", label = TRUE, pt.size = 0.5) + NoLegend()
```

Example 111 (r):
```r
new.cluster.ids <- c("Naive CD4 T", "Memory CD4 T", "CD14+ Mono", "B", "CD8 T", "FCGR3A+ Mono", 
    "NK", "DC", "Platelet")
names(new.cluster.ids) <- levels(pbmc)
pbmc <- RenameIdents(pbmc, new.cluster.ids)
DimPlot(pbmc, reduction = "umap", label = TRUE, pt.size = 0.5) + NoLegend()
```

Example 112 (r):
```r
saveRDS(pbmc, file = "../output/pbmc3k_final.rds")
```

Example 113 (r):
```r
saveRDS(pbmc, file = "../output/pbmc3k_final.rds")
```

---

## Tutorial: Integrating stimulated vs. control PBMC datasets to learn cell-type specific responses

**URL:** http://127.0.0.1:9173/seurat/archive/v3.1/immune_alignment/index.html

**Contents:**
- Tutorial: Integrating stimulated vs. control PBMC datasets to learn cell-type specific responses
    - Compiled: April 17, 2020
  - Integration goals
  - Setup the Seurat objects
  - Perform integration
  - Perform an integrated analysis
  - Identify conserved cell type markers
  - Identify differential expressed genes across conditions

This tutorial walks through an alignment of two groups of PBMCs from Kang et al, 2017. In this experiment, PBMCs were split into a stimulated and control group and the stimulated group was treated with interferon beta. The response to interferon caused cell type specific gene expression changes that makes a joint analysis of all the data difficult, with cells clustering both by stimulation condition and by cell type. Here, we demonstrate our integration strategy, as described in Stuart and Butler et al, 2018, for performing integrated analyses to promote the identification of common cell types and enable comparative analyses. While this example demonstrates the integration of two datasets (conditions), these methods have been extended to multiple datasets. This workflow provides an example of integrating four pancreatic islet datasets.

The following tutorial is designed to give you an overview of the kinds of comparative analyses on complex cell types that are possible using the Seurat integration procedure. Here, we address three main goals:

For convienence, we distribute this dataset through our SeuratData package.

We then identify anchors using the FindIntegrationAnchors function, which takes a list of Seurat objects as input, and use these anchors to integrate the two datasets together with IntegrateData.

Now we can run a single integrated analysis on all cells!

To visualize the two conditions side-by-side, we can use the split.by argument to show each condition colored by cluster.

To identify canonical cell type marker genes that are conserved across conditions, we provide the FindConservedMarkers function. This function performs differential gene expression testing for each dataset/group and combines the p-values using meta-analysis methods from the MetaDE R package. For example, we can calculated the genes that are conserved markers irrespective of stimulation condition in cluster 6 (NK cells).

We can explore these marker genes for each cluster and use them to annotate our clusters as specific cell types.

The DotPlot function with the split.by parameter can be useful for viewing conserved cell type markers across conditions, showing both the expression level and the percentage of cells in a cluster expressing any given gene. Here we plot 2-3 strong marker genes for each of our 13 clusters.

Now that we’ve aligned the stimulated and control cells, we can start to do comparative analyses and look at the differences induced by stimulation. One way to look broadly at these changes is to plot the average expression of both the stimulated and control cells and look for genes that are visual outliers on a scatter plot. Here, we take the average expression of both the stimulated and control naive T cells and CD14 monocyte populations and generate the scatter plots, highlighting genes that exhibit dramatic responses to interferon stimulation.

As you can see, many of the same genes are upregulated in both of these cell types and likely represent a conserved interferon response pathway.

Because we are confident in having identified common cell types across condition, we can ask what genes change in different conditions for cells of the same type. First, we create a column in the meta.data slot to hold both the cell type and stimulation information and switch the current ident to that column. Then we use FindMarkers to find the genes that are different between stimulated and control B cells. Notice that many of the top genes that show up here are the same as the ones we plotted earlier as core interferon response genes. Additionally, genes like CXCL10 which we saw were specific to monocyte and B cell interferon response show up as highly significant in this list as well.

Another useful way to visualize these changes in gene expression is with the split.by option to the FeaturePlot or VlnPlot function. This will display FeaturePlots of the list of given genes, split by a grouping variable (stimulation condition here). Genes such as CD3D and GNLY are canonical cell type markers (for T cells and NK/CD8 T cells) that are virtually unaffected by interferon stimulation and display similar gene expression patterns in the control and stimulated group. IFI6 and ISG15, on the other hand, are core interferon response genes and are upregulated accordingly in all cell types. Finally, CD14 and CXCL10 are genes that show a cell type specific interferon response. CD14 expression decreases after stimulation in CD14 monocytes, which could lead to misclassification in a supervised analysis framework, underscoring the value of integrated analysis. CXCL10 shows a distinct upregulation in monocytes and B cells after interferon stimulation but not in other cell types.

**Examples:**

Example 1 (r):
```r
library(Seurat)
library(SeuratData)
library(cowplot)
library(patchwork)
```

Example 2 (r):
```r
library(Seurat)
library(SeuratData)
library(cowplot)
library(patchwork)
```

Example 3 (r):
```r
InstallData("ifnb")
```

Example 4 (r):
```r
InstallData("ifnb")
```

Example 5 (r):
```r
data("ifnb")
ifnb.list <- SplitObject(ifnb, split.by = "stim")

ifnb.list <- lapply(X = ifnb.list, FUN = function(x) {
    x <- NormalizeData(x)
    x <- FindVariableFeatures(x, selection.method = "vst", nfeatures = 2000)
})
```

Example 6 (r):
```r
data("ifnb")
ifnb.list <- SplitObject(ifnb, split.by = "stim")

ifnb.list <- lapply(X = ifnb.list, FUN = function(x) {
    x <- NormalizeData(x)
    x <- FindVariableFeatures(x, selection.method = "vst", nfeatures = 2000)
})
```

Example 7 (unknown):
```unknown
FindIntegrationAnchors
```

Example 8 (unknown):
```unknown
IntegrateData
```

Example 9 (r):
```r
immune.anchors <- FindIntegrationAnchors(object.list = ifnb.list, dims = 1:20)
```

Example 10 (r):
```r
immune.anchors <- FindIntegrationAnchors(object.list = ifnb.list, dims = 1:20)
```

Example 11 (r):
```r
immune.combined <- IntegrateData(anchorset = immune.anchors, dims = 1:20)
```

Example 12 (r):
```r
immune.combined <- IntegrateData(anchorset = immune.anchors, dims = 1:20)
```

Example 13 (r):
```r
DefaultAssay(immune.combined) <- "integrated"

# Run the standard workflow for visualization and clustering
immune.combined <- ScaleData(immune.combined, verbose = FALSE)
immune.combined <- RunPCA(immune.combined, npcs = 30, verbose = FALSE)
# t-SNE and Clustering
immune.combined <- RunUMAP(immune.combined, reduction = "pca", dims = 1:20)
immune.combined <- FindNeighbors(immune.combined, reduction = "pca", dims = 1:20)
immune.combined <- FindClusters(immune.combined, resolution = 0.5)
```

Example 14 (r):
```r
DefaultAssay(immune.combined) <- "integrated"

# Run the standard workflow for visualization and clustering
immune.combined <- ScaleData(immune.combined, verbose = FALSE)
immune.combined <- RunPCA(immune.combined, npcs = 30, verbose = FALSE)
# t-SNE and Clustering
immune.combined <- RunUMAP(immune.combined, reduction = "pca", dims = 1:20)
immune.combined <- FindNeighbors(immune.combined, reduction = "pca", dims = 1:20)
immune.combined <- FindClusters(immune.combined, resolution = 0.5)
```

Example 15 (r):
```r
# Visualization
p1 <- DimPlot(immune.combined, reduction = "umap", group.by = "stim")
p2 <- DimPlot(immune.combined, reduction = "umap", label = TRUE)
plot_grid(p1, p2)
```

Example 16 (r):
```r
# Visualization
p1 <- DimPlot(immune.combined, reduction = "umap", group.by = "stim")
p2 <- DimPlot(immune.combined, reduction = "umap", label = TRUE)
plot_grid(p1, p2)
```

Example 17 (r):
```r
DimPlot(immune.combined, reduction = "umap", split.by = "stim")
```

Example 18 (r):
```r
DimPlot(immune.combined, reduction = "umap", split.by = "stim")
```

Example 19 (unknown):
```unknown
FindConservedMarkers
```

Example 20 (r):
```r
DefaultAssay(immune.combined) <- "RNA"
nk.markers <- FindConservedMarkers(immune.combined, ident.1 = 6, grouping.var = "stim", verbose = FALSE)
head(nk.markers)
```

Example 21 (r):
```r
DefaultAssay(immune.combined) <- "RNA"
nk.markers <- FindConservedMarkers(immune.combined, ident.1 = 6, grouping.var = "stim", verbose = FALSE)
head(nk.markers)
```

Example 22 (unknown):
```unknown
##        CTRL_p_val CTRL_avg_logFC CTRL_pct.1 CTRL_pct.2 CTRL_p_val_adj
## GNLY            0       4.179377      0.944      0.045              0
## NKG7            0       3.163193      0.954      0.084              0
## GZMB            0       2.926436      0.841      0.043              0
## CLIC3           0       2.400545      0.599      0.024              0
## FGFBP2          0       2.242469      0.503      0.020              0
## CTSW            0       2.077683      0.533      0.029              0
##           STIM_p_val STIM_avg_logFC STIM_pct.1 STIM_pct.2 STIM_p_val_adj
## GNLY    0.000000e+00       4.077669      0.951      0.059    0.00000e+00
## NKG7    0.000000e+00       2.901784      0.957      0.080    0.00000e+00
## GZMB    0.000000e+00       3.124419      0.895      0.060    0.00000e+00
## CLIC3   0.000000e+00       2.446643      0.620      0.031    0.00000e+00
## FGFBP2 9.638295e-158       1.476625      0.256      0.016   1.35447e-153
## CTSW    0.000000e+00       2.180716      0.596      0.035    0.00000e+00
##             max_pval minimump_p_val
## GNLY    0.000000e+00              0
## NKG7    0.000000e+00              0
## GZMB    0.000000e+00              0
## CLIC3   0.000000e+00              0
## FGFBP2 9.638295e-158              0
## CTSW    0.000000e+00              0
```

Example 23 (unknown):
```unknown
##        CTRL_p_val CTRL_avg_logFC CTRL_pct.1 CTRL_pct.2 CTRL_p_val_adj
## GNLY            0       4.179377      0.944      0.045              0
## NKG7            0       3.163193      0.954      0.084              0
## GZMB            0       2.926436      0.841      0.043              0
## CLIC3           0       2.400545      0.599      0.024              0
## FGFBP2          0       2.242469      0.503      0.020              0
## CTSW            0       2.077683      0.533      0.029              0
##           STIM_p_val STIM_avg_logFC STIM_pct.1 STIM_pct.2 STIM_p_val_adj
## GNLY    0.000000e+00       4.077669      0.951      0.059    0.00000e+00
## NKG7    0.000000e+00       2.901784      0.957      0.080    0.00000e+00
## GZMB    0.000000e+00       3.124419      0.895      0.060    0.00000e+00
## CLIC3   0.000000e+00       2.446643      0.620      0.031    0.00000e+00
## FGFBP2 9.638295e-158       1.476625      0.256      0.016   1.35447e-153
## CTSW    0.000000e+00       2.180716      0.596      0.035    0.00000e+00
##             max_pval minimump_p_val
## GNLY    0.000000e+00              0
## NKG7    0.000000e+00              0
## GZMB    0.000000e+00              0
## CLIC3   0.000000e+00              0
## FGFBP2 9.638295e-158              0
## CTSW    0.000000e+00              0
```

Example 24 (r):
```r
FeaturePlot(immune.combined, features = c("CD3D", "SELL", "CREM", "CD8A", "GNLY", "CD79A", "FCGR3A", 
    "CCL2", "PPBP"), min.cutoff = "q9")
```

Example 25 (r):
```r
FeaturePlot(immune.combined, features = c("CD3D", "SELL", "CREM", "CD8A", "GNLY", "CD79A", "FCGR3A", 
    "CCL2", "PPBP"), min.cutoff = "q9")
```

Example 26 (r):
```r
immune.combined <- RenameIdents(immune.combined, `0` = "CD14 Mono", `1` = "CD4 Naive T", `2` = "CD4 Memory T", 
    `3` = "CD16 Mono", `4` = "B", `5` = "CD8 T", `6` = "NK", `7` = "T activated", `8` = "DC", `9` = "B Activated", 
    `10` = "Mk", `11` = "pDC", `12` = "Eryth")

DimPlot(immune.combined, label = TRUE)
```

Example 27 (r):
```r
immune.combined <- RenameIdents(immune.combined, `0` = "CD14 Mono", `1` = "CD4 Naive T", `2` = "CD4 Memory T", 
    `3` = "CD16 Mono", `4` = "B", `5` = "CD8 T", `6` = "NK", `7` = "T activated", `8` = "DC", `9` = "B Activated", 
    `10` = "Mk", `11` = "pDC", `12` = "Eryth")

DimPlot(immune.combined, label = TRUE)
```

Example 28 (r):
```r
Idents(immune.combined) <- factor(Idents(immune.combined), levels = c("pDC", "Eryth", "Mk", "DC", 
    "CD14 Mono", "CD16 Mono", "B Activated", "B", "CD8 T", "NK", "T activated", "CD4 Naive T", "CD4 Memory T"))
markers.to.plot <- c("CD3D", "CREM", "HSPH1", "SELL", "GIMAP5", "CACYBP", "GNLY", "NKG7", "CCL5", 
    "CD8A", "MS4A1", "CD79A", "MIR155HG", "NME1", "FCGR3A", "VMO1", "CCL2", "S100A9", "HLA-DQA1", 
    "GPR183", "PPBP", "GNG11", "HBA2", "HBB", "TSPAN13", "IL3RA", "IGJ")
DotPlot(immune.combined, features = rev(markers.to.plot), cols = c("blue", "red"), dot.scale = 8, 
    split.by = "stim") + RotatedAxis()
```

Example 29 (r):
```r
Idents(immune.combined) <- factor(Idents(immune.combined), levels = c("pDC", "Eryth", "Mk", "DC", 
    "CD14 Mono", "CD16 Mono", "B Activated", "B", "CD8 T", "NK", "T activated", "CD4 Naive T", "CD4 Memory T"))
markers.to.plot <- c("CD3D", "CREM", "HSPH1", "SELL", "GIMAP5", "CACYBP", "GNLY", "NKG7", "CCL5", 
    "CD8A", "MS4A1", "CD79A", "MIR155HG", "NME1", "FCGR3A", "VMO1", "CCL2", "S100A9", "HLA-DQA1", 
    "GPR183", "PPBP", "GNG11", "HBA2", "HBB", "TSPAN13", "IL3RA", "IGJ")
DotPlot(immune.combined, features = rev(markers.to.plot), cols = c("blue", "red"), dot.scale = 8, 
    split.by = "stim") + RotatedAxis()
```

Example 30 (r):
```r
library(ggplot2)
library(cowplot)
theme_set(theme_cowplot())
t.cells <- subset(immune.combined, idents = "CD4 Naive T")
Idents(t.cells) <- "stim"
avg.t.cells <- log1p(AverageExpression(t.cells, verbose = FALSE)$RNA)
avg.t.cells$gene <- rownames(avg.t.cells)

cd14.mono <- subset(immune.combined, idents = "CD14 Mono")
Idents(cd14.mono) <- "stim"
avg.cd14.mono <- log1p(AverageExpression(cd14.mono, verbose = FALSE)$RNA)
avg.cd14.mono$gene <- rownames(avg.cd14.mono)

genes.to.label = c("ISG15", "LY6E", "IFI6", "ISG20", "MX1", "IFIT2", "IFIT1", "CXCL10", "CCL8")
p1 <- ggplot(avg.t.cells, aes(CTRL, STIM)) + geom_point() + ggtitle("CD4 Naive T Cells")
p1 <- LabelPoints(plot = p1, points = genes.to.label, repel = TRUE)
p2 <- ggplot(avg.cd14.mono, aes(CTRL, STIM)) + geom_point() + ggtitle("CD14 Monocytes")
p2 <- LabelPoints(plot = p2, points = genes.to.label, repel = TRUE)
plot_grid(p1, p2)
```

Example 31 (r):
```r
library(ggplot2)
library(cowplot)
theme_set(theme_cowplot())
t.cells <- subset(immune.combined, idents = "CD4 Naive T")
Idents(t.cells) <- "stim"
avg.t.cells <- log1p(AverageExpression(t.cells, verbose = FALSE)$RNA)
avg.t.cells$gene <- rownames(avg.t.cells)

cd14.mono <- subset(immune.combined, idents = "CD14 Mono")
Idents(cd14.mono) <- "stim"
avg.cd14.mono <- log1p(AverageExpression(cd14.mono, verbose = FALSE)$RNA)
avg.cd14.mono$gene <- rownames(avg.cd14.mono)

genes.to.label = c("ISG15", "LY6E", "IFI6", "ISG20", "MX1", "IFIT2", "IFIT1", "CXCL10", "CCL8")
p1 <- ggplot(avg.t.cells, aes(CTRL, STIM)) + geom_point() + ggtitle("CD4 Naive T Cells")
p1 <- LabelPoints(plot = p1, points = genes.to.label, repel = TRUE)
p2 <- ggplot(avg.cd14.mono, aes(CTRL, STIM)) + geom_point() + ggtitle("CD14 Monocytes")
p2 <- LabelPoints(plot = p2, points = genes.to.label, repel = TRUE)
plot_grid(p1, p2)
```

Example 32 (unknown):
```unknown
FindMarkers
```

Example 33 (r):
```r
immune.combined$celltype.stim <- paste(Idents(immune.combined), immune.combined$stim, sep = "_")
immune.combined$celltype <- Idents(immune.combined)
Idents(immune.combined) <- "celltype.stim"
b.interferon.response <- FindMarkers(immune.combined, ident.1 = "B_STIM", ident.2 = "B_CTRL", verbose = FALSE)
head(b.interferon.response, n = 15)
```

Example 34 (r):
```r
immune.combined$celltype.stim <- paste(Idents(immune.combined), immune.combined$stim, sep = "_")
immune.combined$celltype <- Idents(immune.combined)
Idents(immune.combined) <- "celltype.stim"
b.interferon.response <- FindMarkers(immune.combined, ident.1 = "B_STIM", ident.2 = "B_CTRL", verbose = FALSE)
head(b.interferon.response, n = 15)
```

Example 35 (unknown):
```unknown
##                 p_val avg_logFC pct.1 pct.2     p_val_adj
## ISG15   9.008631e-168 3.2061225 0.998 0.235 1.265983e-163
## IFIT3   1.566158e-161 3.1240285 0.961 0.049 2.200921e-157
## ISG20   1.206176e-158 2.0549983 1.000 0.662 1.695038e-154
## IFI6    1.544804e-158 2.9139826 0.959 0.077 2.170914e-154
## IFIT1   1.531805e-144 2.8529052 0.899 0.031 2.152645e-140
## MX1     3.490304e-129 2.2712525 0.902 0.113 4.904924e-125
## LY6E    3.320706e-127 2.1767293 0.897 0.146 4.666588e-123
## TNFSF10 2.108526e-114 2.5996223 0.773 0.021 2.963111e-110
## IFIT2   7.373988e-113 2.5114519 0.781 0.035 1.036267e-108
## B2M     1.570724e-101 0.4194467 1.000 1.000  2.207338e-97
## PLSCR1  8.204551e-101 1.9635626 0.792 0.115  1.152986e-96
## IRF7    1.517587e-100 1.8203577 0.837 0.181  2.132665e-96
## CXCL10   7.783861e-92 3.6869595 0.660 0.012  1.093866e-87
## UBE2L6   1.659777e-88 1.4951634 0.855 0.296  2.332484e-84
## EPSTI1   1.324448e-82 1.7540298 0.717 0.103  1.861247e-78
```

Example 36 (unknown):
```unknown
##                 p_val avg_logFC pct.1 pct.2     p_val_adj
## ISG15   9.008631e-168 3.2061225 0.998 0.235 1.265983e-163
## IFIT3   1.566158e-161 3.1240285 0.961 0.049 2.200921e-157
## ISG20   1.206176e-158 2.0549983 1.000 0.662 1.695038e-154
## IFI6    1.544804e-158 2.9139826 0.959 0.077 2.170914e-154
## IFIT1   1.531805e-144 2.8529052 0.899 0.031 2.152645e-140
## MX1     3.490304e-129 2.2712525 0.902 0.113 4.904924e-125
## LY6E    3.320706e-127 2.1767293 0.897 0.146 4.666588e-123
## TNFSF10 2.108526e-114 2.5996223 0.773 0.021 2.963111e-110
## IFIT2   7.373988e-113 2.5114519 0.781 0.035 1.036267e-108
## B2M     1.570724e-101 0.4194467 1.000 1.000  2.207338e-97
## PLSCR1  8.204551e-101 1.9635626 0.792 0.115  1.152986e-96
## IRF7    1.517587e-100 1.8203577 0.837 0.181  2.132665e-96
## CXCL10   7.783861e-92 3.6869595 0.660 0.012  1.093866e-87
## UBE2L6   1.659777e-88 1.4951634 0.855 0.296  2.332484e-84
## EPSTI1   1.324448e-82 1.7540298 0.717 0.103  1.861247e-78
```

Example 37 (unknown):
```unknown
FeaturePlot
```

Example 38 (r):
```r
FeaturePlot(immune.combined, features = c("CD3D", "GNLY", "IFI6"), split.by = "stim", max.cutoff = 3, 
    cols = c("grey", "red"))
```

Example 39 (r):
```r
FeaturePlot(immune.combined, features = c("CD3D", "GNLY", "IFI6"), split.by = "stim", max.cutoff = 3, 
    cols = c("grey", "red"))
```

Example 40 (r):
```r
plots <- VlnPlot(immune.combined, features = c("LYZ", "ISG15", "CXCL10"), split.by = "stim", group.by = "celltype", 
    pt.size = 0, combine = FALSE)
wrap_plots(plots = plots, ncol = 1)
```

Example 41 (r):
```r
plots <- VlnPlot(immune.combined, features = c("LYZ", "ISG15", "CXCL10"), split.by = "stim", group.by = "celltype", 
    pt.size = 0, combine = FALSE)
wrap_plots(plots = plots, ncol = 1)
```

---

## Seurat - Guided Clustering Tutorial • Seurat

**URL:** http://127.0.0.1:9173/seurat/archive/v4.3/pbmc3k_tutorial/index.html

**Contents:**
- Seurat - Guided Clustering Tutorial
    - Compiled: March 27, 2023
- Setup the Seurat Object
- Standard pre-processing workflow
  - QC and selecting cells for further analysis
- Normalizing the data
- Identification of highly variable features (feature selection)
- Scaling the data
- Perform linear dimensional reduction
- Determine the ‘dimensionality’ of the dataset
- Cluster the cells
- Run non-linear dimensional reduction (UMAP/tSNE)
- Finding differentially expressed features (cluster biomarkers)
- Assigning cell type identity to clusters
- Contents

For this tutorial, we will be analyzing the a dataset of Peripheral Blood Mononuclear Cells (PBMC) freely available from 10X Genomics. There are 2,700 single cells that were sequenced on the Illumina NextSeq 500. The raw data can be found here.We start by reading in the data. The Read10X() function reads in the output of the cellranger pipeline from 10X, returning a unique molecular identified (UMI) count matrix. The values in this matrix represent the number of molecules for each feature (i.e. gene; row) that are detected in each cell (column).We next use the count matrix to create a Seurat object. The object serves as a container that contains both data (like the count matrix) and analysis (like PCA, or clustering results) for a single-cell dataset. For a technical discussion of the Seurat object structure, check out our GitHub Wiki. For example, the count matrix is stored in pbmc[["RNA"]]@counts. library(dplyr) library(Seurat) library(patchwork) # Load the PBMC dataset pbmc.data <- Read10X(data.dir = "../data/pbmc3k/filtered_gene_bc_matrices/hg19/") # Initialize the Seurat object with the raw (non-normalized data). pbmc <- CreateSeuratObject(counts = pbmc.data, project = "pbmc3k", min.cells = 3, min.features = 200) pbmc## An object of class Seurat ## 13714 features across 2700 samples within 1 assay ## Active assay: RNA (13714 features, 0 variable features)What does data in a count matrix look like? # Lets examine a few genes in the first thirty cells pbmc.data[c("CD3D", "TCL1A", "MS4A1"), 1:30]## 3 x 30 sparse Matrix of class "dgCMatrix" ## ## CD3D 4 . 10 . . 1 2 3 1 . . 2 7 1 . . 1 3 . 2 3 . . . . . 3 4 1 5 ## TCL1A . . . . . . . . 1 . . . . . . . . . . . . 1 . . . . . . . . ## MS4A1 . 6 . . . . . . 1 1 1 . . . . . . . . . 36 1 2 . . 2 . . . .The . values in the matrix represent 0s (no molecules detected). Since most values in an scRNA-seq matrix are 0, Seurat uses a sparse-matrix representation whenever possible. This results in significant memory and speed savings for Drop-seq/inDrop/10x data. dense.size <- object.size(as.matrix(pbmc.data)) dense.size## 709591472 bytes sparse.size <- object.size(pbmc.data) sparse.size## 29905192 bytes dense.size/sparse.size## 23.7 bytes

We start by reading in the data. The Read10X() function reads in the output of the cellranger pipeline from 10X, returning a unique molecular identified (UMI) count matrix. The values in this matrix represent the number of molecules for each feature (i.e. gene; row) that are detected in each cell (column).We next use the count matrix to create a Seurat object. The object serves as a container that contains both data (like the count matrix) and analysis (like PCA, or clustering results) for a single-cell dataset. For a technical discussion of the Seurat object structure, check out our GitHub Wiki. For example, the count matrix is stored in pbmc[["RNA"]]@counts. library(dplyr) library(Seurat) library(patchwork) # Load the PBMC dataset pbmc.data <- Read10X(data.dir = "../data/pbmc3k/filtered_gene_bc_matrices/hg19/") # Initialize the Seurat object with the raw (non-normalized data). pbmc <- CreateSeuratObject(counts = pbmc.data, project = "pbmc3k", min.cells = 3, min.features = 200) pbmc## An object of class Seurat ## 13714 features across 2700 samples within 1 assay ## Active assay: RNA (13714 features, 0 variable features)What does data in a count matrix look like? # Lets examine a few genes in the first thirty cells pbmc.data[c("CD3D", "TCL1A", "MS4A1"), 1:30]## 3 x 30 sparse Matrix of class "dgCMatrix" ## ## CD3D 4 . 10 . . 1 2 3 1 . . 2 7 1 . . 1 3 . 2 3 . . . . . 3 4 1 5 ## TCL1A . . . . . . . . 1 . . . . . . . . . . . . 1 . . . . . . . . ## MS4A1 . 6 . . . . . . 1 1 1 . . . . . . . . . 36 1 2 . . 2 . . . .The . values in the matrix represent 0s (no molecules detected). Since most values in an scRNA-seq matrix are 0, Seurat uses a sparse-matrix representation whenever possible. This results in significant memory and speed savings for Drop-seq/inDrop/10x data. dense.size <- object.size(as.matrix(pbmc.data)) dense.size## 709591472 bytes sparse.size <- object.size(pbmc.data) sparse.size## 29905192 bytes dense.size/sparse.size## 23.7 bytes

We next use the count matrix to create a Seurat object. The object serves as a container that contains both data (like the count matrix) and analysis (like PCA, or clustering results) for a single-cell dataset. For a technical discussion of the Seurat object structure, check out our GitHub Wiki. For example, the count matrix is stored in pbmc[["RNA"]]@counts. library(dplyr) library(Seurat) library(patchwork) # Load the PBMC dataset pbmc.data <- Read10X(data.dir = "../data/pbmc3k/filtered_gene_bc_matrices/hg19/") # Initialize the Seurat object with the raw (non-normalized data). pbmc <- CreateSeuratObject(counts = pbmc.data, project = "pbmc3k", min.cells = 3, min.features = 200) pbmc## An object of class Seurat ## 13714 features across 2700 samples within 1 assay ## Active assay: RNA (13714 features, 0 variable features)What does data in a count matrix look like? # Lets examine a few genes in the first thirty cells pbmc.data[c("CD3D", "TCL1A", "MS4A1"), 1:30]## 3 x 30 sparse Matrix of class "dgCMatrix" ## ## CD3D 4 . 10 . . 1 2 3 1 . . 2 7 1 . . 1 3 . 2 3 . . . . . 3 4 1 5 ## TCL1A . . . . . . . . 1 . . . . . . . . . . . . 1 . . . . . . . . ## MS4A1 . 6 . . . . . . 1 1 1 . . . . . . . . . 36 1 2 . . 2 . . . .The . values in the matrix represent 0s (no molecules detected). Since most values in an scRNA-seq matrix are 0, Seurat uses a sparse-matrix representation whenever possible. This results in significant memory and speed savings for Drop-seq/inDrop/10x data. dense.size <- object.size(as.matrix(pbmc.data)) dense.size## 709591472 bytes sparse.size <- object.size(pbmc.data) sparse.size## 29905192 bytes dense.size/sparse.size## 23.7 bytes

# Lets examine a few genes in the first thirty cells pbmc.data[c("CD3D", "TCL1A", "MS4A1"), 1:30]## 3 x 30 sparse Matrix of class "dgCMatrix" ## ## CD3D 4 . 10 . . 1 2 3 1 . . 2 7 1 . . 1 3 . 2 3 . . . . . 3 4 1 5 ## TCL1A . . . . . . . . 1 . . . . . . . . . . . . 1 . . . . . . . . ## MS4A1 . 6 . . . . . . 1 1 1 . . . . . . . . . 36 1 2 . . 2 . . . .The . values in the matrix represent 0s (no molecules detected). Since most values in an scRNA-seq matrix are 0, Seurat uses a sparse-matrix representation whenever possible. This results in significant memory and speed savings for Drop-seq/inDrop/10x data. dense.size <- object.size(as.matrix(pbmc.data)) dense.size## 709591472 bytes sparse.size <- object.size(pbmc.data) sparse.size## 29905192 bytes dense.size/sparse.size## 23.7 bytes

The . values in the matrix represent 0s (no molecules detected). Since most values in an scRNA-seq matrix are 0, Seurat uses a sparse-matrix representation whenever possible. This results in significant memory and speed savings for Drop-seq/inDrop/10x data. dense.size <- object.size(as.matrix(pbmc.data)) dense.size## 709591472 bytes sparse.size <- object.size(pbmc.data) sparse.size## 29905192 bytes dense.size/sparse.size## 23.7 bytes

The steps below encompass the standard pre-processing workflow for scRNA-seq data in Seurat. These represent the selection and filtration of cells based on QC metrics, data normalization and scaling, and the detection of highly variable features.QC and selecting cells for further analysisSeurat allows you to easily explore QC metrics and filter cells based on any user-defined criteria. A few QC metrics commonly used by the community includeThe number of unique genes detected in each cell.Low-quality cells or empty droplets will often have very few genesCell doublets or multiplets may exhibit an aberrantly high gene countSimilarly, the total number of molecules detected within a cell (correlates strongly with unique genes)The percentage of reads that map to the mitochondrial genomeLow-quality / dying cells often exhibit extensive mitochondrial contaminationWe calculate mitochondrial QC metrics with the PercentageFeatureSet() function, which calculates the percentage of counts originating from a set of featuresWe use the set of all genes starting with MT- as a set of mitochondrial genes # The [[ operator can add columns to object metadata. This is a great place to stash QC stats pbmc[["percent.mt"]] <- PercentageFeatureSet(pbmc, pattern = "^MT-")Where are QC metrics stored in Seurat?The number of unique genes and total molecules are automatically calculated during CreateSeuratObject()You can find them stored in the object meta data # Show QC metrics for the first 5 cells head(pbmc@meta.data, 5)## orig.ident nCount_RNA nFeature_RNA percent.mt ## AAACATACAACCAC-1 pbmc3k 2419 779 3.0177759 ## AAACATTGAGCTAC-1 pbmc3k 4903 1352 3.7935958 ## AAACATTGATCAGC-1 pbmc3k 3147 1129 0.8897363 ## AAACCGTGCTTCCG-1 pbmc3k 2639 960 1.7430845 ## AAACCGTGTATGCG-1 pbmc3k 980 521 1.2244898 In the example below, we visualize QC metrics, and use these to filter cells.We filter cells that have unique feature counts over 2,500 or less than 200We filter cells that have >5% mitochondrial counts # Visualize QC metrics as a violin plot VlnPlot(pbmc, features = c("nFeature_RNA", "nCount_RNA", "percent.mt"), ncol = 3) # FeatureScatter is typically used to visualize feature-feature relationships, but can be used # for anything calculated by the object, i.e. columns in object metadata, PC scores etc. plot1 <- FeatureScatter(pbmc, feature1 = "nCount_RNA", feature2 = "percent.mt") plot2 <- FeatureScatter(pbmc, feature1 = "nCount_RNA", feature2 = "nFeature_RNA") plot1 + plot2 pbmc <- subset(pbmc, subset = nFeature_RNA > 200 & nFeature_RNA < 2500 & percent.mt < 5)

Seurat allows you to easily explore QC metrics and filter cells based on any user-defined criteria. A few QC metrics commonly used by the community includeThe number of unique genes detected in each cell.Low-quality cells or empty droplets will often have very few genesCell doublets or multiplets may exhibit an aberrantly high gene countSimilarly, the total number of molecules detected within a cell (correlates strongly with unique genes)The percentage of reads that map to the mitochondrial genomeLow-quality / dying cells often exhibit extensive mitochondrial contaminationWe calculate mitochondrial QC metrics with the PercentageFeatureSet() function, which calculates the percentage of counts originating from a set of featuresWe use the set of all genes starting with MT- as a set of mitochondrial genes # The [[ operator can add columns to object metadata. This is a great place to stash QC stats pbmc[["percent.mt"]] <- PercentageFeatureSet(pbmc, pattern = "^MT-")Where are QC metrics stored in Seurat?The number of unique genes and total molecules are automatically calculated during CreateSeuratObject()You can find them stored in the object meta data # Show QC metrics for the first 5 cells head(pbmc@meta.data, 5)## orig.ident nCount_RNA nFeature_RNA percent.mt ## AAACATACAACCAC-1 pbmc3k 2419 779 3.0177759 ## AAACATTGAGCTAC-1 pbmc3k 4903 1352 3.7935958 ## AAACATTGATCAGC-1 pbmc3k 3147 1129 0.8897363 ## AAACCGTGCTTCCG-1 pbmc3k 2639 960 1.7430845 ## AAACCGTGTATGCG-1 pbmc3k 980 521 1.2244898 In the example below, we visualize QC metrics, and use these to filter cells.We filter cells that have unique feature counts over 2,500 or less than 200We filter cells that have >5% mitochondrial counts # Visualize QC metrics as a violin plot VlnPlot(pbmc, features = c("nFeature_RNA", "nCount_RNA", "percent.mt"), ncol = 3) # FeatureScatter is typically used to visualize feature-feature relationships, but can be used # for anything calculated by the object, i.e. columns in object metadata, PC scores etc. plot1 <- FeatureScatter(pbmc, feature1 = "nCount_RNA", feature2 = "percent.mt") plot2 <- FeatureScatter(pbmc, feature1 = "nCount_RNA", feature2 = "nFeature_RNA") plot1 + plot2 pbmc <- subset(pbmc, subset = nFeature_RNA > 200 & nFeature_RNA < 2500 & percent.mt < 5)

The number of unique genes and total molecules are automatically calculated during CreateSeuratObject()You can find them stored in the object meta data # Show QC metrics for the first 5 cells head(pbmc@meta.data, 5)## orig.ident nCount_RNA nFeature_RNA percent.mt ## AAACATACAACCAC-1 pbmc3k 2419 779 3.0177759 ## AAACATTGAGCTAC-1 pbmc3k 4903 1352 3.7935958 ## AAACATTGATCAGC-1 pbmc3k 3147 1129 0.8897363 ## AAACCGTGCTTCCG-1 pbmc3k 2639 960 1.7430845 ## AAACCGTGTATGCG-1 pbmc3k 980 521 1.2244898

In the example below, we visualize QC metrics, and use these to filter cells.We filter cells that have unique feature counts over 2,500 or less than 200We filter cells that have >5% mitochondrial counts # Visualize QC metrics as a violin plot VlnPlot(pbmc, features = c("nFeature_RNA", "nCount_RNA", "percent.mt"), ncol = 3) # FeatureScatter is typically used to visualize feature-feature relationships, but can be used # for anything calculated by the object, i.e. columns in object metadata, PC scores etc. plot1 <- FeatureScatter(pbmc, feature1 = "nCount_RNA", feature2 = "percent.mt") plot2 <- FeatureScatter(pbmc, feature1 = "nCount_RNA", feature2 = "nFeature_RNA") plot1 + plot2 pbmc <- subset(pbmc, subset = nFeature_RNA > 200 & nFeature_RNA < 2500 & percent.mt < 5)

In the example below, we visualize QC metrics, and use these to filter cells.We filter cells that have unique feature counts over 2,500 or less than 200We filter cells that have >5% mitochondrial counts # Visualize QC metrics as a violin plot VlnPlot(pbmc, features = c("nFeature_RNA", "nCount_RNA", "percent.mt"), ncol = 3) # FeatureScatter is typically used to visualize feature-feature relationships, but can be used # for anything calculated by the object, i.e. columns in object metadata, PC scores etc. plot1 <- FeatureScatter(pbmc, feature1 = "nCount_RNA", feature2 = "percent.mt") plot2 <- FeatureScatter(pbmc, feature1 = "nCount_RNA", feature2 = "nFeature_RNA") plot1 + plot2 pbmc <- subset(pbmc, subset = nFeature_RNA > 200 & nFeature_RNA < 2500 & percent.mt < 5)

# FeatureScatter is typically used to visualize feature-feature relationships, but can be used # for anything calculated by the object, i.e. columns in object metadata, PC scores etc. plot1 <- FeatureScatter(pbmc, feature1 = "nCount_RNA", feature2 = "percent.mt") plot2 <- FeatureScatter(pbmc, feature1 = "nCount_RNA", feature2 = "nFeature_RNA") plot1 + plot2 pbmc <- subset(pbmc, subset = nFeature_RNA > 200 & nFeature_RNA < 2500 & percent.mt < 5)

pbmc <- subset(pbmc, subset = nFeature_RNA > 200 & nFeature_RNA < 2500 & percent.mt < 5)

After removing unwanted cells from the dataset, the next step is to normalize the data. By default, we employ a global-scaling normalization method “LogNormalize” that normalizes the feature expression measurements for each cell by the total expression, multiplies this by a scale factor (10,000 by default), and log-transforms the result. Normalized values are stored in pbmc[["RNA"]]@data. pbmc <- NormalizeData(pbmc, normalization.method = "LogNormalize", scale.factor = 10000)For clarity, in this previous line of code (and in future commands), we provide the default values for certain parameters in the function call. However, this isn’t required and the same behavior can be achieved with: pbmc <- NormalizeData(pbmc)

For clarity, in this previous line of code (and in future commands), we provide the default values for certain parameters in the function call. However, this isn’t required and the same behavior can be achieved with: pbmc <- NormalizeData(pbmc)

We next calculate a subset of features that exhibit high cell-to-cell variation in the dataset (i.e, they are highly expressed in some cells, and lowly expressed in others). We and others have found that focusing on these genes in downstream analysis helps to highlight biological signal in single-cell datasets.Our procedure in Seurat is described in detail here, and improves on previous versions by directly modeling the mean-variance relationship inherent in single-cell data, and is implemented in the FindVariableFeatures() function. By default, we return 2,000 features per dataset. These will be used in downstream analysis, like PCA. pbmc <- FindVariableFeatures(pbmc, selection.method = "vst", nfeatures = 2000) # Identify the 10 most highly variable genes top10 <- head(VariableFeatures(pbmc), 10) # plot variable features with and without labels plot1 <- VariableFeaturePlot(pbmc) plot2 <- LabelPoints(plot = plot1, points = top10, repel = TRUE) plot1 + plot2

Our procedure in Seurat is described in detail here, and improves on previous versions by directly modeling the mean-variance relationship inherent in single-cell data, and is implemented in the FindVariableFeatures() function. By default, we return 2,000 features per dataset. These will be used in downstream analysis, like PCA. pbmc <- FindVariableFeatures(pbmc, selection.method = "vst", nfeatures = 2000) # Identify the 10 most highly variable genes top10 <- head(VariableFeatures(pbmc), 10) # plot variable features with and without labels plot1 <- VariableFeaturePlot(pbmc) plot2 <- LabelPoints(plot = plot1, points = top10, repel = TRUE) plot1 + plot2

Next, we apply a linear transformation (‘scaling’) that is a standard pre-processing step prior to dimensional reduction techniques like PCA. The ScaleData() function:Shifts the expression of each gene, so that the mean expression across cells is 0Scales the expression of each gene, so that the variance across cells is 1This step gives equal weight in downstream analyses, so that highly-expressed genes do not dominateThe results of this are stored in pbmc[["RNA"]]@scale.data all.genes <- rownames(pbmc) pbmc <- ScaleData(pbmc, features = all.genes)This step takes too long! Can I make it faster?Scaling is an essential step in the Seurat workflow, but only on genes that will be used as input to PCA. Therefore, the default in ScaleData() is only to perform scaling on the previously identified variable features (2,000 by default). To do this, omit the features argument in the previous function call, i.e. pbmc <- ScaleData(pbmc)Your PCA and clustering results will be unaffected. However, Seurat heatmaps (produced as shown below with DoHeatmap()) require genes in the heatmap to be scaled, to make sure highly-expressed genes don’t dominate the heatmap. To make sure we don’t leave any genes out of the heatmap later, we are scaling all genes in this tutorial. How can I remove unwanted sources of variation, as in Seurat v2?In Seurat v2 we also use the ScaleData() function to remove unwanted sources of variation from a single-cell dataset. For example, we could ‘regress out’ heterogeneity associated with (for example) cell cycle stage, or mitochondrial contamination. These features are still supported in ScaleData() in Seurat v3, i.e.: pbmc <- ScaleData(pbmc, vars.to.regress = "percent.mt")However, particularly for advanced users who would like to use this functionality, we strongly recommend the use of our new normalization workflow, SCTransform(). The method is described in our paper, with a separate vignette using Seurat v3 here. As with ScaleData(), the function SCTransform() also includes a vars.to.regress parameter.

Scaling is an essential step in the Seurat workflow, but only on genes that will be used as input to PCA. Therefore, the default in ScaleData() is only to perform scaling on the previously identified variable features (2,000 by default). To do this, omit the features argument in the previous function call, i.e. pbmc <- ScaleData(pbmc)Your PCA and clustering results will be unaffected. However, Seurat heatmaps (produced as shown below with DoHeatmap()) require genes in the heatmap to be scaled, to make sure highly-expressed genes don’t dominate the heatmap. To make sure we don’t leave any genes out of the heatmap later, we are scaling all genes in this tutorial.

Scaling is an essential step in the Seurat workflow, but only on genes that will be used as input to PCA. Therefore, the default in ScaleData() is only to perform scaling on the previously identified variable features (2,000 by default). To do this, omit the features argument in the previous function call, i.e. pbmc <- ScaleData(pbmc)Your PCA and clustering results will be unaffected. However, Seurat heatmaps (produced as shown below with DoHeatmap()) require genes in the heatmap to be scaled, to make sure highly-expressed genes don’t dominate the heatmap. To make sure we don’t leave any genes out of the heatmap later, we are scaling all genes in this tutorial.

In Seurat v2 we also use the ScaleData() function to remove unwanted sources of variation from a single-cell dataset. For example, we could ‘regress out’ heterogeneity associated with (for example) cell cycle stage, or mitochondrial contamination. These features are still supported in ScaleData() in Seurat v3, i.e.: pbmc <- ScaleData(pbmc, vars.to.regress = "percent.mt")However, particularly for advanced users who would like to use this functionality, we strongly recommend the use of our new normalization workflow, SCTransform(). The method is described in our paper, with a separate vignette using Seurat v3 here. As with ScaleData(), the function SCTransform() also includes a vars.to.regress parameter.

In Seurat v2 we also use the ScaleData() function to remove unwanted sources of variation from a single-cell dataset. For example, we could ‘regress out’ heterogeneity associated with (for example) cell cycle stage, or mitochondrial contamination. These features are still supported in ScaleData() in Seurat v3, i.e.: pbmc <- ScaleData(pbmc, vars.to.regress = "percent.mt")However, particularly for advanced users who would like to use this functionality, we strongly recommend the use of our new normalization workflow, SCTransform(). The method is described in our paper, with a separate vignette using Seurat v3 here. As with ScaleData(), the function SCTransform() also includes a vars.to.regress parameter.

Next we perform PCA on the scaled data. By default, only the previously determined variable features are used as input, but can be defined using features argument if you wish to choose a different subset. pbmc <- RunPCA(pbmc, features = VariableFeatures(object = pbmc))Seurat provides several useful ways of visualizing both cells and features that define the PCA, including VizDimReduction(), DimPlot(), and DimHeatmap() # Examine and visualize PCA results a few different ways print(pbmc[["pca"]], dims = 1:5, nfeatures = 5)## PC_ 1 ## Positive: CST3, TYROBP, LST1, AIF1, FTL ## Negative: MALAT1, LTB, IL32, IL7R, CD2 ## PC_ 2 ## Positive: CD79A, MS4A1, TCL1A, HLA-DQA1, HLA-DQB1 ## Negative: NKG7, PRF1, CST7, GZMB, GZMA ## PC_ 3 ## Positive: HLA-DQA1, CD79A, CD79B, HLA-DQB1, HLA-DPB1 ## Negative: PPBP, PF4, SDPR, SPARC, GNG11 ## PC_ 4 ## Positive: HLA-DQA1, CD79B, CD79A, MS4A1, HLA-DQB1 ## Negative: VIM, IL7R, S100A6, IL32, S100A8 ## PC_ 5 ## Positive: GZMB, NKG7, S100A8, FGFBP2, GNLY ## Negative: LTB, IL7R, CKB, VIM, MS4A7 VizDimLoadings(pbmc, dims = 1:2, reduction = "pca") DimPlot(pbmc, reduction = "pca")In particular DimHeatmap() allows for easy exploration of the primary sources of heterogeneity in a dataset, and can be useful when trying to decide which PCs to include for further downstream analyses. Both cells and features are ordered according to their PCA scores. Setting cells to a number plots the ‘extreme’ cells on both ends of the spectrum, which dramatically speeds plotting for large datasets. Though clearly a supervised analysis, we find this to be a valuable tool for exploring correlated feature sets. DimHeatmap(pbmc, dims = 1, cells = 500, balanced = TRUE) DimHeatmap(pbmc, dims = 1:15, cells = 500, balanced = TRUE)

Seurat provides several useful ways of visualizing both cells and features that define the PCA, including VizDimReduction(), DimPlot(), and DimHeatmap() # Examine and visualize PCA results a few different ways print(pbmc[["pca"]], dims = 1:5, nfeatures = 5)## PC_ 1 ## Positive: CST3, TYROBP, LST1, AIF1, FTL ## Negative: MALAT1, LTB, IL32, IL7R, CD2 ## PC_ 2 ## Positive: CD79A, MS4A1, TCL1A, HLA-DQA1, HLA-DQB1 ## Negative: NKG7, PRF1, CST7, GZMB, GZMA ## PC_ 3 ## Positive: HLA-DQA1, CD79A, CD79B, HLA-DQB1, HLA-DPB1 ## Negative: PPBP, PF4, SDPR, SPARC, GNG11 ## PC_ 4 ## Positive: HLA-DQA1, CD79B, CD79A, MS4A1, HLA-DQB1 ## Negative: VIM, IL7R, S100A6, IL32, S100A8 ## PC_ 5 ## Positive: GZMB, NKG7, S100A8, FGFBP2, GNLY ## Negative: LTB, IL7R, CKB, VIM, MS4A7 VizDimLoadings(pbmc, dims = 1:2, reduction = "pca") DimPlot(pbmc, reduction = "pca")In particular DimHeatmap() allows for easy exploration of the primary sources of heterogeneity in a dataset, and can be useful when trying to decide which PCs to include for further downstream analyses. Both cells and features are ordered according to their PCA scores. Setting cells to a number plots the ‘extreme’ cells on both ends of the spectrum, which dramatically speeds plotting for large datasets. Though clearly a supervised analysis, we find this to be a valuable tool for exploring correlated feature sets. DimHeatmap(pbmc, dims = 1, cells = 500, balanced = TRUE) DimHeatmap(pbmc, dims = 1:15, cells = 500, balanced = TRUE)

DimPlot(pbmc, reduction = "pca")In particular DimHeatmap() allows for easy exploration of the primary sources of heterogeneity in a dataset, and can be useful when trying to decide which PCs to include for further downstream analyses. Both cells and features are ordered according to their PCA scores. Setting cells to a number plots the ‘extreme’ cells on both ends of the spectrum, which dramatically speeds plotting for large datasets. Though clearly a supervised analysis, we find this to be a valuable tool for exploring correlated feature sets. DimHeatmap(pbmc, dims = 1, cells = 500, balanced = TRUE) DimHeatmap(pbmc, dims = 1:15, cells = 500, balanced = TRUE)

In particular DimHeatmap() allows for easy exploration of the primary sources of heterogeneity in a dataset, and can be useful when trying to decide which PCs to include for further downstream analyses. Both cells and features are ordered according to their PCA scores. Setting cells to a number plots the ‘extreme’ cells on both ends of the spectrum, which dramatically speeds plotting for large datasets. Though clearly a supervised analysis, we find this to be a valuable tool for exploring correlated feature sets. DimHeatmap(pbmc, dims = 1, cells = 500, balanced = TRUE) DimHeatmap(pbmc, dims = 1:15, cells = 500, balanced = TRUE)

In particular DimHeatmap() allows for easy exploration of the primary sources of heterogeneity in a dataset, and can be useful when trying to decide which PCs to include for further downstream analyses. Both cells and features are ordered according to their PCA scores. Setting cells to a number plots the ‘extreme’ cells on both ends of the spectrum, which dramatically speeds plotting for large datasets. Though clearly a supervised analysis, we find this to be a valuable tool for exploring correlated feature sets. DimHeatmap(pbmc, dims = 1, cells = 500, balanced = TRUE) DimHeatmap(pbmc, dims = 1:15, cells = 500, balanced = TRUE)

DimHeatmap(pbmc, dims = 1:15, cells = 500, balanced = TRUE)

To overcome the extensive technical noise in any single feature for scRNA-seq data, Seurat clusters cells based on their PCA scores, with each PC essentially representing a ‘metafeature’ that combines information across a correlated feature set. The top principal components therefore represent a robust compression of the dataset. However, how many components should we choose to include? 10? 20? 100?In Macosko et al, we implemented a resampling test inspired by the JackStraw procedure. We randomly permute a subset of the data (1% by default) and rerun PCA, constructing a ‘null distribution’ of feature scores, and repeat this procedure. We identify ‘significant’ PCs as those who have a strong enrichment of low p-value features. # NOTE: This process can take a long time for big datasets, comment out for expediency. More # approximate techniques such as those implemented in ElbowPlot() can be used to reduce # computation time pbmc <- JackStraw(pbmc, num.replicate = 100) pbmc <- ScoreJackStraw(pbmc, dims = 1:20)The JackStrawPlot() function provides a visualization tool for comparing the distribution of p-values for each PC with a uniform distribution (dashed line). ‘Significant’ PCs will show a strong enrichment of features with low p-values (solid curve above the dashed line). In this case it appears that there is a sharp drop-off in significance after the first 10-12 PCs. JackStrawPlot(pbmc, dims = 1:15)An alternative heuristic method generates an ‘Elbow plot’: a ranking of principle components based on the percentage of variance explained by each one (ElbowPlot() function). In this example, we can observe an ‘elbow’ around PC9-10, suggesting that the majority of true signal is captured in the first 10 PCs. ElbowPlot(pbmc)Identifying the true dimensionality of a dataset – can be challenging/uncertain for the user. We therefore suggest these three approaches to consider. The first is more supervised, exploring PCs to determine relevant sources of heterogeneity, and could be used in conjunction with GSEA for example. The second implements a statistical test based on a random null model, but is time-consuming for large datasets, and may not return a clear PC cutoff. The third is a heuristic that is commonly used, and can be calculated instantly. In this example, all three approaches yielded similar results, but we might have been justified in choosing anything between PC 7-12 as a cutoff.We chose 10 here, but encourage users to consider the following:Dendritic cell and NK aficionados may recognize that genes strongly associated with PCs 12 and 13 define rare immune subsets (i.e. MZB1 is a marker for plasmacytoid DCs). However, these groups are so rare, they are difficult to distinguish from background noise for a dataset of this size without prior knowledge.We encourage users to repeat downstream analyses with a different number of PCs (10, 15, or even 50!). As you will observe, the results often do not differ dramatically.We advise users to err on the higher side when choosing this parameter. For example, performing downstream analyses with only 5 PCs does significantly and adversely affect results.

In Macosko et al, we implemented a resampling test inspired by the JackStraw procedure. We randomly permute a subset of the data (1% by default) and rerun PCA, constructing a ‘null distribution’ of feature scores, and repeat this procedure. We identify ‘significant’ PCs as those who have a strong enrichment of low p-value features. # NOTE: This process can take a long time for big datasets, comment out for expediency. More # approximate techniques such as those implemented in ElbowPlot() can be used to reduce # computation time pbmc <- JackStraw(pbmc, num.replicate = 100) pbmc <- ScoreJackStraw(pbmc, dims = 1:20)The JackStrawPlot() function provides a visualization tool for comparing the distribution of p-values for each PC with a uniform distribution (dashed line). ‘Significant’ PCs will show a strong enrichment of features with low p-values (solid curve above the dashed line). In this case it appears that there is a sharp drop-off in significance after the first 10-12 PCs. JackStrawPlot(pbmc, dims = 1:15)An alternative heuristic method generates an ‘Elbow plot’: a ranking of principle components based on the percentage of variance explained by each one (ElbowPlot() function). In this example, we can observe an ‘elbow’ around PC9-10, suggesting that the majority of true signal is captured in the first 10 PCs. ElbowPlot(pbmc)Identifying the true dimensionality of a dataset – can be challenging/uncertain for the user. We therefore suggest these three approaches to consider. The first is more supervised, exploring PCs to determine relevant sources of heterogeneity, and could be used in conjunction with GSEA for example. The second implements a statistical test based on a random null model, but is time-consuming for large datasets, and may not return a clear PC cutoff. The third is a heuristic that is commonly used, and can be calculated instantly. In this example, all three approaches yielded similar results, but we might have been justified in choosing anything between PC 7-12 as a cutoff.We chose 10 here, but encourage users to consider the following:Dendritic cell and NK aficionados may recognize that genes strongly associated with PCs 12 and 13 define rare immune subsets (i.e. MZB1 is a marker for plasmacytoid DCs). However, these groups are so rare, they are difficult to distinguish from background noise for a dataset of this size without prior knowledge.We encourage users to repeat downstream analyses with a different number of PCs (10, 15, or even 50!). As you will observe, the results often do not differ dramatically.We advise users to err on the higher side when choosing this parameter. For example, performing downstream analyses with only 5 PCs does significantly and adversely affect results.

The JackStrawPlot() function provides a visualization tool for comparing the distribution of p-values for each PC with a uniform distribution (dashed line). ‘Significant’ PCs will show a strong enrichment of features with low p-values (solid curve above the dashed line). In this case it appears that there is a sharp drop-off in significance after the first 10-12 PCs. JackStrawPlot(pbmc, dims = 1:15)An alternative heuristic method generates an ‘Elbow plot’: a ranking of principle components based on the percentage of variance explained by each one (ElbowPlot() function). In this example, we can observe an ‘elbow’ around PC9-10, suggesting that the majority of true signal is captured in the first 10 PCs. ElbowPlot(pbmc)Identifying the true dimensionality of a dataset – can be challenging/uncertain for the user. We therefore suggest these three approaches to consider. The first is more supervised, exploring PCs to determine relevant sources of heterogeneity, and could be used in conjunction with GSEA for example. The second implements a statistical test based on a random null model, but is time-consuming for large datasets, and may not return a clear PC cutoff. The third is a heuristic that is commonly used, and can be calculated instantly. In this example, all three approaches yielded similar results, but we might have been justified in choosing anything between PC 7-12 as a cutoff.We chose 10 here, but encourage users to consider the following:Dendritic cell and NK aficionados may recognize that genes strongly associated with PCs 12 and 13 define rare immune subsets (i.e. MZB1 is a marker for plasmacytoid DCs). However, these groups are so rare, they are difficult to distinguish from background noise for a dataset of this size without prior knowledge.We encourage users to repeat downstream analyses with a different number of PCs (10, 15, or even 50!). As you will observe, the results often do not differ dramatically.We advise users to err on the higher side when choosing this parameter. For example, performing downstream analyses with only 5 PCs does significantly and adversely affect results.

An alternative heuristic method generates an ‘Elbow plot’: a ranking of principle components based on the percentage of variance explained by each one (ElbowPlot() function). In this example, we can observe an ‘elbow’ around PC9-10, suggesting that the majority of true signal is captured in the first 10 PCs. ElbowPlot(pbmc)Identifying the true dimensionality of a dataset – can be challenging/uncertain for the user. We therefore suggest these three approaches to consider. The first is more supervised, exploring PCs to determine relevant sources of heterogeneity, and could be used in conjunction with GSEA for example. The second implements a statistical test based on a random null model, but is time-consuming for large datasets, and may not return a clear PC cutoff. The third is a heuristic that is commonly used, and can be calculated instantly. In this example, all three approaches yielded similar results, but we might have been justified in choosing anything between PC 7-12 as a cutoff.We chose 10 here, but encourage users to consider the following:Dendritic cell and NK aficionados may recognize that genes strongly associated with PCs 12 and 13 define rare immune subsets (i.e. MZB1 is a marker for plasmacytoid DCs). However, these groups are so rare, they are difficult to distinguish from background noise for a dataset of this size without prior knowledge.We encourage users to repeat downstream analyses with a different number of PCs (10, 15, or even 50!). As you will observe, the results often do not differ dramatically.We advise users to err on the higher side when choosing this parameter. For example, performing downstream analyses with only 5 PCs does significantly and adversely affect results.

An alternative heuristic method generates an ‘Elbow plot’: a ranking of principle components based on the percentage of variance explained by each one (ElbowPlot() function). In this example, we can observe an ‘elbow’ around PC9-10, suggesting that the majority of true signal is captured in the first 10 PCs. ElbowPlot(pbmc)Identifying the true dimensionality of a dataset – can be challenging/uncertain for the user. We therefore suggest these three approaches to consider. The first is more supervised, exploring PCs to determine relevant sources of heterogeneity, and could be used in conjunction with GSEA for example. The second implements a statistical test based on a random null model, but is time-consuming for large datasets, and may not return a clear PC cutoff. The third is a heuristic that is commonly used, and can be calculated instantly. In this example, all three approaches yielded similar results, but we might have been justified in choosing anything between PC 7-12 as a cutoff.We chose 10 here, but encourage users to consider the following:Dendritic cell and NK aficionados may recognize that genes strongly associated with PCs 12 and 13 define rare immune subsets (i.e. MZB1 is a marker for plasmacytoid DCs). However, these groups are so rare, they are difficult to distinguish from background noise for a dataset of this size without prior knowledge.We encourage users to repeat downstream analyses with a different number of PCs (10, 15, or even 50!). As you will observe, the results often do not differ dramatically.We advise users to err on the higher side when choosing this parameter. For example, performing downstream analyses with only 5 PCs does significantly and adversely affect results.

Identifying the true dimensionality of a dataset – can be challenging/uncertain for the user. We therefore suggest these three approaches to consider. The first is more supervised, exploring PCs to determine relevant sources of heterogeneity, and could be used in conjunction with GSEA for example. The second implements a statistical test based on a random null model, but is time-consuming for large datasets, and may not return a clear PC cutoff. The third is a heuristic that is commonly used, and can be calculated instantly. In this example, all three approaches yielded similar results, but we might have been justified in choosing anything between PC 7-12 as a cutoff.We chose 10 here, but encourage users to consider the following:Dendritic cell and NK aficionados may recognize that genes strongly associated with PCs 12 and 13 define rare immune subsets (i.e. MZB1 is a marker for plasmacytoid DCs). However, these groups are so rare, they are difficult to distinguish from background noise for a dataset of this size without prior knowledge.We encourage users to repeat downstream analyses with a different number of PCs (10, 15, or even 50!). As you will observe, the results often do not differ dramatically.We advise users to err on the higher side when choosing this parameter. For example, performing downstream analyses with only 5 PCs does significantly and adversely affect results.

Identifying the true dimensionality of a dataset – can be challenging/uncertain for the user. We therefore suggest these three approaches to consider. The first is more supervised, exploring PCs to determine relevant sources of heterogeneity, and could be used in conjunction with GSEA for example. The second implements a statistical test based on a random null model, but is time-consuming for large datasets, and may not return a clear PC cutoff. The third is a heuristic that is commonly used, and can be calculated instantly. In this example, all three approaches yielded similar results, but we might have been justified in choosing anything between PC 7-12 as a cutoff.We chose 10 here, but encourage users to consider the following:Dendritic cell and NK aficionados may recognize that genes strongly associated with PCs 12 and 13 define rare immune subsets (i.e. MZB1 is a marker for plasmacytoid DCs). However, these groups are so rare, they are difficult to distinguish from background noise for a dataset of this size without prior knowledge.We encourage users to repeat downstream analyses with a different number of PCs (10, 15, or even 50!). As you will observe, the results often do not differ dramatically.We advise users to err on the higher side when choosing this parameter. For example, performing downstream analyses with only 5 PCs does significantly and adversely affect results.

We chose 10 here, but encourage users to consider the following:Dendritic cell and NK aficionados may recognize that genes strongly associated with PCs 12 and 13 define rare immune subsets (i.e. MZB1 is a marker for plasmacytoid DCs). However, these groups are so rare, they are difficult to distinguish from background noise for a dataset of this size without prior knowledge.We encourage users to repeat downstream analyses with a different number of PCs (10, 15, or even 50!). As you will observe, the results often do not differ dramatically.We advise users to err on the higher side when choosing this parameter. For example, performing downstream analyses with only 5 PCs does significantly and adversely affect results.

Seurat v3 applies a graph-based clustering approach, building upon initial strategies in (Macosko et al). Importantly, the distance metric which drives the clustering analysis (based on previously identified PCs) remains the same. However, our approach to partitioning the cellular distance matrix into clusters has dramatically improved. Our approach was heavily inspired by recent manuscripts which applied graph-based clustering approaches to scRNA-seq data [SNN-Cliq, Xu and Su, Bioinformatics, 2015] and CyTOF data [PhenoGraph, Levine et al., Cell, 2015]. Briefly, these methods embed cells in a graph structure - for example a K-nearest neighbor (KNN) graph, with edges drawn between cells with similar feature expression patterns, and then attempt to partition this graph into highly interconnected ‘quasi-cliques’ or ‘communities’.As in PhenoGraph, we first construct a KNN graph based on the euclidean distance in PCA space, and refine the edge weights between any two cells based on the shared overlap in their local neighborhoods (Jaccard similarity). This step is performed using the FindNeighbors() function, and takes as input the previously defined dimensionality of the dataset (first 10 PCs).To cluster the cells, we next apply modularity optimization techniques such as the Louvain algorithm (default) or SLM [SLM, Blondel et al., Journal of Statistical Mechanics], to iteratively group cells together, with the goal of optimizing the standard modularity function. The FindClusters() function implements this procedure, and contains a resolution parameter that sets the ‘granularity’ of the downstream clustering, with increased values leading to a greater number of clusters. We find that setting this parameter between 0.4-1.2 typically returns good results for single-cell datasets of around 3K cells. Optimal resolution often increases for larger datasets. The clusters can be found using the Idents() function. pbmc <- FindNeighbors(pbmc, dims = 1:10) pbmc <- FindClusters(pbmc, resolution = 0.5)## Modularity Optimizer version 1.3.0 by Ludo Waltman and Nees Jan van Eck ## ## Number of nodes: 2638 ## Number of edges: 95927 ## ## Running Louvain algorithm... ## Maximum modularity in 10 random starts: 0.8728 ## Number of communities: 9 ## Elapsed time: 0 seconds # Look at cluster IDs of the first 5 cells head(Idents(pbmc), 5)## AAACATACAACCAC-1 AAACATTGAGCTAC-1 AAACATTGATCAGC-1 AAACCGTGCTTCCG-1 ## 2 3 2 1 ## AAACCGTGTATGCG-1 ## 6 ## Levels: 0 1 2 3 4 5 6 7 8

As in PhenoGraph, we first construct a KNN graph based on the euclidean distance in PCA space, and refine the edge weights between any two cells based on the shared overlap in their local neighborhoods (Jaccard similarity). This step is performed using the FindNeighbors() function, and takes as input the previously defined dimensionality of the dataset (first 10 PCs).To cluster the cells, we next apply modularity optimization techniques such as the Louvain algorithm (default) or SLM [SLM, Blondel et al., Journal of Statistical Mechanics], to iteratively group cells together, with the goal of optimizing the standard modularity function. The FindClusters() function implements this procedure, and contains a resolution parameter that sets the ‘granularity’ of the downstream clustering, with increased values leading to a greater number of clusters. We find that setting this parameter between 0.4-1.2 typically returns good results for single-cell datasets of around 3K cells. Optimal resolution often increases for larger datasets. The clusters can be found using the Idents() function. pbmc <- FindNeighbors(pbmc, dims = 1:10) pbmc <- FindClusters(pbmc, resolution = 0.5)## Modularity Optimizer version 1.3.0 by Ludo Waltman and Nees Jan van Eck ## ## Number of nodes: 2638 ## Number of edges: 95927 ## ## Running Louvain algorithm... ## Maximum modularity in 10 random starts: 0.8728 ## Number of communities: 9 ## Elapsed time: 0 seconds # Look at cluster IDs of the first 5 cells head(Idents(pbmc), 5)## AAACATACAACCAC-1 AAACATTGAGCTAC-1 AAACATTGATCAGC-1 AAACCGTGCTTCCG-1 ## 2 3 2 1 ## AAACCGTGTATGCG-1 ## 6 ## Levels: 0 1 2 3 4 5 6 7 8

To cluster the cells, we next apply modularity optimization techniques such as the Louvain algorithm (default) or SLM [SLM, Blondel et al., Journal of Statistical Mechanics], to iteratively group cells together, with the goal of optimizing the standard modularity function. The FindClusters() function implements this procedure, and contains a resolution parameter that sets the ‘granularity’ of the downstream clustering, with increased values leading to a greater number of clusters. We find that setting this parameter between 0.4-1.2 typically returns good results for single-cell datasets of around 3K cells. Optimal resolution often increases for larger datasets. The clusters can be found using the Idents() function. pbmc <- FindNeighbors(pbmc, dims = 1:10) pbmc <- FindClusters(pbmc, resolution = 0.5)## Modularity Optimizer version 1.3.0 by Ludo Waltman and Nees Jan van Eck ## ## Number of nodes: 2638 ## Number of edges: 95927 ## ## Running Louvain algorithm... ## Maximum modularity in 10 random starts: 0.8728 ## Number of communities: 9 ## Elapsed time: 0 seconds # Look at cluster IDs of the first 5 cells head(Idents(pbmc), 5)## AAACATACAACCAC-1 AAACATTGAGCTAC-1 AAACATTGATCAGC-1 AAACCGTGCTTCCG-1 ## 2 3 2 1 ## AAACCGTGTATGCG-1 ## 6 ## Levels: 0 1 2 3 4 5 6 7 8

Seurat offers several non-linear dimensional reduction techniques, such as tSNE and UMAP, to visualize and explore these datasets. The goal of these algorithms is to learn the underlying manifold of the data in order to place similar cells together in low-dimensional space. Cells within the graph-based clusters determined above should co-localize on these dimension reduction plots. As input to the UMAP and tSNE, we suggest using the same PCs as input to the clustering analysis. # If you haven't installed UMAP, you can do so via reticulate::py_install(packages = # 'umap-learn') pbmc <- RunUMAP(pbmc, dims = 1:10) # note that you can set `label = TRUE` or use the LabelClusters function to help label # individual clusters DimPlot(pbmc, reduction = "umap")You can save the object at this point so that it can easily be loaded back in without having to rerun the computationally intensive steps performed above, or easily shared with collaborators. saveRDS(pbmc, file = "../output/pbmc_tutorial.rds")

You can save the object at this point so that it can easily be loaded back in without having to rerun the computationally intensive steps performed above, or easily shared with collaborators. saveRDS(pbmc, file = "../output/pbmc_tutorial.rds")

You can save the object at this point so that it can easily be loaded back in without having to rerun the computationally intensive steps performed above, or easily shared with collaborators. saveRDS(pbmc, file = "../output/pbmc_tutorial.rds")

Seurat can help you find markers that define clusters via differential expression. By default, it identifies positive and negative markers of a single cluster (specified in ident.1), compared to all other cells. FindAllMarkers() automates this process for all clusters, but you can also test groups of clusters vs. each other, or against all cells.The min.pct argument requires a feature to be detected at a minimum percentage in either of the two groups of cells, and the thresh.test argument requires a feature to be differentially expressed (on average) by some amount between the two groups. You can set both of these to 0, but with a dramatic increase in time - since this will test a large number of features that are unlikely to be highly discriminatory. As another option to speed up these computations, max.cells.per.ident can be set. This will downsample each identity class to have no more cells than whatever this is set to. While there is generally going to be a loss in power, the speed increases can be significant and the most highly differentially expressed features will likely still rise to the top. # find all markers of cluster 2 cluster2.markers <- FindMarkers(pbmc, ident.1 = 2, min.pct = 0.25) head(cluster2.markers, n = 5)## p_val avg_log2FC pct.1 pct.2 p_val_adj ## IL32 2.892340e-90 1.2013522 0.947 0.465 3.966555e-86 ## LTB 1.060121e-86 1.2695776 0.981 0.643 1.453850e-82 ## CD3D 8.794641e-71 0.9389621 0.922 0.432 1.206097e-66 ## IL7R 3.516098e-68 1.1873213 0.750 0.326 4.821977e-64 ## LDHB 1.642480e-67 0.8969774 0.954 0.614 2.252497e-63 # find all markers distinguishing cluster 5 from clusters 0 and 3 cluster5.markers <- FindMarkers(pbmc, ident.1 = 5, ident.2 = c(0, 3), min.pct = 0.25) head(cluster5.markers, n = 5)## p_val avg_log2FC pct.1 pct.2 p_val_adj ## FCGR3A 8.246578e-205 4.261495 0.975 0.040 1.130936e-200 ## IFITM3 1.677613e-195 3.879339 0.975 0.049 2.300678e-191 ## CFD 2.401156e-193 3.405492 0.938 0.038 3.292945e-189 ## CD68 2.900384e-191 3.020484 0.926 0.035 3.977587e-187 ## RP11-290F20.3 2.513244e-186 2.720057 0.840 0.017 3.446663e-182 # find markers for every cluster compared to all remaining cells, report only the positive # ones pbmc.markers <- FindAllMarkers(pbmc, only.pos = TRUE, min.pct = 0.25, logfc.threshold = 0.25) pbmc.markers %>% group_by(cluster) %>% slice_max(n = 2, order_by = avg_log2FC)## # A tibble: 18 × 7 ## # Groups: cluster [9] ## p_val avg_log2FC pct.1 pct.2 p_val_adj cluster gene ## <dbl> <dbl> <dbl> <dbl> <dbl> <fct> <chr> ## 1 9.57e- 88 1.36 0.447 0.108 1.31e- 83 0 CCR7 ## 2 3.75e-112 1.09 0.912 0.592 5.14e-108 0 LDHB ## 3 0 5.57 0.996 0.215 0 1 S100A9 ## 4 0 5.48 0.975 0.121 0 1 S100A8 ## 5 1.06e- 86 1.27 0.981 0.643 1.45e- 82 2 LTB ## 6 2.97e- 58 1.23 0.42 0.111 4.07e- 54 2 AQP3 ## 7 0 4.31 0.936 0.041 0 3 CD79A ## 8 9.48e-271 3.59 0.622 0.022 1.30e-266 3 TCL1A ## 9 5.61e-202 3.10 0.983 0.234 7.70e-198 4 CCL5 ## 10 7.25e-165 3.00 0.577 0.055 9.95e-161 4 GZMK ## 11 3.51e-184 3.31 0.975 0.134 4.82e-180 5 FCGR3A ## 12 2.03e-125 3.09 1 0.315 2.78e-121 5 LST1 ## 13 3.13e-191 5.32 0.961 0.131 4.30e-187 6 GNLY ## 14 7.95e-269 4.83 0.961 0.068 1.09e-264 6 GZMB ## 15 1.48e-220 3.87 0.812 0.011 2.03e-216 7 FCER1A ## 16 1.67e- 21 2.87 1 0.513 2.28e- 17 7 HLA-DPB1 ## 17 1.92e-102 8.59 1 0.024 2.63e- 98 8 PPBP ## 18 9.25e-186 7.29 1 0.011 1.27e-181 8 PF4Seurat has several tests for differential expression which can be set with the test.use parameter (see our DE vignette for details). For example, the ROC test returns the ‘classification power’ for any individual marker (ranging from 0 - random, to 1 - perfect). cluster0.markers <- FindMarkers(pbmc, ident.1 = 0, logfc.threshold = 0.25, test.use = "roc", only.pos = TRUE)We include several tools for visualizing marker expression. VlnPlot() (shows expression probability distributions across clusters), and FeaturePlot() (visualizes feature expression on a tSNE or PCA plot) are our most commonly used visualizations. We also suggest exploring RidgePlot(), CellScatter(), and DotPlot() as additional methods to view your dataset. VlnPlot(pbmc, features = c("MS4A1", "CD79A")) # you can plot raw counts as well VlnPlot(pbmc, features = c("NKG7", "PF4"), slot = "counts", log = TRUE) FeaturePlot(pbmc, features = c("MS4A1", "GNLY", "CD3E", "CD14", "FCER1A", "FCGR3A", "LYZ", "PPBP", "CD8A"))DoHeatmap() generates an expression heatmap for given cells and features. In this case, we are plotting the top 20 markers (or all markers if less than 20) for each cluster. pbmc.markers %>% group_by(cluster) %>% top_n(n = 10, wt = avg_log2FC) -> top10 DoHeatmap(pbmc, features = top10$gene) + NoLegend()

The min.pct argument requires a feature to be detected at a minimum percentage in either of the two groups of cells, and the thresh.test argument requires a feature to be differentially expressed (on average) by some amount between the two groups. You can set both of these to 0, but with a dramatic increase in time - since this will test a large number of features that are unlikely to be highly discriminatory. As another option to speed up these computations, max.cells.per.ident can be set. This will downsample each identity class to have no more cells than whatever this is set to. While there is generally going to be a loss in power, the speed increases can be significant and the most highly differentially expressed features will likely still rise to the top. # find all markers of cluster 2 cluster2.markers <- FindMarkers(pbmc, ident.1 = 2, min.pct = 0.25) head(cluster2.markers, n = 5)## p_val avg_log2FC pct.1 pct.2 p_val_adj ## IL32 2.892340e-90 1.2013522 0.947 0.465 3.966555e-86 ## LTB 1.060121e-86 1.2695776 0.981 0.643 1.453850e-82 ## CD3D 8.794641e-71 0.9389621 0.922 0.432 1.206097e-66 ## IL7R 3.516098e-68 1.1873213 0.750 0.326 4.821977e-64 ## LDHB 1.642480e-67 0.8969774 0.954 0.614 2.252497e-63 # find all markers distinguishing cluster 5 from clusters 0 and 3 cluster5.markers <- FindMarkers(pbmc, ident.1 = 5, ident.2 = c(0, 3), min.pct = 0.25) head(cluster5.markers, n = 5)## p_val avg_log2FC pct.1 pct.2 p_val_adj ## FCGR3A 8.246578e-205 4.261495 0.975 0.040 1.130936e-200 ## IFITM3 1.677613e-195 3.879339 0.975 0.049 2.300678e-191 ## CFD 2.401156e-193 3.405492 0.938 0.038 3.292945e-189 ## CD68 2.900384e-191 3.020484 0.926 0.035 3.977587e-187 ## RP11-290F20.3 2.513244e-186 2.720057 0.840 0.017 3.446663e-182 # find markers for every cluster compared to all remaining cells, report only the positive # ones pbmc.markers <- FindAllMarkers(pbmc, only.pos = TRUE, min.pct = 0.25, logfc.threshold = 0.25) pbmc.markers %>% group_by(cluster) %>% slice_max(n = 2, order_by = avg_log2FC)## # A tibble: 18 × 7 ## # Groups: cluster [9] ## p_val avg_log2FC pct.1 pct.2 p_val_adj cluster gene ## <dbl> <dbl> <dbl> <dbl> <dbl> <fct> <chr> ## 1 9.57e- 88 1.36 0.447 0.108 1.31e- 83 0 CCR7 ## 2 3.75e-112 1.09 0.912 0.592 5.14e-108 0 LDHB ## 3 0 5.57 0.996 0.215 0 1 S100A9 ## 4 0 5.48 0.975 0.121 0 1 S100A8 ## 5 1.06e- 86 1.27 0.981 0.643 1.45e- 82 2 LTB ## 6 2.97e- 58 1.23 0.42 0.111 4.07e- 54 2 AQP3 ## 7 0 4.31 0.936 0.041 0 3 CD79A ## 8 9.48e-271 3.59 0.622 0.022 1.30e-266 3 TCL1A ## 9 5.61e-202 3.10 0.983 0.234 7.70e-198 4 CCL5 ## 10 7.25e-165 3.00 0.577 0.055 9.95e-161 4 GZMK ## 11 3.51e-184 3.31 0.975 0.134 4.82e-180 5 FCGR3A ## 12 2.03e-125 3.09 1 0.315 2.78e-121 5 LST1 ## 13 3.13e-191 5.32 0.961 0.131 4.30e-187 6 GNLY ## 14 7.95e-269 4.83 0.961 0.068 1.09e-264 6 GZMB ## 15 1.48e-220 3.87 0.812 0.011 2.03e-216 7 FCER1A ## 16 1.67e- 21 2.87 1 0.513 2.28e- 17 7 HLA-DPB1 ## 17 1.92e-102 8.59 1 0.024 2.63e- 98 8 PPBP ## 18 9.25e-186 7.29 1 0.011 1.27e-181 8 PF4Seurat has several tests for differential expression which can be set with the test.use parameter (see our DE vignette for details). For example, the ROC test returns the ‘classification power’ for any individual marker (ranging from 0 - random, to 1 - perfect). cluster0.markers <- FindMarkers(pbmc, ident.1 = 0, logfc.threshold = 0.25, test.use = "roc", only.pos = TRUE)We include several tools for visualizing marker expression. VlnPlot() (shows expression probability distributions across clusters), and FeaturePlot() (visualizes feature expression on a tSNE or PCA plot) are our most commonly used visualizations. We also suggest exploring RidgePlot(), CellScatter(), and DotPlot() as additional methods to view your dataset. VlnPlot(pbmc, features = c("MS4A1", "CD79A")) # you can plot raw counts as well VlnPlot(pbmc, features = c("NKG7", "PF4"), slot = "counts", log = TRUE) FeaturePlot(pbmc, features = c("MS4A1", "GNLY", "CD3E", "CD14", "FCER1A", "FCGR3A", "LYZ", "PPBP", "CD8A"))DoHeatmap() generates an expression heatmap for given cells and features. In this case, we are plotting the top 20 markers (or all markers if less than 20) for each cluster. pbmc.markers %>% group_by(cluster) %>% top_n(n = 10, wt = avg_log2FC) -> top10 DoHeatmap(pbmc, features = top10$gene) + NoLegend()

Seurat has several tests for differential expression which can be set with the test.use parameter (see our DE vignette for details). For example, the ROC test returns the ‘classification power’ for any individual marker (ranging from 0 - random, to 1 - perfect). cluster0.markers <- FindMarkers(pbmc, ident.1 = 0, logfc.threshold = 0.25, test.use = "roc", only.pos = TRUE)We include several tools for visualizing marker expression. VlnPlot() (shows expression probability distributions across clusters), and FeaturePlot() (visualizes feature expression on a tSNE or PCA plot) are our most commonly used visualizations. We also suggest exploring RidgePlot(), CellScatter(), and DotPlot() as additional methods to view your dataset. VlnPlot(pbmc, features = c("MS4A1", "CD79A")) # you can plot raw counts as well VlnPlot(pbmc, features = c("NKG7", "PF4"), slot = "counts", log = TRUE) FeaturePlot(pbmc, features = c("MS4A1", "GNLY", "CD3E", "CD14", "FCER1A", "FCGR3A", "LYZ", "PPBP", "CD8A"))DoHeatmap() generates an expression heatmap for given cells and features. In this case, we are plotting the top 20 markers (or all markers if less than 20) for each cluster. pbmc.markers %>% group_by(cluster) %>% top_n(n = 10, wt = avg_log2FC) -> top10 DoHeatmap(pbmc, features = top10$gene) + NoLegend()

We include several tools for visualizing marker expression. VlnPlot() (shows expression probability distributions across clusters), and FeaturePlot() (visualizes feature expression on a tSNE or PCA plot) are our most commonly used visualizations. We also suggest exploring RidgePlot(), CellScatter(), and DotPlot() as additional methods to view your dataset. VlnPlot(pbmc, features = c("MS4A1", "CD79A")) # you can plot raw counts as well VlnPlot(pbmc, features = c("NKG7", "PF4"), slot = "counts", log = TRUE) FeaturePlot(pbmc, features = c("MS4A1", "GNLY", "CD3E", "CD14", "FCER1A", "FCGR3A", "LYZ", "PPBP", "CD8A"))DoHeatmap() generates an expression heatmap for given cells and features. In this case, we are plotting the top 20 markers (or all markers if less than 20) for each cluster. pbmc.markers %>% group_by(cluster) %>% top_n(n = 10, wt = avg_log2FC) -> top10 DoHeatmap(pbmc, features = top10$gene) + NoLegend()

# you can plot raw counts as well VlnPlot(pbmc, features = c("NKG7", "PF4"), slot = "counts", log = TRUE) FeaturePlot(pbmc, features = c("MS4A1", "GNLY", "CD3E", "CD14", "FCER1A", "FCGR3A", "LYZ", "PPBP", "CD8A"))DoHeatmap() generates an expression heatmap for given cells and features. In this case, we are plotting the top 20 markers (or all markers if less than 20) for each cluster. pbmc.markers %>% group_by(cluster) %>% top_n(n = 10, wt = avg_log2FC) -> top10 DoHeatmap(pbmc, features = top10$gene) + NoLegend()

FeaturePlot(pbmc, features = c("MS4A1", "GNLY", "CD3E", "CD14", "FCER1A", "FCGR3A", "LYZ", "PPBP", "CD8A"))DoHeatmap() generates an expression heatmap for given cells and features. In this case, we are plotting the top 20 markers (or all markers if less than 20) for each cluster. pbmc.markers %>% group_by(cluster) %>% top_n(n = 10, wt = avg_log2FC) -> top10 DoHeatmap(pbmc, features = top10$gene) + NoLegend()

DoHeatmap() generates an expression heatmap for given cells and features. In this case, we are plotting the top 20 markers (or all markers if less than 20) for each cluster. pbmc.markers %>% group_by(cluster) %>% top_n(n = 10, wt = avg_log2FC) -> top10 DoHeatmap(pbmc, features = top10$gene) + NoLegend()

DoHeatmap() generates an expression heatmap for given cells and features. In this case, we are plotting the top 20 markers (or all markers if less than 20) for each cluster. pbmc.markers %>% group_by(cluster) %>% top_n(n = 10, wt = avg_log2FC) -> top10 DoHeatmap(pbmc, features = top10$gene) + NoLegend()

Fortunately in the case of this dataset, we can use canonical markers to easily match the unbiased clustering to known cell types:Cluster IDMarkersCell Type0IL7R, CCR7Naive CD4+ T1CD14, LYZCD14+ Mono2IL7R, S100A4Memory CD4+3MS4A1B4CD8ACD8+ T5FCGR3A, MS4A7FCGR3A+ Mono6GNLY, NKG7NK7FCER1A, CST3DC8PPBPPlatelet new.cluster.ids <- c("Naive CD4 T", "CD14+ Mono", "Memory CD4 T", "B", "CD8 T", "FCGR3A+ Mono", "NK", "DC", "Platelet") names(new.cluster.ids) <- levels(pbmc) pbmc <- RenameIdents(pbmc, new.cluster.ids) DimPlot(pbmc, reduction = "umap", label = TRUE, pt.size = 0.5) + NoLegend() saveRDS(pbmc, file = "../output/pbmc3k_final.rds")Session Info sessionInfo()## R version 4.2.0 (2022-04-22) ## Platform: x86_64-pc-linux-gnu (64-bit) ## Running under: Ubuntu 20.04.5 LTS ## ## Matrix products: default ## BLAS: /usr/lib/x86_64-linux-gnu/openblas-pthread/libblas.so.3 ## LAPACK: /usr/lib/x86_64-linux-gnu/openblas-pthread/liblapack.so.3 ## ## locale: ## [1] LC_CTYPE=en_US.UTF-8 LC_NUMERIC=C ## [3] LC_TIME=en_US.UTF-8 LC_COLLATE=en_US.UTF-8 ## [5] LC_MONETARY=en_US.UTF-8 LC_MESSAGES=en_US.UTF-8 ## [7] LC_PAPER=en_US.UTF-8 LC_NAME=C ## [9] LC_ADDRESS=C LC_TELEPHONE=C ## [11] LC_MEASUREMENT=en_US.UTF-8 LC_IDENTIFICATION=C ## ## attached base packages: ## [1] stats graphics grDevices utils datasets methods base ## ## other attached packages: ## [1] ggplot2_3.4.1 patchwork_1.1.2 SeuratObject_4.1.3 Seurat_4.3.0 ## [5] dplyr_1.1.0 ## ## loaded via a namespace (and not attached): ## [1] Rtsne_0.16 colorspace_2.1-0 deldir_1.0-6 ## [4] ellipsis_0.3.2 ggridges_0.5.4 rprojroot_2.0.3 ## [7] fs_1.6.1 spatstat.data_3.0-0 farver_2.1.1 ## [10] leiden_0.4.3 listenv_0.9.0 ggrepel_0.9.3 ## [13] fansi_1.0.4 R.methodsS3_1.8.2 codetools_0.2-18 ## [16] splines_4.2.0 cachem_1.0.7 knitr_1.42 ## [19] polyclip_1.10-4 jsonlite_1.8.4 ica_1.0-3 ## [22] cluster_2.1.3 R.oo_1.25.0 png_0.1-8 ## [25] uwot_0.1.14 spatstat.sparse_3.0-0 shiny_1.7.4 ## [28] sctransform_0.3.5 compiler_4.2.0 httr_1.4.5 ## [31] Matrix_1.5-3 fastmap_1.1.1 lazyeval_0.2.2 ## [34] limma_3.54.1 cli_3.6.0 later_1.3.0 ## [37] formatR_1.14 htmltools_0.5.4 tools_4.2.0 ## [40] igraph_1.4.1 gtable_0.3.1 glue_1.6.2 ## [43] RANN_2.6.1 reshape2_1.4.4 Rcpp_1.0.10 ## [46] scattermore_0.8 jquerylib_0.1.4 pkgdown_2.0.7 ## [49] vctrs_0.5.2 nlme_3.1-157 spatstat.explore_3.0-6 ## [52] progressr_0.13.0 lmtest_0.9-40 spatstat.random_3.1-3 ## [55] xfun_0.37 stringr_1.5.0 globals_0.16.2 ## [58] mime_0.12 miniUI_0.1.1.1 lifecycle_1.0.3 ## [61] irlba_2.3.5.1 goftest_1.2-3 future_1.31.0 ## [64] MASS_7.3-56 zoo_1.8-11 scales_1.2.1 ## [67] ragg_1.2.5 promises_1.2.0.1 spatstat.utils_3.0-1 ## [70] parallel_4.2.0 RColorBrewer_1.1-3 yaml_2.3.7 ## [73] memoise_2.0.1 reticulate_1.28 pbapply_1.7-0 ## [76] gridExtra_2.3 sass_0.4.5 stringi_1.7.12 ## [79] highr_0.10 desc_1.4.2 rlang_1.0.6 ## [82] pkgconfig_2.0.3 systemfonts_1.0.4 matrixStats_0.63.0 ## [85] evaluate_0.20 lattice_0.20-45 tensor_1.5 ## [88] ROCR_1.0-11 purrr_1.0.1 labeling_0.4.2 ## [91] htmlwidgets_1.6.1 cowplot_1.1.1 tidyselect_1.2.0 ## [94] parallelly_1.34.0 RcppAnnoy_0.0.20 plyr_1.8.8 ## [97] magrittr_2.0.3 R6_2.5.1 generics_0.1.3 ## [100] withr_2.5.0 pillar_1.8.1 fitdistrplus_1.1-8 ## [103] abind_1.4-5 survival_3.3-1 sp_1.6-0 ## [106] tibble_3.1.8 future.apply_1.10.0 crayon_1.5.2 ## [109] KernSmooth_2.23-20 utf8_1.2.3 spatstat.geom_3.0-6 ## [112] plotly_4.10.1 rmarkdown_2.20 grid_4.2.0 ## [115] data.table_1.14.8 digest_0.6.31 xtable_1.8-4 ## [118] tidyr_1.3.0 httpuv_1.6.9 R.utils_2.12.2 ## [121] textshaping_0.3.6 munsell_0.5.0 viridisLite_0.4.1 ## [124] bslib_0.4.2

saveRDS(pbmc, file = "../output/pbmc3k_final.rds")Session Info sessionInfo()## R version 4.2.0 (2022-04-22) ## Platform: x86_64-pc-linux-gnu (64-bit) ## Running under: Ubuntu 20.04.5 LTS ## ## Matrix products: default ## BLAS: /usr/lib/x86_64-linux-gnu/openblas-pthread/libblas.so.3 ## LAPACK: /usr/lib/x86_64-linux-gnu/openblas-pthread/liblapack.so.3 ## ## locale: ## [1] LC_CTYPE=en_US.UTF-8 LC_NUMERIC=C ## [3] LC_TIME=en_US.UTF-8 LC_COLLATE=en_US.UTF-8 ## [5] LC_MONETARY=en_US.UTF-8 LC_MESSAGES=en_US.UTF-8 ## [7] LC_PAPER=en_US.UTF-8 LC_NAME=C ## [9] LC_ADDRESS=C LC_TELEPHONE=C ## [11] LC_MEASUREMENT=en_US.UTF-8 LC_IDENTIFICATION=C ## ## attached base packages: ## [1] stats graphics grDevices utils datasets methods base ## ## other attached packages: ## [1] ggplot2_3.4.1 patchwork_1.1.2 SeuratObject_4.1.3 Seurat_4.3.0 ## [5] dplyr_1.1.0 ## ## loaded via a namespace (and not attached): ## [1] Rtsne_0.16 colorspace_2.1-0 deldir_1.0-6 ## [4] ellipsis_0.3.2 ggridges_0.5.4 rprojroot_2.0.3 ## [7] fs_1.6.1 spatstat.data_3.0-0 farver_2.1.1 ## [10] leiden_0.4.3 listenv_0.9.0 ggrepel_0.9.3 ## [13] fansi_1.0.4 R.methodsS3_1.8.2 codetools_0.2-18 ## [16] splines_4.2.0 cachem_1.0.7 knitr_1.42 ## [19] polyclip_1.10-4 jsonlite_1.8.4 ica_1.0-3 ## [22] cluster_2.1.3 R.oo_1.25.0 png_0.1-8 ## [25] uwot_0.1.14 spatstat.sparse_3.0-0 shiny_1.7.4 ## [28] sctransform_0.3.5 compiler_4.2.0 httr_1.4.5 ## [31] Matrix_1.5-3 fastmap_1.1.1 lazyeval_0.2.2 ## [34] limma_3.54.1 cli_3.6.0 later_1.3.0 ## [37] formatR_1.14 htmltools_0.5.4 tools_4.2.0 ## [40] igraph_1.4.1 gtable_0.3.1 glue_1.6.2 ## [43] RANN_2.6.1 reshape2_1.4.4 Rcpp_1.0.10 ## [46] scattermore_0.8 jquerylib_0.1.4 pkgdown_2.0.7 ## [49] vctrs_0.5.2 nlme_3.1-157 spatstat.explore_3.0-6 ## [52] progressr_0.13.0 lmtest_0.9-40 spatstat.random_3.1-3 ## [55] xfun_0.37 stringr_1.5.0 globals_0.16.2 ## [58] mime_0.12 miniUI_0.1.1.1 lifecycle_1.0.3 ## [61] irlba_2.3.5.1 goftest_1.2-3 future_1.31.0 ## [64] MASS_7.3-56 zoo_1.8-11 scales_1.2.1 ## [67] ragg_1.2.5 promises_1.2.0.1 spatstat.utils_3.0-1 ## [70] parallel_4.2.0 RColorBrewer_1.1-3 yaml_2.3.7 ## [73] memoise_2.0.1 reticulate_1.28 pbapply_1.7-0 ## [76] gridExtra_2.3 sass_0.4.5 stringi_1.7.12 ## [79] highr_0.10 desc_1.4.2 rlang_1.0.6 ## [82] pkgconfig_2.0.3 systemfonts_1.0.4 matrixStats_0.63.0 ## [85] evaluate_0.20 lattice_0.20-45 tensor_1.5 ## [88] ROCR_1.0-11 purrr_1.0.1 labeling_0.4.2 ## [91] htmlwidgets_1.6.1 cowplot_1.1.1 tidyselect_1.2.0 ## [94] parallelly_1.34.0 RcppAnnoy_0.0.20 plyr_1.8.8 ## [97] magrittr_2.0.3 R6_2.5.1 generics_0.1.3 ## [100] withr_2.5.0 pillar_1.8.1 fitdistrplus_1.1-8 ## [103] abind_1.4-5 survival_3.3-1 sp_1.6-0 ## [106] tibble_3.1.8 future.apply_1.10.0 crayon_1.5.2 ## [109] KernSmooth_2.23-20 utf8_1.2.3 spatstat.geom_3.0-6 ## [112] plotly_4.10.1 rmarkdown_2.20 grid_4.2.0 ## [115] data.table_1.14.8 digest_0.6.31 xtable_1.8-4 ## [118] tidyr_1.3.0 httpuv_1.6.9 R.utils_2.12.2 ## [121] textshaping_0.3.6 munsell_0.5.0 viridisLite_0.4.1 ## [124] bslib_0.4.2

sessionInfo()## R version 4.2.0 (2022-04-22) ## Platform: x86_64-pc-linux-gnu (64-bit) ## Running under: Ubuntu 20.04.5 LTS ## ## Matrix products: default ## BLAS: /usr/lib/x86_64-linux-gnu/openblas-pthread/libblas.so.3 ## LAPACK: /usr/lib/x86_64-linux-gnu/openblas-pthread/liblapack.so.3 ## ## locale: ## [1] LC_CTYPE=en_US.UTF-8 LC_NUMERIC=C ## [3] LC_TIME=en_US.UTF-8 LC_COLLATE=en_US.UTF-8 ## [5] LC_MONETARY=en_US.UTF-8 LC_MESSAGES=en_US.UTF-8 ## [7] LC_PAPER=en_US.UTF-8 LC_NAME=C ## [9] LC_ADDRESS=C LC_TELEPHONE=C ## [11] LC_MEASUREMENT=en_US.UTF-8 LC_IDENTIFICATION=C ## ## attached base packages: ## [1] stats graphics grDevices utils datasets methods base ## ## other attached packages: ## [1] ggplot2_3.4.1 patchwork_1.1.2 SeuratObject_4.1.3 Seurat_4.3.0 ## [5] dplyr_1.1.0 ## ## loaded via a namespace (and not attached): ## [1] Rtsne_0.16 colorspace_2.1-0 deldir_1.0-6 ## [4] ellipsis_0.3.2 ggridges_0.5.4 rprojroot_2.0.3 ## [7] fs_1.6.1 spatstat.data_3.0-0 farver_2.1.1 ## [10] leiden_0.4.3 listenv_0.9.0 ggrepel_0.9.3 ## [13] fansi_1.0.4 R.methodsS3_1.8.2 codetools_0.2-18 ## [16] splines_4.2.0 cachem_1.0.7 knitr_1.42 ## [19] polyclip_1.10-4 jsonlite_1.8.4 ica_1.0-3 ## [22] cluster_2.1.3 R.oo_1.25.0 png_0.1-8 ## [25] uwot_0.1.14 spatstat.sparse_3.0-0 shiny_1.7.4 ## [28] sctransform_0.3.5 compiler_4.2.0 httr_1.4.5 ## [31] Matrix_1.5-3 fastmap_1.1.1 lazyeval_0.2.2 ## [34] limma_3.54.1 cli_3.6.0 later_1.3.0 ## [37] formatR_1.14 htmltools_0.5.4 tools_4.2.0 ## [40] igraph_1.4.1 gtable_0.3.1 glue_1.6.2 ## [43] RANN_2.6.1 reshape2_1.4.4 Rcpp_1.0.10 ## [46] scattermore_0.8 jquerylib_0.1.4 pkgdown_2.0.7 ## [49] vctrs_0.5.2 nlme_3.1-157 spatstat.explore_3.0-6 ## [52] progressr_0.13.0 lmtest_0.9-40 spatstat.random_3.1-3 ## [55] xfun_0.37 stringr_1.5.0 globals_0.16.2 ## [58] mime_0.12 miniUI_0.1.1.1 lifecycle_1.0.3 ## [61] irlba_2.3.5.1 goftest_1.2-3 future_1.31.0 ## [64] MASS_7.3-56 zoo_1.8-11 scales_1.2.1 ## [67] ragg_1.2.5 promises_1.2.0.1 spatstat.utils_3.0-1 ## [70] parallel_4.2.0 RColorBrewer_1.1-3 yaml_2.3.7 ## [73] memoise_2.0.1 reticulate_1.28 pbapply_1.7-0 ## [76] gridExtra_2.3 sass_0.4.5 stringi_1.7.12 ## [79] highr_0.10 desc_1.4.2 rlang_1.0.6 ## [82] pkgconfig_2.0.3 systemfonts_1.0.4 matrixStats_0.63.0 ## [85] evaluate_0.20 lattice_0.20-45 tensor_1.5 ## [88] ROCR_1.0-11 purrr_1.0.1 labeling_0.4.2 ## [91] htmlwidgets_1.6.1 cowplot_1.1.1 tidyselect_1.2.0 ## [94] parallelly_1.34.0 RcppAnnoy_0.0.20 plyr_1.8.8 ## [97] magrittr_2.0.3 R6_2.5.1 generics_0.1.3 ## [100] withr_2.5.0 pillar_1.8.1 fitdistrplus_1.1-8 ## [103] abind_1.4-5 survival_3.3-1 sp_1.6-0 ## [106] tibble_3.1.8 future.apply_1.10.0 crayon_1.5.2 ## [109] KernSmooth_2.23-20 utf8_1.2.3 spatstat.geom_3.0-6 ## [112] plotly_4.10.1 rmarkdown_2.20 grid_4.2.0 ## [115] data.table_1.14.8 digest_0.6.31 xtable_1.8-4 ## [118] tidyr_1.3.0 httpuv_1.6.9 R.utils_2.12.2 ## [121] textshaping_0.3.6 munsell_0.5.0 viridisLite_0.4.1 ## [124] bslib_0.4.2

Developed by Paul Hoffman, Satija Lab and Collaborators.

Developed by Paul Hoffman, Satija Lab and Collaborators.

Site built with pkgdown 2.0.7.

Site built with pkgdown 2.0.7.

**Examples:**

Example 1 (unknown):
```unknown
vignettes/pbmc3k_tutorial.Rmd
```

Example 2 (unknown):
```unknown
pbmc3k_tutorial.Rmd
```

Example 3 (unknown):
```unknown
pbmc[["RNA"]]@counts
```

Example 4 (unknown):
```unknown
library(dplyr)
library(Seurat)
library(patchwork)

# Load the PBMC dataset
pbmc.data <- Read10X(data.dir = "../data/pbmc3k/filtered_gene_bc_matrices/hg19/")
# Initialize the Seurat object with the raw (non-normalized data).
pbmc <- CreateSeuratObject(counts = pbmc.data, project = "pbmc3k", min.cells = 3, min.features = 200)
pbmc
```

Example 5 (r):
```r
library(dplyr)
library(Seurat)
library(patchwork)

# Load the PBMC dataset
pbmc.data <- Read10X(data.dir = "../data/pbmc3k/filtered_gene_bc_matrices/hg19/")
# Initialize the Seurat object with the raw (non-normalized data).
pbmc <- CreateSeuratObject(counts = pbmc.data, project = "pbmc3k", min.cells = 3, min.features = 200)
pbmc
```

Example 6 (r):
```r
library(dplyr)
library(Seurat)
library(patchwork)

# Load the PBMC dataset
pbmc.data <- Read10X(data.dir = "../data/pbmc3k/filtered_gene_bc_matrices/hg19/")
# Initialize the Seurat object with the raw (non-normalized data).
pbmc <- CreateSeuratObject(counts = pbmc.data, project = "pbmc3k", min.cells = 3, min.features = 200)
pbmc
```

Example 7 (python):
```python
## An object of class Seurat 
## 13714 features across 2700 samples within 1 assay 
## Active assay: RNA (13714 features, 0 variable features)
```

Example 8 (python):
```python
## An object of class Seurat 
## 13714 features across 2700 samples within 1 assay 
## Active assay: RNA (13714 features, 0 variable features)
```

Example 9 (unknown):
```unknown
# Lets examine a few genes in the first thirty cells
pbmc.data[c("CD3D", "TCL1A", "MS4A1"), 1:30]
```

Example 10 (r):
```r
# Lets examine a few genes in the first thirty cells
pbmc.data[c("CD3D", "TCL1A", "MS4A1"), 1:30]
```

Example 11 (r):
```r
# Lets examine a few genes in the first thirty cells
pbmc.data[c("CD3D", "TCL1A", "MS4A1"), 1:30]
```

Example 12 (python):
```python
## 3 x 30 sparse Matrix of class "dgCMatrix"
##                                                                    
## CD3D  4 . 10 . . 1 2 3 1 . . 2 7 1 . . 1 3 . 2  3 . . . . . 3 4 1 5
## TCL1A . .  . . . . . . 1 . . . . . . . . . . .  . 1 . . . . . . . .
## MS4A1 . 6  . . . . . . 1 1 1 . . . . . . . . . 36 1 2 . . 2 . . . .
```

Example 13 (python):
```python
## 3 x 30 sparse Matrix of class "dgCMatrix"
##                                                                    
## CD3D  4 . 10 . . 1 2 3 1 . . 2 7 1 . . 1 3 . 2  3 . . . . . 3 4 1 5
## TCL1A . .  . . . . . . 1 . . . . . . . . . . .  . 1 . . . . . . . .
## MS4A1 . 6  . . . . . . 1 1 1 . . . . . . . . . 36 1 2 . . 2 . . . .
```

Example 14 (unknown):
```unknown
dense.size <- object.size(as.matrix(pbmc.data))
dense.size
```

Example 15 (r):
```r
dense.size <- object.size(as.matrix(pbmc.data))
dense.size
```

Example 16 (r):
```r
dense.size <- object.size(as.matrix(pbmc.data))
dense.size
```

Example 17 (unknown):
```unknown
## 709591472 bytes
```

Example 18 (unknown):
```unknown
## 709591472 bytes
```

Example 19 (unknown):
```unknown
sparse.size <- object.size(pbmc.data)
sparse.size
```

Example 20 (r):
```r
sparse.size <- object.size(pbmc.data)
sparse.size
```

Example 21 (r):
```r
sparse.size <- object.size(pbmc.data)
sparse.size
```

Example 22 (unknown):
```unknown
## 29905192 bytes
```

Example 23 (unknown):
```unknown
## 29905192 bytes
```

Example 24 (unknown):
```unknown
dense.size/sparse.size
```

Example 25 (r):
```r
dense.size/sparse.size
```

Example 26 (r):
```r
dense.size/sparse.size
```

Example 27 (unknown):
```unknown
## 23.7 bytes
```

Example 28 (unknown):
```unknown
## 23.7 bytes
```

Example 29 (unknown):
```unknown
PercentageFeatureSet()
```

Example 30 (python):
```python
# The [[ operator can add columns to object metadata. This is a great place to stash QC stats
pbmc[["percent.mt"]] <- PercentageFeatureSet(pbmc, pattern = "^MT-")
```

Example 31 (r):
```r
# The [[ operator can add columns to object metadata. This is a great place to stash QC stats
pbmc[["percent.mt"]] <- PercentageFeatureSet(pbmc, pattern = "^MT-")
```

Example 32 (r):
```r
# The [[ operator can add columns to object metadata. This is a great place to stash QC stats
pbmc[["percent.mt"]] <- PercentageFeatureSet(pbmc, pattern = "^MT-")
```

Example 33 (unknown):
```unknown
CreateSeuratObject()
```

Example 34 (unknown):
```unknown
# Show QC metrics for the first 5 cells
head(pbmc@meta.data, 5)
```

Example 35 (r):
```r
# Show QC metrics for the first 5 cells
head(pbmc@meta.data, 5)
```

Example 36 (r):
```r
# Show QC metrics for the first 5 cells
head(pbmc@meta.data, 5)
```

Example 37 (unknown):
```unknown
##                  orig.ident nCount_RNA nFeature_RNA percent.mt
## AAACATACAACCAC-1     pbmc3k       2419          779  3.0177759
## AAACATTGAGCTAC-1     pbmc3k       4903         1352  3.7935958
## AAACATTGATCAGC-1     pbmc3k       3147         1129  0.8897363
## AAACCGTGCTTCCG-1     pbmc3k       2639          960  1.7430845
## AAACCGTGTATGCG-1     pbmc3k        980          521  1.2244898
```

Example 38 (unknown):
```unknown
##                  orig.ident nCount_RNA nFeature_RNA percent.mt
## AAACATACAACCAC-1     pbmc3k       2419          779  3.0177759
## AAACATTGAGCTAC-1     pbmc3k       4903         1352  3.7935958
## AAACATTGATCAGC-1     pbmc3k       3147         1129  0.8897363
## AAACCGTGCTTCCG-1     pbmc3k       2639          960  1.7430845
## AAACCGTGTATGCG-1     pbmc3k        980          521  1.2244898
```

Example 39 (unknown):
```unknown
# Visualize QC metrics as a violin plot
VlnPlot(pbmc, features = c("nFeature_RNA", "nCount_RNA", "percent.mt"), ncol = 3)
```

Example 40 (r):
```r
# Visualize QC metrics as a violin plot
VlnPlot(pbmc, features = c("nFeature_RNA", "nCount_RNA", "percent.mt"), ncol = 3)
```

Example 41 (r):
```r
# Visualize QC metrics as a violin plot
VlnPlot(pbmc, features = c("nFeature_RNA", "nCount_RNA", "percent.mt"), ncol = 3)
```

Example 42 (python):
```python
# FeatureScatter is typically used to visualize feature-feature relationships, but can be used
# for anything calculated by the object, i.e. columns in object metadata, PC scores etc.

plot1 <- FeatureScatter(pbmc, feature1 = "nCount_RNA", feature2 = "percent.mt")
plot2 <- FeatureScatter(pbmc, feature1 = "nCount_RNA", feature2 = "nFeature_RNA")
plot1 + plot2
```

Example 43 (r):
```r
# FeatureScatter is typically used to visualize feature-feature relationships, but can be used
# for anything calculated by the object, i.e. columns in object metadata, PC scores etc.

plot1 <- FeatureScatter(pbmc, feature1 = "nCount_RNA", feature2 = "percent.mt")
plot2 <- FeatureScatter(pbmc, feature1 = "nCount_RNA", feature2 = "nFeature_RNA")
plot1 + plot2
```

Example 44 (r):
```r
# FeatureScatter is typically used to visualize feature-feature relationships, but can be used
# for anything calculated by the object, i.e. columns in object metadata, PC scores etc.

plot1 <- FeatureScatter(pbmc, feature1 = "nCount_RNA", feature2 = "percent.mt")
plot2 <- FeatureScatter(pbmc, feature1 = "nCount_RNA", feature2 = "nFeature_RNA")
plot1 + plot2
```

Example 45 (unknown):
```unknown
pbmc <- subset(pbmc, subset = nFeature_RNA > 200 & nFeature_RNA < 2500 & percent.mt < 5)
```

Example 46 (r):
```r
pbmc <- subset(pbmc, subset = nFeature_RNA > 200 & nFeature_RNA < 2500 & percent.mt < 5)
```

Example 47 (r):
```r
pbmc <- subset(pbmc, subset = nFeature_RNA > 200 & nFeature_RNA < 2500 & percent.mt < 5)
```

Example 48 (unknown):
```unknown
pbmc[["RNA"]]@data
```

Example 49 (unknown):
```unknown
pbmc <- NormalizeData(pbmc, normalization.method = "LogNormalize", scale.factor = 10000)
```

Example 50 (r):
```r
pbmc <- NormalizeData(pbmc, normalization.method = "LogNormalize", scale.factor = 10000)
```

Example 51 (r):
```r
pbmc <- NormalizeData(pbmc, normalization.method = "LogNormalize", scale.factor = 10000)
```

Example 52 (unknown):
```unknown
pbmc <- NormalizeData(pbmc)
```

Example 53 (r):
```r
pbmc <- NormalizeData(pbmc)
```

Example 54 (r):
```r
pbmc <- NormalizeData(pbmc)
```

Example 55 (unknown):
```unknown
FindVariableFeatures()
```

Example 56 (unknown):
```unknown
pbmc <- FindVariableFeatures(pbmc, selection.method = "vst", nfeatures = 2000)

# Identify the 10 most highly variable genes
top10 <- head(VariableFeatures(pbmc), 10)

# plot variable features with and without labels
plot1 <- VariableFeaturePlot(pbmc)
plot2 <- LabelPoints(plot = plot1, points = top10, repel = TRUE)
plot1 + plot2
```

Example 57 (r):
```r
pbmc <- FindVariableFeatures(pbmc, selection.method = "vst", nfeatures = 2000)

# Identify the 10 most highly variable genes
top10 <- head(VariableFeatures(pbmc), 10)

# plot variable features with and without labels
plot1 <- VariableFeaturePlot(pbmc)
plot2 <- LabelPoints(plot = plot1, points = top10, repel = TRUE)
plot1 + plot2
```

Example 58 (r):
```r
pbmc <- FindVariableFeatures(pbmc, selection.method = "vst", nfeatures = 2000)

# Identify the 10 most highly variable genes
top10 <- head(VariableFeatures(pbmc), 10)

# plot variable features with and without labels
plot1 <- VariableFeaturePlot(pbmc)
plot2 <- LabelPoints(plot = plot1, points = top10, repel = TRUE)
plot1 + plot2
```

Example 59 (unknown):
```unknown
ScaleData()
```

Example 60 (unknown):
```unknown
pbmc[["RNA"]]@scale.data
```

Example 61 (unknown):
```unknown
all.genes <- rownames(pbmc)
pbmc <- ScaleData(pbmc, features = all.genes)
```

Example 62 (r):
```r
all.genes <- rownames(pbmc)
pbmc <- ScaleData(pbmc, features = all.genes)
```

Example 63 (r):
```r
all.genes <- rownames(pbmc)
pbmc <- ScaleData(pbmc, features = all.genes)
```

Example 64 (unknown):
```unknown
ScaleData()
```

Example 65 (unknown):
```unknown
pbmc <- ScaleData(pbmc)
```

Example 66 (r):
```r
pbmc <- ScaleData(pbmc)
```

Example 67 (r):
```r
pbmc <- ScaleData(pbmc)
```

Example 68 (unknown):
```unknown
DoHeatmap()
```

Example 69 (unknown):
```unknown
ScaleData()
```

Example 70 (unknown):
```unknown
ScaleData()
```

Example 71 (unknown):
```unknown
pbmc <- ScaleData(pbmc, vars.to.regress = "percent.mt")
```

Example 72 (r):
```r
pbmc <- ScaleData(pbmc, vars.to.regress = "percent.mt")
```

Example 73 (r):
```r
pbmc <- ScaleData(pbmc, vars.to.regress = "percent.mt")
```

Example 74 (unknown):
```unknown
SCTransform()
```

Example 75 (unknown):
```unknown
ScaleData()
```

Example 76 (unknown):
```unknown
SCTransform()
```

Example 77 (unknown):
```unknown
vars.to.regress
```

Example 78 (unknown):
```unknown
pbmc <- RunPCA(pbmc, features = VariableFeatures(object = pbmc))
```

Example 79 (r):
```r
pbmc <- RunPCA(pbmc, features = VariableFeatures(object = pbmc))
```

Example 80 (r):
```r
pbmc <- RunPCA(pbmc, features = VariableFeatures(object = pbmc))
```

Example 81 (unknown):
```unknown
VizDimReduction()
```

Example 82 (unknown):
```unknown
DimHeatmap()
```

Example 83 (python):
```python
# Examine and visualize PCA results a few different ways
print(pbmc[["pca"]], dims = 1:5, nfeatures = 5)
```

Example 84 (r):
```r
# Examine and visualize PCA results a few different ways
print(pbmc[["pca"]], dims = 1:5, nfeatures = 5)
```

Example 85 (r):
```r
# Examine and visualize PCA results a few different ways
print(pbmc[["pca"]], dims = 1:5, nfeatures = 5)
```

Example 86 (unknown):
```unknown
## PC_ 1 
## Positive:  CST3, TYROBP, LST1, AIF1, FTL 
## Negative:  MALAT1, LTB, IL32, IL7R, CD2 
## PC_ 2 
## Positive:  CD79A, MS4A1, TCL1A, HLA-DQA1, HLA-DQB1 
## Negative:  NKG7, PRF1, CST7, GZMB, GZMA 
## PC_ 3 
## Positive:  HLA-DQA1, CD79A, CD79B, HLA-DQB1, HLA-DPB1 
## Negative:  PPBP, PF4, SDPR, SPARC, GNG11 
## PC_ 4 
## Positive:  HLA-DQA1, CD79B, CD79A, MS4A1, HLA-DQB1 
## Negative:  VIM, IL7R, S100A6, IL32, S100A8 
## PC_ 5 
## Positive:  GZMB, NKG7, S100A8, FGFBP2, GNLY 
## Negative:  LTB, IL7R, CKB, VIM, MS4A7
```

Example 87 (unknown):
```unknown
## PC_ 1 
## Positive:  CST3, TYROBP, LST1, AIF1, FTL 
## Negative:  MALAT1, LTB, IL32, IL7R, CD2 
## PC_ 2 
## Positive:  CD79A, MS4A1, TCL1A, HLA-DQA1, HLA-DQB1 
## Negative:  NKG7, PRF1, CST7, GZMB, GZMA 
## PC_ 3 
## Positive:  HLA-DQA1, CD79A, CD79B, HLA-DQB1, HLA-DPB1 
## Negative:  PPBP, PF4, SDPR, SPARC, GNG11 
## PC_ 4 
## Positive:  HLA-DQA1, CD79B, CD79A, MS4A1, HLA-DQB1 
## Negative:  VIM, IL7R, S100A6, IL32, S100A8 
## PC_ 5 
## Positive:  GZMB, NKG7, S100A8, FGFBP2, GNLY 
## Negative:  LTB, IL7R, CKB, VIM, MS4A7
```

Example 88 (unknown):
```unknown
VizDimLoadings(pbmc, dims = 1:2, reduction = "pca")
```

Example 89 (r):
```r
VizDimLoadings(pbmc, dims = 1:2, reduction = "pca")
```

Example 90 (r):
```r
VizDimLoadings(pbmc, dims = 1:2, reduction = "pca")
```

Example 91 (unknown):
```unknown
DimPlot(pbmc, reduction = "pca")
```

Example 92 (r):
```r
DimPlot(pbmc, reduction = "pca")
```

Example 93 (r):
```r
DimPlot(pbmc, reduction = "pca")
```

Example 94 (unknown):
```unknown
DimHeatmap()
```

Example 95 (unknown):
```unknown
DimHeatmap(pbmc, dims = 1, cells = 500, balanced = TRUE)
```

Example 96 (r):
```r
DimHeatmap(pbmc, dims = 1, cells = 500, balanced = TRUE)
```

Example 97 (r):
```r
DimHeatmap(pbmc, dims = 1, cells = 500, balanced = TRUE)
```

Example 98 (unknown):
```unknown
DimHeatmap(pbmc, dims = 1:15, cells = 500, balanced = TRUE)
```

Example 99 (r):
```r
DimHeatmap(pbmc, dims = 1:15, cells = 500, balanced = TRUE)
```

Example 100 (r):
```r
DimHeatmap(pbmc, dims = 1:15, cells = 500, balanced = TRUE)
```

Example 101 (unknown):
```unknown
# NOTE: This process can take a long time for big datasets, comment out for expediency. More
# approximate techniques such as those implemented in ElbowPlot() can be used to reduce
# computation time
pbmc <- JackStraw(pbmc, num.replicate = 100)
pbmc <- ScoreJackStraw(pbmc, dims = 1:20)
```

Example 102 (r):
```r
# NOTE: This process can take a long time for big datasets, comment out for expediency. More
# approximate techniques such as those implemented in ElbowPlot() can be used to reduce
# computation time
pbmc <- JackStraw(pbmc, num.replicate = 100)
pbmc <- ScoreJackStraw(pbmc, dims = 1:20)
```

Example 103 (r):
```r
# NOTE: This process can take a long time for big datasets, comment out for expediency. More
# approximate techniques such as those implemented in ElbowPlot() can be used to reduce
# computation time
pbmc <- JackStraw(pbmc, num.replicate = 100)
pbmc <- ScoreJackStraw(pbmc, dims = 1:20)
```

Example 104 (unknown):
```unknown
JackStrawPlot()
```

Example 105 (unknown):
```unknown
JackStrawPlot(pbmc, dims = 1:15)
```

Example 106 (r):
```r
JackStrawPlot(pbmc, dims = 1:15)
```

Example 107 (r):
```r
JackStrawPlot(pbmc, dims = 1:15)
```

Example 108 (unknown):
```unknown
ElbowPlot()
```

Example 109 (unknown):
```unknown
ElbowPlot(pbmc)
```

Example 110 (r):
```r
ElbowPlot(pbmc)
```

Example 111 (r):
```r
ElbowPlot(pbmc)
```

Example 112 (unknown):
```unknown
FindNeighbors()
```

Example 113 (unknown):
```unknown
FindClusters()
```

Example 114 (unknown):
```unknown
pbmc <- FindNeighbors(pbmc, dims = 1:10)
pbmc <- FindClusters(pbmc, resolution = 0.5)
```

Example 115 (r):
```r
pbmc <- FindNeighbors(pbmc, dims = 1:10)
pbmc <- FindClusters(pbmc, resolution = 0.5)
```

Example 116 (r):
```r
pbmc <- FindNeighbors(pbmc, dims = 1:10)
pbmc <- FindClusters(pbmc, resolution = 0.5)
```

Example 117 (unknown):
```unknown
## Modularity Optimizer version 1.3.0 by Ludo Waltman and Nees Jan van Eck
## 
## Number of nodes: 2638
## Number of edges: 95927
## 
## Running Louvain algorithm...
## Maximum modularity in 10 random starts: 0.8728
## Number of communities: 9
## Elapsed time: 0 seconds
```

Example 118 (unknown):
```unknown
## Modularity Optimizer version 1.3.0 by Ludo Waltman and Nees Jan van Eck
## 
## Number of nodes: 2638
## Number of edges: 95927
## 
## Running Louvain algorithm...
## Maximum modularity in 10 random starts: 0.8728
## Number of communities: 9
## Elapsed time: 0 seconds
```

Example 119 (unknown):
```unknown
# Look at cluster IDs of the first 5 cells
head(Idents(pbmc), 5)
```

Example 120 (r):
```r
# Look at cluster IDs of the first 5 cells
head(Idents(pbmc), 5)
```

Example 121 (r):
```r
# Look at cluster IDs of the first 5 cells
head(Idents(pbmc), 5)
```

Example 122 (unknown):
```unknown
## AAACATACAACCAC-1 AAACATTGAGCTAC-1 AAACATTGATCAGC-1 AAACCGTGCTTCCG-1 
##                2                3                2                1 
## AAACCGTGTATGCG-1 
##                6 
## Levels: 0 1 2 3 4 5 6 7 8
```

Example 123 (unknown):
```unknown
## AAACATACAACCAC-1 AAACATTGAGCTAC-1 AAACATTGATCAGC-1 AAACCGTGCTTCCG-1 
##                2                3                2                1 
## AAACCGTGTATGCG-1 
##                6 
## Levels: 0 1 2 3 4 5 6 7 8
```

Example 124 (unknown):
```unknown
# If you haven't installed UMAP, you can do so via reticulate::py_install(packages =
# 'umap-learn')
pbmc <- RunUMAP(pbmc, dims = 1:10)
```

Example 125 (r):
```r
# If you haven't installed UMAP, you can do so via reticulate::py_install(packages =
# 'umap-learn')
pbmc <- RunUMAP(pbmc, dims = 1:10)
```

Example 126 (r):
```r
# If you haven't installed UMAP, you can do so via reticulate::py_install(packages =
# 'umap-learn')
pbmc <- RunUMAP(pbmc, dims = 1:10)
```

Example 127 (unknown):
```unknown
# note that you can set `label = TRUE` or use the LabelClusters function to help label
# individual clusters
DimPlot(pbmc, reduction = "umap")
```

Example 128 (r):
```r
# note that you can set `label = TRUE` or use the LabelClusters function to help label
# individual clusters
DimPlot(pbmc, reduction = "umap")
```

Example 129 (r):
```r
# note that you can set `label = TRUE` or use the LabelClusters function to help label
# individual clusters
DimPlot(pbmc, reduction = "umap")
```

Example 130 (unknown):
```unknown
saveRDS(pbmc, file = "../output/pbmc_tutorial.rds")
```

Example 131 (r):
```r
saveRDS(pbmc, file = "../output/pbmc_tutorial.rds")
```

Example 132 (r):
```r
saveRDS(pbmc, file = "../output/pbmc_tutorial.rds")
```

Example 133 (unknown):
```unknown
FindAllMarkers()
```

Example 134 (unknown):
```unknown
max.cells.per.ident
```

Example 135 (unknown):
```unknown
# find all markers of cluster 2
cluster2.markers <- FindMarkers(pbmc, ident.1 = 2, min.pct = 0.25)
head(cluster2.markers, n = 5)
```

Example 136 (r):
```r
# find all markers of cluster 2
cluster2.markers <- FindMarkers(pbmc, ident.1 = 2, min.pct = 0.25)
head(cluster2.markers, n = 5)
```

Example 137 (r):
```r
# find all markers of cluster 2
cluster2.markers <- FindMarkers(pbmc, ident.1 = 2, min.pct = 0.25)
head(cluster2.markers, n = 5)
```

Example 138 (unknown):
```unknown
##             p_val avg_log2FC pct.1 pct.2    p_val_adj
## IL32 2.892340e-90  1.2013522 0.947 0.465 3.966555e-86
## LTB  1.060121e-86  1.2695776 0.981 0.643 1.453850e-82
## CD3D 8.794641e-71  0.9389621 0.922 0.432 1.206097e-66
## IL7R 3.516098e-68  1.1873213 0.750 0.326 4.821977e-64
## LDHB 1.642480e-67  0.8969774 0.954 0.614 2.252497e-63
```

Example 139 (unknown):
```unknown
##             p_val avg_log2FC pct.1 pct.2    p_val_adj
## IL32 2.892340e-90  1.2013522 0.947 0.465 3.966555e-86
## LTB  1.060121e-86  1.2695776 0.981 0.643 1.453850e-82
## CD3D 8.794641e-71  0.9389621 0.922 0.432 1.206097e-66
## IL7R 3.516098e-68  1.1873213 0.750 0.326 4.821977e-64
## LDHB 1.642480e-67  0.8969774 0.954 0.614 2.252497e-63
```

Example 140 (python):
```python
# find all markers distinguishing cluster 5 from clusters 0 and 3
cluster5.markers <- FindMarkers(pbmc, ident.1 = 5, ident.2 = c(0, 3), min.pct = 0.25)
head(cluster5.markers, n = 5)
```

Example 141 (r):
```r
# find all markers distinguishing cluster 5 from clusters 0 and 3
cluster5.markers <- FindMarkers(pbmc, ident.1 = 5, ident.2 = c(0, 3), min.pct = 0.25)
head(cluster5.markers, n = 5)
```

Example 142 (r):
```r
# find all markers distinguishing cluster 5 from clusters 0 and 3
cluster5.markers <- FindMarkers(pbmc, ident.1 = 5, ident.2 = c(0, 3), min.pct = 0.25)
head(cluster5.markers, n = 5)
```

Example 143 (unknown):
```unknown
##                       p_val avg_log2FC pct.1 pct.2     p_val_adj
## FCGR3A        8.246578e-205   4.261495 0.975 0.040 1.130936e-200
## IFITM3        1.677613e-195   3.879339 0.975 0.049 2.300678e-191
## CFD           2.401156e-193   3.405492 0.938 0.038 3.292945e-189
## CD68          2.900384e-191   3.020484 0.926 0.035 3.977587e-187
## RP11-290F20.3 2.513244e-186   2.720057 0.840 0.017 3.446663e-182
```

Example 144 (unknown):
```unknown
##                       p_val avg_log2FC pct.1 pct.2     p_val_adj
## FCGR3A        8.246578e-205   4.261495 0.975 0.040 1.130936e-200
## IFITM3        1.677613e-195   3.879339 0.975 0.049 2.300678e-191
## CFD           2.401156e-193   3.405492 0.938 0.038 3.292945e-189
## CD68          2.900384e-191   3.020484 0.926 0.035 3.977587e-187
## RP11-290F20.3 2.513244e-186   2.720057 0.840 0.017 3.446663e-182
```

Example 145 (unknown):
```unknown
# find markers for every cluster compared to all remaining cells, report only the positive
# ones
pbmc.markers <- FindAllMarkers(pbmc, only.pos = TRUE, min.pct = 0.25, logfc.threshold = 0.25)
pbmc.markers %>%
    group_by(cluster) %>%
    slice_max(n = 2, order_by = avg_log2FC)
```

Example 146 (r):
```r
# find markers for every cluster compared to all remaining cells, report only the positive
# ones
pbmc.markers <- FindAllMarkers(pbmc, only.pos = TRUE, min.pct = 0.25, logfc.threshold = 0.25)
pbmc.markers %>%
    group_by(cluster) %>%
    slice_max(n = 2, order_by = avg_log2FC)
```

Example 147 (r):
```r
# find markers for every cluster compared to all remaining cells, report only the positive
# ones
pbmc.markers <- FindAllMarkers(pbmc, only.pos = TRUE, min.pct = 0.25, logfc.threshold = 0.25)
pbmc.markers %>%
    group_by(cluster) %>%
    slice_max(n = 2, order_by = avg_log2FC)
```

Example 148 (unknown):
```unknown
## # A tibble: 18 × 7
## # Groups:   cluster [9]
##        p_val avg_log2FC pct.1 pct.2 p_val_adj cluster gene    
##        <dbl>      <dbl> <dbl> <dbl>     <dbl> <fct>   <chr>   
##  1 9.57e- 88       1.36 0.447 0.108 1.31e- 83 0       CCR7    
##  2 3.75e-112       1.09 0.912 0.592 5.14e-108 0       LDHB    
##  3 0               5.57 0.996 0.215 0         1       S100A9  
##  4 0               5.48 0.975 0.121 0         1       S100A8  
##  5 1.06e- 86       1.27 0.981 0.643 1.45e- 82 2       LTB     
##  6 2.97e- 58       1.23 0.42  0.111 4.07e- 54 2       AQP3    
##  7 0               4.31 0.936 0.041 0         3       CD79A   
##  8 9.48e-271       3.59 0.622 0.022 1.30e-266 3       TCL1A   
##  9 5.61e-202       3.10 0.983 0.234 7.70e-198 4       CCL5    
## 10 7.25e-165       3.00 0.577 0.055 9.95e-161 4       GZMK    
## 11 3.51e-184       3.31 0.975 0.134 4.82e-180 5       FCGR3A  
## 12 2.03e-125       3.09 1     0.315 2.78e-121 5       LST1    
## 13 3.13e-191       5.32 0.961 0.131 4.30e-187 6       GNLY    
## 14 7.95e-269       4.83 0.961 0.068 1.09e-264 6       GZMB    
## 15 1.48e-220       3.87 0.812 0.011 2.03e-216 7       FCER1A  
## 16 1.67e- 21       2.87 1     0.513 2.28e- 17 7       HLA-DPB1
## 17 1.92e-102       8.59 1     0.024 2.63e- 98 8       PPBP    
## 18 9.25e-186       7.29 1     0.011 1.27e-181 8       PF4
```

Example 149 (unknown):
```unknown
## # A tibble: 18 × 7
## # Groups:   cluster [9]
##        p_val avg_log2FC pct.1 pct.2 p_val_adj cluster gene    
##        <dbl>      <dbl> <dbl> <dbl>     <dbl> <fct>   <chr>   
##  1 9.57e- 88       1.36 0.447 0.108 1.31e- 83 0       CCR7    
##  2 3.75e-112       1.09 0.912 0.592 5.14e-108 0       LDHB    
##  3 0               5.57 0.996 0.215 0         1       S100A9  
##  4 0               5.48 0.975 0.121 0         1       S100A8  
##  5 1.06e- 86       1.27 0.981 0.643 1.45e- 82 2       LTB     
##  6 2.97e- 58       1.23 0.42  0.111 4.07e- 54 2       AQP3    
##  7 0               4.31 0.936 0.041 0         3       CD79A   
##  8 9.48e-271       3.59 0.622 0.022 1.30e-266 3       TCL1A   
##  9 5.61e-202       3.10 0.983 0.234 7.70e-198 4       CCL5    
## 10 7.25e-165       3.00 0.577 0.055 9.95e-161 4       GZMK    
## 11 3.51e-184       3.31 0.975 0.134 4.82e-180 5       FCGR3A  
## 12 2.03e-125       3.09 1     0.315 2.78e-121 5       LST1    
## 13 3.13e-191       5.32 0.961 0.131 4.30e-187 6       GNLY    
## 14 7.95e-269       4.83 0.961 0.068 1.09e-264 6       GZMB    
## 15 1.48e-220       3.87 0.812 0.011 2.03e-216 7       FCER1A  
## 16 1.67e- 21       2.87 1     0.513 2.28e- 17 7       HLA-DPB1
## 17 1.92e-102       8.59 1     0.024 2.63e- 98 8       PPBP    
## 18 9.25e-186       7.29 1     0.011 1.27e-181 8       PF4
```

Example 150 (unknown):
```unknown
cluster0.markers <- FindMarkers(pbmc, ident.1 = 0, logfc.threshold = 0.25, test.use = "roc", only.pos = TRUE)
```

Example 151 (r):
```r
cluster0.markers <- FindMarkers(pbmc, ident.1 = 0, logfc.threshold = 0.25, test.use = "roc", only.pos = TRUE)
```

Example 152 (r):
```r
cluster0.markers <- FindMarkers(pbmc, ident.1 = 0, logfc.threshold = 0.25, test.use = "roc", only.pos = TRUE)
```

Example 153 (unknown):
```unknown
FeaturePlot()
```

Example 154 (unknown):
```unknown
RidgePlot()
```

Example 155 (unknown):
```unknown
CellScatter()
```

Example 156 (unknown):
```unknown
VlnPlot(pbmc, features = c("MS4A1", "CD79A"))
```

Example 157 (r):
```r
VlnPlot(pbmc, features = c("MS4A1", "CD79A"))
```

Example 158 (r):
```r
VlnPlot(pbmc, features = c("MS4A1", "CD79A"))
```

Example 159 (unknown):
```unknown
# you can plot raw counts as well
VlnPlot(pbmc, features = c("NKG7", "PF4"), slot = "counts", log = TRUE)
```

Example 160 (r):
```r
# you can plot raw counts as well
VlnPlot(pbmc, features = c("NKG7", "PF4"), slot = "counts", log = TRUE)
```

Example 161 (r):
```r
# you can plot raw counts as well
VlnPlot(pbmc, features = c("NKG7", "PF4"), slot = "counts", log = TRUE)
```

Example 162 (unknown):
```unknown
FeaturePlot(pbmc, features = c("MS4A1", "GNLY", "CD3E", "CD14", "FCER1A", "FCGR3A", "LYZ", "PPBP",
    "CD8A"))
```

Example 163 (r):
```r
FeaturePlot(pbmc, features = c("MS4A1", "GNLY", "CD3E", "CD14", "FCER1A", "FCGR3A", "LYZ", "PPBP",
    "CD8A"))
```

Example 164 (r):
```r
FeaturePlot(pbmc, features = c("MS4A1", "GNLY", "CD3E", "CD14", "FCER1A", "FCGR3A", "LYZ", "PPBP",
    "CD8A"))
```

Example 165 (unknown):
```unknown
DoHeatmap()
```

Example 166 (unknown):
```unknown
pbmc.markers %>%
    group_by(cluster) %>%
    top_n(n = 10, wt = avg_log2FC) -> top10
DoHeatmap(pbmc, features = top10$gene) + NoLegend()
```

Example 167 (r):
```r
pbmc.markers %>%
    group_by(cluster) %>%
    top_n(n = 10, wt = avg_log2FC) -> top10
DoHeatmap(pbmc, features = top10$gene) + NoLegend()
```

Example 168 (r):
```r
pbmc.markers %>%
    group_by(cluster) %>%
    top_n(n = 10, wt = avg_log2FC) -> top10
DoHeatmap(pbmc, features = top10$gene) + NoLegend()
```

Example 169 (unknown):
```unknown
new.cluster.ids <- c("Naive CD4 T", "CD14+ Mono", "Memory CD4 T", "B", "CD8 T", "FCGR3A+ Mono",
    "NK", "DC", "Platelet")
names(new.cluster.ids) <- levels(pbmc)
pbmc <- RenameIdents(pbmc, new.cluster.ids)
DimPlot(pbmc, reduction = "umap", label = TRUE, pt.size = 0.5) + NoLegend()
```

Example 170 (r):
```r
new.cluster.ids <- c("Naive CD4 T", "CD14+ Mono", "Memory CD4 T", "B", "CD8 T", "FCGR3A+ Mono",
    "NK", "DC", "Platelet")
names(new.cluster.ids) <- levels(pbmc)
pbmc <- RenameIdents(pbmc, new.cluster.ids)
DimPlot(pbmc, reduction = "umap", label = TRUE, pt.size = 0.5) + NoLegend()
```

Example 171 (r):
```r
new.cluster.ids <- c("Naive CD4 T", "CD14+ Mono", "Memory CD4 T", "B", "CD8 T", "FCGR3A+ Mono",
    "NK", "DC", "Platelet")
names(new.cluster.ids) <- levels(pbmc)
pbmc <- RenameIdents(pbmc, new.cluster.ids)
DimPlot(pbmc, reduction = "umap", label = TRUE, pt.size = 0.5) + NoLegend()
```

Example 172 (unknown):
```unknown
saveRDS(pbmc, file = "../output/pbmc3k_final.rds")
```

Example 173 (r):
```r
saveRDS(pbmc, file = "../output/pbmc3k_final.rds")
```

Example 174 (r):
```r
saveRDS(pbmc, file = "../output/pbmc3k_final.rds")
```

Example 175 (unknown):
```unknown
sessionInfo()
```

Example 176 (r):
```r
sessionInfo()
```

Example 177 (r):
```r
sessionInfo()
```

Example 178 (unknown):
```unknown
## R version 4.2.0 (2022-04-22)
## Platform: x86_64-pc-linux-gnu (64-bit)
## Running under: Ubuntu 20.04.5 LTS
## 
## Matrix products: default
## BLAS:   /usr/lib/x86_64-linux-gnu/openblas-pthread/libblas.so.3
## LAPACK: /usr/lib/x86_64-linux-gnu/openblas-pthread/liblapack.so.3
## 
## locale:
##  [1] LC_CTYPE=en_US.UTF-8       LC_NUMERIC=C              
##  [3] LC_TIME=en_US.UTF-8        LC_COLLATE=en_US.UTF-8    
##  [5] LC_MONETARY=en_US.UTF-8    LC_MESSAGES=en_US.UTF-8   
##  [7] LC_PAPER=en_US.UTF-8       LC_NAME=C                 
##  [9] LC_ADDRESS=C               LC_TELEPHONE=C            
## [11] LC_MEASUREMENT=en_US.UTF-8 LC_IDENTIFICATION=C       
## 
## attached base packages:
## [1] stats     graphics  grDevices utils     datasets  methods   base     
## 
## other attached packages:
## [1] ggplot2_3.4.1      patchwork_1.1.2    SeuratObject_4.1.3 Seurat_4.3.0      
## [5] dplyr_1.1.0       
## 
## loaded via a namespace (and not attached):
##   [1] Rtsne_0.16             colorspace_2.1-0       deldir_1.0-6          
##   [4] ellipsis_0.3.2         ggridges_0.5.4         rprojroot_2.0.3       
##   [7] fs_1.6.1               spatstat.data_3.0-0    farver_2.1.1          
##  [10] leiden_0.4.3           listenv_0.9.0          ggrepel_0.9.3         
##  [13] fansi_1.0.4            R.methodsS3_1.8.2      codetools_0.2-18      
##  [16] splines_4.2.0          cachem_1.0.7           knitr_1.42            
##  [19] polyclip_1.10-4        jsonlite_1.8.4         ica_1.0-3             
##  [22] cluster_2.1.3          R.oo_1.25.0            png_0.1-8             
##  [25] uwot_0.1.14            spatstat.sparse_3.0-0  shiny_1.7.4           
##  [28] sctransform_0.3.5      compiler_4.2.0         httr_1.4.5            
##  [31] Matrix_1.5-3           fastmap_1.1.1          lazyeval_0.2.2        
##  [34] limma_3.54.1           cli_3.6.0              later_1.3.0           
##  [37] formatR_1.14           htmltools_0.5.4        tools_4.2.0           
##  [40] igraph_1.4.1           gtable_0.3.1           glue_1.6.2            
##  [43] RANN_2.6.1             reshape2_1.4.4         Rcpp_1.0.10           
##  [46] scattermore_0.8        jquerylib_0.1.4        pkgdown_2.0.7         
##  [49] vctrs_0.5.2            nlme_3.1-157           spatstat.explore_3.0-6
##  [52] progressr_0.13.0       lmtest_0.9-40          spatstat.random_3.1-3 
##  [55] xfun_0.37              stringr_1.5.0          globals_0.16.2        
##  [58] mime_0.12              miniUI_0.1.1.1         lifecycle_1.0.3       
##  [61] irlba_2.3.5.1          goftest_1.2-3          future_1.31.0         
##  [64] MASS_7.3-56            zoo_1.8-11             scales_1.2.1          
##  [67] ragg_1.2.5             promises_1.2.0.1       spatstat.utils_3.0-1  
##  [70] parallel_4.2.0         RColorBrewer_1.1-3     yaml_2.3.7            
##  [73] memoise_2.0.1          reticulate_1.28        pbapply_1.7-0         
##  [76] gridExtra_2.3          sass_0.4.5             stringi_1.7.12        
##  [79] highr_0.10             desc_1.4.2             rlang_1.0.6           
##  [82] pkgconfig_2.0.3        systemfonts_1.0.4      matrixStats_0.63.0    
##  [85] evaluate_0.20          lattice_0.20-45        tensor_1.5            
##  [88] ROCR_1.0-11            purrr_1.0.1            labeling_0.4.2        
##  [91] htmlwidgets_1.6.1      cowplot_1.1.1          tidyselect_1.2.0      
##  [94] parallelly_1.34.0      RcppAnnoy_0.0.20       plyr_1.8.8            
##  [97] magrittr_2.0.3         R6_2.5.1               generics_0.1.3        
## [100] withr_2.5.0            pillar_1.8.1           fitdistrplus_1.1-8    
## [103] abind_1.4-5            survival_3.3-1         sp_1.6-0              
## [106] tibble_3.1.8           future.apply_1.10.0    crayon_1.5.2          
## [109] KernSmooth_2.23-20     utf8_1.2.3             spatstat.geom_3.0-6   
## [112] plotly_4.10.1          rmarkdown_2.20         grid_4.2.0            
## [115] data.table_1.14.8      digest_0.6.31          xtable_1.8-4          
## [118] tidyr_1.3.0            httpuv_1.6.9           R.utils_2.12.2        
## [121] textshaping_0.3.6      munsell_0.5.0          viridisLite_0.4.1     
## [124] bslib_0.4.2
```

Example 179 (unknown):
```unknown
## R version 4.2.0 (2022-04-22)
## Platform: x86_64-pc-linux-gnu (64-bit)
## Running under: Ubuntu 20.04.5 LTS
## 
## Matrix products: default
## BLAS:   /usr/lib/x86_64-linux-gnu/openblas-pthread/libblas.so.3
## LAPACK: /usr/lib/x86_64-linux-gnu/openblas-pthread/liblapack.so.3
## 
## locale:
##  [1] LC_CTYPE=en_US.UTF-8       LC_NUMERIC=C              
##  [3] LC_TIME=en_US.UTF-8        LC_COLLATE=en_US.UTF-8    
##  [5] LC_MONETARY=en_US.UTF-8    LC_MESSAGES=en_US.UTF-8   
##  [7] LC_PAPER=en_US.UTF-8       LC_NAME=C                 
##  [9] LC_ADDRESS=C               LC_TELEPHONE=C            
## [11] LC_MEASUREMENT=en_US.UTF-8 LC_IDENTIFICATION=C       
## 
## attached base packages:
## [1] stats     graphics  grDevices utils     datasets  methods   base     
## 
## other attached packages:
## [1] ggplot2_3.4.1      patchwork_1.1.2    SeuratObject_4.1.3 Seurat_4.3.0      
## [5] dplyr_1.1.0       
## 
## loaded via a namespace (and not attached):
##   [1] Rtsne_0.16             colorspace_2.1-0       deldir_1.0-6          
##   [4] ellipsis_0.3.2         ggridges_0.5.4         rprojroot_2.0.3       
##   [7] fs_1.6.1               spatstat.data_3.0-0    farver_2.1.1          
##  [10] leiden_0.4.3           listenv_0.9.0          ggrepel_0.9.3         
##  [13] fansi_1.0.4            R.methodsS3_1.8.2      codetools_0.2-18      
##  [16] splines_4.2.0          cachem_1.0.7           knitr_1.42            
##  [19] polyclip_1.10-4        jsonlite_1.8.4         ica_1.0-3             
##  [22] cluster_2.1.3          R.oo_1.25.0            png_0.1-8             
##  [25] uwot_0.1.14            spatstat.sparse_3.0-0  shiny_1.7.4           
##  [28] sctransform_0.3.5      compiler_4.2.0         httr_1.4.5            
##  [31] Matrix_1.5-3           fastmap_1.1.1          lazyeval_0.2.2        
##  [34] limma_3.54.1           cli_3.6.0              later_1.3.0           
##  [37] formatR_1.14           htmltools_0.5.4        tools_4.2.0           
##  [40] igraph_1.4.1           gtable_0.3.1           glue_1.6.2            
##  [43] RANN_2.6.1             reshape2_1.4.4         Rcpp_1.0.10           
##  [46] scattermore_0.8        jquerylib_0.1.4        pkgdown_2.0.7         
##  [49] vctrs_0.5.2            nlme_3.1-157           spatstat.explore_3.0-6
##  [52] progressr_0.13.0       lmtest_0.9-40          spatstat.random_3.1-3 
##  [55] xfun_0.37              stringr_1.5.0          globals_0.16.2        
##  [58] mime_0.12              miniUI_0.1.1.1         lifecycle_1.0.3       
##  [61] irlba_2.3.5.1          goftest_1.2-3          future_1.31.0         
##  [64] MASS_7.3-56            zoo_1.8-11             scales_1.2.1          
##  [67] ragg_1.2.5             promises_1.2.0.1       spatstat.utils_3.0-1  
##  [70] parallel_4.2.0         RColorBrewer_1.1-3     yaml_2.3.7            
##  [73] memoise_2.0.1          reticulate_1.28        pbapply_1.7-0         
##  [76] gridExtra_2.3          sass_0.4.5             stringi_1.7.12        
##  [79] highr_0.10             desc_1.4.2             rlang_1.0.6           
##  [82] pkgconfig_2.0.3        systemfonts_1.0.4      matrixStats_0.63.0    
##  [85] evaluate_0.20          lattice_0.20-45        tensor_1.5            
##  [88] ROCR_1.0-11            purrr_1.0.1            labeling_0.4.2        
##  [91] htmlwidgets_1.6.1      cowplot_1.1.1          tidyselect_1.2.0      
##  [94] parallelly_1.34.0      RcppAnnoy_0.0.20       plyr_1.8.8            
##  [97] magrittr_2.0.3         R6_2.5.1               generics_0.1.3        
## [100] withr_2.5.0            pillar_1.8.1           fitdistrplus_1.1-8    
## [103] abind_1.4-5            survival_3.3-1         sp_1.6-0              
## [106] tibble_3.1.8           future.apply_1.10.0    crayon_1.5.2          
## [109] KernSmooth_2.23-20     utf8_1.2.3             spatstat.geom_3.0-6   
## [112] plotly_4.10.1          rmarkdown_2.20         grid_4.2.0            
## [115] data.table_1.14.8      digest_0.6.31          xtable_1.8-4          
## [118] tidyr_1.3.0            httpuv_1.6.9           R.utils_2.12.2        
## [121] textshaping_0.3.6      munsell_0.5.0          viridisLite_0.4.1     
## [124] bslib_0.4.2
```

---
