R: Heatmap con colori basati sui gruppi, valori NA in grigio e caratteri inclusi

Aug 22 2020

Sto cercando di creare una mappa di calore usando ggplot e geom_tile. Il colore di riempimento è basato sui miei valori x e alfa basato sui valori. Sulla base di un piccolo esempio (a sinistra), vorrei che il mio Plot fosse simile a questo esempio (a destra). Due problemi:

  1. Ottengo errori per gli elementi del carattere sulla mia scala alfa - è possibile trattarli come NA/ignorarli?
  2. I valori NA effettivi sono colorati con lo stesso colore del gruppo a cui appartengono, invece di avere tutti un riempimento grigio.

I dati reali sono molto più grandi e contengono sfaccettature .. spero che questo non rovini nessuna possibile soluzione. Ecco il mio set di dati di esempio e il mio codice (semi-funzionante):


X <- rep(st, each=3)
Y <- rep(st, times=3)

Values<- c('Apple', 2,3,NA, "Banana", 3,1,2,"Pear")

Data <- data.frame(X,Y,Values)

ggplot(Data, mapping = aes(x=X, y=Y, fill=X, 
                           alpha=Values # excluding this part I get a result, just not as I want it
       )) + 
  geom_tile(colour="white") +
  ylab("Y") + 
  xlab("X")+
  scale_fill_manual("Assay", 
                    values = c( 'red', 'yellow', 'green'),
                    na.value = 'grey')+
  scale_alpha("Value", na.value = 0.02)+
  ggtitle("Results Summary")+       
  theme( strip.text.y.left = element_text(angle = 0))+
  geom_text(label=Data$Values)

Grazie in anticipo per qualsiasi aiuto :)

Risposte

3 stefan Aug 22 2020 at 18:30

Il tuo primo problema può essere risolto convertendo Valuesin un valore numerico, ovvero mappando as.numeric(Values)su alpha.

Per quanto riguarda la seconda questione. Man mano che si mappa Xsul riempimento, le tessere vengono colorate in base a X. Se vuoi riempire le NA in modo diverso così come le tessere X==Y, devi definire i colori di riempimento di conseguenza. A tal fine il mio approccio aggiunge una colonna fillal df e fa uso di scale_fill_identity.

Si noti che ho spostato alphae fillin geom_tilemodo che non vengano trasmessi a geom_text...

... e seguendo il suggerimento di @AllanCameron ho invertito l'ordine di "Y" in modo che la trama sia in linea con l'output desiderato.

library(ggplot2)
library(dplyr)

X <- rep(c('Apple', "Banana", "Pear"), each=3)
Y <- rep(c('Apple', "Banana", "Pear"), times=3)
Y <- factor(Y, levels = c("Pear", "Banana", "Apple"))

Values<- c('Apple', 2,3,NA, "Banana", 3,1,2,"Pear")

Data <- data.frame(X,Y,Values)
Data <- Data %>% 
  mutate(fill = case_when(
    is.na(Values) ~ "grey",
    X == Y ~ "white",
    X == "Apple" ~ "red",
    X == "Banana" ~ "yellow",
    X == "Pear" ~ "green"
  ))

ggplot(Data, mapping = aes(x=X, y=Y)) + 
  geom_tile(aes(fill=fill, alpha=as.numeric(Values)), colour="white") +
  ylab("Y") + 
  xlab("X")+
  scale_fill_identity("Assay") +
  scale_alpha("Value")+
  ggtitle("Results Summary")+       
  theme(strip.text.y.left = element_text(angle = 0))+
  geom_text(aes(label=if_else(!is.na(Values), Values, "NA")))
#> Warning in FUN(X[[i]], ...): NAs introduced by coercion