1

Let say I did four measurements/experiments (M1..M4) producing intensity values which vary across 5 locations (loc_1...5). I observed various classes of elements (n=7). Now I would like to summarize the results into a single diagram using facet_grid and geom_raster from ggplot2. I end up with the diagram below (see image).

Now the question is whether there is a simple solution to force rows to fill the space in each facet (i.e to drop unused rows in each panel).

Thank you

rm(list=ls())
library(ggplot2)
library(reshape2)

set.seed(123)

# let's create a fake dataset
nb.mesure <- 4
n.row <- 200
n.col <- 5
nb.class <- 7


d <- matrix(round(runif(n.row * n.col),2), nc=n.col) 
colnames(d) <- sprintf("Loc_%02d", 1:5)

# These strings will be the row names of each heatmap
# in the subsequent facet plot
elements <- sample(replicate(n.row/2, 1:100))

# let's create a data.frame d
d <- data.frame(d, 
                mesure = sort(rep(c("M1","M2","M3", "M4"), n.row/4)),
                elements= elements,
                class=sample(nb.class, 
                             length(elements), 
                             rep=T,
                             prob = seq(0.01, 0.25, length.out=7))
                             )



# Data are melt
dm <- melt(d, id.var=c( "mesure", "elements", "class"))
colnames(dm) <- c("mesure","elements", "class", "pos", "intensity")

# Plotting
p <- ggplot(dm, aes(x = pos, y = elements, fill = intensity))
p <- p + geom_raster()                                        
p <- p + facet_grid(mesure~class , scales = "free", space="free_y")
p <- p + theme_bw()
p <- p + theme(text = element_text(size=8))
p <- p + theme(text = element_text(family = "mono", face = "bold"))
p <- p + theme(axis.text.y = element_blank(), 
               axis.ticks.y=element_blank(),
               axis.text.x = element_text(colour="grey20",
                                           size=6,angle=45,
                                        vjust = 0.3))
print(p)

Example resul

dputhier
  • 734
  • 1
  • 7
  • 23

1 Answers1

1

If your goal is to introduce NA values (or something else) for all missing combinations of mesure, elements, class and pos you can use the complete function from the tidyr package like so:

library(tidyr)

dm <- complete(dm, mesure, elements, class, pos, fill = list(intensity = NA))

enter image description here

UPDATE

In case you want to have the non-NA values expand to fill each facet you have to move away from facet_grid and switch to facet_wrap.

p <- p + facet_wrap(mesure~class , scales = "free_y", nrow = 4)

enter image description here

Jeroen Boeye
  • 580
  • 4
  • 18
  • Thanks Jeroen for answering. I don't want to introduce NA (sorry if it was ot clear). The idea would be to have different heights for the rows with non NA values so that they would fill the whole sub panels. Alternatively I would be interested in a way to shrink some sub panels vertically so that only row with non NA values would be shown. I understand that it is a little weird as row are supposed to point to the same element in each class. However I have hidden row names since in my case, I'm just interest in having a global feeling about intensities of elements from class 1...7 in M1..M4. – dputhier Mar 24 '17 at 13:25
  • By the way thank you for the complete function which I guess can be very helpful. – dputhier Mar 24 '17 at 13:30
  • You're welcome, I see what you mean now. The answer is updated. – Jeroen Boeye Mar 24 '17 at 14:40
  • 1
    That's the most natural solution. Thanks a lot. – dputhier Mar 24 '17 at 14:55