Glitch in pheatmap() condition grouping, along with other points of confusion - r

I wanted to have my conditions labelled on the heatmap I am making for DGE.
This code:
mat <- assay(rld)[topVarGenes,]
condition = c("black", "orange")
names(condition) = c("Dark", "Light")
ann_colors = list(condition = condition)
pheatmap(mat, color = colorRampPalette(rev(brewer.pal(n = 7, name = "RdYlBu")))(24), annotation_colors = ann_colors[1], border_color = "grey60", fontsize = 12, scale = "row")
produces this heatmap:
But, this heatmap doesn't have the conditions labelled above the columns like I wanted. So I tried this code:
annotation <- data.frame(annotation)
pheatmap(mat, annotation = annotation, color = colorRampPalette(rev(brewer.pal(n = 7, name = "RdYlBu")))(24), border_color = "grey60", fontsize = 12, scale = "row")
Which almost works, but doesn't use the colors I want to label the conditions (samples 1-3 are "dark" condition and are to be labelled black and samples 4-6 are "light" condition and are to be labelled orange). This graph also includes a funky column label under condition for sample which is redundant and I don't know how to get rid of it. Also, the data.frame(annotation) is an excel sheet I imported of samples and corresponding conditions.
Adding back the annotation_colors to the code:
pheatmap(mat, annotation = annotation, color = colorRampPalette(rev(brewer.pal(n = 7, name = "RdYlBu")))(24), annotation_colors = ann_colors, border_color = "grey60", fontsize = 12, scale = "row")
produces this error:
Error in convert_annotations(annotation_col, annotation_colors) :
Factor levels on variable condition do not match with annotation_colors
Lastly, I tried this bit of code I found in a stack overflow post to define annotation, which gets R to use the correct colors, but they are not in the correct order for the conditions because the %% 2==0 causes it to label every other sample as 'light', but I can't think of anything else to do. Here is the code:
annotation <- data.frame(condition = factor(1:6 %% 2==0, labels = c("Dark", "Light")))
Help is greatly appreciated!

It's not so clear in the vignette, but you can follow the steps below to generate the right data.frame and list, no reason not to work:
First I make a matrix like yours:
library(pheatmap)
M = cbind(matrix(runif(30,min=0,max=0.5),ncol=3),
matrix(runif(30,min=0.3,max=0.8),ncol=3))
rownames(M) = paste0("row",1:10)
colnames(M) = paste0("sample",1:6)
Let's say first 3 columns are "light", and last 3 columns are "dark". We create a data.frame for this, important thing is to have rownames that match the colnames of your matrix:
ann_column = data.frame(
condition = rep(c("light","dark"),each=3))
rownames(ann_col) = colnames(M)
ann_column
condition
1 light
2 light
3 light
4 dark
5 dark
6 dark
Now for the colors, you need a list, and the names need to match the data frame above, and inside the light, you specify what factor matches what color, so:
ann_colors = list(condition = c(dark="black",light="orange"))
And we draw it:
pheatmap(M,annotation_col=ann_col,annotation_colors=ann_colors)

Related

GGplot is refusing to change the colors of my row annotation

