Passing a variable name to a function in R

前端 未结 4 835
悲&欢浪女
悲&欢浪女 2020-12-02 07:25

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

相关标签:
4条回答
  • 2020-12-02 07:55

    If you put the variable name between quotes when you call the function, it works:

    > b <- function(data,name) { within(data,print(name)) }
    > b(a, "x")
    [1] "x"
        x  y
    1   1  1
    2   2  2
    3   3  3
    4   4  4
    5   5  5
    6   6  6
    7   7  7
    8   8  8
    9   9  9
    10 10 10
    
    0 讨论(0)
  • 2020-12-02 07:57

    Very old thread but you can also use the get command as well. It seems to work better for me.

    a <- data.frame(x = 1:10, y = 11:20)
    
    b <- function(df, name){
    
       get(name, df)
    
     }
    
    b(a, "x")
     [1]  1  2  3  4  5  6  7  8  9 10 
    
    0 讨论(0)
  • 2020-12-02 08:04

    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

    0 讨论(0)
  • 2020-12-02 08:05

    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)]
    
    0 讨论(0)
提交回复
热议问题