[R] Using names in function with ellipsis (non standard evaluation?)

David Winsemius dwinsemius at comcast.net
Thu May 28 21:55:44 CEST 2015


On May 28, 2015, at 11:03 AM, Duncan Murdoch wrote:

> On 28/05/2015 1:40 PM, Luca Cerone wrote:
>> Hi everybody,
>> 
>> this is probably a silly question, but I can't find a way to recognize
>> the names that are passed
>> to variables in ellipsis.
>> 
>> For example, say I have a "core" function that receives some extra
>> parameters through ...
>> e.g.
>> 
>> f <- function(...) {
>>    params <- c(...)
>>    #dothehardworkhere using "names(params)"
>> }
> 
> The usual method is to use list(...) which retains the names, not c(...).
>> 
>> and then I want to create a function g where some of the parameters
>> are set like:
>> 
>> g <- function(x,y) f(x,y)
>> 
>> I figure I probably have to use to substitute in f, but it is not
>> clear to me how.
>> 
>> Definitely what I need to achieve is that when I call:
>> 
>> g(1,2) then in f params is the vector c(x=1,y=2);
>> similarly I want to be able to call g(y=2, x=1)
>> and have params = c(x=1,y=2) in f.
>> 
>> Can you please help me understanding how to do this?
> 
> Can't you just call g(...)?  I don't understand what the problem is.

I certainly agree that the problem statement is unclear. Using list(...) returns a value that is predictably a list whereas using c(...) may return an atomic vector or a list depending on the mode of the arguments. But in both instances names are available.

> f <- function(...) {
+   params <- c(...)
+   print( names(params))
+ }
> f(x=2,y=3)
[1] "x" "y"
> f <- function(...) {
+   params <- list(...)
+   print( names(params))
+ }
> f(x=2,y=3)
[1] "x" "y"
> f <- function(...) {
+   params <- list(...)
+   str(params)
+ }
> f(x=2,y=3)
List of 2
 $ x: num 2
 $ y: num 3
> f <- function(...) {
+   params <- c(...)
+   str(params)
+ }
> f(x=2,y=3)
 Named num [1:2] 2 3
 - attr(*, "names")= chr [1:2] "x" "y"
> f(x=2,y=list(3))
List of 2
 $ x: num 2
 $ y: num 3

Passing to the next function requires some extra effort:

> g <- function(...) {lis <- list(...); x<-lis[['x']]; y=lis[['y']]; f(x,y) }
> f <- function(x,y) x^y

> g(y=2, x=10)
[1] 100


Explicitly extracting named values into the local function environment seemed a bit convoluted but successful. This lets the lis object be the first place to look but evaluation will pull in tokens that are not found in that list

> g <- function(...) {lis <- list(...); eval(expression( f(x,y)), envir=lis) }
> g(y=2, x=10)
[1] 100

> g <- function(...) {lis <- list(...); eval(expression( f(x,y)), envir=lis) }
> g(y=2)
[1] 64
> x
[1] 8


The naive attempt fails because the names are not on the search list:
> rm(x); rm(y)
> g <- function(...) {lis <- list(...); f(x,y) }
> g(y=2, x=10)
Error in f(x, y) : object 'x' not found


If those symbols existed outside the g()  function, they would be found and used:

> y=3 ; x=8  # outside the function body

> g(y=2, x=10)
[1] 512  Not expected


-- 

David Winsemius
Alameda, CA, USA



More information about the R-help mailing list