From bolker at zoo.ufl.edu  Fri Jun 29 23:29:36 2007
From: bolker at zoo.ufl.edu (Ben Bolker)
Date: Fri, 29 Jun 2007 17:29:36 -0400
Subject: [Rd] sweep sanity checking?
Message-ID: <468579C0.7090809@zoo.ufl.edu>


  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)), ...)
  }



[Rd] sweep sanity checking?
Ben Bolker