Question

I'm having a bit of a trouble here, please help me. I have this data

set.seed(4)
mydata <- data.frame(var = rnorm(100),
                     temp = rnorm(100),
                     subj = as.factor(rep(c(1:10),5)),
                     trt = rep(c("A","B"), 50))

and this model that fits them

lm  <- lm(var ~ temp * subj, data = mydata)

I want to plot the results with lattice and fit the regression line, predicted with my model, through them. To do so, I'm using this approach, outlined "Lattice Tricks for the power useR" by D. Sarkar

temp_rng <- range(mydata$temp, finite = TRUE)

grid <- expand.grid(temp = do.breaks(temp_rng, 30),
                    subj = unique(mydata$subj),
                    trt = unique(mydata$trt))

model <- cbind(grid, var = predict(lm, newdata = grid))

orig <- mydata[c("var","temp","subj","trt")]

combined <- make.groups(original = orig, model = model)


xyplot(var ~ temp | subj, 
       data = combined,
       groups = which,
       type = c("p", "l"),
       distribute.type = TRUE
       )

So far every thing is fine, but I also want to assign a fill color to the data points for the two treatments trt=1 and trt=2.

So I have written this piece of code, that works fine, but when it comes to plot the regression line, it seems that type is not recognized by the panel function...

my.fill <- c("black", "grey")

plot <- with(combined,
        xyplot(var ~ temp | subj,
              data = combined,
              group = combined$which,
              type = c("p", "l"),
              distribute.type = TRUE,
              panel = function(x, y, ..., subscripts){
                     fill <- my.fill[combined$trt[subscripts]] 
                     panel.xyplot(x, y, pch = 21, fill = my.fill, col = "black")
                     },
             key = list(space = "right",
                     text = list(c("trt1", "trt2"), cex = 0.8),
                     points = list(pch = c(21), fill = c("black", "grey")),
                     rep = FALSE)
                     )
      )
plot

I've also tried to move type and distribute type within panel.xyplot, as well as subsetting the data in it panel.xyplot like this

plot <- with(combined,
        xyplot(var ~ temp | subj,
              data = combined,
              panel = function(x, y, ..., subscripts){
                     fill <- my.fill[combined$trt[subscripts]] 
                     panel.xyplot(x[combined$which=="original"], y[combined$which=="original"], pch = 21, fill = my.fill, col = "black")
                     panel.xyplot(x[combined$which=="model"], y[combined$which=="model"], type = "l", col = "black")
                     },
             key = list(space = "right",
                     text = list(c("trt1", "trt2"), cex = 0.8),
                     points = list(pch = c(21), fill = c("black", "grey")),
                     rep = FALSE)
                     )
      )
plot

but no success with that either.

Can anyone help me to get the predicted values plotted as a line instead of being points?

Was it helpful?

Solution

This might be a job for the latticeExtra package.

library(latticeExtra)
p1 <- xyplot(var ~ temp | subj, data=orig, panel=function(..., subscripts) {
  fill <- my.fill[combined$trt[subscripts]] 
  panel.xyplot(..., pch=21, fill=my.fill, col="black")
})
p2 <- xyplot(var ~ temp | subj, data=model, type="l")
p1+p2

enter image description here

I'm not sure what's going on in your first attempt, but the one with the subscripts isn't working because x and y are a subset of the data for subj, so subsetting them using a vector based on combined won't work the way you think it will. Try this instead.

xyplot(var ~ temp | subj, groups=which, data = combined,
       panel = function(x, y, groups, subscripts){
         fill <- my.fill[combined$trt[subscripts]]
         g <- groups[subscripts]
         panel.points(x[g=="original"], y[g=="original"], pch = 21, 
                      fill = my.fill, col = "black")
         panel.lines(x[g=="model"], y[g=="model"], col = "black")
       },
       key = list(space = "right",
         text = list(c("trt1", "trt2"), cex = 0.8),
         points = list(pch = c(21), fill = c("black", "grey")),
         rep = FALSE)
       )

OTHER TIPS

It might be easier to simply use the panel.lmline function on just your original data:

xyplot(var ~ temp | subj,
        data = orig,
        panel = function(x,y,...,subscripts){
            fill <- my.fill[orig$trt[subscripts]]
            panel.xyplot(x, y, pch = 21, fill = my.fill,col = "black")
            panel.lmline(x,y,col = "salmon")
        },
        key = list(space = "right",
                     text = list(c("trt1", "trt2"), cex = 0.8),
                     points = list(pch = c(21), fill = c("black", "grey")),
                     rep = FALSE)
)

enter image description here

This may be trivial, but you may try:

xyplot(... , type=c("p","l","r"))

"p" adds points, "l" connects them with broken lines, "r" fits a linear model through your data. type="r" alone will plot only regression lines without showing data points.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top