3

I need to use xyplot in combination with dlply, to plot on several pages. Following the example below, one page for each value of x, conditioning on y:

set.seed(1)
df <- as.data.frame(cbind(
    x = c("AV","DZ"),   
    y=rep(c(letters[1:4]),5), 
    stringsAsFactors = F))
df$z <- rnorm(20)
df$q <- rnorm(20)
plotter <- function(dataframe) { xyplot(q ~ z | y, data=dataframe)}
charts <- dlply(df, .(x), plotter)
charts

Now, if I want to change the color of the strip background (as usefully explained here), should I pick the value of the color from a list as well? Should I use a list of vectors? A dataframe? A combination of x & y values? Two nested plyr functions? Let's suppose that the four panel colours should be the following:

"blue"  "red"   "blue"  "green"

How would you suggest to modify the col parameter in the myStripStyle function (proposed in the link) that follows?

bgColors <- c("black", "green4", "blue", "red", "purple", "yellow")
txtColors <- c("white", "yellow", "white", "white", "green", "red")
# Create a function to be passed to "strip=" argument of xyplot
myStripStyle <- function(which.panel, factor.levels, ...) {
panel.rect(0, 0, 1, 1,
col = bgColors[which.panel],
border = 1)
panel.text(x = 0.5, y = 0.5,
font=2,
lab = factor.levels[which.panel],
col = txtColors[which.panel])
}

To be honest, I think that this question could have already been answered somewhere else, but I couldn't find any mix of plyr functions and lattice graphics that could help me to change parameters in this way.

Community
  • 1
  • 1
MaZe
  • 239
  • 1
  • 4
  • 13

1 Answers1

1

This is a hack and somebody with experience in lattice should really add a proper answer. But this will do what you desire, so here it goes. You can specify allLevels in the global environment. Then you recalculate which.panel within myStripStyle using the global variable allLevels.

allLevels <- levels(df$y)
# Create a function to be passed to "strip=" argument of xyplot
myStripStyle <- function(which.panel, factor.levels,  ...) {
  # recalculate which.panel based on allLevels
  which.panel <- match(factor.levels, allLevels)[which.panel]
  panel.rect(0, 0, 1, 1,
             col = bgColors[which.panel],
             border = 1)
  panel.text(x = 0.5, y = 0.5,
             font=2,
             lab = allLevels[which.panel],
             col = txtColors[which.panel])
}
plotter <- function(dataframe) { xyplot(q ~ z | y, data=dataframe, strip=myStripStyle)}
# 
dlply(df, .(x), plotter) 
shadow
  • 21,823
  • 4
  • 63
  • 77
  • Thansk shadow, I got your hack and it's indeed useful to start thinking about a solution. But as usual things are a little more complex than what dummy dataframes show... My levels are a combination of two factors. let's say `y` and `v` so the real plotter function woul be like this `plotter <- function(dataframe) { xyplot(q ~ z | y+v, data=dataframe, strip=myStripStyle)}` How would you change `allLevels` and subsequently (I think) `which.panel` function? – MaZe Feb 26 '15 at 11:47
  • Note that in this case also `plotter(df)` does not work anymore (only colors by `y`). I don't really understand the `lattice` `strip` argument, so I really cannot help you. But it's probably best to ask a new question about extending `myStripStyle` to the 2-dimensional case. Adding something along the lines of `allLevels = expand.grid(levels(df$y), levels(df$v))` with appropriate solution for `which.panel` should then be fairly simple. – shadow Feb 26 '15 at 13:09