Question

This is a data.frame whose third "column" is in fact a matrix:

pred.Alb <- structure(list(Age = 
   c(20, 30, 40, 50, 60, 70, 80, 20, 30, 40, 
   50, 60, 70, 80), Sex = structure(c(1L, 1L, 1L, 1L, 1L, 1L, 1L, 
   2L, 2L, 2L, 2L, 2L, 2L, 2L), .Label = c("Male", "Female"), 
   class = "factor"), 
pred = structure(c(4.34976914720261, 4.3165897157342, 4.2834102842658, 
4.23952109360855, 4.15279286619591, 4.05535487959442, 3.95791689299294, 
4.02417706540447, 4.05661037005163, 4.08904367469879, 4.0942071858864, 
3.9902915232358, 3.85910606712565, 3.72792061101549, 4.37709246711838, 
4.38914906337186, 4.40120565962535, 4.3964228776405, 4.32428258270227, 
4.23530290952571, 4.14632323634915, 4.3, 4.3, 4.3, 4.28809523809524, 
4.22857142857143, 4.15714285714286, 4.08571428571429, 4.59781730640631, 
4.59910124381436, 4.60038518122242, 4.58132673532165, 4.48089875618564, 
4.36012839374081, 4.23935803129598, 4.39298701298701, 4.39711229946524, 
4.40123758594347, 4.39484310896076, 4.34636957813428, 4.28737628384687, 
4.22838298955946), .Dim = c(14L, 3L), .Dimnames = list(c("1", 
"2", "3", "4", "5", "6", "7", "8", "9", "10", "11", "12", 
"13", "14"), c("tau= 0.10", "tau= 0.25", "tau= 0.50")))), 
  .Names = c("Age", "Sex", "pred"), out.attrs =
  structure(list(dim = structure(c(7L, 2L), .Names = c("Age", "Sex")), 
  dimnames = structure(list(Age = c("Age=20", 
        "Age=30", "Age=40", "Age=50", "Age=60", "Age=70", "Age=80"), 
Sex = c("Sex=Male", "Sex=Female")),
.Names = c("Age", "Sex"))), 
.Names = c("dim", "dimnames")), row.names = c(NA, -14L), 
 class = "data.frame")

It was created with this code:

require(rms) # also loads Hmisc
require(quantreg) # might also get loaded by rms
rqAlb10fit2 <- rq(BL_ALBUMIN ~ rcs(Age,3) *Sex , data=redBan, 
                                    tau= c(0.1, 0.25, 0.5) )
pred.Alb <- expand.grid(Age=seq(20,80,by=10), Sex=c("Male", "Female") ) 
pred.Alb$pred <- predict(rqAlb10fit2, 
  newdata=expand.grid(Age=seq(20,80,by=10), Sex=c("Male", "Female") ) )

I would like to have a line plot of the predictions by Sex and tau level. I can get a points plot with:

xyplot(pred~Age|Sex, data=pred.Alb, type="p")

When I add type="l", the lines slew back and forth connecting the various levels of tau.

I doubt that it matters, but running on Mac 10.7.5 with quantreg_4.96/rms_3.6-3/Hmisc_3.10-1. If you want to show me a ggplot solution with classic theme, I'm OK with that too, it's just that I am not very good with ggplot2 and Harrell's rms package is mated to lattice.

Was it helpful?

Solution

The problem appears to be that y loses its dimension attribute when it's passed into the panel function, becoming a simple vector. It still goes ahead and plots, recycling x to match y's length, which you can't see type="p", but can when type="l".

Here is a custom panel function that accomplishes what you want by first converting y back to a matrix and then calling panel.xyplot separately on each of its columns:

panel.matplot <- function(x,y,...) {
    y <- matrix(y, nrow=length(x))
    apply(y, 2, function(Y) panel.xyplot(x,Y, ...))
}

xyplot(pred~Age|Sex, data=pred.Alb, type="l", panel=panel.matplot)

enter image description here


BTW: In cases like this, I often find it useful to poke around 'inside' the panel function call. A simple way to do this is to construct a dummy panel function containing a browser() call. Here, for example, is how I discovered the problem in this case:

xyplot(pred~Age|Sex, data=pred.Alb, type="l",
       panel = function(x,y,...) browser())
Browse[2]> x
# [1] 20 30 40 50 60 70 80
Browse[2]> y
#  [1] 4.349769 4.316590 4.283410 4.239521 4.152793 4.055355 3.957917 4.377092
#  [9] 4.389149 4.401206 4.396423 4.324283 4.235303 4.146323 4.597817 4.599101
# [17] 4.600385 4.581327 4.480899 4.360128 4.239358

... at which point the required fix is both (a) pretty obvious and (b) can be tested out from within the existing browser call.

OTHER TIPS

You can do this by reshaping to long and using the groups argument to xyplot:

pred2 <- as.data.frame(pred.Alb$pred)
varying=names(pred2)
pred2$Age <- pred.Alb$Age
pred2$Sex <- pred.Alb$Sex
pred2.long <- reshape(pred2, direction='long', varying=varying, sep='= ')

xyplot(tau~Age|Sex, data=pred2.long, type="l", groups=time)

enter image description here

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