Daniel Kornhauser
2009-May-07 21:50 UTC
[R] How to properly shade the background panels of an xyplot?
Hi: Here is simplified example of what I am having trouble with: I want to set the gray shade of the background of each panel of a xyplot with its mean. My aim is to be able to compare at a glance which panel has the highest mean. But, in order to achieve this I have to normalize the means between 0 and 1. The normalization is necessary to stay within the valid range for the gray() command. I can?t figure out how to do it :-( Here is an example where I use max(Oats$yield) (the all around maximum value) to normalize. Note that what I am looking for is an expression what would mean something like this as max(<mean of every panel>) # Start Example, just copy and paste data(Oats, package = "MEMSS") tp1.oats <- xyplot(yield ~ nitro | Variety + Block, data = Oats, panel = function(x, y, subscripts, ...) { # How to normalize my heatmap metric with # the value of the panel that has maximum average ? # metric = eval(mean(y)/ max(<mean-of-each-panel>))))) metric = eval(mean(y)/max(Oats$yield)) panel.fill(col = gray(metric)) panel.lines(x,y) } ) print(tp1.oats) # End Example Does anybody have any suggestion how I can get max(<mean-of-each-panel>) ? Thanks PS: Deepayan THANKS to your reply to my previous email it was exactly what I needed.
Deepayan Sarkar
2009-May-07 23:52 UTC
[R] How to properly shade the background panels of an xyplot?
On Thu, May 7, 2009 at 2:50 PM, Daniel Kornhauser <dkor at northwestern.edu> wrote:> Hi: > > Here is simplified example of what I am having trouble with: > I want to set the gray shade of the background of each panel of a > xyplot with its mean. > My aim is to be able to compare at a glance which panel has the highest mean. > But, in order to achieve this I have to normalize the means between 0 and 1. > The normalization is necessary to stay within the valid range for the > gray() command. > I can?t figure out how to do it :-( > > Here is an example where I use max(Oats$yield) (the all around maximum > value) to normalize. > Note that what I am looking for is an expression what would mean > something like this as max(<mean of every panel>) > > # Start Example, just copy and paste > data(Oats, package = "MEMSS") > tp1.oats <- xyplot(yield ~ nitro | Variety + Block, > ? ? ? ? ? ? ? ? ? ? ?data = Oats, > ? ? ? ? ? ? ? ? ? ? ?panel = function(x, y, subscripts, ...) { > ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?# How to normalize my heatmap metric with > ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?# the value of the panel that has maximum average ? > ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?# metric = eval(mean(y)/ max(<mean-of-each-panel>))))) > ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?metric = eval(mean(y)/max(Oats$yield)) > ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?panel.fill(col = gray(metric)) > ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?panel.lines(x,y) > ? ? ? ? ? ? ? ? ? ? ? ? ?} > ? ? ? ? ? ? ? ? ? ? ? ?) > print(tp1.oats) > # End Example > > Does anybody have any suggestion how I can get max(<mean-of-each-panel>) ?The simple answer is to use tapply():> with(Oats, tapply(yield, list(Variety, Block), mean))I II III IV V VI Golden Rain 133.25 113.25 86.75 108.0 95.50 90.25 Marvellous 129.75 121.25 118.50 95.0 85.25 109.00 Victory 143.00 87.25 82.50 91.5 92.00 89.50 So, xyplot(yield ~ nitro | Variety + Block, data = Oats, max.mean = max(with(Oats, tapply(yield, list(Variety, Block), mean))), panel = function(x, y, subscripts, max.mean, ...) { metric = mean(y)/max.mean panel.fill(col = gray(metric)) panel.lines(x,y) }) For the general problem of sharing/aggregating per-panel information, you can use the prepanel function, which is guaranteed to run once for every panel (or rather every packet, to be more precise) with the same arguments as the panel function. This example takes advantage of the persistence of environments: xyplot(yield ~ nitro | Variety + Block, data = Oats, aux.env = new.env(parent = emptyenv()), prepanel = function(x, y, aux.env, ...) { aux.env$max.mean.y <- max(aux.env$max.mean.y, mean(y)) list() }, panel = function(x, y, subscripts, aux.env, ...) { metric = mean(y) / aux.env$max.mean.y panel.fill(col = gray(metric)) panel.lines(x,y) }) -Deepayan