This R notebook enables the reproduction of the analysis described in:
Tzani et al. Tracing production instability in a clonally-derived CHO cell line using single cell transcriptomics (2020) bioRxiv
In this study, the four biological replicates of a clonally derived CHO cell line were sampled at 72hrs post-seeding and analysed on the BD Rhapsody system whole transcriptome analysis. The FASTQ data were converted to a cell gene count matrix using the Seven Bridges Genomics BD Rhapsody WTA pipeline and combined into a single sample.
The FASTQ files for this study are available from the NCBI Sequence Read Archive ID: PRJNA661407
The associated github repository can be found here
package_list <- c("monocle", "plyr", "dplyr", "ggExtra", "reshape",
"colorRamps", "stringr", "BioParallel", "ggpubr", "DT", "WebGestaltR",
"ggalt", "biomaRt", "patchwork", "viridis", "gridExtra",
"grid", "gganimate", "hrbthemes", "jcolors", "cowplot", "data.table",
"GGally", "ggplotify", "writexl", "Seurat")
lapply(package_list, require, character.only = TRUE)
Here we set a seed to facilitate the reproducibility of the analysis
# set a seed for reproducibility
set.seed(38)
# ggplot theme
theme_ms <- function(base_size = 10, base_family = "Helvetica") {
library(grid)
(theme_bw(base_size = base_size, base_family = base_family) +
theme(text = element_text(color = "black"), axis.title = element_text(face = "bold",
size = rel(1)), plot.title = element_text(face = "bold",
size = rel(1)), axis.text = element_text(size = rel(1),
color = "black"), legend.title = element_text(face = "bold"),
legend.text = element_text(face = "bold"), legend.background = element_rect(fill = "transparent"),
legend.key.size = unit(0.8, "lines"), panel.border = element_rect(color = "black",
size = 1), panel.grid = element_blank()))
}
# pallette for groups
colour.set <- c("#29BF12", "#009ACD", "#B1740F", "#DB2763", "#9A32CD",
"#628395", "#17377A", "#E5C616", "#FF7844", "#E48F1B")
# color for expression values
color.gradient <- scale_color_gradientn(colors = matlab.like(200),
trans = "log10")
# create a directory for saving figures
figsdir <- "./figures/"
if (!dir.exists(figsdir)) {
dir.create(figsdir)
}
# function to save figures
saveManuscriptPlot <- function(p, width, height) {
figfile <- file.path(figsdir, sprintf("%s.png", gsub("\\.",
"_", deparse(substitute(p)))))
ggsave(figfile, plot = p, width = width, height = height,
units = "in", device = "png")
}
Create a function to determine the relative expression of a gene from a Monocle cell dataset. When the expression of a gene is than the detection limit, the gene is equal to the detection limit.
monocle_relative_expression <- function(cds, gene) {
normalized_expression <- t(exprs(cds[gene, ]))/sizeFactors(cds)
normalized_expression[normalized_expression < cds@lowerDetectionLimit] <- cds@lowerDetectionLimit
return(normalized_expression)
}
We import data from the Seven Bridges Genomics (SBG) platform for analysis in R. The UMI data for each replicate is stored in a separate CSV file with each row representing an individual cell, the column represents a gene. In this experiment, 4 biological replicates for the CHOK1 DP12 cell line were analysed using Rhapsody WTA. We create a batch ID than be used to regress any technical variation due to batch. We determine the genes detected in at least one replicate. If a gene is not detected in a replicate we assign a 0 UMI value for that replicate. The replicates are then combined in a single matrix.
raw_umi_r1 <- read.table("scrnaseq_data/CHOK1DP12_r1.csv", sep = ",",
header = T, row.names = 1, check.names = FALSE)
raw_umi_r1_batch <- rep("rep1", dim(raw_umi_r1)[1])
raw_umi_r2 <- read.table("scrnaseq_data/CHOK1DP12_r2.csv", sep = ",",
header = T, row.names = 1, check.names = FALSE)
raw_umi_r2_batch <- rep("rep2", dim(raw_umi_r2)[1])
raw_umi_r3 <- read.table("scrnaseq_data/CHOK1DP12_r3.csv", sep = ",",
header = T, row.names = 1, check.names = FALSE)
raw_umi_r3_batch <- rep("rep3", dim(raw_umi_r3)[1])
raw_umi_r4 <- read.table("scrnaseq_data/CHOK1DP12_r4.csv", sep = ",",
header = T, row.names = 1, check.names = FALSE)
raw_umi_r4_batch <- rep("rep4", dim(raw_umi_r4)[1])
# determine the genes detected in at least 1 replicate
detected_genes <- unique(c(colnames(raw_umi_r1), colnames(raw_umi_r2),
colnames(raw_umi_r3), colnames(raw_umi_r4)))
unique_genes <- unique(detected_genes)
# add a 0 column if gene is not detected in that replicate
raw_umi_r1[, setdiff(detected_genes, colnames(raw_umi_r1))] <- 0
raw_umi_r2[, setdiff(detected_genes, colnames(raw_umi_r2))] <- 0
raw_umi_r3[, setdiff(detected_genes, colnames(raw_umi_r3))] <- 0
raw_umi_r4[, setdiff(detected_genes, colnames(raw_umi_r4))] <- 0
raw_umi <- rbind(raw_umi_r1, raw_umi_r2, raw_umi_r3, raw_umi_r4)
# add text to cell label for Monocle compatability later
rownames(raw_umi) <- str_c("cell_", rownames(raw_umi)) # add text to ensure comparability with monocle plotting later
raw_umi_batch <- c(raw_umi_r1_batch, raw_umi_r2_batch, raw_umi_r3_batch,
raw_umi_r4_batch) # record which Rhapsody cartridge the data came from
The primary analysis package for this analysis Monocle v2 . To use Monocle we must first create a cell dataset (CDS) object containing the UMI data. During this process we assign a detection limit along with the expressionFamily - in this case negbinomial().
pheno.data <- rep("cho", dim(raw_umi)[1])
pheno.data.df <- data.frame(type = pheno.data, batch = raw_umi_batch)
rownames(pheno.data.df) <- rownames(raw_umi)
pd <- new("AnnotatedDataFrame", data = pheno.data.df)
f.data <- colnames(raw_umi)
f.data.df <- data.frame(type = f.data) # Must be data frame object
rownames(f.data.df) <- colnames(raw_umi)
fd <- new("AnnotatedDataFrame", data = f.data.df)
cells <- new("CellDataSet", exprs = t(raw_umi), phenoData = pd,
featureData = fd, lowerDetectionLimit = 0.5, expressionFamily = negbinomial())
paste("Raw data for", dim(cells)[2], "and", dim(cells)[1], " genes captured")
[1] "Raw data for 4673 and 20594 genes captured"
To compare a matched bulkRNASeq dataset to our single cell data were calculated a gene-level transcripts per million (TPM) value using Kallisto.
# import the TPM results from Kalisto for the four matched bulk samples
bulk_tpm <- read.table("bulkrnaseq_data/gene_mab_tpms_all_samples.tsv",
header = T, row.names = 1)
# separate the bulk samples from the Kalisto TPM output and convert to log(tpm+1)
bulk_tpm_r1 <- log((bulk_tpm[, 2]) + 1)
names(bulk_tpm_r1) <- rownames(bulk_tpm)
bulk_tpm_r2 <- log((bulk_tpm[, 3]) + 1)
names(bulk_tpm_r2) <- rownames(bulk_tpm)
bulk_tpm_r3 <- log((bulk_tpm[, 4]) + 1)
names(bulk_tpm_r3) <- rownames(bulk_tpm)
bulk_tpm_r4 <- log((bulk_tpm[, 5]) + 1)
names(bulk_tpm_r4) <- rownames(bulk_tpm)
# determine the correlation between each of the scRNASeq samples
bulk_tpm <- data.frame(cbind(bulk_tpm_r1, bulk_tpm_r2, bulk_tpm_r3,
bulk_tpm_r4))
# rename the columns for each replicate
colnames(bulk_tpm) <- c("Replicate 1", "Replicate 2", "Replicate 3",
"Replicate 4")
To compare to the bulk RNASeq data we merge the scRNASeq to pseudoBulk profiles, 1 for each replicate and convert expression to TPM. We then determine the agreement between the replicates
# separate the scRNA by Rhapsody cartridge from the monocle CDS sum the UMI counts and convert to log(TPM+1)
pseudocounts_r1 <- rowSums(exprs(cells)[, pData(cells)$batch ==
"rep1"])
pseudocounts_r2 <- rowSums(exprs(cells)[, pData(cells)$batch ==
"rep2"])
pseudocounts_r3 <- rowSums(exprs(cells)[, pData(cells)$batch ==
"rep3"])
pseudocounts_r4 <- rowSums(exprs(cells)[, pData(cells)$batch ==
"rep4"])
# create logged pseduobulk TPM
norm_pseudocounts_r1 <- log(((pseudocounts_r1)/sum(pseudocounts_r1/1e+06)) +
1)
norm_pseudocounts_r2 <- log(((pseudocounts_r2)/sum(pseudocounts_r2/1e+06)) +
1)
norm_pseudocounts_r3 <- log(((pseudocounts_r3)/sum(pseudocounts_r3/1e+06)) +
1)
norm_pseudocounts_r4 <- log(((pseudocounts_r4)/sum(pseudocounts_r4/1e+06)) +
1)
# determine the correlation between each of the scRNASeq samples
norm_pseudocounts <- data.frame(cbind(norm_pseudocounts_r1, norm_pseudocounts_r2,
norm_pseudocounts_r3, norm_pseudocounts_r4))
colnames(norm_pseudocounts) <- c("Replicate 1", "Replicate 2",
"Replicate 3", "Replicate 4")
fig.cor.scRNASeq <- ggpairs(norm_pseudocounts, lower = list(continuous = wrap("points",
alpha = 0.3, size = 0.01), combo = wrap("dot", alpha = 0.4,
size = 0.2))) + theme_ms() + theme(panel.spacing = grid::unit(1,
"lines"))
# save the plot for Supplementary Figure 1
s.fig1 <- fig.cor.scRNASeq
saveManuscriptPlot(s.fig1, 8, 8)
s.fig1
Determine the agreement between the bulkRNASeq replicates
fig.cor.bulkRNASeq <- ggpairs(bulk_tpm, lower = list(continuous = wrap("points",
alpha = 0.3, size = 0.01), combo = wrap("dot", alpha = 0.4,
size = 0.2))) + theme_ms() + theme(panel.spacing = grid::unit(1,
"lines"))
s.fig2 <- fig.cor.bulkRNASeq
saveManuscriptPlot(s.fig2, 8, 8)
s.fig2
Comparison of each scRNASeq sample to it’s respective matched bulkRNASeq sample.
# annotate the genes with biomaRt
ensembl <- useMart(host = "http://sep2019.archive.ensembl.org",
biomart = "ENSEMBL_MART_ENSEMBL", dataset = "cgpicr_gene_ensembl")
picr_annotation <- getBM(attributes = c("ensembl_gene_id", "entrezgene_id",
"external_gene_name", "description", "gene_biotype"), filters = c("ensembl_gene_id"),
values = rownames(bulk_tpm), mart = ensembl, uniqueRows = TRUE)
# the seven bridges genomics pipeline outputs both symbols and ens gene ids get the ids that are matched to gene symbols in the cds
symbols_cds <- as.character(fData(cells)$type[grep("ENSCGR",
fData(cells)$type, invert = TRUE)])
matched_to_cds_symbols <- picr_annotation[as.character(picr_annotation$external_gene_name) %in%
fData(cells)$type, ]
matched_to_cds_symbols <- unique(setDT(matched_to_cds_symbols),
by = c("ensembl_gene_id", "external_gene_name"))
matched_to_cds_symbols <- matched_to_cds_symbols[, c(1, 3)]
# ensembl ids are common to bulk and scRNASeq
ensembl_cds <- as.character(fData(cells)$type[grep("ENSCGR",
fData(cells)$type)])
# the PICR geneome has no MT chromosome, add the ensembl ids for the CHOK1 mtDNA genome
mito.genes <- c("ND1", "ND2", "COX1", "COX2", "ATP8", "ATP6",
"COX3", "ND3", "ND4L", "ND4", "ND5", "ND6", "CYTB")
mito.ensembl <- c("ENSCGRG00000000006", "ENSCGRG00000000010",
"ENSCGRG00000000016", "ENSCGRG00000000019", "ENSCGRG00000000021",
"ENSCGRG00000000022", "ENSCGRG00000000023", "ENSCGRG00000000025",
"ENSCGRG00000000027", "ENSCGRG00000000028", "ENSCGRG00000000032",
"ENSCGRG00000000033", "ENSCGRG00000000035")
# create the ids for both datasets and include the mAb genes
cds_ids <- c(matched_to_cds_symbols$external_gene_name, ensembl_cds,
"heavy_chain", "light_chain", mito.genes)
bulk_ids <- c(matched_to_cds_symbols$ensembl_gene_id, ensembl_cds,
"heavy_chain", "light_chain", mito.ensembl)
# determine the density of points to colour plot
density_r1 <- densCols(bulk_tpm_r1[bulk_ids], norm_pseudocounts_r1[cds_ids],
colramp = colorRampPalette(rev(rainbow(10, end = 4/6))),
nbin = 64)
density_r2 <- densCols(bulk_tpm_r2[bulk_ids], norm_pseudocounts_r2[cds_ids],
colramp = colorRampPalette(rev(rainbow(10, end = 4/6))),
nbin = 64)
density_r3 <- densCols(bulk_tpm_r3[bulk_ids], norm_pseudocounts_r3[cds_ids],
colramp = colorRampPalette(rev(rainbow(10, end = 4/6))),
nbin = 64)
density_r4 <- densCols(bulk_tpm_r4[bulk_ids], norm_pseudocounts_r4[cds_ids],
colramp = colorRampPalette(rev(rainbow(10, end = 4/6))),
nbin = 64)
# create the data frame for the plot
bulk_sc_cor_df <- data.frame(replicate = c(rep("Replicate 1",
length(bulk_ids)), rep("Replicate 2", length(bulk_ids)),
rep("Replicate 3", length(bulk_ids)), rep("Replicate 4",
length(bulk_ids))), bulk_tpm = c(bulk_tpm_r1[bulk_ids],
bulk_tpm_r2[bulk_ids], bulk_tpm_r3[bulk_ids], bulk_tpm_r4[bulk_ids]),
scrnaseq_tpm = c(norm_pseudocounts_r1[cds_ids], norm_pseudocounts_r1[cds_ids],
norm_pseudocounts_r1[cds_ids], norm_pseudocounts_r1[cds_ids]),
density = c(density_r1, density_r2, density_r3, density_r4))
fig.scatter.sc.v.bulk <- bulk_sc_cor_df %>% ggplot() + geom_point(aes(x = bulk_tpm,
y = scrnaseq_tpm, col = density), size = 0.1) + scale_color_identity() +
stat_cor(method = "pearson", aes(x = bulk_tpm, y = scrnaseq_tpm),
inherit.aes = TRUE) + facet_wrap(~replicate) + theme_ms() +
labs(x = "Bulk RNASeq Log(TPM+1)", y = "Pseudobulk RNASeq Log(TPM+1)") +
theme(strip.background = element_blank())
s.fig3 <- fig.scatter.sc.v.bulk
saveManuscriptPlot(s.fig3, 8, 8)
s.fig3
The first stage of preprocessing in the Monocle workflow aims to eliminate poor quality cells from further analysis. In this section we calculate metrics to enable filtering of poor quality cells from the analysis - total UMIs, and fraction of UMIs that originate from mitochondrial genes.
Cells that have too few UMIs per cells as well as those that have too many UMIs per cell are removed from the analysis.
# determine the sum of UMIs captured for each cell
pData(cells)$total.mRNAs <- Matrix::colSums(exprs(cells))
# determine the average number of UMIs captured per cell
pData(cells)$sample.mean.mRNAs <- mean(pData(cells)$total.mRNAs)
# set the limits
pData(cells)$lower.bound <- pData(cells)$sample.mean.mRNAs/2.5
pData(cells)$upper.bound <- pData(cells)$sample.mean.mRNAs *
2.5
# identify cells passing the filter
total_mRNA_passed <- row.names(subset(pData(cells), total.mRNAs >
lower.bound[1] & total.mRNAs < upper.bound[1]))
# plot the distribution of all cells and the filters used
fig.total.mRNA <- ggplot(data = pData(cells)$totalmRNAs, aes(pData(cells)$total.mRNAs)) +
geom_histogram(binwidth = 200, fill = "#084594") + geom_vline(xintercept = pData(cells)$lower.bound[1],
linetype = "dashed", color = "red", size = 0.75) + geom_vline(xintercept = pData(cells)$upper.bound[1],
linetype = "dashed", color = "red", size = 0.75) + xlab("Total UMIs") +
ylab("Number of cells") + theme_ms() + theme(axis.text = element_text(size = rel(1)),
axis.title = element_text(face = "bold", size = rel(1)))
fig1.b <- fig.total.mRNA
saveManuscriptPlot(fig1.b, 6, 6)
fig1.b
A cell with >= 15% of the total UMIs originating from mitochondrial genes is removed.
# determine the fraction of UMIs from mito mRNAs
pData(cells)$mito.mRNAs <- Matrix::colSums(exprs(cells[row.names(subset(fData(cells),
rownames(fData(cells)) %in% mito.genes)), ]))
pData(cells)$frac.mito.mRNAs <- pData(cells)$mito.mRNAs/pData(cells)$total.mRNAs # percentage of total UMIs from mtDNA
# filter
mito_mRNA_passed <- row.names(subset(pData(cells), frac.mito.mRNAs <
0.15)) # the cells with < 15% of UMIs from mtDNA
fig.mtDNA.frac <- pData(cells) %>% group_by(as.factor(raw_umi_batch)) %>%
dplyr::select(frac.mito.mRNAs) %>% ggplot(aes(y = frac.mito.mRNAs,
x = as.factor(raw_umi_batch), fill = as.factor(raw_umi_batch))) +
geom_violin(show.legend = FALSE) + geom_point(position = "jitter",
alpha = 0.2, size = 0.01, color = "black") + geom_hline(yintercept = 0.15,
linetype = "dashed", color = "red", size = 1) + ylab("Mitochondrial UMIs (%)") +
xlab(" ") + scale_y_continuous(labels = scales::percent) +
scale_x_discrete(labels = c(rep1 = "Rep 1", rep2 = "Rep 2",
rep3 = "Rep 3", rep4 = "Rep 4")) + theme_ms() + theme(legend.position = "none",
axis.text = element_text(size = rel(1)), axis.title = element_text(face = "bold",
size = rel(1))) + scale_fill_jcolors("pal3")
fig1.c <- fig.mtDNA.frac
saveManuscriptPlot(fig1.c, 6, 6)
fig1.c
# IDs of cells passing both criteria
qc_passed_cells <- intersect(mito_mRNA_passed, total_mRNA_passed)
# retain cells passsing
cells.filter <- cells[, qc_passed_cells]
# plot for each replicate
total_cells <- table(pData(cells)$batch)
qc_passed_cells <- table(pData(cells.filter)$batch)
filtered_cells <- total_cells - qc_passed_cells
df_qc <- t(rbind(qc_passed_cells, filtered_cells))
dat.m <- melt(df_qc)
qc_df <- dat.m %>%
dplyr::group_by(Var1) %>%
dplyr::arrange(Var1, desc(Var2)) %>%
dplyr::mutate(lab_ypos = cumsum(value) - 0.5 * value)
fig.cells.removed <- ggplot(data = qc_df, aes(x = Var1, y = value)) +
geom_col(aes(fill = Var2), width = 0.7, position = position_stack(reverse = TRUE)) +
theme(
legend.title = element_blank(),
legend.position = "top",
panel.background = element_blank(),
axis.line.y = element_line(),
axis.text.x = element_text(face = "bold")
) +
scale_y_continuous(limits = c(0, 1500)) +
labs(x = " ", y = "Number of cells") +
scale_x_discrete(labels = c(
"rep1" = "Rep 1", "rep2" = "Rep 2",
"rep3" = "Rep 3", "rep4" = "Rep 4"
)) +
theme_ms() +
theme(legend.position = "none", axis.text = element_text(size = rel(1)), axis.title = element_text(face = "bold", size = rel(1))) +
theme(
legend.title = element_blank(),
legend.position = (c(.75, .94))
# legend.text = element_text(size = 12)
) +
scale_fill_manual(values = c("#3CA437", "#D7263D"), labels = c("Passed", "Removed"))
fig1.d <- fig.cells.removed
saveManuscriptPlot(fig1.d, 6, 6)
fig1.d
We now remove genes that are not expressed in more than 50 cells in our dataset or the maximum expression is less than 2 UMIs in any cell
cells.filter <- estimateSizeFactors(cells.filter)
cells.filter <- estimateDispersions(cells.filter)
cells.filter <- detectGenes(cells.filter, min_expr = 0.1)
cells.filter <- cells.filter[row.names(subset(fData(cells.filter),
num_cells_expressed > 100)), ]
fData(cells.filter)$max.expression <- cells.filter %>% exprs() %>%
(qlcMatrix::rowMax) %>% as.double()
max.expr.cutoff <- 4
cells.filter <- cells.filter[row.names(subset(fData(cells.filter),
max.expression > max.expr.cutoff)), ]
# remove mitochondrial genes from the analysis
cells.filter <- cells.filter[!row.names(subset(fData(cells.filter))) %in%
mito.genes, ]
fig.genes.expression <- ggplot(data = pData(cells)$num_genes_expressed,
aes(pData(cells.filter)$num_genes_expressed)) + geom_histogram(binwidth = 15,
fill = "#084594") + theme_ms() + xlab("Detected genes") +
ylab("Number of cells") + theme(legend.position = "none",
axis.text = element_text(size = rel(1)), axis.title = element_text(face = "bold",
size = rel(1)))
fig1.e <- fig.genes.expression
saveManuscriptPlot(fig1.e, 6, 6)
fig1.e
p1 <- (ggplot() + theme_void() + labs(tag = "(a)"))/(ggplot() +
theme_void())
p2 <- (ggplot() + theme_void())/(ggplot() + theme_void())
p3 <- (fig1.b + labs(tag = "(b)"))/(fig1.d + labs(tag = "(d)"))
p4 <- (fig1.c + labs(tag = "(c)"))/(fig1.e + labs(tag = "(e)"))
figure1 <- p1 | p2 | p3 | p4
# figure1 <- figure1 + plot_annotation(tag_levels = 'a',tag_prefix = '(', tag_suffix = ')') + plot_annotation(tag_levels = 'a',tag_prefix = '(', tag_suffix = ')')
saveManuscriptPlot(figure1, 12, 8)
The SBG platform utilises the ENSEMBL GTF file for the PICR genome. To improve the annotation of the genes we utlise the corresponding Entrez IDs for those genes labelled with and “ENSCGRG” IDs to obtain a gene symbol
# set bioMart
ensembl <- useMart(host = "http://sep2019.archive.ensembl.org",
biomart = "ENSEMBL_MART_ENSEMBL", dataset = "cgpicr_gene_ensembl")
# make a gene_short_name column for the CDS object
fData(cells.filter)$gene_short_name <- rownames(cells.filter)
# how many of the genes have no gene symbol sum(str_count(fData(cells.filter)$gene_short_name, 'ENSCGR*'))
unannotated <- fData(cells.filter)$gene_short_name[grep("ENSCGR",
fData(cells.filter)$gene_short_name)]
# biomart query
annotation <- getBM(attributes = c("ensembl_gene_id", "entrezgene_id",
"external_gene_name", "description", "gene_biotype"), filters = c("ensembl_gene_id"),
values = unannotated, mart = ensembl, uniqueRows = TRUE)
# store the final annotation
annotation$final <- "Unannotated"
# 1) add the ensembl annotated external gene names to final columns annotation$final[!annotation$external_gene_name == ''] <- annotation$external_gene_name[!annotation$external_gene_name == '']
# 2) where we have no external gene name from ensembl but we do have an entrez ID
match_entrez_ids <- annotation %>% dplyr::filter(!is.na(entrezgene_id))
# load NCBI annotations
cgr_entrez <- readLines("./genelists/cgr_ncbi_ids.txt")
# match entrezID
split_gene_info <- strsplit(cgr_entrez[grepl(paste(match_entrez_ids[,
2], collapse = "|"), cgr_entrez)], "\t")
# extract the matched symbols
entrez_matched <- cbind(sapply(split_gene_info, "[", 2), sapply(split_gene_info,
"[", 3))
colnames(entrez_matched) <- c("entrez_gene_id", "symbol")
# add the symbols to the annotation
annotation$final[match(entrez_matched[, 1], annotation$entrezgene_id)] <- entrez_matched[,
2]
# add the new annotations to the CDS object
fData(cells.filter)$gene_short_name[match(annotation$ensembl_gene_id,
fData(cells.filter)$gene_short_name)] <- annotation$final
For the next section we used the cell cycle scoring function of Seurat to determine which phase of the cell cycles cells were in. Using this function will allow us to correct the effect of cell cycle in subsequent analyses.
# extract the raw counts from the cds and make a Seurat oject containing the batch variable
cho.obj <- CreateSeuratObject(counts = exprs(cells.filter), project = "chok1_dp12",
min.cells = 3, min.features = 200)
cho.obj <- AddMetaData(object = cho.obj, metadata = pData(cells.filter)$batch,
col.name = "batch")
Before scoring cells by the cell cycle phase any variation due to batch is removed
Here we use custom CHO cell genes involved in cell cycle
s.genes <- read.table("./genelists/cho.s.txt", stringsAsFactors = F)
g2m.genes <- read.table("./genelists/cho.g2m.txt", stringsAsFactors = F)
# run the seurat cell cycle scoring module
cho.obj <- CellCycleScoring(cho.obj, s.features = s.genes$V1,
g2m.features = g2m.genes$V1, set.ident = TRUE)
pData(cells.filter)$S.Score <- cho.obj$S.Score
pData(cells.filter)$G2M.Score <- cho.obj$G2M.Score
pData(cells.filter)$cc_phase <- cho.obj$Phase
To conduct an exploratory analysis of CHO K1 DP12N1 scRNASeq data we perform an unsupervised dimensionality reduction and visualisation using t-Stocastic neighbour embedding (t-SNE).
Identify the most variable genes in the scRNASeq dataset.
options(warn = -1) # suppress warnings that otherwise clutter output
#' prioritize variable genes for the analysis
disp_table <- dispersionTable(cells.filter)
unsup_clustering_genes <- subset(disp_table, mean_expression >
0.1)
cells.filter <- setOrderingFilter(cells.filter, unsup_clustering_genes$gene_id)
fig.variable.genes <- plot_ordering_genes(cells.filter) + theme_ms() +
theme(aspect.ratio = 1) + xlab("Mean Expression") + ylab("Dispersion") +
theme(aspect.ratio = 1, axis.text = element_text(size = rel(1)),
axis.title = element_text(face = "bold", size = rel(1)))
fig2.a <- fig.variable.genes
saveManuscriptPlot(fig2.a, 6, 6)
fig2.a
The dimensionality of the single cell expression data was further reduced using principal components analysis (PCA) and following determination of the proportion of variance captured by each component, the first 12 PCs were selected for t-SNE.
fig.pc.variance <- plot_pc_variance_explained(cells.filter, return_all = FALSE) +
geom_vline(xintercept = 12, linetype = "dashed", color = "red",
size = 0.5) + labs(x = "Principal Component", y = "Variance Explained") +
theme_ms() + theme(aspect.ratio = 1, axis.text = element_text(size = rel(1)),
axis.title = element_text(face = "bold", size = rel(1)))
fig2.b <- fig.pc.variance
saveManuscriptPlot(fig2.b, 6, 6)
fig2.b
To account for potential heterogeneity from technical and biological confounding factors, we corrected the UMI count data prior to t-SNE, ensuring that covariation between multiple factors was removed simultaneously. For technical covariates, possible batch effects arising from use of different cell isolation cartridges as well as differences in the total number of UMIs captured and genes detected per cell were regressed out.
cells.filter <- reduceDimension(cells.filter, max_components = 2,
num_dim = 12, reduction_method = "tSNE", verbose = FALSE,
residualModelFormulaStr = "~batch + num_genes_expressed + total.mRNAs + S.Score + G2M.Score",
norm_method = "vstExprs")
The Monocle densityPeak with parameters rho = 2 & delta = 4 is used to identify subclusters in the data. Note: the t-SNE plot with identified clusters is shown below.
cells.filter <- clusterCells(cells.filter, rho_threshold = 2,
delta_threshold = 4, skip_rho_sigma = T)
Distance cutoff calculated to 3.224882
fig.scatter.rho.delta <- plot_rho_delta(cells.filter, rho_threshold = 2,
delta_threshold = 4) + theme_ms() + theme(aspect.ratio = 1)
fig_s_5 <- fig.scatter.rho.delta
saveManuscriptPlot(fig_s_5, 6, 6)
fig_s_5
Here we show the effect of correcting for cell cycle on the t-SNE visualisation.
cells.filter <- reduceDimension(cells.filter, max_components = 2,
num_dim = 12, reduction_method = "tSNE", verbose = FALSE,
residualModelFormulaStr = "~batch + num_genes_expressed + total.mRNAs",
norm_method = "vstExprs")
fig.tsne.cc_uncorrected <- plot_cell_clusters(cells.filter, color = "cc_phase",
cell_size = 0.8) + scale_y_continuous(limits = c(-35, 35)) +
scale_x_continuous(limits = c(-35, 35)) + labs(x = "t-SNE 1",
y = "t-SNE 2") + guides(color = guide_legend(override.aes = list(size = 5))) +
theme_ms() + theme(legend.position = "right", aspect.ratio = 1,
axis.text = element_text(size = rel(1)), axis.title = element_text(face = "bold",
size = rel(1.5)))
fig_s_4a <- fig.tsne.cc_uncorrected
saveManuscriptPlot(fig_s_4a, 6, 6)
fig_s_4a
# correct and repeat with Seurat cc_scores
cells.filter <- reduceDimension(cells.filter, max_components = 2,
num_dim = 12, reduction_method = "tSNE", verbose = FALSE,
residualModelFormulaStr = "~batch + num_genes_expressed + total.mRNAs + S.Score + G2M.Score",
norm_method = "vstExprs")
# show the cell cycle uncorrected
fig.tsne.cc_corrected <- plot_cell_clusters(cells.filter, color = "cc_phase",
cell_size = 0.8) + scale_y_continuous(limits = c(-35, 35)) +
scale_x_continuous(limits = c(-35, 35)) + labs(x = "t-SNE 1",
y = "t-SNE 2") + guides(color = guide_legend(override.aes = list(size = 5))) +
theme_ms() + theme(legend.position = "right", aspect.ratio = 1,
axis.text = element_text(size = rel(1)), axis.title = element_text(face = "bold",
size = rel(1.5)))
fig_s_4b <- fig.tsne.cc_corrected
saveManuscriptPlot(fig_s_4b, 6, 6)
fig_s_4b
Visualiation of cell density in 2D t-SNE plot, show the presence of sub-clusters confirming the presence of transcriptional heterogeneity.
# extract the monocle reduced dimesions
tsne_coordinates <- t(reducedDimA(cells.filter))
df <- data.frame(x = tsne_coordinates[, 1], y = tsne_coordinates[,
2], d = densCols(tsne_coordinates[, 1], tsne_coordinates[,
2], nbin = 64, bandwidth = 1.5, colramp = colorRampPalette(rev(rainbow(10,
end = 4/6)))))
fig.tsne.density <- ggplot(df) + geom_point(aes(x, y, col = d),
size = 0.2) + scale_color_identity() + theme_ms() + theme(aspect.ratio = 1,
panel.grid.major = element_blank(), panel.grid.minor = element_blank(),
axis.text = element_text(size = rel(1)), axis.title = element_text(face = "bold",
size = rel(1))) + scale_y_continuous(limits = c(-35,
35)) + scale_x_continuous(limits = c(-35, 35)) + labs(x = "t-SNE 1",
y = "t-SNE 2")
fig2.c <- fig.tsne.density
saveManuscriptPlot(fig2.c, 6, 6)
fig2.c
To identify groups of cells form the tSNE plot we use densityPeak algorithm. Each cluster is assinged a color for reference.
fig.tsne.cluster <- plot_cell_clusters(cells.filter, color = "Cluster",
cell_size = 0.5) + scale_y_continuous(limits = c(-35, 35)) +
scale_x_continuous(limits = c(-35, 35)) + labs(x = "t-SNE 1",
y = "t-SNE 2") + guides(color = guide_legend(override.aes = list(size = 5))) +
theme_ms() + theme(legend.position = "none", aspect.ratio = 1,
axis.text = element_text(size = rel(1)), axis.title = element_text(face = "bold",
size = rel(1))) + scale_color_jcolors("pal8")
fig2.d <- fig.tsne.cluster
saveManuscriptPlot(fig2.d, 6, 6)
fig2.d
figure2 <- (fig2.a | fig2.b)/(fig2.c | fig2.d) + plot_annotation(tag_levels = "a",
tag_prefix = "(", tag_suffix = ")")
saveManuscriptPlot(figure2, 9, 9)
Using Monocle’s differential gene test the genes that differ between the clusters of cells are identified. We again regress out confounding factors i.e. batch and cell cycle phase
# monocle differential expression by cluster
tictoc::tic()
cluster_de <- differentialGeneTest(cells.filter, fullModelFormulaStr = "~batch + num_genes_expressed + total.mRNAs + S.Score + G2M.Score + Cluster",
reducedModelFormulaStr = "~batch + num_genes_expressed + total.mRNAs + S.Score + G2M.Score",
cores = 32)
tictoc::toc()
472.447 sec elapsed
From the bulk RNASeq data we find that both the heavy and light chain were expressed in the top 2% of all genes. The expression of the light chain (median TPM = 7.9) was higher than that of the heavy chain (median TPM = 6.4).
mab_genes <- c("heavy_chain", "light_chain")
# expression of the mAb genes in bulkRNASeq
bulk_tpm_replicates <- cbind(bulk_tpm_r1[bulk_ids], bulk_tpm_r2[bulk_ids],
bulk_tpm_r3[bulk_ids], bulk_tpm_r4[bulk_ids])
# take the median of the log(TPM+1)
bulk_tpm_median <- data.frame(median_tpm = apply(bulk_tpm_replicates,
1, median))
bulk_tpm_max <- data.frame(median_tpm = apply(bulk_tpm_replicates,
1, max))
bulk_tpm_min <- data.frame(median_tpm = apply(bulk_tpm_replicates,
1, min))
hc_median_tpm <- bulk_tpm_median["heavy_chain", 1]
lc_median_tpm <- bulk_tpm_median["light_chain", 1]
gapdh_median_tpm <- bulk_tpm_median["ENSCGRG00015003621", 1]
actb_median_tpm <- bulk_tpm_median["ENSCGRG00015013883", 1]
fig.density.mab.bulk <- bulk_tpm_median %>% ggplot() + geom_density(aes(x = median_tpm),
fill = "#2E6657", alpha = 0.2) + theme_ms() + # theme(aspect.ratio = 1) +
labs(x = "Log (median bulk TPM +1)") + geom_segment(aes(x = hc_median_tpm,
y = 0, xend = hc_median_tpm, yend = 0.4), linetype = "dashed",
color = "#558aa6", arrow = arrow(length = unit(0.15, "cm"),
ends = "first", type = "closed")) + annotate("text",
x = hc_median_tpm, y = 0.42, label = "Heavy chain", color = "#558aa6") +
geom_segment(aes(x = lc_median_tpm, y = 0, xend = lc_median_tpm,
yend = 0.5), linetype = "dashed", color = "#B1740F",
arrow = arrow(length = unit(0.15, "cm"), ends = "first",
type = "closed")) + annotate("text", x = lc_median_tpm +
0.45, y = 0.52, label = "Light chain", color = "#B1740F") +
geom_segment(aes(x = gapdh_median_tpm, y = 0, xend = gapdh_median_tpm,
yend = 0.6), linetype = "dashed", color = "grey", arrow = arrow(length = unit(0.15,
"cm"), ends = "first", type = "closed")) + annotate("text",
x = gapdh_median_tpm, y = 0.62, label = "Gapdh", color = "grey") +
scale_x_continuous(expand = c(0, 0)) + scale_y_continuous(expand = c(0,
0))
s_fig5 <- fig.density.mab.bulk
saveManuscriptPlot(s_fig5, 12, 6)
s_fig5
Heavy and light chain expression across the population.
# create a relative expression violin plot for the heavy and light chain
pData(cells.filter)$rel.exprs.hc <- monocle_relative_expression(cells.filter,
"heavy_chain")
pData(cells.filter)$rel.exprs.lc <- monocle_relative_expression(cells.filter,
"light_chain")
cds_exprs <- cbind(pData(cells.filter)$rel.exprs.hc, pData(cells.filter)$rel.exprs.lc)
cds_exprs <- reshape2::melt(as.matrix(cds_exprs))
colnames(cds_exprs) <- c("Cell", "Gene", "expression")
# log10 adjust the expression
cds_exprs$adjusted_expression <- log10(cds_exprs$expression)
fig.violin.mab <- ggplot(aes_string(x = "Gene", y = "expression",
fill = "Gene"), data = cds_exprs) + geom_violin(alpha = 0.2) +
geom_boxplot(width = 0.2) + expand_limits(y = c(0.5, 1)) +
scale_y_log10() + scale_fill_jcolors("pal6") + theme(legend.position = "none") +
theme_ms() + scale_x_discrete(labels = c(heavy_chain = "Heavy Chain",
light_chain = "Light Chain")) + # stat_summary(fun.y='median',geom='line', aes(group='f_id', col='grey'), position=position_dodge(width= 0.9)) +
theme(legend.position = "none", aspect.ratio = 1, axis.text = element_text(size = rel(1)),
axis.title = element_text(face = "bold", size = rel(1))) +
labs(y = "Relative expression", x = "") + stat_compare_means(method = "wilcox.test",
label.x = 0.75)
fig3.b <- fig.violin.mab
saveManuscriptPlot(fig3.b, 6, 6)
fig3.b
Light expression visualised in the t-SNE space.
fig.tsne.rel.hc <- plot_cell_clusters(cells.filter, color = "rel.exprs.hc",
cell_size = 0.5) + color.gradient + theme_ms() + theme(panel.grid.major = element_blank(),
panel.grid.minor = element_blank(), legend.position = "right",
aspect.ratio = 1, axis.text = element_text(size = rel(1)),
axis.title = element_text(face = "bold", size = rel(1)),
plot.title = element_text(face = "bold", size = rel(1))) +
scale_y_continuous(limits = c(-35, 35)) + scale_x_continuous(limits = c(-35,
35)) + labs(x = "t-SNE 1", y = "t-SNE 2") + labs(x = "t-SNE 1",
y = "t-SNE 2", color = "Relative\nExpression", title = "Heavy Chain")
fig3.d <- fig.tsne.rel.hc
saveManuscriptPlot(fig3.d, 6, 6)
fig3.d
Assessing the difference in heavy chain expession for the t-SNE clusters.
pData(cells.filter) %>%
group_by(Cluster) %>%
summarise(`Cell number` = n(), `Median relative HC expression` = median(rel.exprs.hc), `Max. expression` = max(rel.exprs.hc)) %>%
DT::datatable(
rownames = T,
options = list(
pagelength = T,
scrollX = T,
columnDefs = list(list(
className = "dt-head-center dt-center",
targets = 1:2
))
)
) %>%
formatSignif(digits = 2, columns = 3:4)
print(paste("Heavy chain DE q-value for cluster = ", signif(cluster_de["heavy_chain", ]$qval, 2)), sep = "")
[1] "Heavy chain DE q-value for cluster = 1.6e-53"
fig.box.hc.cluster <- pData(cells.filter) %>%
group_by(Cluster) %>%
ggplot(aes(x = Cluster, y = rel.exprs.hc, fill = Cluster)) +
geom_violin(alpha = 0.2) +
geom_boxplot(alpha = 0.5, width = 0.2) +
scale_y_log10(limits = c(0.5, 1e2)) +
theme_ms() +
theme(
legend.position = "none",
# aspect.ratio = 1,
axis.text = element_text(size = rel(1)),
axis.title = element_text(face = "bold", size = rel(1)),
plot.title = element_text(size = rel(1))
) +
labs(y = "Relative expression", x = "Cluster", title = "Heavy Chain") +
scale_fill_jcolors("pal8") +
annotate("text", x = "2", y = 75, label = expression("DE q-value = " * 1.6 * " \u00D7 " * 10^{
-53
}))
fig3.f <- fig.box.hc.cluster
saveManuscriptPlot(fig3.f, 6, 3)
fig3.f
Light expression visualised in the t-SNE space.
fig.tsne.rel.lc <- plot_cell_clusters(cells.filter, color = "rel.exprs.lc",
cell_size = 0.5) + color.gradient + theme_ms() + theme(panel.grid.major = element_blank(),
panel.grid.minor = element_blank(), legend.position = "right",
aspect.ratio = 1, axis.text = element_text(size = rel(1)),
axis.title = element_text(face = "bold", size = rel(1)),
plot.title = element_text(face = "bold", size = rel(1))) +
scale_y_continuous(limits = c(-35, 35)) + scale_x_continuous(limits = c(-35,
35)) + labs(x = "t-SNE 1", y = "t-SNE 2") + labs(x = "t-SNE 1",
y = "t-SNE 2", color = "Relative\nExpression", title = "Light Chain")
fig3.e <- fig.tsne.rel.lc
saveManuscriptPlot(fig3.e, 6, 6)
fig3.e
Assessing the difference in heavy chain expession for the t-SNE clusters.
pData(cells.filter) %>%
group_by(Cluster) %>%
summarise(`Cell number` = n(), `Median relative LC expression` = median(rel.exprs.lc), `Max. expression` = max(rel.exprs.lc)) %>%
DT::datatable(
rownames = T,
options = list(
pagelength = T,
scrollX = T,
columnDefs = list(list(
className = "dt-head-center dt-center",
targets = 1:2
))
)
) %>%
formatSignif(digits = 2, columns = 3:4)
print(paste("Light chain DE q-values for cluster = ", signif(cluster_de["light_chain", ]$qval, 2)), sep = "")
[1] "Light chain DE q-values for cluster = 1.3e-36"
fig.box.lc.cluster <- pData(cells.filter) %>%
group_by(Cluster) %>%
ggplot(aes(x = Cluster, y = rel.exprs.lc, fill = Cluster)) +
geom_violin(alpha = 0.2) +
geom_boxplot(alpha = 0.5, width = 0.2) +
scale_y_log10(limits = c(0.5, 1e2)) +
theme_ms() +
theme(
legend.position = "none",
# aspect.ratio = 1,
axis.text = element_text(size = rel(1)),
axis.title = element_text(face = "bold", size = rel(1)),
plot.title = element_text(size = rel(1))
) +
labs(y = "Relative expression", x = "Cluster", title = "Light Chain") +
scale_fill_jcolors("pal8") +
annotate("text", x = "2", y = 75, label = expression("DE q-value = " * 1.3 * " \u00D7 " * 10^{
-36
}))
fig3.g <- fig.box.lc.cluster
saveManuscriptPlot(fig3.g, 6, 3)
fig3.g
Create and save figure 3 for the manuscript.
p1 <- fig3.b | fig2.d + theme(legend.position = "right")
p2 <- fig3.f/fig3.g
p3 <- fig3.d + theme(legend.position = "right") | fig3.e + theme(legend.position = "right")
p4 <- p1/p2/p3
figure3 <- p4 + plot_annotation(tag_levels = "a", tag_prefix = "(",
tag_suffix = ")")
saveManuscriptPlot(figure3, 9, 12)
Using the genes found to vary beteen the identified clusters we first project onto a 2D space using the DDRTree algorithm before ording the cells in pseduotime
de_genes <- cluster_de %>%
arrange(qval) %>%
filter(qval < 0.01)
cells.filter <- setOrderingFilter(cells.filter, de_genes$type)
cells.filter <- reduceDimension(cells.filter,
max_components = 2,
reduction_method = "DDRTree",
residualModelFormulaStr = "~batch + num_genes_expressed + total.mRNAs + S.Score + G2M.Score",
norm_method = "vstExprs"
)
cells.filter <- orderCells(cells.filter)
# cell states are assigned arbitrary numbers, here we reassign #
# to read left to right in the trajectory plot
pData(cells.filter)$State <- mapvalues(pData(cells.filter)$State,
from = c(
"6", "7", "5", "4",
"8", "3", "2", "9", "1"
),
to = c(
"1", "2", "3", "4",
"5", "6", "7", "8", "9"
)
)
pData(cells.filter)$State <- factor(pData(cells.filter)$State,
levels = c("1", "2", "3", "4", "5", "6", "7", "8", "9")
)
fig.trajectory.state <- plot_cell_trajectory(cells.filter,
theta = 0,
show_branch_points = FALSE,
color_by = "State",
cell_size = 0.5
) +
labs(x = "Component 1", y = "Component 2", title = "Monocle trajectory") +
guides(color = guide_legend(override.aes = list(size = 5))) +
theme_ms() +
scale_x_reverse() + # we reverse the direction of the x-axis so that State 1 is at the left
scale_color_manual(values = colour.set) +
scale_alpha(pData(cells.filter)$State) +
theme(
axis.text = element_text(size = rel(1)),
axis.title = element_text(face = "bold", size = rel(1))
)
# modify the transperancy of the cells on the plot
# fig.trajectory.state <- ggplot_build(fig.trajectory.state)
# fig.trajectory.state$data[[2]]$alpha <- 0.3
#
# fig.trajectory.state <- ggplot_gtable(fig.trajectory.state)
fig5.a <- fig.trajectory.state
saveManuscriptPlot(fig5.a, 8, 4)
fig5.a
# plot the number of cells in each state
fig.bar.state.cells <- pData(cells.filter) %>%
dplyr::group_by(State) %>%
dplyr::summarise(num_cells = n()) %>%
ggplot(aes(x = State, y = num_cells, fill = State)) +
geom_text(aes(label = num_cells), position = position_dodge(width = 0.9), vjust = -0.25) +
geom_bar(alpha = 1, stat = "identity") +
ylim(c(0, 1050)) +
theme(legend.position = "none") +
theme_ms() +
theme(
legend.position = "none",
axis.text = element_text(size = rel(1)),
axis.title = element_text(face = "bold", size = rel(1))
) +
labs(y = "Number of cells", x = "State") +
scale_fill_manual(values = colour.set)
fig5.b <- fig.bar.state.cells
saveManuscriptPlot(fig5.b, 6, 6)
fig5.b
pData(cells.filter) %>% group_by(State) %>% summarise(`Cell number` = n(),
`Median relative HC expression` = median(rel.exprs.hc), `Max. expression` = max(rel.exprs.hc)) %>%
DT::datatable(rownames = T, options = list(pagelength = T,
scrollX = T, columnDefs = list(list(className = "dt-head-center dt-center",
targets = 1:2)))) %>% formatSignif(digits = 2, columns = 3:4)
pData(cells.filter) %>% group_by(State) %>% summarise(`Cell number` = n(),
`Median relative LC expression` = median(rel.exprs.lc), `Max. expression` = max(rel.exprs.lc)) %>%
DT::datatable(rownames = T, options = list(pagelength = T,
scrollX = T, columnDefs = list(list(className = "dt-head-center dt-center",
targets = 1:2)))) %>% formatSignif(digits = 2, columns = 3:4)
fig.box.hc.state <- pData(cells.filter) %>% group_by(State) %>%
ggplot(aes(x = State, y = rel.exprs.hc, fill = State)) +
geom_violin(alpha = 0.2) + geom_boxplot(alpha = 1, width = 0.15) +
scale_y_log10(limits = c(0.5, 100)) + theme_ms() + theme(legend.position = "none",
axis.text = element_text(size = rel(1)), axis.title = element_text(face = "bold",
size = rel(1)), plot.title = element_text(size = rel(1))) +
labs(y = "Relative expression", x = "State", title = "Heavy Chain") +
stat_compare_means(label.y.npc = c(0.95), label = "p.signif",
method = "wilcox.test", ref.group = "1", hide.ns = TRUE,
size = 7) + scale_fill_manual(values = colour.set)
fig5.c <- fig.box.hc.state
saveManuscriptPlot(fig5.c, 6, 6)
fig5.c
# overlay the heavy chain expression on the trajectory plot
fig.trajectory.rel.hc <- plot_cell_trajectory(cells.filter, theta = 0,
show_branch_points = FALSE, color_by = "rel.exprs.hc", cell_size = 0.5) +
color.gradient + labs(x = "Component 1", y = "Component 2",
color = "Relative\nExpression", title = "Heavy Chain") +
theme_ms() + theme(legend.position = "right", axis.text = element_text(size = rel(1)),
axis.title = element_text(face = "bold", size = rel(1)),
plot.title = element_text(size = rel(1))) + scale_x_reverse()
fig5.e <- fig.trajectory.rel.hc
saveManuscriptPlot(fig5.e, 12, 6)
fig5.e
# relative expression of the light chain in each cell state
fig.box.lc.state <- pData(cells.filter) %>%
group_by(State) %>%
ggplot(aes(x = State, y = rel.exprs.lc, fill = State)) +
geom_violin(alpha = 0.2) +
geom_boxplot(alpha = 1, width = 0.15) +
scale_y_log10(limits = c(0.5, 1e2)) +
theme(legend.position = "none") +
theme_ms() +
theme(
legend.position = "none",
axis.text = element_text(size = rel(1)),
axis.title = element_text(face = "bold", size = rel(1)),
plot.title = element_text(size = rel(1))
) +
labs(y = "Relative expression", x = "State", title = "Light Chain") +
stat_compare_means(
label.y.npc = c(0.95),
label = "p.signif",
method = "wilcox.test",
ref.group = "1",
hide.ns = TRUE,
size = 7,
color = "black"
) +
scale_fill_manual(values = colour.set)
fig5.d <- fig.box.lc.state
saveManuscriptPlot(fig5.d, 6, 6)
fig5.d
# overlay the light chain expression on the trajectory plot
fig.trajectory.rel.lc <- plot_cell_trajectory(cells.filter, theta = 0,
show_branch_points = FALSE, color_by = "rel.exprs.lc", cell_size = 0.5) +
color.gradient + labs(x = "Component 1", y = "Component 2",
color = "Relative\nExpression", title = "Light Chain") +
theme_ms() + theme(legend.position = "right", axis.text = element_text(size = rel(1)),
axis.title = element_text(face = "bold", size = rel(1)),
plot.title = element_text(size = rel(1))) + scale_x_reverse()
fig5.f <- fig.trajectory.rel.lc
saveManuscriptPlot(fig5.f, 12, 6)
fig5.f
Create and save figure 5 in the manuscript.
p1 <- (fig5.a + labs(tag = "(a)"))/(fig5.e + labs(tag = "(c)"))/(fig5.f +
labs(tag = "(e)"))
p2 <- (fig5.b + labs(tag = "(b)"))/(fig5.c + labs(tag = "(d)"))/(fig5.d +
labs(tag = "(f)"))
figure5 <- p1 | p2 + plot_annotation(tag_levels = "a", tag_prefix = "(",
tag_suffix = ")")
saveManuscriptPlot(figure5, 16, 11)
Cell state 1 is set as the root or beginning of the trajectory
# set the root state
cells.filter <- orderCells(cells.filter, root_state = 1)
fig.trajectory.pseudotime <- plot_cell_trajectory(cells.filter,
color_by = "Pseudotime", theta = 0, show_branch_points = FALSE,
cell_size = 0.5) + labs(x = "Component 1", y = "Component 2",
title = "Monocle pseudotime") + scale_color_viridis_c(option = "D") +
theme_ms() + theme(legend.position = "right", legend.title.align = 0.5,
axis.text = element_text(size = rel(1)), axis.title = element_text(face = "bold",
size = rel(1))) + scale_x_reverse()
fig6.a <- fig.trajectory.pseudotime
saveManuscriptPlot(fig6.a, 7, 3)
fig6.a
Identification of genes that correlated with Pseudotime. Those genes found to have a qval < 0.01 using the Monocle differentialGeneTest
function were considered significant
pseudotime_de <- differentialGeneTest(cells.filter, fullModelFormulaStr = "~batch + num_genes_expressed + total.mRNAs + S.Score + G2M.Score + sm.ns(Pseudotime, df = 3)",
reducedModelFormulaStr = "~batch + num_genes_expressed + total.mRNAs + S.Score + G2M.Score",
cores = 32)
# select significant genes
pseudotime_de <- pseudotime_de[pseudotime_de$qval < 0.01, ]
# save the results for Table S3
table.s3 <- pseudotime_de %>% arrange(qval) %>% dplyr::select(type,
gene_short_name, num_cells_expressed, max.expression, pval,
qval) %>% dplyr::rename(`SBG Annotation` = type, `Gene Symbol` = gene_short_name,
`p-value` = pval, `adj p-value` = qval)
tabsdir <- "./tables/"
if (!dir.exists(tabsdir)) {
dir.create(tabsdir)
}
fn <- paste("tables/Table S3.xlsx", sep = "")
suppressMessages(if (file.exists(fn)) {
file.remove(fn)
})
[1] TRUE
write_xlsx(list(pseudotime_de = table.s3), path = fn, format_headers = TRUE)
cluster_number <- 5
fig.heatmap.pseudotime <- plot_pseudotime_heatmap(cells.filter[rownames(pseudotime_de),
], cores = 32, use_gene_short_name = F, num_clusters = cluster_number,
show_rownames = F, return_heatmap = T, norm_method = "vstExprs")
fig6.b <- fig.heatmap.pseudotime
saveManuscriptPlot(fig6.b, 6, 6)
fig6.b
Use WebGestaltR to determine if the identified clusters of genes are enriched when compared to GO. Those biological processes with a Benjamini Hochberg adjusted p-value < 0.05 were considered significantly enriched.
datatable(enrich_result[[1]]$enrichResult[, c(1, 2, 4, 5, 7,
8, 9)], rownames = T, filter = "top", options = list(pagelength = T,
scrollX = T, columnDefs = list(list(className = "dt-head-center dt-center",
targets = 3:6)))) %>% formatSignif(digits = 2, columns = 5:7)
datatable(enrich_result[[2]]$enrichResult[, c(1, 2, 4, 5, 8,
9)], rownames = T, filter = "top", options = list(pagelength = T,
scrollX = T, columnDefs = list(list(className = "dt-head-center dt-center",
targets = 3:6)))) %>% formatSignif(digits = 2, columns = 5:6)
Overlay the expression of genes found to significantly correlate with the progression of cells along the trajectory.
Plot the expression of the Prosaposin gene
# relative expression
pData(cells.filter)$rel.exprs.psap <- monocle_relative_expression(cells.filter,
"Psap")
fig.traj.rel.psap <- plot_cell_trajectory(cells.filter, theta = 0,
show_branch_points = FALSE, color_by = "rel.exprs.psap",
cell_size = 0.5) + color.gradient + labs(x = "Component 1",
y = "Component 2", title = "Psap", color = "Relative\nexpression") +
theme_ms() + theme(legend.position = "right", axis.text = element_text(size = rel(1)),
axis.title = element_text(face = "bold", size = rel(1)),
plot.title = element_text(size = rel(1))) + scale_x_reverse()
fig6.c <- fig.traj.rel.psap
saveManuscriptPlot(fig6.c, 7, 3)
fig6.c
Plot the expression of the Heme oxygenase 1 gene
# relative expression
pData(cells.filter)$rel.exprs.hmox1 <- monocle_relative_expression(cells.filter,
"Hmox1")
fig.traj.rel.hmox1 <- plot_cell_trajectory(cells.filter, theta = 0,
show_branch_points = FALSE, color_by = "rel.exprs.hmox1",
cell_size = 0.5) + color.gradient + labs(x = "Component 1",
y = "Component 2", title = "Hmox1", color = "Relative\nexpression") +
theme_ms() + theme(legend.position = "right", axis.text = element_text(size = rel(1)),
axis.title = element_text(face = "bold", size = rel(1)),
plot.title = element_text(size = rel(1))) + scale_x_reverse()
fig6.e <- fig.traj.rel.hmox1
saveManuscriptPlot(fig6.e, 7, 3)
fig6.e
Plot the expression of the Ferritin 1 heavy chain 1 gene
# relative expression
pData(cells.filter)$rel.exprs.fth1 <- monocle_relative_expression(cells.filter,
"Fth1")
fig.traj.rel.fth1 <- plot_cell_trajectory(cells.filter, theta = 0,
show_branch_points = FALSE, color_by = "rel.exprs.fth1",
cell_size = 0.5) + color.gradient + labs(x = "Component 1",
y = "Component 2", title = "Fth1", color = "Relative\nexpression") +
theme_ms() + theme(legend.position = "right", axis.text = element_text(size = rel(1)),
axis.title = element_text(face = "bold", size = rel(1)),
plot.title = element_text(size = rel(1))) + scale_x_reverse()
fig6.f <- fig.traj.rel.fth1
saveManuscriptPlot(fig6.f, 7, 3)
fig6.f
Create and save figure 6 in the manuscript.
p1 <- (fig6.a + labs(tag = "(a)"))/(ggplot() + theme_void() +
labs(tag = "(b)"))/(ggplot() + theme_void())/(ggplot() +
theme_void())/(ggplot() + theme_void())
p2 <- (fig6.f + labs(tag = "(c)"))/(fig6.e + labs(tag = "(d)"))/(fig6.c +
labs(tag = "(e)"))
figure6 <- p1 | p2
saveManuscriptPlot(figure6, 12, 10)
devtools::session_info()
─ Session info ───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
setting value
version R version 4.0.2 (2020-06-22)
os Ubuntu 16.04.5 LTS
system x86_64, linux-gnu
ui X11
language (EN)
collate en_IE.UTF-8
ctype en_IE.UTF-8
tz Europe/Dublin
date 2020-11-05
─ Packages ───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
! package * version date lib source
abind 1.4-5 2016-07-21 [1] CRAN (R 4.0.2)
AnnotationDbi 1.50.1 2020-06-29 [1] Bioconductor
apcluster 1.4.8 2019-08-21 [1] CRAN (R 4.0.2)
ape 5.4 2020-06-03 [1] CRAN (R 4.0.2)
ash 1.0-15 2015-09-01 [1] CRAN (R 4.0.2)
askpass 1.1 2019-01-13 [1] CRAN (R 4.0.2)
assertthat 0.2.1 2019-03-21 [1] CRAN (R 4.0.2)
backports 1.1.8 2020-06-17 [1] CRAN (R 4.0.2)
Biobase * 2.48.0 2020-04-27 [1] Bioconductor
BiocFileCache 1.12.0 2020-04-27 [1] Bioconductor
BiocGenerics * 0.34.0 2020-04-27 [1] Bioconductor
BiocManager 1.30.10 2019-11-16 [1] CRAN (R 4.0.2)
biomaRt * 2.44.1 2020-06-17 [1] Bioconductor
bit 1.1-15.2 2020-02-10 [1] CRAN (R 4.0.2)
bit64 0.9-7 2017-05-08 [1] CRAN (R 4.0.2)
blob 1.2.1 2020-01-20 [1] CRAN (R 4.0.2)
bookdown 0.20 2020-06-23 [1] CRAN (R 4.0.2)
broom 0.7.0 2020-07-09 [1] CRAN (R 4.0.2)
callr 3.4.3 2020-03-28 [1] CRAN (R 4.0.2)
car 3.0-8 2020-05-21 [1] CRAN (R 4.0.2)
carData 3.0-4 2020-05-22 [1] CRAN (R 4.0.2)
cellranger 1.1.0 2016-07-27 [1] CRAN (R 4.0.2)
cli 2.0.2 2020-02-28 [1] CRAN (R 4.0.2)
P cluster 2.1.0 2019-06-19 [?] CRAN (R 4.0.0)
P codetools 0.2-16 2018-12-24 [?] CRAN (R 4.0.0)
colorRamps * 2.3 2012-10-29 [1] CRAN (R 4.0.2)
colorspace 1.4-1 2019-03-18 [1] CRAN (R 4.0.2)
combinat 0.0-8 2012-10-29 [1] CRAN (R 4.0.2)
cowplot * 1.0.0 2019-07-11 [1] CRAN (R 4.0.2)
cpp11 0.2.1 2020-08-11 [1] CRAN (R 4.0.2)
crayon 1.3.4 2017-09-16 [1] CRAN (R 4.0.2)
crosstalk 1.1.0.1 2020-03-13 [1] CRAN (R 4.0.2)
curl 4.3 2019-12-02 [1] CRAN (R 4.0.2)
data.table * 1.12.8 2019-12-09 [1] CRAN (R 4.0.2)
DBI 1.1.0 2019-12-15 [1] CRAN (R 4.0.2)
dbplyr 1.4.4 2020-05-27 [1] CRAN (R 4.0.2)
DDRTree * 0.1.5 2017-04-30 [1] CRAN (R 4.0.2)
densityClust 0.3 2017-10-24 [1] CRAN (R 4.0.2)
desc 1.2.0 2018-05-01 [1] CRAN (R 4.0.2)
devtools 2.3.0 2020-04-10 [1] CRAN (R 4.0.2)
digest 0.6.25 2020-02-23 [1] CRAN (R 4.0.2)
docopt 0.7.1 2020-06-24 [1] CRAN (R 4.0.2)
doParallel 1.0.15 2019-08-02 [1] CRAN (R 4.0.2)
doRNG 1.8.2 2020-01-27 [1] CRAN (R 4.0.2)
dplyr * 1.0.0 2020-05-29 [1] CRAN (R 4.0.2)
DT * 0.14 2020-06-24 [1] CRAN (R 4.0.2)
ellipsis 0.3.1 2020-05-15 [1] CRAN (R 4.0.2)
evaluate 0.14 2019-05-28 [1] CRAN (R 4.0.2)
extrafont 0.17 2014-12-08 [1] CRAN (R 4.0.2)
extrafontdb 1.0 2012-06-11 [1] CRAN (R 4.0.2)
fansi 0.4.1 2020-01-08 [1] CRAN (R 4.0.2)
farver 2.0.3 2020-01-16 [1] CRAN (R 4.0.2)
fastICA 1.2-2 2019-07-08 [1] CRAN (R 4.0.2)
fastmap 1.0.1 2019-10-08 [1] CRAN (R 4.0.2)
fitdistrplus 1.1-1 2020-05-19 [1] CRAN (R 4.0.2)
FNN 1.1.3 2019-02-15 [1] CRAN (R 4.0.2)
forcats 0.5.0 2020-03-01 [1] CRAN (R 4.0.2)
foreach 1.5.0 2020-03-30 [1] CRAN (R 4.0.2)
P foreign 0.8-80 2020-05-24 [?] CRAN (R 4.0.2)
formatR 1.7 2019-06-11 [1] CRAN (R 4.0.2)
fs 1.4.2 2020-06-30 [1] CRAN (R 4.0.2)
future 1.18.0 2020-07-09 [1] CRAN (R 4.0.2)
future.apply 1.6.0 2020-07-01 [1] CRAN (R 4.0.2)
gdtools 0.2.2 2020-04-03 [1] CRAN (R 4.0.2)
generics 0.0.2 2018-11-29 [1] CRAN (R 4.0.2)
GGally * 2.0.0 2020-06-06 [1] CRAN (R 4.0.2)
ggalt * 0.4.0 2017-02-15 [1] CRAN (R 4.0.2)
gganimate * 1.0.6 2020-07-08 [1] CRAN (R 4.0.2)
ggExtra * 0.9 2019-08-27 [1] CRAN (R 4.0.2)
ggplot2 * 3.3.2 2020-06-19 [1] CRAN (R 4.0.2)
ggplotify * 0.0.5 2020-03-12 [1] CRAN (R 4.0.2)
ggpubr * 0.4.0 2020-06-27 [1] CRAN (R 4.0.2)
ggrepel 0.8.2 2020-03-08 [1] CRAN (R 4.0.2)
ggridges 0.5.2 2020-01-12 [1] CRAN (R 4.0.2)
ggsignif 0.6.0 2019-08-08 [1] CRAN (R 4.0.2)
globals 0.12.5 2019-12-07 [1] CRAN (R 4.0.2)
glue 1.4.1 2020-05-13 [1] CRAN (R 4.0.2)
gridExtra * 2.3 2017-09-09 [1] CRAN (R 4.0.2)
gridGraphics 0.5-0 2020-02-25 [1] CRAN (R 4.0.2)
gtable 0.3.0 2019-03-25 [1] CRAN (R 4.0.2)
haven 2.3.1 2020-06-01 [1] CRAN (R 4.0.2)
hms 0.5.3 2020-01-08 [1] CRAN (R 4.0.2)
HSMMSingleCell 1.8.0 2020-05-07 [1] Bioconductor
htmltools 0.5.0 2020-06-16 [1] CRAN (R 4.0.2)
htmlwidgets 1.5.1 2019-10-08 [1] CRAN (R 4.0.2)
httpuv 1.5.4 2020-06-06 [1] CRAN (R 4.0.2)
httr 1.4.1 2019-08-05 [1] CRAN (R 4.0.2)
ica 1.0-2 2018-05-24 [1] CRAN (R 4.0.2)
igraph 1.2.5 2020-03-19 [1] CRAN (R 4.0.2)
IRanges 2.22.2 2020-05-21 [1] Bioconductor
irlba * 2.3.3 2019-02-05 [1] CRAN (R 4.0.2)
iterators 1.0.12 2019-07-26 [1] CRAN (R 4.0.2)
jcolors * 0.0.4 2019-05-22 [1] CRAN (R 4.0.2)
jsonlite 1.7.0 2020-06-25 [1] CRAN (R 4.0.2)
P KernSmooth 2.23-17 2020-04-26 [?] CRAN (R 4.0.0)
knitr * 1.29 2020-06-23 [1] CRAN (R 4.0.2)
labeling 0.3 2014-08-23 [1] CRAN (R 4.0.2)
later 1.1.0.1 2020-06-05 [1] CRAN (R 4.0.2)
P lattice 0.20-41 2020-04-02 [?] CRAN (R 4.0.0)
lazyeval 0.2.2 2019-03-15 [1] CRAN (R 4.0.2)
leiden 0.3.3 2020-02-04 [1] CRAN (R 4.0.2)
lifecycle 0.2.0 2020-03-06 [1] CRAN (R 4.0.2)
limma 3.44.3 2020-06-12 [1] Bioconductor
listenv 0.8.0 2019-12-05 [1] CRAN (R 4.0.2)
lmtest 0.9-37 2019-04-30 [1] CRAN (R 4.0.2)
magick 2.4.0 2020-06-23 [1] CRAN (R 4.0.2)
magrittr 1.5 2014-11-22 [1] CRAN (R 4.0.2)
maps 3.3.0 2018-04-03 [1] CRAN (R 4.0.2)
P MASS 7.3-51.6 2020-04-26 [?] CRAN (R 4.0.0)
P Matrix * 1.2-18 2019-11-27 [?] CRAN (R 4.0.0)
matrixStats 0.56.0 2020-03-13 [1] CRAN (R 4.0.2)
memoise 1.1.0 2017-04-21 [1] CRAN (R 4.0.2)
mime 0.9 2020-02-04 [1] CRAN (R 4.0.2)
miniUI 0.1.1.1 2018-05-18 [1] CRAN (R 4.0.2)
monocle * 2.16.0 2020-04-27 [1] Bioconductor
munsell 0.5.0 2018-06-12 [1] CRAN (R 4.0.2)
P nlme 3.1-148 2020-05-24 [?] CRAN (R 4.0.2)
openssl 1.4.2 2020-06-27 [1] CRAN (R 4.0.2)
openxlsx 4.1.5 2020-05-06 [1] CRAN (R 4.0.2)
packrat 0.5.0 2018-11-14 [1] CRAN (R 4.0.2)
patchwork * 1.0.1 2020-06-22 [1] CRAN (R 4.0.2)
pbapply 1.4-2 2019-08-31 [1] CRAN (R 4.0.2)
pheatmap 1.0.12 2019-01-04 [1] CRAN (R 4.0.2)
pillar 1.4.6 2020-07-10 [1] CRAN (R 4.0.2)
pkgbuild 1.0.8 2020-05-07 [1] CRAN (R 4.0.2)
pkgconfig 2.0.3 2019-09-22 [1] CRAN (R 4.0.2)
pkgload 1.1.0 2020-05-29 [1] CRAN (R 4.0.2)
plotly 4.9.2.1 2020-04-04 [1] CRAN (R 4.0.2)
plyr * 1.8.6 2020-03-03 [1] CRAN (R 4.0.2)
png 0.1-7 2013-12-03 [1] CRAN (R 4.0.2)
prettyunits 1.1.1 2020-01-24 [1] CRAN (R 4.0.2)
processx 3.4.3 2020-07-05 [1] CRAN (R 4.0.2)
progress 1.2.2 2019-05-16 [1] CRAN (R 4.0.2)
proj4 1.0-10 2020-03-02 [1] CRAN (R 4.0.2)
promises 1.1.1 2020-06-09 [1] CRAN (R 4.0.2)
proxy 0.4-24 2020-04-25 [1] CRAN (R 4.0.2)
ps 1.3.3 2020-05-08 [1] CRAN (R 4.0.2)
purrr 0.3.4 2020-04-17 [1] CRAN (R 4.0.2)
qlcMatrix 0.9.7 2018-04-20 [1] CRAN (R 4.0.2)
R6 2.4.1 2019-11-12 [1] CRAN (R 4.0.2)
RANN 2.6.1 2019-01-08 [1] CRAN (R 4.0.2)
rappdirs 0.3.1 2016-03-28 [1] CRAN (R 4.0.2)
RColorBrewer 1.1-2 2014-12-07 [1] CRAN (R 4.0.2)
Rcpp 1.0.5 2020-07-06 [1] CRAN (R 4.0.2)
RcppAnnoy 0.0.16 2020-03-08 [1] CRAN (R 4.0.2)
readr 1.3.1 2018-12-21 [1] CRAN (R 4.0.2)
readxl 1.3.1 2019-03-13 [1] CRAN (R 4.0.2)
remotes 2.1.1 2020-02-15 [1] CRAN (R 4.0.2)
reshape * 0.8.8 2018-10-23 [1] CRAN (R 4.0.2)
reshape2 1.4.4 2020-04-09 [1] CRAN (R 4.0.2)
reticulate 1.16 2020-05-27 [1] CRAN (R 4.0.2)
rio 0.5.16 2018-11-26 [1] CRAN (R 4.0.2)
rlang 0.4.7 2020-07-09 [1] CRAN (R 4.0.2)
rmarkdown 2.3 2020-06-18 [1] CRAN (R 4.0.2)
rmdformats * 0.3.7 2020-03-11 [1] CRAN (R 4.0.2)
rngtools 1.5 2020-01-23 [1] CRAN (R 4.0.2)
ROCR 1.0-11 2020-05-02 [1] CRAN (R 4.0.2)
rprojroot 1.3-2 2018-01-03 [1] CRAN (R 4.0.2)
RSQLite 2.2.0 2020-01-07 [1] CRAN (R 4.0.2)
rstatix 0.6.0 2020-06-18 [1] CRAN (R 4.0.2)
rsvd 1.0.3 2020-02-17 [1] CRAN (R 4.0.2)
Rtsne 0.15 2018-11-10 [1] CRAN (R 4.0.2)
Rttf2pt1 1.3.8 2020-01-10 [1] CRAN (R 4.0.2)
rvcheck 0.1.8 2020-03-01 [1] CRAN (R 4.0.2)
S4Vectors 0.26.1 2020-05-16 [1] Bioconductor
scales 1.1.1 2020-05-11 [1] CRAN (R 4.0.2)
sctransform 0.2.1 2019-12-17 [1] CRAN (R 4.0.2)
sessioninfo 1.1.1 2018-11-05 [1] CRAN (R 4.0.2)
Seurat * 3.1.5 2020-04-16 [1] CRAN (R 4.0.2)
shiny 1.5.0 2020-06-23 [1] CRAN (R 4.0.2)
slam 0.1-47 2019-12-21 [1] CRAN (R 4.0.2)
sparsesvd 0.2 2019-07-15 [1] CRAN (R 4.0.2)
stringi 1.4.6 2020-02-17 [1] CRAN (R 4.0.2)
stringr * 1.4.0 2019-02-10 [1] CRAN (R 4.0.2)
P survival 3.2-3 2020-06-13 [?] CRAN (R 4.0.1)
svglite 1.2.3.2 2020-07-07 [1] CRAN (R 4.0.2)
systemfonts 0.3.0 2020-09-01 [1] CRAN (R 4.0.2)
testthat 2.3.2 2020-03-02 [1] CRAN (R 4.0.2)
tibble 3.0.3 2020-07-10 [1] CRAN (R 4.0.2)
tictoc 1.0 2014-06-17 [1] CRAN (R 4.0.2)
tidyr 1.1.0 2020-05-20 [1] CRAN (R 4.0.2)
tidyselect 1.1.0 2020-05-11 [1] CRAN (R 4.0.2)
tsne 0.1-3 2016-07-15 [1] CRAN (R 4.0.2)
tweenr 1.0.1 2018-12-14 [1] CRAN (R 4.0.2)
usethis 1.6.1 2020-04-29 [1] CRAN (R 4.0.2)
uwot 0.1.8 2020-03-16 [1] CRAN (R 4.0.2)
vctrs 0.3.1 2020-06-05 [1] CRAN (R 4.0.2)
VGAM * 1.1-3 2020-04-28 [1] CRAN (R 4.0.2)
viridis * 0.5.1 2018-03-29 [1] CRAN (R 4.0.2)
viridisLite * 0.3.0 2018-02-01 [1] CRAN (R 4.0.2)
WebGestaltR * 0.4.3 2020-01-16 [1] CRAN (R 4.0.2)
whisker 0.4 2019-08-28 [1] CRAN (R 4.0.2)
withr 2.2.0 2020-04-20 [1] CRAN (R 4.0.2)
writexl * 1.3 2020-05-05 [1] CRAN (R 4.0.2)
xfun 0.15 2020-06-21 [1] CRAN (R 4.0.2)
XML 3.99-0.4 2020-07-05 [1] CRAN (R 4.0.2)
xtable 1.8-4 2019-04-21 [1] CRAN (R 4.0.2)
yaml 2.2.1 2020-02-01 [1] CRAN (R 4.0.2)
zip 2.0.4 2019-09-01 [1] CRAN (R 4.0.2)
zoo 1.8-8 2020-05-02 [1] CRAN (R 4.0.2)
[1] /mnt/HDD2/colin/CHO_cell_scRNASeq/packrat/lib/x86_64-pc-linux-gnu/4.0.2
[2] /mnt/HDD2/colin/CHO_cell_scRNASeq/packrat/lib-ext/x86_64-pc-linux-gnu/4.0.2
[3] /mnt/HDD2/colin/CHO_cell_scRNASeq/packrat/lib-R/x86_64-pc-linux-gnu/4.0.2
P ── Loaded and on-disk path mismatch.