# [R] Biplots

Damon Wischik djw1005 at cam.ac.uk
Fri Mar 14 16:46:02 CET 2003

```A little while ago, I asked for help on producing biplots with more
options than are provided by the function biplot in library mva. No help
was forthcoming, so I wrote my own function, essentially a lattice version
of biplot with some extra features for plotting axes. In case anyone is
interested, here is a pointer to my code:
http://www.statslab.cam.ac.uk/~djw1005/Stats/Interests/biplot.html
It's just source code; when I have time, and when I've debugged, I shall
wrap it up into a library.

The extra features are: groups parameters, so that different points and
biplot axes can be coloured differently; plotting the ranges of the biplot
axes, together with tickmarks; the usual lattice conditioning.

If anyone has any comments, I would be delighted to hear them. My routines
are barely documented, so you would probably need to look at the source
code. Undoubtedly I have written some parts poorly: there are many parts
of R programming in general and lattice in particular that I don't
understand.

The basic use is like this:

m <-
data.frame(row.names=c("Me","Law","Pitt","Li","Deneuve",
"Clooney","Zwilliger"),
looks=c(8,9,4,6,10,5,4),
charm=c(6,7,1,5,9,7,8),
acting=c(0,8,3,9,9,6,7),
success=c(2,6,9,5,8,9,6),
sex=c("male","male","male","female","female","male","female"))
res <- princompfull(m[,c("looks","charm","acting","success")])
res\$observations\$sex <- m\$sex
res\$variables\$type <- c("personal","personal","worldly","worldly")

xyaplot (y~x, groups=sex, data=res\$observations,
axes=y~x|type, data.axes=res\$variables,
axes.spec=list(origin="o",min="min",max="max",ticks=TRUE),
label="label", label.axes="label")

I first call (my own routine) princompfull, which is an extended version
of princomp, also returning information about the range of values in each
column. Then I call xyaplot. This takes two formulae, one a standard
formula as used by xyplot, for the observations; the other specifying a
unit vector in the direction of each axis, referring to the data frame
data.axes, which is a data frame with a row for each axis. You can specify
groups= for the observations and groups.axes= for the axes.  You can also
use axes.spec, label and label.axes to give extra specifications (see the
web page referred to above).

I came across two issues in lattice, which may be bugs, or just my
misunderstanding. The adj parameter in ltext doesn't work properly for
specifying vertical alignment, and as.factorOrShingle does not convert a
logical vector into factors.

I depart from standard lattice usage in some ways. My panel functions take
a subset of rows of the entire data frame, not a preprocessed set of
points together with subscripts. I always find that in other plots, e.g.
xyplot, I need access to the original data frame to plot my points
properly, and this makes it easier.

I also depart from standard lattice usage in that the values in axes.spec,
and of label and label.axes, should be character strings, referring to
columns of the relevant data frames. I found this more flexible than the
standard lattice usage of giving expressions which must be evaluated in
the appropriate context: it means my main xyaplot routine doesn't need to
know about those arguments (and in particular it doesn't need to worry
about subsetting the data frame according to those arguments): they can
just be passed straight to the panel function.  (For this, I loose two
things: the ability to put in arbitrary expressions, and the freedom to
work without data frames.)

Damon Wischik.

```