问题
It's quite clear How to label panels in lattice using panel.text
or ltext
arguments. However, what if I want to use a different, unique label for each panel in lattice? Let me illustrate my point with this simplified Dotplot
:
library(Hmisc)
#example data
data <- data.frame(transport=rep(c("bicycle","bus"),each=2),
att=rep(c("behaviour control","intention"),2),
value=c(4.134,4.5,3.77,2.4), Lo=c(3.92,4.37,3.51,2.2),
Hi=c(4.34,4.62,4.02,2.61))
#labels I want to use
labels.hi=c("likely","easy")
labels.lo=c("unlikely","difficult")
#example dotplot
png("test.png",width=300, height=400)
Dotplot(transport ~ Cbind(value, Lo, Hi) | att, data, col=1,
panel = function(x, y,...) {
panel.Dotplot(x, y,...)
ltext(2.5,1.5, labels=labels.lo)
ltext(4.5,1.5, labels=labels.hi)
})
dev.off()
This code gives me the plot below:

The upper panel gets a correct labels ("unlikely" and "likely"), but the lower panel just gets duplicate of the upper panel labels. Instead, I want to plot the remaining labels ("easy", "difficult") in the lower panel, but in the same location as upper panel.
I know I could define each label separately using ltext
argument for every label, but it's quite impractical solution considering that my 'real-life' plot (heh) has more panels, and much more different unique labels. Any suggestions? Lattice only please.
回答1:
(Nice to see a good lattice question.) I don't agree with agstudy that subscripts would be a good indexing strategy. In this case they work by accident because your points are the same number as your labels and in the same order. Subscripts are that mechanism for picking individual data points for panels rather than a mechanism for indexing panels. Consider using the packet.number()
or panel.number()
functions. In this instance I believe they return the same values, but consult their shared help page if you have more complex conditioning factors in mind:
Dotplot(transport ~ Cbind(value, Lo, Hi) | att, data, col=1,
panel = function(x, y,...) {
panel.Dotplot(x, y,...)
if(packet.number()==1){ ltext(c(2.5,4.5) ,1.5, labels= labels.lo)}
if(packet.number()==2){ ltext(c(2.5,4.5) ,1.5, labels=labels.hi)}
})
If you had your labels in a matrix it would have been easy to use indexing with "[".
lab.mat=matrix(c( labels.hi,labels.lo), 2)
lab.mat
# [,1] [,2]
#[1,] "likely" "unlikely"
#[2,] "easy" "difficult"
png("test.png",width=300, height=400)
Dotplot(transport ~ Cbind(value, Lo, Hi) | att, data, col=1,
panel = function(x, y,...) {
panel.Dotplot(x, y,...)
{ ltext(c(2.5,4.5) ,1.5, labels= lab.mat[packet.number(),])}
})
dev.off()

回答2:
I think you are looking for subscripts
argument:
labels=c("likely","easy","unlikely","difficult")
#example dotplot
Dotplot(transport ~ Cbind(value, Lo, Hi) | att, data, col=1,
panel = function(x, y,subscripts,...) {
panel.Dotplot(x, y,...)
ltext(c(2.5,4.5),1.5, labels[subscripts])
})

回答3:
I don't have enough reputation points to comment, but I wanted to add a small tweak that builds off @42- for those working with POSIXct dates. NOTE: I am not a developer, coder, or claim that this will work for every data set/user—this is just a hack I needed.
If you need to add text to multiple plots when using dates on, say, the x axis you must add the as.POSIXct function to the specified dates denoting the location of the text. I also include the panel.xyplot to demonstrate as you must specify the type of plot you're working with. In the example I placed two labels per panel (pre-specified like in OP example) on two panels at the same y.
Example:
panel = function(x, y,...) {
panel.xyplot(x, y,...)
if(packet.number()==YOUR 1ST PANEL){ ltext(c(as.POSIXct("YOUR 1ST DATE"), as.POSIXct("YOUR 2ND DATE")), YOUR Y VALUE, labels = YOUR LABELS)}
if(packet.number()==YOUR 2ND PANEL){ ltext(c(as.POSIXct("YOUR 1ST DATE"), as.POSIXct("YOUR 2ND DATE")), YOUR Y VALUE, labels = YOUR LABELS)}
})
Hope this can be of use to someone. Cheers.
来源:https://stackoverflow.com/questions/20126137/add-different-unique-labels-to-each-panel-in-lattice