library(knitr) opts_chunk$set( warning = FALSE, message = FALSE, fig.path = 'figure/', cache.path = 'cache/', cache = FALSE, dpi=100 )
library(HoneyBADGER)
HoneyBADGER
identifies and quantitatively infers the presence of CNV and LOH events in single cells using allele and normalized expression information from single-cell RNA-seq data. In this tutorial, we will use HoneyBADGER
to detect CNVs in glioblastoma tumor cells from patient MGH31 from Patel et al. The single-cell RNA-seq data has been prepared for you and is included in the HoneyBADGER
package.
First, load the gene expression matrices for tumor cells along with a normal expression reference derived from averaging normal brain samples found in GTex. Also load a corresponding biomaRt instance (for human) to obtain chromosomal coordinate information for our genes.
data(gexp) ## tumor cells data(ref) ## reference require(biomaRt) ## for gene coordinates mart.obj <- useMart(biomart = "ENSEMBL_MART_ENSEMBL", dataset = 'hsapiens_gene_ensembl', host = "jul2015.archive.ensembl.org") print(gexp[1:5,1:5]) print(ref[1:5]) print(mart.obj)
Make a new HoneyBADGER
object and initialize the gene expression matrices. The data has already been filtered for highly expressed shared genes and scaled for library size differences so we can override the default filtering and scaling.
hb <- new('HoneyBADGER', name='MGH31') hb$setGexpMats(gexp, ref, mart.obj, filter=FALSE, scale=FALSE, verbose=TRUE)
The inputted gene expression matrix is normalized using the reference such that we may expect large-scale deviations in expression from the reference on average to be indicative of underlying CNVs. We can visualize the smoothed gene expression using the following profile.
hb$plotGexpProfile() ## initial visualization
Here, each row is a single cell. Genes are organized based on their position along each chromosome. Expression has been smoothed using a sliding window approach. Red indicates higher average expression compared to the reference and blue indicates lower. Visually, such expression-based karyotyping already suggests some chromosomal abnormalities. To provide a more quantitative assessment, we can model the gene expression variance and use an iterative HMM approach to identify regions affected by CNVs.
hb$setMvFit(verbose=TRUE) ## model variance hb$setGexpDev(verbose=TRUE) ## model necessary expression deviation to identify CNVs hb$calcGexpCnvBoundaries(init=TRUE, verbose=FALSE) ## HMM ## double check what CNVs were identified bgf <- hb$bound.genes.final genes <- hb$genes regions.genes <- range(genes[unlist(bgf)]) print(regions.genes)
Indeed, our initial HMM has identified a number of candidate CNVs to test. We can now retest all identified CNVs on all cells to derive the final posterior probability of each CNV in each cell. We can cluster cells on these posterior probabilities and visualize them as a heatmap.
hb$retestIdentifiedCnvs(retestBoundGenes = TRUE, retestBoundSnps = FALSE, verbose=FALSE) ## look at final results results <- hb$summarizeResults(geneBased=TRUE, alleleBased=FALSE) print(head(results[,1:5])) ## visualize as heatmap trees <- hb$visualizeResults(geneBased=TRUE, alleleBased=FALSE, details=TRUE, margins=c(25,15))
We can again visualize our results, this time, ordering the cells based on their posterior probabilities of harboring CNVs.
## order cells hc <- trees$hc order <- hc$labels[hc$order] ## plot all chromosomes hb$plotGexpProfile(cellOrder=order) ## plot just identified cnvs hb$plotGexpProfile(cellOrder=order, region=hb$cnvs[['gene-based']][['amp']]) hb$plotGexpProfile(cellOrder=order, region=hb$cnvs[['gene-based']][['del']])
We thus confidently identify amplifications on Chr 5, 7, 20 and deletions on Chr 10, 13, and 14 affecting a subset of cells.
We can also identify CNVs using allele information. The allele model relies on persistent allelic imbalance detected from putative heterozygous variants to identify CNVs. Therefore, allele data for common heterozygous variants from ExAC for the same set of cells has also been prepared for you. Add them to your existing HoneyBADGER
object.
data(r) ## alternate allele data(cov.sc) ## total coverage library(TxDb.Hsapiens.UCSC.hg19.knownGene) ## in order to map SNPs to genes txdb <- TxDb.Hsapiens.UCSC.hg19.knownGene
The allele matrices have already been filtered for sites with coverage in any cell and where both annotated alleles are observed. We will filter these SNPs further to guard against potential RNA-editing or sequencing errors before mapping them to genes.
#hb <- new('HoneyBADGER', name='MGH31') ## Add to existing hb object hb$setAlleleMats(r.init=r, n.sc.init=cov.sc, het.deviance.threshold=0.1, n.cores=detectCores()) hb$setGeneFactors(txdb) ## map SNPs to genes
We can visualize the allelic patterns using the following lesser allele fraction profile.
hb$plotAlleleProfile() ## visualize individual SNPs #hb$plotSmoothedAlleleProfile() ## smoothed option for high density data
Here, each row is again a single cell. Each column is a SNP. Dot size illustrates coverage at the SNP site and color denotes the allele bias with yellow meaning equal observation of both alleles. Blue is mono-allelic detection of either the lesser allele, defined as the allele that is less frequently observed across our population of cells. And red being the other allele. In the presence of a deletion, we expect to see persistent depletion of this lesser allele across our population of cells harboring the deletion. Indeed, we again can already visually suspect some chromosomal abnormalities on Chr 10, 13, and 14. To provide a more quantitative assessment, we can again use an HMM approach to identify regions affected by these deletions and LOHs.
hb$calcAlleleCnvBoundaries(init=TRUE, verbose=FALSE) ## HMM ## double check what CNVs were identified bsf <- get('bound.snps.final', slot(hb, '.xData')) snps <- get('snps', slot(hb, '.xData')) regions.snp <- range(snps[unlist(bsf)]) print(regions.snp)
Indeed, our initial HMM has identified a number of candidate CNVs to test. We can now retest all identified CNVs on all cells to derive the final posterior probability of each CNV in each cell.
hb$retestIdentifiedCnvs(retestBoundGenes=FALSE, retestBoundSnps=TRUE, verbose=FALSE) ## look at final results results <- hb$summarizeResults(geneBased=FALSE, alleleBased=TRUE) print(head(results[,1:5])) ## visualize as heatmap trees2 <- hb$visualizeResults(geneBased=FALSE, alleleBased=TRUE, details=TRUE, margins=c(25,15))
We can again visualize our results, this time, ordering the cells based on our previously identified cell ordering for comparison.
## order cells hc2 <- trees2$hc order2 <- hc2$labels[hc2$order] ## plot all chromosomes hb$plotAlleleProfile(cellOrder=order) ## order cells by same order as previously ## plot just identified cnvs hb$plotAlleleProfile(cellOrder=order, region=hb$cnvs[['allele-based']][['del.loh']]) ## compare to new order hb$plotAlleleProfile(cellOrder=order2) hb$plotGexpProfile(cellOrder=order2)
Thus, we confirm the deletion on Chr 10, 13, and 14 in agreement with our expression-based approach. While an allele-based approach is not able to identify amplifications like an expression-based approach, we are generally able to have improved resolution for identifying smaller deletions such as the one on Chr 19.
Leveraging both allele and expression information can improve power and allow us to identify potential copy-neutral LOHs. We can test regions identified by either the expression or allele-based HMMs using both expression and allele information and repeat downstream visualizations as desired.
hb$retestIdentifiedCnvs(retestBoundGenes=TRUE, retestBoundSnps=TRUE, verbose=FALSE) results <- hb$summarizeResults(geneBased=TRUE, alleleBased=TRUE)
Add the following code to your website.
For more information on customizing the embed code, read Embedding Snippets.