1

enter image description here

I have a simple trellis scatterplot. Two panels - male/female. ID is a unique number for each participant. The var1 is a total test time. Mean.values is a vector of two numbers (the means for gender).

No point including a best fit line so what I want is to plot a trend line of the mean in each panel. The two panels have different means, say male = 1 minute, female = 2 minutes.

xyplot(var1 ~ ID|Gender, data=DF,                
                   group = Gender,
                   panel=function(...) { 
                     panel.xyplot(...) 
                     panel.abline(h=mean.values) 
                    })

At the minute the graph is coming out so that both trendlines appear in each panel. I want only one trendline in each.

Does anyone have the way to do this?

I have tried a number of different ways including the long code for function Addline which just doesn't work for me. I just want to define which panel im looking at and i've looked at ?panel.number but not sure how that works as its coming up that I don't have a current row. (current.row(prefix)).

There must be a simple way of doing this?

[EDIT - Here's the actual data i'm using] I've tried to simplify the DF

library(lattice) 

dput(head(DF))
structure(list(ID = 1:6, Var1 = c(2333858, 4220644, 
2941774, 2368496, 3165740, 3630300), mean = c(2412976, 2412976, 
2412976, 2412976, 2412976, 2412976), Gender = structure(c(1L, 
1L, 1L, 1L, 1L, 1L), .Label = c("1", "2"), class = "factor")), .Names = c("ID", 
"Var1", "mean", "Gender"), row.names = c(NA, 6L), class = "data.frame")

dput(tail(DF))
structure(list(ID = 161:166, Var1= c(2825246, 3552170, 
3688882, 2487760, 3849108, 3085342), mean = c(3689805, 3689805, 
3689805, 3689805, 3689805, 3689805), Gender = structure(c(2L, 
2L, 2L, 2L, 2L, 2L), .Label = c("1", "2"), class = "factor")), .Names = c("ID", 
"Var1", "mean", "Gender"), row.names = 109:114, class = "data.frame")

plot i'm using:

 xyplot((Var1/1000) ~ ID|Gender, data=DF,                
   group = Gender,scales=list(x=list(at=NULL)),
   panel=function(...) { 
     panel.xyplot(...) 
     panel.abline(h=mean.values) })

causes 2 lines.

[EDIT - This is the code which includes the function Addline & is everywhere on all the posts and doesn't seem to work for me]

 addLine<- function(a=NULL, b=NULL, v = NULL, h = NULL, ..., once=F) { tcL <- trellis.currentLayout() k<-0 for(i in 1:nrow(tcL)) for(j in 1:ncol(tcL)) if (tcL[i,j] > 0) {  k<-k+1 trellis.focus("panel", j, i, highlight = FALSE) if (once) panel.abline(a=a[k], b=b[k], v=v[k], h=h[k], ...) else  panel.abline(a=a,b=b, v=v, h=h, ...) trellis.unfocus() } } 

then writing after the trellis plot (mean.values being a vector of two numbers, mean for female, mean for male)

addLine(v=(mean.values), once=TRUE) 

Update - I managed to do it in ggplot2. Make the ggplot using facet_wrap then -

hline.data <- data.frame(z = c(2413, 3690), Gender = c("Female","Male")) 

This creates a DF of the two means and the Gender, 2x2 DF

myplot <- myplot + geom_hline(aes(yintercept = z), hline.data)

This adds the lines to the ggplot.

Rachel
  • 47
  • 5
  • Is `mean.values` the means of the `var1` values? It would help if you provided a [reproducible example](http://stackoverflow.com/questions/5963269/how-to-make-a-great-r-reproducible-example) with sample input data. – MrFlick Aug 01 '15 at 21:41
  • Yes that's right - mean of var1. I'll get on the data soon just wondering if im missing something obvious. – Rachel Aug 01 '15 at 21:47

2 Answers2

3

If you just wanted plot the mean of values you are drawing on the plot aready, you can skip the mean.values variable and just do

xyplot(Var1 ~ ID|Gender, data=DF,                
    group = Gender,
    panel=function(x,y,...) { 
        panel.xyplot(x,y,...) 
        panel.abline(h=mean(y)) 
    }
)

With the sample data

DF<-data.frame(
    ID=1:10, 
    Gender=rep(c("M","F"), each=5), 
    Var1=c(5,6,7,6,5,8,9,10,8,9)
)

this produces

enter image description here

MrFlick
  • 195,160
  • 17
  • 277
  • 295
  • This takes a mean for the whole of Var1 without accounting for male/female and so then it plots one line across both panels. I'm looking for a mean line for female and a mean line for male. – Rachel Aug 02 '15 at 08:06
  • This calculates a mean per panel and since you condition on gender, this means it calculates a different mean per gender. I'm not sure why you think it only calculates an overall mean. – MrFlick Aug 02 '15 at 14:09
  • When I coded it myself it would not separate the lines by panel and was giving just one overall mean line which was a pain. It's probably going to be because of the DF but I got it working in ggplot so i'm happy. Putting this is as the answer as it will likely work for other people! Cheers. – Rachel Aug 02 '15 at 20:09
0

I believe lattice has a specific panel function for this, panel.average().

Try replacing panel.abline(h=mean.values) with panel.average(...).

If that doesn't solve the problem, we might need more information; try using dput() on your data (e.g., dput(DF), or some representative subset).

rbatt
  • 4,677
  • 4
  • 23
  • 41
  • I've simplified in the post - dput gives a massive output. I'll try and bring the first 5 values of each 'gender' type - it wasn't gender I was looking at but easier to explain ;) – Rachel Aug 01 '15 at 21:56
  • Also - I did try panel.average() earlier but was struggling with listing the x, y. I'll try that again quickly first. – Rachel Aug 01 '15 at 21:57
  • It doesn't seem that `panel.average` is meant to achieve what the OP requests. – BenBarnes Aug 10 '15 at 07:54