There are some issues with my ggplot chart that I can't seem to fix.
# as you may geuss from the file name I have provided this matrix below
vis.matrix <- read.csv("csvfileprovidedbelow.csv")
# setting up annotation_row
cell_df <- data.frame ("Cells" = c(rep("Putative Engram Cell", 10), rep("Random Cell",10))
)
rownames(cell_df) <- rownames(vis.matrix)
cell_df$Cells <- as.factor(cell_df$Cells)
#setting up colors
newCols <- colorRampPalette(grDevices::rainbow(length(unique(cell_df$Cells))))
annoCol <- c("2AFE00", "ACACAC") # green and grey
names(annoCol) <- levels(cell_df$Cells)
annoCol <- list(category = annoCol)
color=colorRampPalette(c("navy", "white", "red"))(50)
#plotting
pheatmap(vis.matrix,cluster_rows = F, cluster_cols=F, annotation_row = cell_df,
annotation_names_col = F, scale = "column", color = color,
annotation_row_colors = annoCol,
show_rownames = F)
Result
For some reason the Cells are not the colors I selected, you can search those colors here: https://www.color-hex.com/
Don't know why ggplot is ignoring the input I'm giving it. Also would like to remove the word "Cells" beside the color bars on the graph, it's unescessary the legend already explains what it is.
Variables as csv's for reproduction(copy and paste!)
vis.matrix is here:
"","LINGO1","ARC","INHBA","BDNF","MAPK4","ADGRL3","PTGS2","CHGB","BRINP1","KCNK1"
"P57_CATCGGGCATGTCGAT",-0.368245729284319,3.47987283505039,2.94634318740768,5.57309275653906,1.28904872906168,5.3650511213102,-0.368245729284319,2.25850383984707,4.60363764575367,-0.368245729284319
"P57_GAAGCAGGTAAAGGAG",-0.384074162377759,4.36118508997518,3.70326968156081,4.89874111968957,1.65959775959153,4.36118508997518,-0.384074162377759,-0.384074162377759,4.89874111968957,2.85506919772029
"P57_TGACTTTTCTTTACAC",-0.357194851773428,2.40812492004642,3.13225019258772,5.67855340720666,-0.357194851773428,3.13225019258772,-0.357194851773428,4.87697271476829,1.38752767040715,-0.357194851773428
"P57_CTAGAGTGTCCGACGT",1.50110424640379,3.34315724311024,2.57863617381809,6.67240079339861,3.34315724311024,3.93616585502151,-0.340948750302666,1.50110424640379,5.77821885172796,3.34315724311024
"P57_CCTTACGTCCAAGTAC",-0.381478022176755,4.73256922534426,2.17554560158375,6.70465771162764,1.23182426263886,3.36449387848259,-0.381478022176755,2.17554560158375,4.45842883227008,3.36449387848259
"P57_ATCCGAAGTGTGACCC",2.60172319423431,1.50562420175544,-0.36816940232616,5.57161579079479,1.50562420175544,3.37941780583703,-0.36816940232616,3.37941780583703,4.47551679831591,3.98264461101114
"P57_TCCACACAGCTCCTCT",-0.364903374339472,2.59101007342497,2.59101007342497,5.23001785519025,-0.364903374339472,3.36504411201368,-0.364903374339472,1.5000703688371,1.5000703688371,-0.364903374339472
"P57_CTGAAGTGTGCTTCTC",-0.384690873645543,3.35025193111807,2.83241374986762,4.71429931551947,3.35025193111807,3.35025193111807,-0.384690873645543,3.35025193111807,2.16480422093696,2.16480422093696
"P57_CTGATAGAGAATCTCC",1.6886646742164,2.87694996247181,-0.342722443403036,7.39148929746973,1.6886646742164,5.75143890945527,-0.342722443403036,5.75143890945527,4.37401237658979,-0.342722443403036
"P57_GGAGCAACATACAGCT",-0.351186802480077,1.4651606822983,1.4651606822983,5.40649850082577,-0.351186802480077,4.34400333395122,-0.351186802480077,1.4651606822983,5.09785565185506,1.4651606822983
"A57_CGTCTACCAGACGCAA",-0.229651158962319,-0.229651158962319,-0.229651158962319,-0.229651158962319,-0.229651158962319,3.72717582194343,-0.229651158962319,-0.229651158962319,-0.229651158962319,-0.229651158962319
"P57_GTTCGGGCAATGGACG",-0.269219507178484,-0.269219507178484,-0.269219507178484,-0.269219507178484,-0.269219507178484,4.26241026631276,-0.269219507178484,-0.269219507178484,-0.269219507178484,-0.269219507178484
"P56_GGTATTGTCATGTCTT",-0.294887130864939,-0.294887130864939,-0.294887130864939,-0.294887130864939,-0.294887130864939,5.06808977241301,-0.294887130864939,-0.294887130864939,-0.294887130864939,-0.294887130864939
"A67_AAATGCCAGATAGTCA",4.03836820795661,-0.211281061058977,-0.211281061058977,-0.211281061058977,-0.211281061058977,-0.211281061058977,-0.211281061058977,-0.211281061058977,-0.211281061058977,-0.211281061058977
"P76_CCCTGATAGAGGACTC",-0.507269585219581,-0.507269585219581,-0.507269585219581,1.90264065061749,-0.507269585219581,4.86614536666517,-0.507269585219581,1.40253909173334,-0.507269585219581,0.697685532698955
"P56_GATCGATTCCGTCAAA",2.00727896845415,-0.313514850319463,-0.313514850319463,2.00727896845415,-0.313514850319463,3.36485632434217,-0.313514850319463,-0.313514850319463,-0.313514850319463,-0.313514850319463
"P57_GCTGCAGCATAGGATA",2.32839123926114,-0.289105834618761,-0.289105834618761,-0.289105834618761,-0.289105834618761,2.32839123926114,-0.289105834618761,-0.289105834618761,-0.289105834618761,4.94588831314104
"P82_AGGATAACATAGGTTC",1.39699437520094,-0.501641808549684,0.696264250985952,1.39699437520094,-0.501641808549684,4.49353661848721,-0.501641808549684,-0.501641808549684,1.89417031052159,-0.501641808549684
"P82_CCAAGCGTCCGGCTTT",-0.328980171926236,-0.328980171926236,-0.328980171926236,4.08682708745919,-0.328980171926236,1.87892345776647,-0.328980171926236,-0.328980171926236,4.08682708745919,-0.328980171926236
"P57_CAGCGACCATGTCCTC",-0.316475979591103,-0.316475979591103,-0.316475979591103,2.18079240270816,-0.316475979591103,6.13886914288907,-0.316475979591103,2.18079240270816,-0.316475979591103,4.67806078500742
pheatmap is not ggplot. It is drawn using grid graphics.
Anyway, you would pass the color specification as follows:
pheatmap(vis.matrix, cluster_rows = F, cluster_cols=F, annotation_row = cell_df,
annotation_names_col = F, scale = "column", color = color,
annotation_colors = list(Cells = c("Putative Engram Cell" = "#2AFE00",
"Random Cell" = "#ACACAC")),
show_rownames = F)

