Martin Maechler
1998-Mar-26 11:04 UTC
S programming style & "missing(.)" [was "regarding bugs in barplot" on R-core]
[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 _._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._