S programming style & "missing(.)" [was "regarding bugs in barplot" on R-core]
Martin Maechler
Martin Maechler <maechler@stat.math.ethz.ch>
Thu, 26 Mar 1998 12:04:30 +0100
[The part about S (S-plus and R being dialects of S) programming
(at the end) makes me cc'ing this to R-devel. MM]
On R-core,
>>>>> "Paul" == Paul Murrell <paul@stat.auckland.ac.nz> writes:
Paul> hi (i) the problem with the positioning of the legend in your
Paul> barplot example:
Paul> barplot(matrix(1:12,ncol=3),bes=T,legend.text=c("ABC","B2","C3","D4"),col=1:4)
Paul> was actually a bug in legend() (now fixed)
thank you for the fix (I'm probably also among the culprits..).
Since it's mentioned here, following is the patch against 0.61.2:
--- R-0.61.2/src/library/base/R/legend Wed Nov 12 04:53:32 1997
+++ R-devel/src/library/base/R/legend.R Thu Mar 26 06:02:23 1998
@@ -60,13 +60,17 @@
if(!merge) w <- w + x.intersp * xchar
if(merge) w <- w + x.intersp * xchar
## (w,h) are now the final box width/height. --> Adjust (x,y) :
- x <- x - xjust * w
- y <- y + (1 - yjust) * h
+ left <- x - xjust * w
+ top <- y + (1 - yjust) * h
+ right <- left+w
+ bottom <- top-h
+ if (xlog) { left <- 10^left; right <- 10^right }
+ if (ylog) { top <- 10^top; bottom <- 10^bottom }
if (bty != "n")
- rect(x, y, x+w, y-h, col = bg)
+ rect(left, top, right, bottom, col = bg)
## (xt[],yt[]) := 'current' vectors of (x/y) legend text
- xt <- rep(x, n.leg) + xchar
- yt <- y - (1:n.leg) * ychar
+ xt <- rep(left, n.leg) + xchar
+ yt <- top - (1:n.leg) * ychar
if (!missing(fill)) { #- draw filled boxes -------------
xx <- cbind(xt, xt + xbox)
if (xlog) xx <- 10^xx
Paul> (ii) i am told that the "!missing(col)" condition that meant a
Paul> legend would not be drawn if col was not specified is a
Paul> historical "feature" (from when col did not have a default
Paul> value). i have removed the condition.
thank you, Paul.
May I add something much more general here
(and also pertinent to barplot(.)):
==================================
My point: || almost never use missing(arg) ||
|| rather use is.null(arg) ||
==================================
(I have the impression that this rule is actually even observed by
increasingly more S "programmers").
This actually goes back to a discussion on S-news of Dec. 20-22, 1994,
Rick Becker started to give "S Programming Style" hints,
John Maindonald added to them, giving the is.null(.) hint,
and Rich Heiberger and me ``concluded'']
Here an excerpt of these December 1994 mailings:
RMH:
My conclusion is that an explicit NULL default value is safer than
a missing default.
MM:
MM94> I completely agree ---
MM94> it has the further advantage (hidden in RMH's example)
MM94> that you can explicitly set the parameter to NULL
MM94> which allows for the following nice code in a calling function :
MM94>
MM94> myfunction <- function(.........) {
MM94> .....
MM94> mm <- sub.function(x,y,z,u,v,w, def.par = if(abcdef) pi )
MM94> .....
MM94> }
MM94>
MM94> The ``if(CC) A'' as an expression returns NULL if CC evaluates to FALSE
MM94> such that in the example, the def.par argument
MM94> is either set to pi or NULL.
MM94> WITHIN sub.function(.),
MM94> missing(def.par) evaluates to FALSE in BOTH cases,
MM94> whereas
MM94> is.null(def.par)
MM94> tells you if the default is taken or not....
MM94>
MM94> such that when sub.function(.) uses missing(def.par)
MM94> the above code fragment would have to look more ugly, repeating the whole
MM94> argument list of sub.function [think of a LOOOONG list x,y,z,u,v,w,...]
MM94>
MM94> myfunction <- function(.........) {
MM94> .....
MM94> mm <- if(abcdef) sub.function(x,y,z,u,v,w, def.par = pi )
MM94> else sub.function(x,y,z,u,v,w)
MM94> .....
MM94> }
-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-
r-devel mailing list -- Read http://www.ci.tuwien.ac.at/~hornik/R/R-FAQ.html
Send "info", "help", or "[un]subscribe"
(in the "body", not the subject !) To: r-devel-request@stat.math.ethz.ch
_._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._