Deparse value of a function passed to a secondary function

Viewed 84

I have a function, defined as follows

fn1 <- function(var = NULL) {
  if (missing(var)) var else deparse(substitute(var))
}

I can call this function and it gives me what I want.

fn1()                                                                                                                                                
# NULL

fn1(test)                                                                                                                                            
# [1] "test"

I now want to functionalise the deparsing of var.

fn2 <- function(var = NULL) {
  deparse_var(var)
}

deparse_var <- function(var) {
  if (missing(var)) var else deparse(substitute(var))
}

But this does not give me the intended result

fn2()                                                                                                                                                
# [1] "var"

fn2(test)                                                                                                                                            
# [1] "var"

Since I have the value of var inside deparse_var(), I can check whether or not it is NULL. But the deparse does not work if it isn't.

deparse_var <- function(var) {
  if (is.null(var)) var else deparse(substitute(var))
}

fn2()
# [1] NULL

fn2(test)
# Error in deparse_var(var) : object 'test' not found
3 Answers

We can substitute on the first frame

deparse_var <- function(var) {
  if (is.null(var)) var else deparse(substitute(var, sys.frame(1)))
}

fn2 <- function(var = NULL) {
  deparse_var(var)
}
fn2()  
#NULL 

fn2(test)   
#[1] "test"

Or using missing

deparse_var <- function(var) {
   if (missing(var)) var else deparse(substitute(var, sys.frame(1)))
 }

fn2()
#[1] "NULL"
fn2(test)
#[1] "test"

In order to rectify the "NULL" to NULL, an if/else can be added. From @nathaneastwood's comments

deparse_var <- function(var) {
  res <- if (missing(var)) var else deparse(substitute(var, sys.frame(1))) 
  if (res == "NULL" && is.null(var)) NULL else res
}

How about the below? Should work for missing, NULL and others.

deparse_var <- function(var) {
  if (missing(var)) return(NULL)
  res <- deparse(substitute(var, sys.frame(1L))) 
  if (!identical(res, "NULL")) res
}

Note: You may want to adjust the visibility of the result as desired.

For anyone stumbling across this post. I continued to have issues with the solutions posted. However the below solution does work.

deparse_var <- function(var) {
  sub_var <- eval(substitute(substitute(var)), parent.frame())
  if (is.symbol(sub_var)) var <- as.character(sub_var)
  var
}

You can see the results below

fn2 <- function(var = NULL) {
  deparse_var(var)
}

fn2()
[1] NULL

fn2(test)
[1] "test"

fn2("test")
[1] "test"
Related