Skip to content

round() ignores missing arguments if it is used inside another function where some arguments are missing.

7 messages · Joris Meys, Simon Urbanek, Gavin Simpson +3 more

#
I have stumbled across some behaviour in R that I really can't place,
and that makes coding a bit tricky. I know that I can work around it
when explicitly checking for missing arguments, but still...
I have two functions. I have a first function based on paste

? ? fun1 <- function(x,y){
? ? ? print(missing(y))
? ? ? paste(x,'X',sep=y)
? ? }

If I try this function without specifying `y`, I get the (expected)
error message:

? ? > fun1(letters[1:6])
? ? [1] TRUE
? ? Error in paste(x, "X", sep = y) :
? ? ? argument "y" is missing, with no default

The second one with round :
? ? fun2 <- function(x,y){? ? ? print(missing(y))? ? ? round(x,digits=y)? ? }
If I try this function without specifying `y`, it works unexpectedly
whereas it shouldn't :
? ? > fun2(100.1)? ? [1] TRUE? ? [1] 100
In my view, fun1 should definitely give the error message as well, as
it is not intended to have a default behaviour when y is missing.
Still, the round() function ignores the fact y is missing. Is this by
design, is there a check missing in round, or is something else going
on that I am overlooking?

Cheers
Joris
R version 2.14.0 (2011-10-31)
Platform: i386-pc-mingw32/i386 (32-bit)

locale:
[1] LC_COLLATE=English_United Kingdom.1252
[2] LC_CTYPE=English_United Kingdom.1252
[3] LC_MONETARY=English_United Kingdom.1252
[4] LC_NUMERIC=C
[5] LC_TIME=English_United Kingdom.1252

attached base packages:
[1] stats     graphics  grDevices utils     datasets  methods
[7] base

loaded via a namespace (and not attached):
[1] tools_2.14.0
#
On Nov 18, 2011, at 10:43 AM, Joris Meys wrote:

            
function (x, digits = 0)  .Primitive("round")

it has a default so it is fine for digits to be missing since it will have value 0 in that case ...

Cheers,
S
#
On Fri, 2011-11-18 at 16:43 +0100, Joris Meys wrote:
round() is implemented as:
function (x, digits = 0)  .Primitive("round")

using the .Primitive means of calling C code. `?.Primitve` refers you to
the R Internals manual, which basically states that how the compiled
functions should be called and number of arguments etc is stored in a
table. This table is given here:

http://svn.r-project.org/R/trunk/src/main/names.c

The relevant part of which is:

/* printname	c-entry		offset	eval	arity	pp-kind	     precedence	rightassoc
 * ---------	-------		------	----	-----	-------      ----------	----------*/
....
/* Mathematical Functions */
/* primitives: these are group generic and so need to eval args (possibly internally) */
{"round",	do_Math2,	10001,	0,	-1,	{PP_FUNCALL, PREC_FN,	0}},


the eval column indicates features of how arguments are evaluated and
what have you. A value of 0 equates to 000 and the last 0 indicates
whether arguments are to be evaluated with 0 indicating no evaluation
and 1 evaluation.

round is indicated to not evaluate its arguments. I don't follow the C
code well enough to know if it should be catching the missing argument
further on - it must be because it is falling back to the default, but
the above explains that the not evaluating arguments is intended.

G

  
    
#
On Fri, Nov 18, 2011 at 5:10 PM, Gavin Simpson <gavin.simpson at ucl.ac.uk> wrote:
So if I understand it right, the y argument is not evaluated in the
fun2 function but deeper in the C code. that explains the lack of the
error message, thanks! I keep on learning every day.
Cheers

Joris
#
You can also see the odd behavior without wrapping round in another 
function:

 > round(100.1, digits=)
[1] 100
On 11/18/2011 10:19 AM, Joris Meys wrote:
#
On Fri, Nov 18, 2011 at 9:34 AM, Kevin R. Coombes
<kevin.r.coombes at gmail.com> wrote:
Hmm... is there a reason for why the parser accepts that construct?
Some example:
expression(f(a=))
expression(f[a=])
Error in parse.default(text = "(a=)") : <text>:1:4: unexpected ')'
1: (a=)

/Henrik
#
On Nov 19, 2011, at 04:35 , Henrik Bengtsson wrote:

            
Yes. See e.g. help(alist) for actual usage. 

It can also be used to pass empty arguments to FUN in apply-constructs:

a <- matrix(1:12, 3, 4)
f <- function(i, j) a[i,j]
lapply(1:4, f, i=)