ropensci / iheatmapr

Complex, interactive heatmaps in R
https://docs.ropensci.org/iheatmapr
Other
267 stars 35 forks source link

Allow add_colorbar() to get entirely new levels for an existing variable #75

Open halhen opened 3 years ago

halhen commented 3 years ago

I've run in to a case of "No elements in common between groups with name: var" that might not be appropriate.

Example case:

I'd like to compare gene expression of two sets of samples A and B; genes on Y and samples on X. To compare A and B I plot two main heatmaps next to each other. I'd also like for both groups to have some discrete column annotations. I'd like for these to have the same name, the same legend and the same colors.

If I now happen to add an annotation that have completely different levels for A and B -- no value of the annotation for group A exists in group B and vice versa, but the variable is the same -- I get an error from https://github.com/ropensci/iheatmapr/blob/a31ffc006d1f50ca5c0bb97675d9e4d3c17a5d08/R/colorbars.R#L244 .

A second case is when the annotation added for B only contain NA values -- in this case, the code above will again find 0 shared variables and will stop().

Maybe there is an important reason to stop() in this case. Or maybe it is to protect from the possibility of the user adding two different annotations with the same name? If it's the latter, would you consider only to give a warning(), to allow from the example given above?

A workaround is to make each annotation column a factor with -all- the necessary levels -- either all allowed levels for the variable or, to keep the number of ticks minimal, the ones available in either A or B.

Reproducible example:

library(iheatmapr)

A <- matrix(rnorm(6), ncol = 3)
colnames(A) <- c('S1', 'S2', 'S3')
rownames(A) <- c('G1', 'G2')

B <- A

annotation_A <- data.frame(var = c('a', 'b', 'c'))
rownames(annotation_A) <- c('S1', 'S2', 'S3')

annotation_B <- data.frame(var = c('d', 'e', 'f'))
rownames(annotation_B) <- c('S1', 'S2', 'S3')

annotation_NA <- dplyr::mutate(annotation_A, var = NA)

# Works
main_heatmap(A) %>%
  add_col_annotation(annotation_A) %>%
  add_main_heatmap(B) %>%
  add_col_annotation(annotation_A)

# Fails
main_heatmap(A) %>%
  add_col_annotation(annotation_A) %>%
  add_main_heatmap(B) %>%
  add_col_annotation(annotation_B)

# Fails too
main_heatmap(A) %>%
  add_col_annotation(annotation_A) %>%
  add_main_heatmap(B) %>%
  add_col_annotation(annotation_NA)
AliciaSchep commented 3 years ago

Thanks for the reproducible example. I think you're probably right that having an error rather than a warning (or even just message) is too much. I don't recall why it was implemented that way, my best guess is an attempt to provide safeguard for the logic of combining color bars -- that it might combine things that a user doesn't want combined. I'll test out what switching it to a warning or message would do.

AliciaSchep commented 3 years ago

It seems like the way the merging of the colorbars is done is generally broken unless the inputs are factors with the same levels.