A friend of mine just got bitten by the fact that
sweep() will happily sweep out a STATS vector
of an arbitrary length -- even one whose length
is not a divisor of any of the margins -- without
complaining. I know the answer to this could
be "well just don't do that", but it's easy to make
a mistake in which margin you're sweeping ...
What would R-core think of the following 'enhanced'
sweep? It always warns if dim(x)[MARGIN] is
not a multiple of length(STATS) {it's very hard indeed
for me to think of a situation where you'd actually
want this}; if check.margin=TRUE it is a bit stricter,
complaining whenever dim(x)[MARGIN] doesn't
match length(STATS).
This change seems fairly harmless since it never does anything
more than warn; the default for check.margin could
be FALSE if you wanted to allow people a bit more rope
to hang themselves with ... (of course this won't prevent
you from sweeping the wrong margin of a square matrix,
but nothing will).
cheers
Ben Bolker
sweep <- function (x, MARGIN, STATS, FUN = "-", check.margin=TRUE,
...)
{
FUN <- match.fun(FUN)
dims <- dim(x)
if (check.margin && dims[MARGIN]!=length(STATS)) {
warning("length(STATS) != dim(x)[MARGIN]")
} else if (dims[MARGIN] %% length(STATS)!=0)
warning("dim(x)[MARGIN] is not a multiple of length(STATS)")
perm <- c(MARGIN, (1:length(dims))[-MARGIN])
FUN(x, aperm(array(STATS, dims[perm]), order(perm)), ...)
}