Adding the split according to the specific rowname in a circular heatmap using R

I am a newer in R. I would like to create a circular heatmap and set some split according to https://jokergoo.github.io/2020/05/21/make-circular-heatmaps/, which says :
If the value for split argument is a factor, the order of the factor levels controls the order of heatmaps. If split is a simple vector, the order of heatmaps is unique(split).
# note since circos.clear() was called in the previous plot,
# now the layout starts from theta = 0 (the first sector is 'e')
circos.heatmap(mat1, split = factor(split, levels = c("e", "d", "c", "b", "a")),
col = col_fun1, show.sector.labels = TRUE)
refered result plot
my data was like this:
esters.csv
This is my code
library(circlize)
library(ComplexHeatmap)
library(dendextend)
mat1=read.csv("esters.csv")
row.names(mat1)<-mat1[,1]#
mat2<-mat1[,-1]##remove the first column
mat3<-mat1[-1,]##remove the first row
#Draw circoheatmap
col_fun1 = colorRamp2(c(0, 0.00001, 0.0001, 0.001, 0.01,0.1, 0.4, 0.8), c("#FAFAFA", "#EAF7E7", "#E0F3DC", "#D7F0D1", "#CDEBC6", "#D5E4FD", "#8CACE3", "#5E7192"))##
circos.par(start.degree = 90, gap.degree = 10, gap.after = c(10))##
mat1 = mat1[sample(165, 165), ] # randomly permute rows
split = sample(letters[1:5], 165, replace = TRUE)
splits = factor(split, levels = letters[1:5])
circos.heatmap(mat2, col = col_fun1, split = splits,
dend.track.height = 0.15,
dend.side = "inside",
rownames.side = "outside",
dend.callback = function(dend, m, si) {
color_branches(dend, k = 4, col = 1:4)
}
)
#By default, the numeric matrix is clustered on rows.
#Used to draw legend
lgd = Legend(title = "Relative abundance", col_fun = col_fun1)
grid.draw(lgd)
circos.clear()
I want to add the split according to the specific row name, like "ester40", "ester80", "ester128". For example, the first split or sector contained 40 rows named "ester1, ester2, ester3, ester4,...to ester40" and all columns from "H6d_T" to "M10d_P".
I tried my best to understand it, but it still did not work.
Did anyone could tell me what should I type in
split = ???

R: Conditional formatting a column with percentage(%) value

