Skip to content

controlling the x axis of boxplots

2 messages · Chris Evans, Rich FitzJohn

#
v 2.0.1 (sooooh old!) on Win2k

I think I know the answer to this but I can hope ...

I have data for continuous variables (measures of residents) by a 
categorical variable in range (1,22), the units in which they live.  

I want to plot these data with a pair of boxplots one above another 
with same x-axis (1,22) using par(mfrow=c(2,1)) and then plotting 
first for the women then for the men.  My problem is that some units 
have only men, some have only women, and some have both.  I'd like 
both plots to have the same x axis and the notched, varwidth boxplots 
to locate themselves with some gaps so that the units are in the same 
place on the x axis on each plot.

I think that I can't do this with boxplot or bxp as both work out the 
x axis from the work that boxplot has done on the data.  Although 
there also seem to be useful extensions or alternative boxplots in 
other packages, I can't see one that does what I want and I think 
that rolling my own from bxp is really beyond my skills.

Am I right that it doesn't exist in the CRAN packages?  If not, 
apologies and point me where I should look?  If I am right (boo hoo!) 
I don't suppose anyone has written this or is feeling like 
demonstrating their personal genius with R coding?!!!  If they were, 
I don't think I'd be the only one to end up owing them a great deal 
of gratitude!

Thanks as ever to all who have made and continue to make R what it 
is: brilliant!

Chris
#
Hi Chris,

You can get the desired effect by using the "at" argument to boxplot,
and by setting up the plot dimensions manually.

men <- data.frame(grp=rep(letters[c(1, 2, 4, 6)], each=10),
                  response=rnorm(40))
women <- data.frame(grp=rep(letters[c(2:5, 7)], each=10),
                    response=rnorm(50))

## Determine all levels used, the number of levels, and appropriate
## xlim for the plot
grp.levs <- sort(unique(c(levels(men$grp), levels(women$grp))))
nlevs <- length(grp.levs)
xlim <- c(.5, nlevs+.5)

## Determine which of the levels are present in men and women; these
## are the x coordinates to draw the boxes (this will need tweaking if
## you are using ordered factors).
at.men <- match(levels(men$grp), grp.levs)
at.women <- match(levels(women$grp), grp.levs)

par(mfrow=c(2,1))
## boxplot() does not take an xlim argument, so you'll have to set up
## the plot yourself (including the axis, since the default is not
## appropriate for a boxplot).
plot(NA, type="n", xlim=xlim, ylim=range(men$response), xlab="",
     ylab="Response", xaxt="n")
axis(1, 1:nlevs, grp.levs)
boxplot(response ~ grp, men, at=at.men, add=TRUE)

plot(NA, type="n", xlim=xlim, ylim=range(women$response),
     xlab="Group", ylab="Response", xaxt="n")
axis(1, 1:nlevs, grp.levs)
boxplot(response ~ grp, women, at=at.women, add=TRUE)

Cheers,
Rich
On 4/20/05, Chris Evans <chris at psyctc.org> wrote: