2015-03-27 7 views
7

Ich habe eine Heatmap, die immer komplexer wird. Ein Beispiel für die geschmolzenen Daten:ggplot2: Komplexere Facettierung

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 

Mit ggplot2 und geom_tile konnte ich eine schöne Heatmap der Daten erzeugen. Ich bin stolz auf den Code (dies ist meine erste Erfahrung in R), so haben sie unten geschrieben:

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")' 

Wie Sie sehen können, gibt es ziemlich viel manuelle Umordnung beteiligt, da sonst der Code ist ziemlich einfach . Hier ist die Bildausgabe:

heatmap

Allerdings können Sie feststellen, dass eine ganze Spalte von Informationen, „Unterklasse“ nicht verwendet wird. Grundsätzlich passt jede Unterklasse in eine Klasse. Es wäre perfekt, wenn ich diese Subclasses innerhalb der bereits angezeigten Klassenfacette facettieren könnte. Soweit ich weiß, ist das unmöglich. Um genau zu sein, hat nur Klasse A unterschiedliche Unterklassen. Die anderen Klassen haben einfach ihren Klassennamen gespiegelt (F = Klasse f). Gibt es eine andere Möglichkeit, diese Heatmap so zu organisieren, dass ich alle relevanten Informationen anzeigen kann? Die fehlenden Subclasses enthalten einige der wichtigsten Daten und sind am notwendigsten, um Rückschlüsse aus den Daten zu ziehen. Ein alternativer Ansatz besteht darin, die Subclases anstelle der Klassen zu facettieren, sie manuell neu anzuordnen, so dass die Classes zusammen gruppiert sind, und dann eine Art Box um sie herum zu zeichnen, um jede Klasse abzugrenzen. Ich habe keine Ahnung, wie das gemacht werden würde.

Jede Hilfe wäre sehr nützlich. Bitte lassen Sie mich wissen, wenn Sie weitere Informationen benötigen.

+0

Wo Sie haben 'facet_grid (Klasse ~ Clade,', ändern Sie es zu 'facet_grid (Klasse + Subclass ~ Clade,' – Gregor

+0

Obwohl, für die Bestellung der Etiketten, möchten Sie wahrscheinlich 'Subclass + Klasse ". – Gregor

+0

Das ist ein Weg, es zu tun, danke. Es ist nicht genau das, was ich mir vorstellte (verschachtelte Facetten), da es einfach in die Unterklassen aufbricht und dann ein Klassenlabel hinzufügt. Ich schätze, es ist nicht so schön wie ich wie, aber vielleicht ist das so gut, wie es geht. Danke für deine Eingabe, @Gregor. – Nic

Antwort

7

Dies wird einen neuen Streifen rechts neben dem Originalstreifen und links von der Legende einfügen.

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

Drehen meines Kommentars in eine Antwort mit einigen einfachen Demo-Daten:

Dies ist nicht schwer (es gibt sogar Beispiele in ?facet_grid, obwohl sie nach unten hin sind).

# 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 ~ .) 

Sie können dies mit beliebig vielen Faktoren auf beiden Seiten des ~!

+0

Funktionell ist es genau das, was ich will ästhetisch ist es nicht das, wonach ich suche. Aber das ist wahrscheinlich mein Problem, nicht von ggplot2. Ich mag es nicht, wie es die Klassenlabels für jede verschachtelte Unterklasse wiederholt. Mache ich einen Sinn? Für mich scheint es der richtige Weg zu sein, einen größeren Klassenbalken (den grauen Etikettenbereich) zu haben, der die Gesamtheit der Daten, die er enthält, mit einer Untermenge von verschachtelten Unterklassen-Etiketten überspannt. @Gregor – Nic

+0

@Nic Ja, ich verstehe jetzt. Das Problem ist, dass 'ggplot' nicht weiß, dass die Faktoren verschachtelt sind, also ist die Lösung allgemein dafür, ob sie verschachtelt oder gekreuzt sind. – Gregor

+0

@Nic, so etwas [http://stackoverflow.com/.../annotating-facet-title-as-strip-over-facet.....]http://stackoverflow.com/questions/ 22818061/Annotieren-Facetten-Titel-als-Strip-über-Facette/22825447 # 22825447) –

Verwandte Themen