I will need to do color conditional formatting for 1 particular column, format it to percentage, and export the file as .xlsx. Note that I have 5 data frames that I will run this rule code with, and compile them into 1 workbook each in different sheets. I am stuck on the part where I can't seem to set the conditional rule if I formatted the percentage in it. And vice versa, if I conditional format it first, I'm not sure how I can format percentage for that column. Please refer to my code below.
## Dataframe
cost_table <- read.table(text = "FRUIT COST SUPPLY_RATE
1 APPLE 15 0.026377
2 ORANGE 14 0.01122
3 KIWI 13 0.004122
5 BANANA 11 0.017452
6 AVOCADO 10 0.008324 " , header = TRUE)
## This is the line where I label the %. However if I do that, conditional formatting will not recognize it in the rule
cost_table$SUPPLY_RATE <- label_percent(accuracy = 0.01)(cost_table$SUPPLY_RATE)
## Creating workbook and sheet
Fruits_Table <- createWorkbook()
addWorksheet(Fruits_Table,"List 1")
writeData(Fruits_Table,"List 1",cost_table)
## Style color for conditional formatting
posStyle <- createStyle(fontColour = "#006100", bgFill = "#C6EFCE")
negStyle <- createStyle(fontColour = "#9C0006", bgFill = "#FFC7CE")
## If Supply rate is above 1.5%, it will be green, if it's equivalent or below, it will be red
conditionalFormatting(Fruits_Table, "List 1",
cols = 3,
rows = 2:6, rule = "C2> 0.015", style = posStyle
)
conditionalFormatting(Fruits_Table, "List 1",
cols = 3,
rows = 2:6, rule = "C2<= 0.015", style = negStyle
)
The output should be as shown below.
Regarding Borderline info
What I'm looking at is to apply outside border for c2:c6.
To clarify my purpose, the final output will be shown as below. I have some other codes to format the borders for the headers and column A:B. Because of the percentage style, it affected my borderline.
You don't need to use label_percent from scales package.
You can apply the percentage format along with the color rules to the workbook by using style and then addStyle functions. Another thing, I found in the documented examples of conditionalFormatting that you don't need to specify the column name (such as C) in the rule argument if your rule apply to only one column with no relation to values in another column.
Here is the code that I used:
Fruits_Table <- createWorkbook()
addWorksheet(Fruits_Table,"List 1")
writeData(Fruits_Table,"List 1",cost_table)
conditionalFormatting(Fruits_Table, "List 1",
cols = 3,
rows = 2:6, rule = "> 0.015", style = posStyle)
conditionalFormatting(Fruits_Table, "List 1",
cols = 3,
rows = 2:6, rule = "<= 0.015",
style = negStyle)
percent_style <- createStyle(numFmt = "PERCENTAGE")
addStyle(Fruits_Table,"List 1", style = ,percent_style, rows = 2:6, cols = 3)
I tried that code and it works.
saveWorkbook(Fruits_Table, "my_fruits_table.xlsx", )
Updated to add borderline info
In case you want to create borderline along with the percentage format, you can use border and borderStyle as follows:
percent_border_style<- createStyle(numFmt = "PERCENTAGE",
border = "TopBottomLeftRight",
borderStyle = "medium" )
addStyle(Fruits_Table,"List 1",
style = ,percent_border_style,
rows = 2:6, cols = 3)
saveWorkbook(Fruits_Table, "borderline_fruits_table.xlsx", )
Here is the borderline result
In case you want to customize different styles to different cells, as you explained in your comment, you need to createStyle for a particular style, and then you use addStyle to apply that particular style to a particular cell. So, you need to specify the row and the column for each style. To keep the percentage format style, you also need to keep numFmt to each addStyle.
Here is an example code to apply outside borders to the targeted column. The code customizes borders to three groups of cells:
top_side_line <- createStyle(numFmt = "PERCENTAGE",
border = "TopLeftRight",
borderStyle = "medium")
side_line <- createStyle(numFmt = "PERCENTAGE",
border = "LeftRight",
borderStyle = "medium")
bottom_side_line <- createStyle(numFmt = "PERCENTAGE",
border = "BottomLeftRight",
borderStyle = "medium")
addStyle(Fruits_Table,"List 1",
style = top_side_line, rows = 2, cols = 3)
addStyle(Fruits_Table,"List 1",
style = side_line, rows = 3:5, cols = 3)
addStyle(Fruits_Table,"List 1",
style = bottom_side_line, rows = 6, cols = 3)
saveWorkbook(Fruits_Table, "newline_fruits_table.xlsx")
Here is the result:

Plotly gauge graph and crosstalk filtering for flexdashboard

I am trying the create a plotly gauge graph for a flexdashboard which should change value depending on the chosen filter in crosstalk::filter_select().
I have tried and tried but cannot get the filter to work. This is an example with mtcars of what I am trying to do. I noticed that if the SharedData object has only one value, then it works, but otherwise plotly does not show any data.
mtcars_data <- tibble::rownames_to_column(mtcars, "Car")
shared_mtcars <- SharedData$new(mtcars_data)
row1 <- bscols(filter_select("Car", "Car", shared_mtcars, ~Car, multiple = F)
)
fig <- plot_ly(shared_mtcars,
domain = list(x = c(0, 1), y = c(0, 1)),
value = ~mpg,
title = list(text = "MPG"),
type = "indicator",
mode = "gauge+number")
bscols(row1, fig, widths = 12)
This code results in a graph with no data. If I subset mtcars_data to take the first row or the first two rows (which happen to have the same value for mpg) then it works. If I subset rows 1 and 3, it doesn't.
I might be missing something - in that case would really appreciate any feedback.

How to zoom in on/extract a subsection of/extract colours from a heatmap.2 in R?

I'm creating heatmaps in R using heatmap.2 (I think it needs to be heatmap.2 because I'm using 1 dataset to generate the colours of the heatmap and a second dataset to overlay numerical data).
Here is a sample of my code so far. The actual data set is 30 columns and 1000 rows.
heatmap_all_data <-
data.frame(name = c("John", "Mark", "Luke", "Jack", "Will", "Jim", "Clive", "Steve"),
trait_1 = c(1, 2, 5, 8, 5, 3, 7, 8),
trait_2 = c(5, 7, 3, 4, 6, 3, 2, 1)) %>%
column_to_rownames(var="name")
heatmap_colour <- colorRampPalette(brewer.pal(11, "RdYlBu"))(1000)
heatmap.2(as.matrix(heatmap_all_data),
scale = "column",
key = FALSE,
dendrogram = "none",
Rowv = FALSE,
Colv = FALSE,
trace = "none",
col = rev(heatmap_colour),
labRow = row.names(heatmap_all_data))
Which generates the following heatmap: https://i.stack.imgur.com/lK8Sc.png
NOW, the problem is I only want a subsection of this data, e.g I want the following heatmap:
heatmap_part_data <-
data.frame(name = c("John", "Mark", "Luke"),
trait_1 = c(1, 2, 5),
trait_2 = c(5, 7, 3)) %>%
column_to_rownames(var="name")
heatmap_colour <- colorRampPalette(brewer.pal(11, "RdYlBu"))(1000)
heatmap.2(as.matrix(heatmap_part_data),
scale = "column",
key = FALSE,
dendrogram = "none",
Rowv = FALSE,
Colv = FALSE,
trace = "none",
col = rev(heatmap_colour),
labRow = row.names(heatmap_part_data))
https://i.stack.imgur.com/j33Ic.png
BUT, I want each cell to keep the same colours as the original. I.e. I want the colours in my subsetted heatmap to be relative to the total data and not just the subsetted data. (In the real example I want to show 10 out of 1000 entries).
So, I need to either "zoom in" and rescale the top section of the heatmap and then crop the image, extract the top section of the heatmap into a new object while maintaining the same colours, or extract information about the colours in the full heatmap and overwrite the default colours in the subsetted heatmap.
The goal is basically to output an image of the subsetted data heatmap with each colour in each cell the same as in the all_data heatmap.
I hope this is clear - please advise if you need any clarification!
Many thanks for taking the time to read and I hope someone can help.
Best,
Ryan
Found the solution!
So I switched from heatmap.2 to heatmaply - same functionality but with interactivity. With heatmaply you can drag an area over the heatmap and zoom into that area which gives the desired result but I wanted to consistently zoom to a specific area.
From this website (https://plotly.com/r/axes/) I found out about the Layout function of the wider plotly library (that heatmaply is part of).
So to the existing code you can add:
%>% layout(yaxis = list(range = c(10.5, 0.5)))
(Need to add 0.5 to centre the rows properly)
Et voila! The heatmap colours are generated relative to the wider dataset but only a subset is shown.

Resources