2015-03-27 15 views
7

Ho una mappa termica che continua a diventare sempre più complessa. Un esempio dei dati fusa:ggplot2: sfaccettatura più complessa

head(df2) 
    Class  Subclass   Family    variable value 
1  A chemosensory family_1005117 caenorhabditis_elegans 10 
2  A chemosensory family_1011230 caenorhabditis_elegans  4 
3  A chemosensory family_1022539 caenorhabditis_elegans 10 
4  A  other family_1025293 caenorhabditis_elegans NA 
5  A chemosensory family_1031345 caenorhabditis_elegans 10 
6  A chemosensory family_1033309 caenorhabditis_elegans 10 
tail(df2) 
    Class Subclass  Family  variable value 
6496  C class c family_455391 trichuris_muris  1 
6497  C class c family_812893 trichuris_muris NA 
6498  F class f family_225491 trichuris_muris  1 
6499  F class f family_236822 trichuris_muris  1 
6500  F class f family_276074 trichuris_muris  1 
6501  F class f family_768194 trichuris_muris NA 

Utilizzando ggplot2 e geom_tile, sono stato in grado di produrre una bella heatmap dei dati. Sono orgoglioso del codice (questa è la mia prima esperienza in R), così ho postato qui sotto:

df2[df2 == 0] <- NA 
df2[df2 > 11] <- 10 
df2.t <- data.table(df2) 
df2.t[, clade := ifelse(variable %in% c("pristionchus_pacificus", "caenorhabditis_elegans", "ancylostoma_ceylanicum", "necator_americanus", "nippostrongylus_brasiliensis", "angiostrongylus_costaricensis", "dictyocaulus_viviparus", "haemonchus_contortus"), "Clade V", 
       ifelse(variable %in% c("meloidogyne_hapla","panagrellus_redivivus", "rhabditophanes_kr3021", "strongyloides_ratti"), "Clade IV", 
       ifelse(variable %in% c("toxocara_canis", "dracunculus_medinensis", "loa_loa", "onchocerca_volvulus", "ascaris_suum", "brugia_malayi", "litomosoides_sigmodontis", "syphacia_muris", "thelazia_callipaeda"), "Clade III", 
       ifelse(variable %in% c("romanomermis_culicivorax", "trichinella_spiralis", "trichuris_muris"), "Clade I", 
       ifelse(variable %in% c("echinococcus_multilocularis", "hymenolepis_microstoma", "mesocestoides_corti", "taenia_solium", "schistocephalus_solidus"), "Cestoda", 
       ifelse(variable %in% c("clonorchis_sinensis", "fasciola_hepatica", "schistosoma_japonicum", "schistosoma_mansoni"), "Trematoda", NA))))))] 
df2.t$clade <- factor(df2.t$clade, levels = c("Clade I", "Clade III", "Clade IV", "Clade V", "Cestoda", "Trematoda")) 
plot2 <- ggplot(df2.t, aes(variable, Family)) 
tile2 <- plot2 + geom_tile(aes(fill = value)) + facet_grid(Class ~ clade, scales = "free", space = "free") 
tile2 <- tile2 + scale_x_discrete(expand = c(0,0)) + scale_y_discrete(expand = c(0,0)) 
tile2 <- tile2 + theme(axis.text.y = element_blank(), axis.ticks.y = element_blank(), legend.position = "right", axis.text.x = element_text(angle = 90, hjust = 1, vjust = 0.55), axis.text.y = element_text(size = rel(0.35)), panel.border = element_rect(fill=NA,color="grey", size=0.5, linetype="solid")) 
tile2 <- tile2 + xlab(NULL) 
tile2 <- tile2 + scale_fill_gradientn(breaks = c(1,2,3,4,5,6,7,8,9,10),labels = c("1", "2", "3", "4", "5", "6", "7", "8", "9", ">10"), limits = c(1, 10), colours = palette(11), na.value = "white", name = "Members")' 

Come si può vedere, c'è un bel po 'di riordino manuale coinvolti, altrimenti il ​​codice è piuttosto semplice . Ecco l'output immagine:

heatmap

