Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Passing a variable name to a function in R

I've noticed that quite a few packages allow you to pass symbol names that may not even be valid in the context where the function is called. I'm wondering how this works and how I can use it in my own code?

Here is an example with ggplot2:

a <- data.frame(x=1:10,y=1:10) library(ggplot2) qplot(data=a,x=x,y=y) 

x and y don't exist in my namespace, but ggplot understands that they are part of the data frame and postpones their evaluation to a context in which they are valid. I've tried doing the same thing:

b <- function(data,name) { within(data,print(name)) } b(a,x) 

However, this fails miserably:

Error in print(name) : object 'x' not found 

What am I doing wrong? How does this work?

Note: this is not a duplicate of Pass variable name to a function in r

like image 887
static_rtti Avatar asked Oct 02 '13 09:10

static_rtti


People also ask

Can you pass a variable to a function?

In JavaScript, you cannot pass parameters by reference; that is, if you pass a variable to a function, its value is copied and handed to the function (pass by value). Therefore, the function can't change the variable. If you need to do so, you must wrap the value of the variable (e.g., in an array).

What is a variable passed into a function called?

A parameter is a named variable passed into a function. Parameter variables are used to import arguments into functions. For example: function example(parameter) { console.


2 Answers

I've recently discovered what I think is a better approach to passing variable names.

a <- data.frame(x = 1:10, y = 1:10)  b <- function(df, name){     eval(substitute(name), df) }  b(a, x)   [1]  1  2  3  4  5  6  7  8  9 10 

Update The approach uses non standard evaluation. I began explaining but quickly realized that Hadley Wickham does it much better than I could. Read this http://adv-r.had.co.nz/Computing-on-the-language.html

like image 59
Jacob H Avatar answered Sep 28 '22 05:09

Jacob H


You can do this using match.call for example:

b <-  function(data,name) {    ## match.call return a call containing the specified arguments    ## and the function name also    ## I convert it to a list , from which I remove the first element(-1)   ## which is the function name    pars <- as.list(match.call()[-1])   data[,as.character(pars$name)]  }   b(mtcars,cyl)  [1] 6 6 4 6 8 6 8 4 4 6 6 8 8 8 8 8 8 4 4 4 4 8 8 8 8 4 4 4 8 6 8 4 

explanation:

match.call returns a call in which all of the specified arguments are specified by their full names.

So here the output of match.call is 2 symbols:

b <-  function(data,name) {   str(as.list(match.call()[-1]))  ## I am using str to get the type and name }  b(mtcars,cyl) List of 2  $ data: symbol mtcars  $ name: symbol cyl 

So Then I use first symbol mtcars ansd convert the second to a string:

mtcars[,"cyl"] 

or equivalent to :

eval(pars$data)[,as.character(pars$name)] 
like image 21
agstudy Avatar answered Sep 28 '22 07:09

agstudy