#' Make nice colors for metadata
#'
#' The function will take a metadata table and use Set2 palette when
#' number of levels is > 3 or a set or orange/blue colors other wise.
#'
#' @param ann Data.frame with metadata information. Each column will be used to
#' generate a palette suitable for the values in there.
#' @param col_fun Whether to return a function for continuous variables
#' (compatible with [ComplexHeatmap::HeatmapAnnotation()]) or
#' the colors themself (comparible with [pheatmap::pheatmap())]).
#' @param con_values Color to be used for continuous variables.
#' @param cat_values Color to be used for 2-levels categorical variables.
#' @param palette Palette to use from `brewer.pal()` for
#' multi-levels categorical variables.
#' @examples
#' data(humanGender)
#' library(DESeq2)
#' library(ComplexHeatmap)
#' idx <- c(1:10, 75:85)
#' dse <- DESeqDataSetFromMatrix(assays(humanGender)[[1]][1:10, idx],
#' colData(humanGender)[idx,], design=~group)
#' th <- HeatmapAnnotation(df = colData(dse),
#' col = degColors(colData(dse), TRUE))
#' Heatmap(log2(counts(dse)+0.5), top_annotation = th)
#'
#' custom <- degColors(colData(dse), TRUE,
#' con_values = c("white", "red"),
#' cat_values = c("white", "black"),
#' palette = "Set1")
#' th <- HeatmapAnnotation(df = colData(dse),
#' col = custom)
#' Heatmap(log2(counts(dse)+0.5), top_annotation = th)
#' @export
degColors <- function(ann, col_fun = FALSE,
con_values = c("grey80", "black"),
cat_values = c("orange", "steelblue"),
palette = "Set2"){
col <- lapply(names(ann), function(a){
if (class(ann[[a]][1])[1] == "numeric"){
fn = colorRamp2(c(min(ann[[a]]),
max(ann[[a]])),
con_values)
if (col_fun){
return(fn)
}else{
return(fn(ann[[a]]))
}
}
if (length(unique(ann[[a]])) < 3){
v <- cat_values[1:length(unique(ann[[a]]))]
names(v) <- unique(ann[[a]])
return(v)
}
v <- brewer.pal(length(unique(ann[[a]])), palette)
names(v) <- unique(ann[[a]])
v
})
names(col) <- names(ann)
col
}
#' Plot top genes allowing more variables to color and shape points
#'
#' @param dds [DESeq2::DESeqDataSet] object or SummarizedExperiment
#' or Matrix or data.frame. In case of a DESeqDataSet object, always
#' the normalized expression will be used
#' from `counts(dds, normalized = TRUE)`.
#' @param res [DESeq2::DESeqResults] object.
#' @param n Integer number of genes to plot from the `res` object. It will
#' take the top N using padj values to order the table.
#' @param genes Character of gene names matching rownames of count data.
#' @param xs Character, colname in colData that will be used as X-axes.
#' @param group Character, colname in colData to color points and add different
#' lines for each level.
#' @param batch Character, colname in colData to shape points, normally used by
#' batch effect visualization.
#' @param ann Columns in rowData (if available) used to print gene names. First
#' element in the vector is the column name in rowData that matches the
#' row.names of the `dds` or `count` object. Second element in the vector
#' is the column name in rowData that it will be used as the title for each
#' gene or feature figure.
#' @param metadata Metadata in case dds is a matrix.
#' @param slot Name of the slot to use to get count data.
#' @param log2 Whether to apply or not log2 transformation.
#' @param xsLab Character, alternative label for x-axis (default: same as xs)
#' @param ysLab Character, alternative label for y-axis..
#' @param color Color to use to plot groups. It can be one color, or a palette
#' compatible with `ggplot2::scale_color_brewer()`.
#' @param groupLab Character, alternative label for group (default: same as group).
#' @param batchLab Character, alternative label for batch (default: same as batch).
#' @param sizePoint Integer, indicates the size of the plotted points (default 1).
#' @return ggplot showing the expresison of the genes
#' @examples
#' data(humanGender)
#' library(DESeq2)
#' idx <- c(1:10, 75:85)
#' dse <- DESeqDataSetFromMatrix(assays(humanGender)[[1]][1:1000, idx],
#' colData(humanGender)[idx,], design=~group)
#' dse <- DESeq(dse)
#' degPlot(dse, genes = rownames(dse)[1:10], xs = "group")
#' degPlot(dse, genes = rownames(dse)[1:10], xs = "group", color = "orange")
#' degPlot(dse, genes = rownames(dse)[1:10], xs = "group", group = "group",
#' color = "Accent")
#' @export
degPlot = function(dds, xs, res = NULL, n = 9, genes = NULL,
group = NULL, batch = NULL,
metadata = NULL,
ann = c("geneID", "symbol"),
slot = 1L,
log2 = TRUE,
xsLab = xs,
ysLab = "abundance",
color = "black",
groupLab = group, batchLab = batch,
sizePoint = 1){
if (class(dds)[1] %in% c("data.frame", "matrix"))
dds = SummarizedExperiment(assays = SimpleList(counts = as.matrix(dds)),
colData = metadata)
if ( !("assays" %in% slotNames(dds)) )
stop("dds object doesn't have assays slot")
if (!is.null(res))
res <- res[order(res$padj),] %>% .[!is.na(res$padj),]
if (is.null(genes))
genes = row.names(res)[1L:n]
anno <- as.data.frame(rowData(dds))
metadata = data.frame(colData(dds))
if (class(dds)[1] == "DESeqDataSet")
counts <- counts(dds, normalized = TRUE)
else counts <- assays(dds)[[slot]]
stopifnot(class(counts)[1] == "data.frame" | class(counts)[1] == "matrix")
if (log2 & max(counts) < 500L)
warning("Data seems to be already in log2. Please use log2 = FALSE.")
if (log2){
counts <- log2(counts + 0.2)
ysLab <- paste("log2", ysLab)
}
newgenes <- genes
if (ncol(anno) > 0) {
name <- intersect(names(anno), ann)
if (length(name) != 2L)
message("No genes were mapped to rowData. check ann parameter values.")
if (length(name) == 2L)
newgenes <- anno[match(genes, anno[, ann[1L]]), ann[2L]]
if (sum(is.na(newgenes)) > 0)
warning(sum(is.na(newgenes)), " cannot be mapped to ", name[2L],
". Those will be skipped.")
}
dd <- melt(as.data.frame(counts[genes, , drop = FALSE]) %>%
mutate(gene = factor(newgenes, levels=newgenes)))
colnames(dd) = c("gene", "sample", "count")
dd <-dd[!is.na(dd[["gene"]]),]
dd$xs = as.factor(metadata[as.character(dd$sample), xs])
if (!is.null(group)) {
dd[, groupLab] = as.factor(metadata[as.character(dd$sample), group])
}else {
groupLab = "fake"
dd[, groupLab] = "fake"
}
if (!is.null(batch)) {
dd[, batchLab] = as.factor(metadata[as.character(dd$sample), batch])
p = ggplot(dd, aes_string(x = "xs", y = "count", color = groupLab,
shape = batchLab))
}else{
p = ggplot(dd, aes_string(x = "xs", y = "count", color = groupLab))
}
p = p +
# geom_violin(alpha=0.3) +
stat_smooth(fill = "grey80", method = 'loess') +
geom_point(size = sizePoint, alpha = 0.7,
position = position_jitterdodge(dodge.width = 0.9)) +
facet_wrap(~gene, scales = "free_y") +
xlab(xsLab) +
ylab(ysLab)
if (length(unique(dd[, groupLab])) == 1L) {
stopifnot(length(color) == 1)
p = p +
scale_color_manual(guide = "none", values = color) +
scale_fill_manual(guide = "none", values = color)
}else{
if (color == "black")
color = "Set1"
p = p +
scale_color_brewer(palette = color) +
scale_fill_brewer(palette = color)
}
p = p + theme_bw() +
theme(strip.background = element_rect(fill = "white"),
strip.text = element_text(colour = "black"))
suppressWarnings(p)
}
#' Plot selected genes on a wide format
#'
#' @param counts [DESeq2::DESeqDataSet] object or expression matrix
#' @param genes character genes to plot.
#' @param group character, colname in colData to color points and add different
#' lines for each level
#' @param metadata data.frame, information for each sample. Not needed if
#' [DESeq2::DESeqDataSet] given as counts.
#' @param batch character, colname in colData to shape points, normally used by
#' batch effect visualization
#' @return ggplot showing the expresison of the genes on the x
#' axis
#' @examples
#' data(humanGender)
#' library(DESeq2)
#' idx <- c(1:10, 75:85)
#' dse <- DESeqDataSetFromMatrix(assays(humanGender)[[1]][1:1000, idx],
#' colData(humanGender)[idx,], design=~group)
#' dse <- DESeq(dse)
#' degPlotWide(dse, rownames(dse)[1:10], group = "group")
#' @export
degPlotWide <- function(counts, genes, group, metadata=NULL, batch=NULL){
if (is.null(metadata))
metadata = data.frame(colData(counts))
metadata = data.frame(metadata)
if (class(counts)[1] == "DESeqDataSet") {
dd = bind_rows(lapply(genes,function(gene){
plotCounts(counts, gene,
intgroup = group, returnData = TRUE) %>%
mutate(count = log2(count + 1)) %>%
mutate(gene = gene, sample = row.names(metadata))}))
dd$group = dd[[group]]
}else if (class(counts)[1] == "matrix") {
dd = melt(counts[genes, ])
colnames(dd) = c("gene", "sample", "count")
dd$group = as.factor(metadata[as.character(dd$sample), group])
}else{
stop("No supported for class", class(counts)[1])
}
if (is.null(group)) {
dd$treatment = "one_group"
}else{
dd$treatment = dd[,"group"]
}
p = ggplot(dd, aes_string(x = "gene", y = "count", color = "treatment"))
if (!is.null(batch)) {
dd$batch = as.factor(metadata[dd$sample, batch])
p = ggplot(dd, aes_string(x = "gene", y = "count",
color = "treatment", shape = "batch"))
}
p = p +
geom_point(position = position_jitterdodge(dodge.width = 0.9)) +
xlab("Genes") +
ylab("Normalized Counts") +
theme_bw() +
theme(axis.text.x = element_text(angle = 45L, hjust = 1L))
p
}
Add the following code to your website.
For more information on customizing the embed code, read Embedding Snippets.