On Mon, Feb 16, 2009 at 4:23 PM, Martin Morgan <mtmorgan@fhcrc.org> wrote:

> Stavros Macrakis <macrakis@alum.mit.edu> writes:
> >    matrix(tapply(mm, outer(rfact,cfact,paste), mean),
> >               length(unique(rfact)))
>
> or the variant
>
>  idx <- outer(rfact, (cfact - 1) * max(rfact), "+")
>  matrix(tapply(m, idx, mean), max(rfact))
>
> The assumption is that cfact, rfact are integer valued with max(rfact)
> <= nrow(m), max(cfact) <= ncol(m).
>
> I think Stavros' solution will run in to trouble when there are more
> than 9 row blocks, and '10 1' sorts before '2 1', for instance.
>

Quite so!  Thank you for the correction, and sorry for the sloppy
programming -- using outer/paste like that is indeed a dirty hack.

I suppose the clean way to do this would be to define a cartesian product of
two factors with the induced lexicographic order (is there a standard
function for doing this?):

   `*.factor` <- function(f1,f2)
       factor(  t(outer(f1,f2,paste)),
                    levels=t(outer(unique(f1),unique(f2),paste)),
                    ordered=TRUE)

and then I think this will work for arbitrary factors rfact and cfact:

matrix(tapply(mm, rfact*cfact, mean),
             length(unique(rfact)))

This allows arbitrary factors, and preserves their input order. Or have I
made another foolish mistake?

           -s

	[[alternative HTML version deleted]]


