How to extract the object name when the object is piped to a function?

Is it possible to extract the object name when the object is piped to a function?
(rationale: inside the function I would use both the object and the object name)

library(magrittr)
cars = mtcars

variable_name <- function(variable, folder = "temp"){
  # variable_name <- rlang::as_name(rlang::enquo(variable))
  variable_name <- rlang::as_label(rlang::enquo(variable))
  print(variable_name)
}

variable_name(cars)
#> [1] "cars"

cars %>% variable_name()
#> [1] "."

Can you suggest a solution which is working for both cases? Thank you.

2 Likes

Depending on what you exactly want to do, you can either use substitute(.) or deparse(substitute(.))

library(dplyr)

variable_name <- function(object_name, folder = "temp") {
  # return object_name
  object_name
  }

x <- mtcars %>% substitute(.)
x %>% class()
#> [1] "name"
x
#> mtcars

y <- mtcars %>% variable_name(object_name = deparse(substitute(.)))
y %>% class()
#> [1] "character"
y
#> [1] "mtcars"

Created on 2021-03-20 by the reprex package (v1.0.0)

Just in case you want to see an example, I created a show_summaries() function where I use something similar

# Examples usage show_summaries -------------------------------------------

# mpg %>% show_summaries()

# ## call function w/ providing description for section titles
# mpg %>% show_summaries(description = "mpg tidyverse dataset")
# 
# ## for description, determine name of input object
# mpg %>% show_summaries(description = substitute(.))
# 
# ## same, but now for a list object
# ability.cov %>% show_summaries(substitute(.))
# ## use `deparse()` to extract the name of a list within a list
# ability.cov$cov %>% show_summaries(description = deparse(substitute(.)))
1 Like

@lars
My goal is create a function which extracts the received object's name regardless the used syntax:

  • the object is an argument of the function: variable_name(cars)
  • the object is piped to the function: cars %>% variable_name()

And inside the function both the object and the (parsed) object name will be used further.

You mean like this?

# option 1
mtcars %>% variable_name(object_name = deparse(substitute(.)))
# option 2
variable_name(mtcars, object_name = deparse(substitute(mtcars)))

Notice that in option 1, the dot . in the substitute is basically a shorthand of the object passed in with the pipeline.
In option 2, that won't work, so you have to pass the object name explicitly.

@lars Thank you.
Your recommendation can work, although I don't prefer when formulas are included in the arguments, because I have to remember those "embedded" formulas (deparse(substitute())) and alter them when reusing the function for another object.
Like here: variable_name(mtcars, object_name = deparse(substitute(mtcars)))

My goal is to write a function which can be reused easily. Maybe this is harder to achieve, but later it will compensate when including in the code (and I can learn a lot during this process).

Yes, I fully understand your goal as that is exactly the same for me when I created my own show_summaries() functies - but this implementation was the best I could figure out.

Hopefully, someone else with a more thorough understanding of R and the (calling) environments would know if this can be achieved and what the approach would be then.

Nice challenge :slight_smile:

This topic was automatically closed 21 days after the last reply. New replies are no longer allowed.

If you have a query related to it or one of the replies, start a new topic and refer back with a link.