zerocool
zerocool

Reputation: 369

Get name of variable passed as function parameter

I am trying to catch the name of a variable passed to a function, the right way. The name of interest noi is a data frame column or a vector. Below is my minimum working example. Ideally, I would like to receive a character vector which contains only "noi"

library(dplyr)
df <- data.frame(noi = seq(1:3))

example_fun <- function( x ){
  deparse(substitute(x))  
}

The result depends on the way I structure my input. Now I have an idea why this happens, but how would I do it correctly to have the desired result, regardless of how I call the function.

# Base
example_fun(df$noi)
[1] "df$noi"

# Pipe
df$noi %>% example_fun() 
[1] "."

# Mutate
df %>% mutate(example_fun(noi))
  noi example_fun(noi)
1   1              noi
2   2              noi
3   3              noi

Thanks in advance!

Upvotes: 4

Views: 247

Answers (1)

ekoam
ekoam

Reputation: 8844

Perhaps decorate that variable with a "comment" attribute in another function? Note that the variable you want to decorate has to be wrapped directly in the decoration function z; otherwise, an error is raised (by design and for robustness).

example_fun <- function(x){
  attr(x, "comment")
}

z <- function(x) {
  nm <- substitute(x)
  nm <- as.character(
    if (is.symbol(nm) && !identical(nm, quote(.))) {
      nm
    } else if (length(nm) > 1L && (identical(nm[[1L]], quote(`[[`)) || identical(nm[[1L]], quote(`$`)))) {
      tail(nm, 1L)
    } else {
      stop("not a valid symbol or extract operator.", call. = match.call())
    }
  )
  `comment<-`(x, nm)
}

Output

> example_fun(z(df$noi))
[1] "noi"
> z(df$noi) %>% (function(x) x + 1) %>% example_fun()
[1] "noi"
> df %>% mutate(example_fun(z(noi)))
  noi example_fun(z(noi))
1   1                 noi
2   2                 noi
3   3                 noi
> z(df[["noi"]]) %>% example_fun()
[1] "noi"
> with(df, z(noi)) %>% example_fun()
[1] "noi"
> z(with(df, noi)) %>% example_fun()
 Error in z(with(df, noi)) : not a valid symbol or extract operator.
> df$noi %>% z()
 Error in z(.) : not a valid symbol or extract operator. 

... but this may not be a robust method. It is extremely difficult to achieve what you want in a robust way, especially when a pipeline is involved. I think you should read Hadley's Advanced R and learn more about how bindings and environments work.

Upvotes: 2

Related Questions