[R] how to change strip text of effect plot
John Fox
jfox at mcmaster.ca
Wed Jan 12 14:00:23 CET 2011
Dear Deepayan, Josh, and Ronggui,
I've recently changed plot.eff() so that it returns an object, normally "printed" by print.plot.eff(). You can therefore manipulate the lattice object, as Deepayan suggests. This change is currently in the development version of the effects package on R-Forge, not yet on CRAN.
I agree with both Josh and Deepayan that it would be simpler for you just to name the levels of the factor with the labels you want.
Best,
John
--------------------------------
John Fox
Senator William McMaster
Professor of Social Statistics
Department of Sociology
McMaster University
Hamilton, Ontario, Canada
http://socserv.mcmaster.ca/jfox
> -----Original Message-----
> From: r-help-bounces at r-project.org [mailto:r-help-bounces at r-project.org]
> On Behalf Of Deepayan Sarkar
> Sent: January-12-11 7:26 AM
> To: Joshua Wiley
> Cc: r help
> Subject: Re: [R] how to change strip text of effect plot
>
> On Wed, Jan 12, 2011 at 10:36 AM, Joshua Wiley <jwiley.psych at gmail.com>
> wrote:
> > Hmm, I felt like it was the clearest, most direct way. Then again,
> > things of this nature (overide defaults using arguments rather than
> > changing what you feed the functions) do seem to be a common request
> > both for lattice and ggplot2. In any case, my memory of the lattice
> > book and a quick search of the archives suggest that the typical way
> > to do this when dealing with lattice functions such as xyplot() would
> > be to define a custom strip function. For example:
> >
> > strip = function(..., factor.levels) strip.default(..., factor.levels
> > = c("low", "medium", "high"))
> >
> > however, if I am not mistaken, you are plotting an object of class
> > "efflist", which dispatches plot.efflist which eventually dispatches
> > plot.eff, in the bowels of plot.eff is the call to xyplot(), with its
> > own strip function already defined. I did not see a way to override
> > this, nor did I see an option to pass an argument to it.
> >
> > It is trivial to edit the function's code to work with such a change.
> > You could probably create a local copy of it, make the necessary
> > changes, and then just ensure that your object gets dispatched to your
> > revised function rather than the packages original. Even easier, I
> > suppose:
> >
> > debug(plot)
> > plot(eff.cowles, 'neuroticism:ex2',factor.names=F) ## follow along
> > until it has just created the object "plot"
> > ## then overwrite that with your desired changes (factor.levels) ##
> > before it is printed to the screen
> >
> > plot <- xyplot(eval(parse(text = paste("fit ~", predictors[x.var],
> > "|", paste(predictors[-x.var], collapse = "*")))), strip =
> > function(..., factor.levels) strip.default(..., factor.levels =
> > c("low", "medium", "high"),
> > strip.names = c(factor.names, TRUE)), panel = function(x,
> > y, subscripts, x.vals, rug, lower, upper, has.se, ...) {
> > llines(x, y, lwd = 2, col = colors[1], ...)
> > if (rug)
> > lrug(x.vals)
> > if (has.se) {
> > llines(x, lower[subscripts], lty = 2, col = colors[2])
> > llines(x, upper[subscripts], lty = 2, col = colors[2])
> > }
> > if (has.thresholds) {
> > panel.abline(h = thresholds, lty = 3)
> > panel.text(rep(current.panel.limits()$xlim[1],
> > length(thresholds)),
> > thresholds, threshold.labels, adj = c(0, 0),
> > cex = 0.75)
> > panel.text(rep(current.panel.limits()$xlim[2],
> > length(thresholds)),
> > thresholds, threshold.labels, adj = c(1, 0),
> > cex = 0.75)
> > }
> > }, ylim = ylim, ylab = ylab, xlab = if (missing(xlab))
> > predictors[x.var]
> > else xlab, x.vals = x.vals, rug = rug, main = main, lower =
> > x$lower,
> > upper = x$upper, has.se = has.se, data = x, scales = list(y =
> > list(at = tickmarks$at,
> > labels = tickmarks$labels), alternating = alternating),
> > ...)
> >
> > alternately still, you could rename the factor levels in the object
> > "eff.cowles", which is sort of inbetween changing your data and
> > changing the strip label defaults.
> >
> > I can understand why it seems like there should be a simpler solution,
> > but I honestly do not see one. The factor.levels argument does not
> > even work inside xyplot(), it needs to be in the strip function, and
> > that is nested far away from plot(effobject). I do not see any
> > documentation that suggests a way, nor do I see any formal arguments
> > to facilitate it. Then again, I'm not an expert in lattice or the
> > effects package.
>
>
> One generally useful fact is that if you can get hold of the "trellis"
> object being plotted, you may be able to change the strip labels before
> plotting it. For example,
>
> > foo <- trellis.last.object()
>
> or in this case
>
> > foo <- plot(eff.cowles[['neuroticism:ex2']],factor.names=F)
>
> (this returns the object, but also forces a plot), followed by
>
> > dimnames(foo)
> $ex2
> [1] "(1.98,8.99]" "(8.99,16]" "(16,23]"
> > dimnames(foo)$ex2 <- c("low", "medium", "high") foo
>
> But I would tend to agree with Josh, that specifying labels in the
> cut() call is the more natural approach. It is not the job of graphics
> functions to modify (characteristics of) your data.
>
> -Deepayan
>
>
> > Best regards,
> >
> > Josh
> >
> > On Tue, Jan 11, 2011 at 8:06 PM, Wincent <ronggui.huang at gmail.com>
> wrote:
> >> Sure that is one way to go.
> >> Since it is possible to pass lattice arguments to that high level
> >> function, and there should be ways to relabel/custom the strip text
> >> in the lattice plotting system, I would think such an indirect method
> >> a last resort.
> >>
> >> Thank you.
> >>
> >> Ronggui
> >>
> >> On 12 January 2011 11:51, Joshua Wiley <jwiley.psych at gmail.com>
> wrote:
> >>> Hi,
> >>>
> >>> I am guessing this is not what you meant by "on the fly", but I
> >>> think it will be by far the easiest way. Plotting an effects object
> >>> is a high level plot with a lot of defaults and automation built in
> >>> to make your life simple. The cost is that it is less
> >>> flexible---you work its way, not vice versa. If you want the factor
> >>> named high, just label it that way to begin with. If you think it
> >>> makes the graphs more interpretable/meaningful, then it will make
> model summaries, etc.
> >>> better also. Worst case, you fit the model twice (one with fancy
> >>> names, one with numbers), which unless you have a massive dataset
> >>> will not take long or be an onerous burden anyways. Here's how you
> >>> can include labels directly in cut():
> >>>
> >>> Cowles$ex2 <- cut(Cowles$extraversion, 3, c("low", "medium",
> >>> "high")) mod.cowles <- glm(volunteer ~
> >>> sex+neuroticism*ex2,data=Cowles, family=binomial) eff.cowles <-
> >>> allEffects(mod.cowles) plot(eff.cowles,
> >>> 'neuroticism:ex2',factor.names=F)
> >>>
> >>> Cheers,
> >>>
> >>> Josh
> >>>
> >>> On Tue, Jan 11, 2011 at 7:21 PM, Wincent <ronggui.huang at gmail.com>
> wrote:
> >>>> Dear r heper,
> >>>>
> >>>> How can I change the strip text, for example (16,23] in the
> >>>> following example, to other more informative text such as "high
> >>>> level" on the fly?
> >>>>
> >>>> library(effects)
> >>>> Cowles$ex2 <- cut(Cowles$extraversion,3) mod.cowles <-
> >>>> glm(volunteer ~ sex+neuroticism*ex2,data=Cowles, family=binomial)
> >>>> eff.cowles <- allEffects(mod.cowles) plot(eff.cowles,
> >>>> 'neuroticism:ex2',factor.names=F)
> >>>>
> >>>> Thank you.
> >>>>
> >>>> Ronggui
>
> ______________________________________________
> R-help at r-project.org mailing list
> https://stat.ethz.ch/mailman/listinfo/r-help
> PLEASE do read the posting guide http://www.R-project.org/posting-
> guide.html
> and provide commented, minimal, self-contained, reproducible code.
More information about the R-help
mailing list