From P.Dalgaard at biostat.ku.dk  Wed Jun  3 12:24:27 2009
From: P.Dalgaard at biostat.ku.dk (Peter Dalgaard)
Date: Wed, 03 Jun 2009 12:24:27 +0200
Subject: [Rd] Vectorize fails for function with ... arglist
In-Reply-To: <8b356f880906022007k712c26a7g7497f24e03ac4e39@mail.gmail.com>
References: <8b356f880906022007k712c26a7g7497f24e03ac4e39@mail.gmail.com>
Message-ID: <4A264F5B.4030704@biostat.ku.dk>

Stavros Macrakis wrote:
> Vectorize is defined to return a function that acts as if 'mapply' was
> called.
> 
> So we have:
> 
>> mapply(dput,1:2)            # mapply form
> 1L                                      # calls dput on each element of 1:2
> 2L
> [1] 1 2
>> Vectorize(dput)(1:2)        # Vectorize form
> 1L                                        # same behavior
> 2L
> [1] 1 2
> 
> Same thing with a named argument:
> 
>> mapply(function(a)dput(a),1:2)
> 1L
> 2L
> [1] 1 2
>> Vectorize(function(a)dput(a))(1:2)
> 1L
> 2L
> [1] 1 2
> 
> But though mapply has no problem with function(...):
> 
>> mapply(function(...)dput(list(...)),1:2)
> list(1L)
> list(2L)
> [[1]]
> [1] 1
> 
> [[2]]
> [1] 2
> 
>> mapply(function(...)dput(list(...)),1:2,11:12)
> list(1L, 11L)
> list(2L, 12L)
>      [,1] [,2]
> [1,] 1    2
> [2,] 11   12
> 
> Vectorize fails silently in this case:
> 
>> Vectorize(function(...)dput(list(...))(1:2)
> list(1:2)                    # calls dput with entire vector
>                                 # invisible result inherited from dput
> 
>> Vectorize(function(...)dput(list(...)))(1:2,11:12)
> list(1:2, 11:12)
> 
> and sure enough:
> 
>> Vectorize(function(...)list(...))
> function(...)list(...)                            # returns arg unmodified!
> 
> I looked at the code, and ... args are *explicitly* rejected. I see no
> logical reason for this inconsistency, and the documentation doesn't require
> it.

I think it's a feature. There's no way of telling which "..." arguments
to vectorize over, and there are arguments that cannot be vectorized, so
vectorizing over all of them by default looks like a bad idea.  The
generic case is that the extra arguments could be things like
na.action=na.omit, which you just want to pass through to the scalar
function.


If you need the full feature set of mapply, use mapply. The
documentation looks like it could be improved, though.

	-p

> 
>               -s
> 
> PS This is not an artificial example concocted to demonstrate
> inconsistencies.  I had written the following function which wraps another
> function in a tryCatch:
> 
>        catcher <- function(f) function(...)
> tryCatch(do.call(f,list(...)),error=function(e) NA)
> 
> (The '...' argument list allows this to work with a function of any number
> of arguments.)
> 
> but instead of catching individual errors in
> Vectorize(catcher(fun))(1:10,1:10), it caught them all as one big error,
> which was not at all the goal.
> 
> 	[[alternative HTML version deleted]]
> 
> ______________________________________________
> R-devel at r-project.org mailing list
> https://stat.ethz.ch/mailman/listinfo/r-devel


-- 
   O__  ---- Peter Dalgaard             ?ster Farimagsgade 5, Entr.B
  c/ /'_ --- Dept. of Biostatistics     PO Box 2099, 1014 Cph. K
 (*) \(*) -- University of Copenhagen   Denmark      Ph:  (+45) 35327918
~~~~~~~~~~ - (p.dalgaard at biostat.ku.dk)              FAX: (+45) 35327907



[Rd] Vectorize fails for function with ... arglist
Peter Dalgaard