From brahm at alum.mit.edu  Mon May  5 16:04:47 2003
From: brahm at alum.mit.edu (David Brahm)
Date: Mon May  5 21:05:11 2003
Subject: [Rd] Suppressing Scientific Notation
Message-ID: <16054.46543.828428.318509@arbres1a.fmr.com>

Big thanks to Prof Brian Ripley <ripley@stats.ox.ac.uk> and Martin Maechler
<maechler@stat.math.ethz.ch> for help in building a patch to allow suppression
of scientific notation!  The working patch is attached below.  Most helpfully,
BDR persuaded me to avoid mucking with the options.c code entirely, so I really
only needed to do three things:

 1) Add a component "scipen" to the R_print_par_t struct defined in Print.h,
 2) Set it via GetOption in PrintDefaults, using 0 if the option is undefined,
 3) Use it in format.c to penalize the character count for scientific notation.

Normally, R prints "1e+05" rather than "100000" because the former takes only 5
characters, while the latter takes 6, and 5 < 6.  Now if you set
  R> options(scipen=3)
R will penalize the scientific notation version by 3 characters, and will print
"100000" in this example because 5+3 >= 6.  ("scipen" = "scientific notation
penalty".)  Setting e.g. options(scipen=999) will prevent effectively all
scientific notation.

   Note I have not documented the new option, and I have not measured how much
of a performance hit it entails (though I hope the use of PrintDefaults keeps
that low).  Anyway, I submit this patch as a possible future enhancement of R.
-- 
                              -- David Brahm (brahm@alum.mit.edu)


############################# Patch file follows #############################
#
# Go into the R-1.7.0 directory and type "patch -p1 < scipen.diff" where
#   "scipen.diff" is this file, and "patch" is the GNU patch utility.
#
diff -cr R-1.7.0/src/include/Print.h R-1.7.0.mod/src/include/Print.h
*** R-1.7.0/src/include/Print.h	2003-01-31 10:00:34.000000000 -0500
--- R-1.7.0.mod/src/include/Print.h	2003-05-05 12:34:56.614703522 -0400
***************
*** 38,43 ****
--- 38,44 ----
      int na_width;
      int na_width_noquote;
      int digits;
+     int scipen;
      int gap;
      int quote;
      int right;
diff -cr R-1.7.0/src/main/format.c R-1.7.0.mod/src/main/format.c
*** R-1.7.0/src/main/format.c	2003-01-24 11:44:50.000000000 -0500
--- R-1.7.0.mod/src/main/format.c	2003-05-05 12:38:51.181370171 -0400
***************
*** 283,289 ****
      *n = mxns - 1;
      *m = neg + (*n > 0) + *n + 4 + *e; /* width m for E	 format */
  
!     if (mF <= *m) { /* IFF it needs less space : "F" (Fixpoint) format */
  	*e = 0;
  	*n = rgt;
  	*m = mF;
--- 283,289 ----
      *n = mxns - 1;
      *m = neg + (*n > 0) + *n + 4 + *e; /* width m for E	 format */
  
!     if (mF <= *m  + R_print.scipen) { /* Fixpoint if it needs less space */
  	*e = 0;
  	*n = rgt;
  	*m = mF;
***************
*** 392,398 ****
  	else *er = 1;
  	*nr = mxns - 1;
  	*mr = neg + (*nr > 0) + *nr + 4 + *er;
! 	if (mF <= *mr) { /* IFF it needs less space : "F" (Fixpoint) format */
  	    *er = 0;
  	    *nr = rt;
  	    *mr = mF;
--- 392,398 ----
  	else *er = 1;
  	*nr = mxns - 1;
  	*mr = neg + (*nr > 0) + *nr + 4 + *er;
!         if (mF <= *mr + R_print.scipen) { /* Fixpoint if it needs less space */
  	    *er = 0;
  	    *nr = rt;
  	    *mr = mF;
***************
*** 418,424 ****
  	else *ei = 1;
  	*ni = i_mxns - 1;
  	*mi = (*ni > 0) + *ni + 4 + *ei;
! 	if (mF <= *mi) { /* IFF it needs less space : "F" (Fixpoint) format */
  	    *ei = 0;
  	    *ni = i_rt;
  	    *mi = mF;
--- 418,424 ----
  	else *ei = 1;
  	*ni = i_mxns - 1;
  	*mi = (*ni > 0) + *ni + 4 + *ei;
!         if (mF <= *mi + R_print.scipen) { /* Fixpoint if it needs less space */
  	    *ei = 0;
  	    *ni = i_rt;
  	    *mi = mF;
diff -cr R-1.7.0/src/main/print.c R-1.7.0.mod/src/main/print.c
*** R-1.7.0/src/main/print.c	2003-03-04 05:51:24.000000000 -0500
--- R-1.7.0.mod/src/main/print.c	2003-05-05 12:37:06.998036850 -0400
***************
*** 86,91 ****
--- 86,93 ----
      R_print.quote = 1;
      R_print.right = 0;
      R_print.digits = GetOptionDigits(rho);
+     R_print.scipen = asInteger(GetOption(install("scipen"), rho));
+     if (R_print.scipen == NA_INTEGER) R_print.scipen = 0;
      R_print.gap = 1;
      R_print.width = GetOptionWidth(rho);
  }
#
############################# End of patch file #############################


[Rd] Suppressing Scientific Notation
David Brahm