[R] plotting results from tapply
Marc Schwartz
marc_schwartz at comcast.net
Fri Jan 26 18:46:23 CET 2007
On Fri, 2007-01-26 at 11:50 -0500, Michael Rennie wrote:
> Hi, there
>
> I'm trying to plot what is returned from a call to tapply, and can't figure
> out how to do it. My guess is that it has something to do with the
> inclusion of row names when you ask for the values you're interested in,
> but if anyone has any ideas on how to get it to work, that would be
> stellar. Here's some example code:
>
> y1<-rnorm(40, 2)
> x1<-rep(1:2, each=20)
> x2<-rep(1:2, each=10 times=2)
>
> ex.dat<-data.frame(cbind(y1,x1,x2))
>
> ex.dat$x1<-factor(ex.dat$x1, labels=c("A", "B"))
> ex.dat$x2<-factor(ex.dat$x2, labels=c("C", "D"))
>
> attach(ex.dat)
>
> xbar<-tapply(ex.dat$y1, ex.dat[,-1], mean)
> xbar
>
> #values I'd like to plot:
> row.names(xbar) #levels of x1
> xbar[,1] #mean response of y1 for group C (x2) across x1
>
> #plot mean response y1 for group C against x1 (i.e., using x2 as a grouping
> factor).
> plot(row.names(xbar), xbar[,1], ylim=range[y1])
>
> #This is where things break down. The error message states that I need
> "finite xlim values" but I haven't assigned anything to xlim. If I just
> plot the data:
>
> plot(x1, y1)
>
> #This works fine.
>
> #And, I can get this to work:
>
> stripchart(xbar[1,]~row.names(xbar), vert=T)
>
> #However, I'd like to then add the values for the second set of means
> (i.e., mean values for group D against x1, or (xbar[,2])) to the plot.
> #I tried following up the previous command with:
>
> points(row.names(xbar), xbar[,2])
>
> #But that returns an error as well (NAs introduced by coercion).
>
>
>
> Any suggestions?
>
> Cheers,
>
> Mike
>
> PS- some of you might suggest for me to use interaction.plot, since this is
> essentially what I'm building here. True, but I can't get error bars using
> interaction.plot. I'm therefore trying to build my own version where I can
> specify the inclusion of error bars. Presumably the interaction.plot has
> figured out how to do what I'm attempting, so I have some faith that I am
> on the right track....
Michael,
The problem is that when you are using the rownames for 'xbar', they are
a character vector:
> str(rownames(xbar))
chr [1:2] "A" "B
When you attempt to use the same values from 'ex.dat$x1', they are
factors, which are being coerced to their numeric equivalents, so that
they can work as x axis values.
> str(ex.dat$x1)
Factor w/ 2 levels "A","B": 1 1 1 1 1 1 1 1 1 1 ...
> as.numeric(ex.dat$x1)
[1] 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 2 2 2 2 2 2 2 2 2 2 2 2 2 2
[35] 2 2 2 2 2 2
I might note using the following:
par(mfcol = c(1, 3))
with(ex.dat, plot(1:2, xbar[, 1], ylim = range(y1),
type = "b", col = "red",
lty = c("dashed", "solid"),
xaxt = "n", xlab = "x1",
ylab = "mean of y1"))
with(ex.dat, points(1:2, xbar[, 2], col = "blue",
type = "b"))
axis(1, at = 1:2, labels = c("A", "B"))
matplot(1:2, xbar, col = c("red", "blue"),
pch = 21, type = "b", ylim = range(y1),
lty = c("dashed", "solid"),
xaxt = "n", xlab = "x1",
ylab = "mean of y1")
axis(1, at = 1:2, labels = c("A", "B"))
with(ex.dat, interaction.plot(x1, x2, response = y1,
type = "b", pch = 21,
col = c("red", "blue"),
ylim = range(ex.dat$y1),
legend = FALSE))
You get basically the same 3 plots, with the principal difference in
interaction.plot() being a different x axis range.
Using interaction.plot(), you can get the proper basic plot and then add
the CI's if you wish, since you know the x axis values of the mean
estimates, which is 1:NumberOfGroups (as in a boxplot).
interaction.plot() actually uses matplot() internally.
HTH,
Marc Schwartz
More information about the R-help
mailing list