Tuttavia, si può notare che tutta una colonna di informazioni, "sottoclasse" non viene utilizzato. Fondamentalmente, ciascuna Sottoclasse rientra in una Classe. Sarebbe perfetto se fossi in grado di sfaccettare queste sottoclassi all'interno del facet della classe già visualizzato. Per quanto ne so, questo è impossibile. Per essere precisi, solo la Classe A ha sottoclassi diverse. Le altre Classi hanno semplicemente il nome della classe speculare (F = classe f). C'è un altro modo per organizzare questa heatmap in modo da poter visualizzare tutte le informazioni rilevanti? Le sottoclassi mancanti contengono alcuni dei dati più cruciali e saranno le più necessarie per trarre inferenze dai dati.

Un approccio alternativo sarebbe quello di sfaccettare le Sottoclassi anziché le Classi, riordinarle manualmente in modo che le Classi siano raggruppate insieme e quindi disegnare una sorta di riquadro attorno a esse per delimitare ogni Classe. Non ho idea di come sarebbe stato fatto.

Qualsiasi aiuto sarebbe molto utile. Per favore fatemi sapere se avete bisogno di ulteriori informazioni.

+0

Dove avete 'facet_grid (classe ~ clade,', modificarlo a 'facet_grid (Class + sottoclasse ~ clade,' – Gregor

+0

Anche se, per l'ordinazione delle etichette, probabilmente si vuole 'sottoclasse + Class'. – Gregor

+0

Questo è un modo per farlo, grazie. Non è esattamente ciò che immaginavo (facce nidificate), poiché lo suddivide semplicemente nelle Sottoclassi e poi aggiunge un'etichetta di Classe. Immagino che non sia così carina come vorrei Mi piace, ma forse è buono come lo è.Grazie per il tuo contributo, @ Gregor. – Nic

risposta

7

Questo inserirà una nuova striscia a destra della striscia originale e alla sinistra della legenda.

library(ggplot2) 
library(gtable) 
library(grid) 

p <- ggplot(mtcars, aes(mpg, wt, colour = factor(vs))) + geom_point() 
p <- p + facet_grid(cyl ~ gear) 

# Convert the plot to a grob 
gt <- ggplotGrob(p) 

# Get the positions of the right strips in the layout: t = top, l = left, ... 
strip <-c(subset(gt$layout, grepl("strip-r", gt$layout$name), select = t:r)) 

# New column to the right of current strip 
gt <- gtable_add_cols(gt, gt$widths[9], max(strip$r)) 

# Add grob, the new strip, into new column 
gt <- gtable_add_grob(gt, 
    list(rectGrob(gp = gpar(col = NA, fill = "grey85", size = .5)), 
    textGrob("Number of Cylinders", rot = -90, vjust = .27, 
     gp = gpar(cex = .75, fontface = "bold", col = "black"))), 
     t = min(strip$t), l = max(strip$r) + 1, b = max(strip$b), name = c("a", "b")) 

# Add small gap between strips 
gt <- gtable_add_cols(gt, unit(1/5, "line"), max(strip$r)) 

# Draw it 
grid.newpage() 
grid.draw(gt) 

enter image description here

2

Girando il mio commento in una risposta con alcuni semplici dati demo:

Questo non è difficile (c'è anche esempi in ?facet_grid, anche se sono verso il basso).

# generate some nested data 
dat = data.frame(x = rnorm(12), y = rnorm(12), class = rep(LETTERS[1:2], each = 6), 
       subclass = rep(letters[1:6], each = 2)) 

# plot it 
ggplot(dat, aes(x, y)) + geom_point() + 
    facet_grid(subclass + class ~ .) 

Si può fare questo con un numero arbitrario di fattori su entrambi i lati della ~!

+0

Funzionalmente, è esattamente quello che voglio. esteticamente, non è quello che sto cercando. Ma probabilmente è il mio problema, non quello di ggplot2. Non mi piace come ripete le etichette di classe per ogni sottoclasse nidificata. Ho un senso? Per me, sembra che il modo giusto per farlo sarebbe avere una barra di Classe più grande (l'area dell'etichetta grigia) che copre l'insieme dei dati che contiene con un sottoinsieme di etichette sottoclasse annidate. @ Gregor – Nic

+0

@Nic Sì, ho capito ora. Il problema è che 'ggplot' non sa che i fattori sono nidificati, quindi la soluzione è generale se sono nidificati o incrociati. – Gregor

+0

@Nic, qualcosa di simile [http://stackoverflow.com/.../annotating-facet-title-as-strip-over-facet.....](http://stackoverflow.com/questions/ 22818061/annotating-facet-title-as-strip-over-facet/22825447 # 22825447) –

Problemi correlati