In R, how to get an object's name after it is sent to a function?

R

R Problem Overview


I am looking for the reverse of get().

Given an object name, I wish to have the character string representing that object extracted directly from the object.

Trivial example with foo being the placeholder for the function I am looking for.

z <- data.frame(x=1:10, y=1:10)

test <- function(a){
  mean.x <- mean(a$x)
  print(foo(a))
  return(mean.x)}

test(z)

Would print:

  "z"

My work around, which is harder to implement in my current problem is:

test <- function(a="z"){
  mean.x <- mean(get(a)$x)
  print(a)
  return(mean.x)}

test("z")

R Solutions


Solution 1 - R

The old deparse-substitute trick:

a<-data.frame(x=1:10,y=1:10)
test<-function(z){
   mean.x<-mean(z$x)
   nm <-deparse(substitute(z))
   print(nm)
   return(mean.x)}
 
 test(a)
#[1] "a"   ... this is the side-effect of the print() call
#          ... you could have done something useful with that character value
#[1] 5.5   ... this is the result of the function call

Edit: Ran it with the new test-object

Note: this will not succeed inside a local function when a set of list items are passed from the first argument to lapply (and it also fails when an object is passed from a list given to a for-loop.) You would be able to extract the ".Names"-attribute and the order of processing from the structure result, if it were a named vector that were being processed.

> lapply( list(a=4,b=5), function(x) {nm <- deparse(substitute(x)); strsplit(nm, '\\[')} )
$a      # This "a" and the next one in the print output are put in after processing
$a[[1]]
[1] "X"    ""     "1L]]"  # Notice that there was no "a"


$b
$b[[1]]
[1] "X"    ""     "2L]]"

> lapply( c(a=4,b=5), function(x) {nm <- deparse(substitute(x)); strsplit(nm, '\\[')} )
$a
$a[[1]]   # but it's theoretically possible to extract when its an atomic vector
[1] "structure(c(4, 5), .Names = c(\"a\", \"b\"))" ""                                            
[3] "1L]]"                                        


$b
$b[[1]]
[1] "structure(c(4, 5), .Names = c(\"a\", \"b\"))" ""                                            
[3] "2L]]"  

Solution 2 - R

deparse(quote(var))

My intuitive understanding In which the quote freeze the var or expression from evaluation and the deparse function which is the inverse of parse function makes that freezed symbol back to String

Solution 3 - R

Note that for print methods the behavior can be different.

print.foo=function(x){ print(deparse(substitute(x))) }
test = list(a=1, b=2)
class(test)="foo"
#this shows "test" as expected
print(test)

#this (just typing 'test' on the R command line)
test
#shows
#"structure(list(a = 1, b = 2), .Names = c(\"a\", \"b\"), class = \"foo\")"

Other comments I've seen on forums suggests that the last behavior is unavoidable. This is unfortunate if you are writing print methods for packages.

Solution 4 - R

To elaborate on Eli Holmes' answer:

  1. myfunc works beautifully
  2. I was tempted to call it within another function (as discussed in his Aug 15, '20 comment)
  3. Fail
  4. Within a function, coded directly (rather than called from an external function), the deparse(substitute() trick works well.
  5. This is all implicit in his answer, but for the benefit of peeps with my degree of obliviousness, I wanted to spell it out.
an_object <- mtcars
myfunc <- function(x) deparse(substitute(x))

myfunc(an_object)
#> [1] "an_object"

# called within another function 
wrapper <- function(x){
  myfunc(x)
}

wrapper(an_object)
#> [1] "x"

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionEtienne Low-D&#233;carieView Question on Stackoverflow
Solution 1 - RIRTFMView Answer on Stackoverflow
Solution 2 - RcloudscomputesView Answer on Stackoverflow
Solution 3 - REli HolmesView Answer on Stackoverflow
Solution 4 - RRichard CareagaView Answer on Stackoverflow