-
Notifications
You must be signed in to change notification settings - Fork 3
3 scRNA: Copy Number Inference
A major challenge for single cell RNA sequencing of human tumors is to distinguish cancer cells from non-malignant cell types, as well as the presence of multiple tumor subclones. Previous studies showed many tumor cells are aneuploid with a high extent of genomic alteration. CopyKAT and InferCNV are two computational tools to identify genome-wide copy number alterations in single cells, separate tumor cells from normal cells, and identify tumor subclones using high-throughput scRNA-seq data. The underlying logic for calculating DNA copy number events from RNAseq data is that gene expression levels of many adjacent genes can provide depth information to infer genomic copy number in that region. Both tools provide a copy number heatmap and aneuploid cell predictions in their results.
Install copykat in R studio
library("devtools")
install_github("navinlabcode/copykat")
install.packages("readr")
BiocManager::install("ComplexHeatmap")
Install inferCNV in R studio pre-requisite: Install the JAGS package. This can be installed for Mac, Windows, or Linux. Be sure to download and install the corresponding package matching your OS.)
#library("devtools")
#devtools::install_github("broadinstitute/infercnv")
#basic
library(devtools)
library(readr)
library(dplyr)
library(magrittr)
library(circlize)
#make input matrix
library(Seurat)
#infer tools
library(copykat)
#library(infercnv)
#plot heatmap
library(ComplexHeatmap)
library(BiocParallel)
1.stabilize variance and smooth outliers:
The workflow takes the gene expression matrix of unique molecular identifier (UMI) counts as input for the calculations. The analysis begins with the annotation of genes in rows to order them by their genomic coordinates. Freeman–Tukey transformation is performed to stabilize variance, followed by polynomial dynamic linear modeling (DLM) to smooth the outliers in the single-cell UMI counts (Fig. 1a).
2.identify the confident normal cells:
The next step is to detect a subset of diploid cells with high confidence to infer the copy number baseline values of the normal 2N (diploid) cells. To do this, we pool single cells into several small hierarchical clusters(hclust) and estimate the variance of each cluster using a Gaussian mixture model (GMM). The cluster with minimal estimated variance is defined as the ‘confident diploid cells’ by following a strict classification criterion (Fig. 1b left panel). A single cell is defined as a confident diploid cell when the neutral distribution accounts for at least 99% of the expressed genes (Fig. 1b right panel).
3.identify the breakpoints and calculate the ratio in segments:
To detect chromosome breakpoints, we integrate a Poisson-gamma model and Markov Chain Monte Carlo (MCMC) iterations to generate posterior means per gene window (taking at least 25 genes per segment) and then apply Kolmogorov–Smirnov (KS) tests to join adjacent windows that do not have significant differences in their means (merge when D < KS.cut). After identifying the breakpoints across the genome, the final copy number values for each segment are calculated as the posterior averages of all genes spanning across the adjacent chromosome breakpoints in each cell (Fig. 1c).
4.identify the aneuploid and diploid cells:
We then perform hierarchical clustering of the single-cell copy number data, and cutree to identify the largest distance between the aneuploid tumor cells and the diploid stromal cells. The cluster with the most overlap of pre-defined confident normal will be classified as diploid cells. However, if the genomic distance is not significant, we switch to the GMM definition model to predict single tumor cells one by one (Fig. 1d).
5.identify subclone structure:
Finally, we cluster the single-cell copy number data to identify clonal subpopulations and calculate consensus profiles representing the subclonal genotypes for further analysis of their gene expression differences (Fig. 1e).
The only input file that you need to prepare to run copykat is the raw gene expression matrix, with gene ids in rows and cell names in columns. The gene ids can be gene symbol or ensemble id. The matrix values are often the count of unique molecular identifier (UMI) from high throughput single cell RNAseq data. Early generation scRNAseq data may be summarized as TPM values or total read counts, which should also work.
option1.prepare from 10X output (we will skip this option for the workshop).
data.path.to.cellranger.outs <-"your_sample/outs/filtered_feature_bc_matrix/"
library(Seurat)
library(readr)
library(dplyr)
raw <- Read10X(data.dir = data.path.to.cellranger.outs)
raw <- CreateSeuratObject(counts = raw, project = "copycat.test", min.cells = 0, min.features = 0)
exp.rawdata <- as.matrix(raw@assays$RNA@counts)
exp.rawdata[1:5,1:5] #rownames: gene symbol; colnames: cell id
option2.prepare from processed seurat obejct.
input_dir = '/path/to/your/folder' ########create a new folder with any name you like
dir.create(input_dir,recursive = T)
setwd(input_dir)
raw <- read_rds('~/Downloads/workshop_data/input_seu.rds')# data was from TNBC5 in Ruli Gao et al, NBT, 2021
##########you can also practice for basic scRNA-seq preprocessing step with this object
exp.rawdata <- as.matrix(raw@assays$RNA@counts)
raw@meta.data$celltype %>% table()
normal = rownames(raw@meta.data[raw@meta.data$celltype %in% c('Fibro', 'Mye', 'T'),]) #copykat can also take normal stromal cellname as reference
Now we have prepared the input (raw UMI count matrix). We are ready to run copykat.
parameters:
id.type = 'S' (input matrix gene_id is gene symbol)
ngene.chr = 5 (cell filter: at least 5 genes in each chromosome to calculate DNA copy numbers. To keep more cells, we can tune this down to ngene.chr=1)
win.size = 25 (gene window: 25 genes per window)
LOW.DR = 0.05, UP.DR=0.2 (gene filter: keep genes expressed in >5%(LOW.DR) cells for data quality control. Use genes expressed in >20%(UP.DR) cells for segmentation)
sam.name = "test" (your sample name)
distance = "euclidean" (distance parameters for clustering that include "euclidean" distance and correlational distance, ie. 1-"pearson" and "spearman" similarity. In general, correlational distances tend to favor noisy data, while euclidean distance tends to favor data with larger CN segments.)
norm.cell.names = "" (if you already identify the stromal cells, such as fibroblasts, meyloid cells, t cells, endothelial cells, etc you can output the cell names in the matrix to tell copykat "here, we have reference data you can use to calculate the baseline ratio". Default is "", meaning NOT inputing any normal reference)
output.seg = "FALSE" (output seg file which can be directly loaded to IGV viewer for visualization. Default is FALSE)
plot.genes = "TRUE" (plot of single cell copy number results, using gene by cell matrix. This is by default, plot.genes="TRUE". Gene names are labelled at the bottom of heatmap. You need to zoom in to read the tiny font.)
genome = "hg20" (the input data genome annotation version, if it's a mouse data, use "mm10")
n.cores=20 (parallel computation)
#with ref (you can practice with this command later by yourself)
copykat.test <- copykat(rawmat=exp.rawdata, id.type="S", ngene.chr=5, win.size=25, KS.cut=0.1, LOW.DR=0.05, UP.DR=0.2, sam.name="test", distance <- "euclidean", norm.cell.names=normal, output.seg="FALSE", plot.genes="FALSE", genome="hg20",n.cores=4)
#without ref (take ~10 min with 4 cores)
copykat.test <- copykat(rawmat=exp.rawdata, id.type="S", ngene.chr=5, win.size=25, KS.cut=0.1, LOW.DR=0.05, UP.DR=0.2, sam.name="test", distance <- "euclidean", norm.cell.names="", output.seg="FALSE", plot.genes="FALSE", genome="hg20",n.cores=4)
#######if running with cellline, organoids, or samples with of all tumor cells, copyKAT has a cellline mode: copykat.test <- copykat(rawmat=exp.rawdata, id.type="S", ngene.chr=5, win.size=25, KS.cut=0.1, LOW.DR=0.05, UP.DR=0.2, sam.name="test", distance <- "euclidean", norm.cell.names="", output.seg="FALSE", cell.line="yes" ,plot.genes="FALSE", genome="hg20",n.cores=4)
go to the output_dir
you will find your result test_copykat_heatmap.jpeg
result without reference
result with reference \

#read copykat prediction
output_dir <- "/Path/to/your/copykay_result/folder/" ######Or you can load the result from this path: "/grid/singlecellcourse/home/ruiye/copykat_no_reference"
setwd(output_dir)
library(Seurat)
library(readr)
library(dplyr)
pred.test <- read.table('~/Downloads/workshop_data/test_copykat_prediction.txt',header = T)
head(pred.test)
dim(pred.test)
table(pred.test$copykat.pred)
dim(pred.test)
## 3027 2
## cell.names copykat.pred
## 1 Tumor_ARTC26_AAACCCACAAGTATCC aneuploid
## 2 Tumor_ARTC26_AAACCCACATAGCACT aneuploid
## 3 Tumor_ARTC26_AAACGAACAAAGGATT aneuploid
## 4 Tumor_ARTC26_AAACGAACAAGATGTA aneuploid
## 5 Tumor_ARTC26_AAACGAATCGTGTCAA aneuploid
## 6 Tumor_ARTC26_AAACGCTAGAGCAAGA aneuploid
table(pred.test$copykat.pred)
# 1989 aneuploid cells (some cells were classified as not defined because of low quality)
## aneuploid diploid not.defined
## 1989 918 120
pred.test <- pred.test[-which(pred.test$copykat.pred=="not.defined"),] #remove not.defined (low quality) cells
dim(pred.test)
head(pred.test)
## 2907 2
## cell.names copykat.pred
## 1 Tumor_ARTC26_AAACCCACAAGTATCC aneuploid
## 2 Tumor_ARTC26_AAACCCACATAGCACT aneuploid
## 3 Tumor_ARTC26_AAACGAACAAAGGATT aneuploid
## 4 Tumor_ARTC26_AAACGAACAAGATGTA aneuploid
## 5 Tumor_ARTC26_AAACGAATCGTGTCAA aneuploid
## 6 Tumor_ARTC26_AAACGCTAGAGCAAGA aneuploid
#assign the result back to the seurat object
raw@meta.data$copykat_pred_default <- pred.test$copykat.pred[match(colnames(raw),pred.test$cell.names)]
table(raw$copykat_pred_default) ####sanity check whether results are assigned
#########visualize which cells are assigned to aneuploid cells on umap
#######better to re-run RNA clustering first, you can read in a re-clustered object here:
raw <- read_rds("~/Downloads/workshop_data/seurat_obj_reclustered.rds")
DimPlot(raw,group.by = "copykat_pred_default")
DimPlot(raw,group.by = "celltype")


#read copykat logratio matrix
copykat_matrix <- read.delim("~/Downloads/workshop_data/test_copykat_CNA_results.txt")
copykat_matrix[1:5,1:5]; dim(copykat_matrix)
## chrom chrompos abspos Tumor_ARTC26_AAACCCACAAGTATCC Tumor_ARTC26_AAACCCACATAGCACT
## 1 1 1042457 1042457 -0.1365976 -0.097993
## 2 1 1265484 1265484 -0.1365976 -0.097993
## 3 1 1519859 1519859 -0.1365976 -0.097993
## 4 1 1826619 1826619 -0.1365976 -0.097993
## 5 1 2058465 2058465 -0.1365976 -0.097993
## 1] 12167 2910
library(ComplexHeatmap)
annotation <- copykat_matrix[,1:3] ######first 3 columns are related to chromosomal locations
gene_order <- data.frame(annotation)
copykat_matrix <- copykat_matrix[,4:ncol(copykat_matrix)] ####subset matrix to only contain inferred copy number ratios for cells
expression_matrix_t <- data.frame(t(copykat_matrix))
#######prepare chromosome annotation bar for the heatmap
chr_lengths <- rle(as.numeric(gene_order$chrom))$lengths
chr_binary <- as.numeric(c(rep(c(2, 1),11),2))
chr <-data.frame(chr = rep.int(x = chr_binary, times = chr_lengths))
# getting lengths for chr numbers annotation
chr_rl_c <- c(1, cumsum(chr_lengths))
# creating a data frame to calculate rowMeans
chr_df <-
data.frame(
a = chr_rl_c[1:length(chr_rl_c) - 1],
b = chr_rl_c[2:length(chr_rl_c)]
)
chr_l_means <- round(rowMeans(chr_df))
chrom.names <- c(1:22,"X")
# creating the vector for chr number annotations
v <- vector(length = sum(chr_lengths), mode = "character")
suppressWarnings(v[chr_l_means] <- chrom.names)
v[is.na(v)] <- ""
# chr bar with the chr names
chr_bar_COPYKAT <-
ComplexHeatmap::HeatmapAnnotation(
chr_text = ComplexHeatmap::anno_text(v[1:ncol(expression_matrix_t)],
gp = grid::gpar(fontsize = 14)
),
df = as.character(chr[1:nrow(chr), ]),
show_legend = FALSE,
show_annotation_name = FALSE,
which = "column",
col = list(df = c("1" = "grey88", "2" = "black"))
)
#######
annotation_df <- data.frame(rownames(expression_matrix_t))
rownames(annotation_df) <- annotation_df$rownames.expression_matrix_t.
annotation_df$copykay_predict <- pred.test$copykat.pred[match(rownames(annotation_df),pred.test$cell.names)] ###adding copykat prediction
annotation_df$celltype <- raw@meta.data$celltype[match(rownames(annotation_df),colnames(raw))] ######adding cell type info
table(annotation_df$copykay_predict)
table(annotation_df$celltype)
ht_mtx <- expression_matrix_t
mtx_srt <- annotation_df
#######reorder cell by cell type, then by copykat result
mtx_srt <- mtx_srt[order(mtx_srt$celltype,mtx_srt$copykay_predict),]
ht_mtx <- ht_mtx[rownames(mtx_srt),]
#######prepare row annotations for the heatmap
anno_mtx <- mtx_srt %>% dplyr::select(c("copykay_predict","celltype"))
rownames(anno_mtx) <- NULL
copykat_anno <- rowAnnotation(copykat_predict = anno_mtx$copykay_predict,col = list(copykat_predict = c("aneuploid"="red","diploid"="blue")))
library(RColorBrewer)
celltype_col <- setNames(brewer.pal(4,"Set1"),unique(anno_mtx$celltype))
celltype_anno <- rowAnnotation(celltype = anno_mtx$celltype,
col = list(celltype = celltype_col))
pdf("Copykat_ht_regeneraetd.pdf", height = 8, width = 8,useDingbats = F)
ComplexHeatmap::Heatmap(as.matrix(ht_mtx), cluster_columns = FALSE, border = TRUE, cluster_rows = FALSE, show_row_dend = FALSE,
row_split = anno_mtx$copykay_predict,
name = "Log2(ratio)", show_row_names = F, show_column_names = F, row_title = paste0(nrow(ht_mtx), " single cells"),
use_raster = T, raster_quality = 5, col = circlize::colorRamp2(breaks = c(-0.5,0,0.5), c("dodgerblue3", "white", "firebrick3")),
top_annotation = chr_bar_COPYKAT, left_annotation = c(copykat_anno,celltype_anno))
dev.off()
this is the heatmap with all cells
step 5: Identify cancer subclones if you are interested to look at the copy number subclonal structures
#####subset only to tumor cells
mtx_srt <- mtx_srt[mtx_srt$celltype=="Tumor",]
ht_mtx_tumor <- ht_mtx[rownames(ht_mtx) %in% rownames(mtx_srt),]
######Run hclust to cluster cells into different clusters/groups/subclones. You can also use other clustering algorithms (i.e. leiden, louvain, etc.).
dist_mat <- parallelDist::parallelDist(as.matrix(ht_mtx_tumor),method = 'euclidean')
hclust_avg <- fastcluster::hclust(dist_mat, method = 'ward.D')
fit <- cutree(hclust_avg, k = 10) ####here we get 10 clusters
mtx_srt$hclust <- fit[match(rownames(mtx_srt),names(fit))]
table(mtx_srt$hclust)
######reorder cells by hclust results
mtx_srt <- mtx_srt[order(mtx_srt$hclust,mtx_srt$copykay_predict),]
ht_mtx_tumor <- ht_mtx_tumor[rownames(mtx_srt),]
#######prepare for row annotations for the heatmap
anno_mtx <- mtx_srt %>% dplyr::select(c("copykay_predict","hclust"))
rownames(anno_mtx) <- NULL
anno_mtx$hclust <- paste0("group",anno_mtx$hclust)
copykat_anno <- rowAnnotation(copykat_predict = anno_mtx$copykay_predict,col = list(copykat_predict = c("aneuploid"="red","diploid"="blue")))
library(RColorBrewer)
hclust_col <- setNames(brewer.pal(10,"Set3"),paste0("group",1:10))
hclust_anno <- rowAnnotation(Hclust = anno_mtx$hclust,
col = list(Hclust = hclust_col))
pdf("copykat_ht_reclustered.pdf", height = 8, width = 8,useDingbats = F)
ComplexHeatmap::Heatmap(as.matrix(ht_mtx_tumor), cluster_columns = FALSE, border = TRUE, cluster_rows = FALSE, show_row_dend = FALSE,
row_split = anno_mtx$hclust,
name = "Log2(ratio)", show_row_names = F, show_column_names = F, row_title = paste0(nrow(ht_mtx), " single cells"),
use_raster = T, raster_quality = 5, col = circlize::colorRamp2(breaks = c(-0.5,0,0.5), c("dodgerblue3", "white", "firebrick3")),
top_annotation = chr_bar_COPYKAT, left_annotation = c(hclust_anno,copykat_anno))
dev.off()
this is the heatmap with all tumor cells

step 6: comparing the result with ground truth scDNA-seq data. Attention! Some false positive/negative copy number events are generated from the inferred data!
false negative events: chr2q gain, chr4 loss, chr6 loss, chr18 loss,chrX loss false positive events: Chr2 focal gain, chr3p gain, chr4p gain, chr5 focal events, chr8p gain, chr10p gain, chr14p gain

library(Seurat)
library(readr)
library(dplyr)
library(infercnv)
input_dir = '/path/to/your/folder/'
dir.create(input_dir,recursive = T) ########create a folder to store inferCNV result
setwd(input_dir)
#####check the input file requirement here: https://github.com/broadinstitute/inferCNV/wiki/File-Definitions
#count matrix
exp.rawdata <- as.matrix(raw@assays$RNA@counts)
write.table(exp.rawdata,'./input_count_matrix.txt',row.names = T,quote = F,sep = '\t')
#cell type annotation dataframe
anno <- FetchData(raw,vars = "celltype")
table(anno$celltype)
#######set all non-malignant cells as reference cells (normal)
anno$celltype <- ifelse(anno$celltype=="Tumor","Tumor","normal")
write.table(anno, file="input_cell_annotation.txt", sep="\t", quote = FALSE, row.names = T,col.names = F)
#gene chromosomal position annotation dataframe
##common gene coordinates (hg19,hg38,mm10) can be found here: https://data.broadinstitute.org/Trinity/CTAT/cnv/
#########since inferCNV will take very long time to run (~45 min with 30 cores), we won't run it in the workshop. You can practice on your own. It is recommended to run it in terminal (bash)
infercnv_obj = CreateInfercnvObject(raw_counts_matrix="input_count_matrix.txt", #####change the count matrix file name if you named it differently
annotations_file="input_cell_annotation.txt",
delim="\t",
gene_order_file="hg38_gencode_v27.txt",
ref_group_names="normal")
#or run without ref (may have wrong prediction)
infercnv_obj <- CreateInfercnvObject(raw_counts_matrix= 'input_count_matrix.txt',
annotations_file="input_cell_annotation.txt",
delim="\t",
gene_order_file="hg38_gencode_v27",
ref_group_names=NULL)
out_dir="output" #######inferCNV result will be saved to this subfolder
infercnv_obj = infercnv::run(infercnv_obj,
cutoff=0.1, # cutoff=1 works well for Smart-seq2, and cutoff=0.1 works well for 10x Genomics
out_dir=out_dir,
cluster_by_groups=TRUE,
num_threads = 30,
plot_steps=FALSE,
denoise=TRUE,
HMM=TRUE
)

library(ComplexHeatmap)
inferCNV_obj <- read_rds("~/Downloads/workshop_data/inferCNV_output/run.final.infercnv_obj")
expression_matrix <- data.frame(inferCNV_obj@expr.data)
expression_matrix[1:5,1:5]
gene_order <- data.frame(inferCNV_obj@gene_order)
expression_matrix_t <- data.frame(t(expression_matrix))
chr_lengths <- rle(as.numeric(gene_order$chr))$lengths
chr_binary <- rep(c(2, 1), length(chr_lengths) / 2)
chr <-
data.frame(chr = rep.int(x = chr_binary, times = chr_lengths))
# getting lengths for chr numbers annotation
chr_rl_c <- c(1, cumsum(chr_lengths))
# creating a data frame to calculate rowMeans
chr_df <-
data.frame(
a = chr_rl_c[1:length(chr_rl_c) - 1],
b = chr_rl_c[2:length(chr_rl_c)]
)
chr_l_means <- round(rowMeans(chr_df))
chrom.names <- c(1:22)
# creating the vector for chr number annotations
v <- vector(length = sum(chr_lengths), mode = "character")
suppressWarnings(v[chr_l_means] <- chrom.names)
v[is.na(v)] <- ""
# chr bar with the chr names
chr_bar_inferCNV <-
ComplexHeatmap::HeatmapAnnotation(
chr_text = ComplexHeatmap::anno_text(v[1:ncol(expression_matrix_t)],
gp = grid::gpar(fontsize = 14)
),
df = as.character(chr[1:nrow(chr), ]),
show_legend = FALSE,
show_annotation_name = FALSE,
which = "column",
col = list(df = c("1" = "grey88", "2" = "black"))
)
annotation_infercnv <- read.delim("~/Downloads/workshop_data/inferCNV_output/infercnv.observation_groupings.txt",sep = " ")
annotation_df <- data.frame(rownames(expression_matrix_t))
rownames(annotation_df) <- annotation_df$rownames.expression_matrix_t.
annotation_df$sample <- ifelse(rownames(annotation_df) %in% rownames(annotation_infercnv),"sample","reference")
table(annotation_df$sample)
dist_mat <- parallelDist::parallelDist(as.matrix(expression_matrix_t),method = 'euclidean')
hclust_avg <- fastcluster::hclust(dist_mat, method = 'ward.D')
fit <- cutree(hclust_avg, k = 10)
annotation_df$hclust <- fit[match(rownames(annotation_df),names(fit))]
mtx_srt <- annotation_df
mtx_srt <- mtx_srt[order(mtx_srt$hclust),]
ht_mtx <- expression_matrix_t[rownames(mtx_srt),]
anno_mtx <- mtx_srt %>% dplyr::select(c("hclust","sample"))
rownames(anno_mtx) <- NULL
anno_mtx$hclust <- paste0("group",anno_mtx$hclust)
hclust_col <- setNames(brewer.pal(10,"Set3"),paste0("group",1:10))
hclust_anno <- rowAnnotation(Hclust = anno_mtx$hclust,
col = list(Hclust = hclust_col))
sample_anno <- rowAnnotation(sample = anno_mtx$sample,na_col="white",
col = list(sample = c("sample"="#8DD3C7","reference"="grey")))
pdf("inferCNV_ht_regeneraetd.pdf", height = 8, width = 8,useDingbats = F)
ComplexHeatmap::Heatmap(as.matrix(ht_mtx), cluster_columns = FALSE, border = TRUE, cluster_rows = FALSE, show_row_dend = FALSE,
row_split = anno_mtx$sample,
name = "Modified Expression", show_row_names = F, show_column_names = F, row_title = paste0(nrow(ht_mtx), " single cells"),
use_raster = T, raster_quality = 5, col = circlize::colorRamp2(breaks = c(0.75,1,1.25), c("dodgerblue3", "white", "firebrick3")),
top_annotation = chr_bar_inferCNV, left_annotation = c(hclust_anno,sample_anno))
dev.off()

inferCNV did not capture: chr2q gain, chr3p loss, chr4 loss, chr6 loss, chr10 loss, chr11 loss, chr18 loss, chrX gain & chrX loss

inferCNV: 45 min (using 30 cores)
copykat: 10 mins (using 4 cores)\
inferCNV: normalized genes expression matrix, ordered by chromosome position
copykat: copy number ratios in 220k genomic bin, easily taken by copykit \
inferCNV: \
1.wrong prediction when supply no reference group
2.failed to capture chr10 & chr11 loss compared to copykat
sessionInfo()
# R version 4.1.2 (2021-11-01)
# Platform: x86_64-pc-linux-gnu (64-bit)
# Running under: Red Hat Enterprise Linux
# Matrix products: default
# BLAS/LAPACK: /usr/lib64/libopenblasp-r0.3.3.so
# locale:
# [1] LC_CTYPE=en_US.UTF-8 LC_NUMERIC=C LC_TIME=en_US.UTF-8 LC_COLLATE=en_US.UTF-8 LC_MONETARY=en_US.UTF-8
# [6] LC_MESSAGES=en_US.UTF-8 LC_PAPER=en_US.UTF-8 LC_NAME=C LC_ADDRESS=C LC_TELEPHONE=C
# [11] LC_MEASUREMENT=en_US.UTF-8 LC_IDENTIFICATION=C
# attached base packages:
# [1] stats4 stats graphics grDevices utils datasets methods base
# other attached packages:
# [1] infercnv_1.21.0 Matrix_1.5-3 magrittr_2.0.3 copykit_0.1.0 DNAcopy_1.68.0
# [6] Rsubread_2.8.2 SingleCellExperiment_1.16.0 SummarizedExperiment_1.24.0 Biobase_2.54.0 GenomicRanges_1.46.1
#[11] GenomeInfoDb_1.30.1 IRanges_2.28.0 S4Vectors_0.32.4 BiocGenerics_0.40.0 MatrixGenerics_1.6.0
#[16] matrixStats_0.63.0 stringr_1.5.0 RColorBrewer_1.1-3 mclust_5.4.9 BiocParallel_1.28.3
#[21] copykat_1.1.0 dplyr_1.1.3 readr_2.1.4 SeuratObject_4.1.3 Seurat_4.3.0
#[26] devtools_2.4.5 usethis_2.1.6
#loaded via a namespace (and not attached):
# [1] scattermore_0.8 prabclus_2.3-2 coda_0.19-4 tidyr_1.3.0 ggplot2_3.4.2 knitr_1.41
# [7] irlba_2.3.5.1 multcomp_1.4-25 DelayedArray_0.20.0 data.table_1.14.6 RCurl_1.98-1.9 doParallel_1.0.17
# [13] generics_0.1.3 callr_3.7.3 cowplot_1.1.1 lambda.r_1.2.4 TH.data_1.1-0 RANN_2.6.1
# [19] future_1.29.0 tzdb_0.2.0 spatstat.data_3.0-0 httpuv_1.6.6 viridis_0.6.2 xfun_0.40
# [25] hms_1.1.1 evaluate_0.23 promises_1.2.0.1 argparse_2.2.2 DEoptimR_1.0-10 fansi_1.0.3
# [31] caTools_1.18.2 igraph_1.3.5 DBI_1.1.2 htmlwidgets_1.6.2 futile.logger_1.4.3 spatstat.geom_3.0-3
# [37] purrr_1.0.1 ellipsis_0.3.2 ggnewscale_0.4.6 RcppParallel_5.1.5 libcoin_1.0-9 deldir_1.0-6
# [43] vctrs_0.6.3 ggalluvial_0.12.3 remotes_2.4.2 ROCR_1.0-11 abind_1.4-5 cachem_1.0.6
# [49] withr_2.5.0 robustbase_0.93-9 progressr_0.13.0 sctransform_0.3.5 treeio_1.18.1 prettyunits_1.1.1
# [55] goftest_1.2-3 cluster_2.1.2 ape_5.8 segmented_1.4-0 lazyeval_0.2.2 crayon_1.5.2
# [61] spatstat.explore_3.0-6 edgeR_3.36.0 pkgconfig_2.0.3 nlme_3.1-160 pkgload_1.3.4 nnet_7.3-17
# [67] rlang_1.1.1 globals_0.16.2 diptest_0.76-0 lifecycle_1.0.3 miniUI_0.1.1.1 sandwich_3.0-2
# [73] dbscan_1.1-10 polyclip_1.10-4 lmtest_0.9-40 aplot_0.1.2 zoo_1.8-11 ggridges_0.5.4
# [79] GlobalOptions_0.1.2 processx_3.8.3 png_0.1-8 viridisLite_0.4.1 rjson_0.2.21 bitops_1.0-7
# [85] KernSmooth_2.23-20 shape_1.4.6 coin_1.4-2 parallelly_1.32.1 spatstat.random_3.0-1 gridGraphics_0.5-1
# [91] scales_1.2.1 memoise_2.0.1 plyr_1.8.8 ica_1.0-3 gplots_3.1.3 zlibbioc_1.40.0
# [97] compiler_4.1.2 clue_0.3-60 fitdistrplus_1.1-8 cli_3.6.2 XVector_0.34.0 urlchecker_1.0.1
#[103] listenv_0.8.0 patchwork_1.1.2 pbapply_1.6-0 ps_1.7.5 formatR_1.11 MASS_7.3-58.1
#[109] tidyselect_1.2.0 stringi_1.7.8 forcats_0.5.1 yaml_2.3.6 locfit_1.5-9.6 ggrepel_0.9.2
#[115] grid_4.1.2 tools_4.1.2 parallelDist_0.2.6 future.apply_1.10.0 parallel_4.1.2 circlize_0.4.14
#[121] rstudioapi_0.13 rjags_4-14 bluster_1.4.0 foreach_1.5.2 gridExtra_2.3 Rtsne_0.16
#[127] digest_0.6.34 shiny_1.7.3 fpc_2.2-9 Rcpp_1.0.10 later_1.3.0 RcppAnnoy_0.0.20
#[133] httr_1.4.4 ComplexHeatmap_2.10.0 kernlab_0.9-29 colorspace_2.0-3 fs_1.5.2 tensor_1.5
#[139] reticulate_1.28 splines_4.1.2 uwot_0.1.14 yulab.utils_0.0.4 tidytree_0.3.8 spatstat.utils_3.0-1
#[145] sp_1.5-1 phyclust_0.1-30 ggplotify_0.1.0 flexmix_2.3-17 plotly_4.10.1 sessioninfo_1.2.2
#[151] xtable_1.8-4 jsonlite_1.8.8 ggtree_3.2.1 futile.options_1.0.1 modeltools_0.2-23 ggfun_0.0.5
#[157] R6_2.5.1 profvis_0.3.7 pillar_1.9.0 htmltools_0.5.6 mime_0.12 glue_1.6.2
#[163] fastmap_1.1.0 BiocNeighbors_1.12.0 class_7.3-20 codetools_0.2-18 pkgbuild_1.3.1 mvtnorm_1.1-3
#[169] utf8_1.2.2 lattice_0.20-45 spatstat.sparse_3.0-0 tibble_3.2.1 mixtools_1.2.0 leiden_0.4.3
#[175] gtools_3.9.2 limma_3.50.1 survival_3.4-0 rmarkdown_2.18 munsell_0.5.0 fastcluster_1.2.3
#[181] GetoptLong_1.0.5 GenomeInfoDbData_1.2.7 iterators_1.0.14 reshape2_1.4.4 gtable_0.3.1
For more info about us click here.