From maechler at stat.math.ethz.ch  Thu Jul  6 10:17:29 2006
From: maechler at stat.math.ethz.ch (Martin Maechler)
Date: Thu, 6 Jul 2006 10:17:29 +0200
Subject: [Rd] RFC: more generous print.table(*, zero.print = .) behavior
In-Reply-To: <17578.35823.368413.65517@stat.math.ethz.ch>
References: <40D3930AC1C8EA469E39536E5BC80835023FB024@EXDKBA021.corp.novocorp.net>
	<x264ik9sey.fsf@viggo.kubism.ku.dk>
	<17573.16044.463160.287875@stat.math.ethz.ch>
	<17578.35823.368413.65517@stat.math.ethz.ch>
Message-ID: <17580.50969.268861.114149@stat.math.ethz.ch>

Hmm,
I'm replying once more to myself  (as popular wisdom says, "talking to
 oneself" is probably a dangerous sign of increasing mental
 disorder.... ;-()

>>>>> "MM" == Martin Maechler <maechler at stat.math.ethz.ch>
>>>>>     on Tue, 4 Jul 2006 17:40:31 +0200 writes:

>>>>> "MM" == Martin Maechler <maechler at stat.math.ethz.ch>
>>>>>     on Fri, 30 Jun 2006 17:09:32 +0200 writes:

>>>>> "PD" == Peter Dalgaard <p.dalgaard at biostat.ku.dk>
>>>>>     on 29 Jun 2006 12:18:13 +0200 writes:

    PD> "BXC (Bendix Carstensen)" <bxc at steno.dk> writes:

    BXC> The function addmargins() adds margins to a table, but returns a matrix.
    BXC> But even after converted to a table the print.zero="." option of
    BXC> print.table() does not work:
    BXC> 
    BXC> > x <- sample( 1:7, 20, replace=T )
    BXC> > y <- sample( 1:7, 20, replace=T )
    BXC> > tt <- table( x, y )
    BXC> > tx <- as.table( addmargins( table( x, y ) ) )
    BXC> > print( tt, zero.print="." )
    BXC> y
    BXC> x   1 2 3 4 5 6 7
    BXC> 1 1 2 2 . . 1 .
    BXC> 2 1 . . 1 . . .
    BXC> 3 . . . . . . 2
    BXC> 4 1 . . . . 1 .
    BXC> 5 1 . 1 . . 1 .
    BXC> 6 . 1 . 1 . . .
    BXC> 7 . . 1 . 1 1 .
    BXC> > print( tx, zero.print="." )
    BXC> y
    BXC> x      1  2  3  4  5  6  7 Sum
    BXC> 1    1  2  2  0  0  1  0   6
    BXC> 2    1  0  0  1  0  0  0   2
    BXC> 3    0  0  0  0  0  0  2   2
    BXC> 4    1  0  0  0  0  1  0   2
    BXC> 5    1  0  1  0  0  1  0   3
    BXC> 6    0  1  0  1  0  0  0   2
    BXC> 7    0  0  1  0  1  1  0   3
    BXC> Sum  4  3  4  2  1  4  2  20
    BXC> 
    BXC> Is this a facility of print.table?
    BXC> The attributes() of tt and tx have identical stucture. 

    PD> It appears to be intentional.
    PD> 
    PD> print.table has
    PD> 
    PD> if (is.integer(x) && zero.print != "0" && any(i0 <- !ina &
    PD> x == 0))
    PD> xx[i0] <- sub("0", zero.print, xx[i0])
    PD> 
    PD> and of course,
    PD> 
    PD> > storage.mode(tx)
    PD> [1] "double"
    PD> > storage.mode(tt)
    PD> [1] "integer"
    PD> 
    PD> The reason could be that it is not entirely clear what to expect for
    PD> values that are zero up to round-off.
    PD> 
    PD> storage.mode(tx) <- "integer" fixes things up.

    MM> On the other hand, I'm pretty sure I was the one who added
    MM> 'zero.print' and I don't oppose at all to change

    MM> is.integer(x)   to   all(x == round(x))

    MM> {and then for efficiency swap the *order* of the tests inside that if(.)}
    MM> which I think would be a bit more convenient and still ok (*)
    MM> here.

    MM> Martin Maechler, ETH Zurich

    MM> (*) yes, one could then construct artificial cases where the
    MM> if(.) test would ``conceptually'' be wrong, but I think that
    MM> would not matter for all practical cases.

    MM> In R-devel,  

    MM> -  addmargins(x, ...) now returns a "table" when 'x' was one.

    MM> -  print.table(x, zero.print = ch) now also ``zero-prints'' when
    MM> 'x' is not "integer" but numeric with integer values.

I still wonder now about the originaly reason why such a test
should be done at all.  If   'zero.print = ch' is explicitly
specified shouldn't it be used in any case, even in those cases
where a value ``accidentally became 0'' ?

I'm currently tending to think that we should drop that test 
[ 'all(x == round(x))'  which originally was 'is.integer(x)' ]
entirely.

What do others think?

    MM> Bendix' original example can now be slightly shortened *and*
    MM> works as desired (in R-devel, aka 2.4.0 -- to-be):

    >> set.seed(1)
    >> x <- sample( 1:7, 20, replace=TRUE)
    >> y <- sample( 1:7, 20, replace=TRUE)
    >> tx <- addmargins( table(x, y) )
    >> print(tx, zero.print = ".")
    MM> y
    MM> x      1  2  3  4  5  6  7 Sum
    MM> 1    .  .  1  .  .  .  .   1
    MM> 2    .  1  .  1  1  .  1   4
    MM> 3    .  2  .  .  .  1  .   3
    MM> 4    .  .  .  .  1  .  .   1
    MM> 5    .  .  1  1  1  .  1   4
    MM> 6    .  .  1  .  .  2  .   3
    MM> 7    3  .  1  .  .  .  .   4
    MM> Sum  3  3  4  2  3  3  2  20
    >> 

    MM> Hoping, this will be useful..
    MM> Martin Maechler, ETH Zurich

    MM> ______________________________________________
    MM> R-devel at r-project.org mailing list
    MM> https://stat.ethz.ch/mailman/listinfo/r-devel



[Rd] RFC: more generous print.table(*, zero.print = .) behavior
Martin Maechler