8

The title isn't super descriptive as the problem is longer than a reasonable title I could think of could display.

I want to have a function that grabs object names from other functions that can be used as arguments in another function. Here's a barebones attempt:

grab <- function(x) {
    as.character(substitute(x))
}

FUN <- function(foo, bar = grab(foo)) {
    bar
}

FUN(mtcars)

Here I's want FUN to return the character string "mtcars" but it returns "foo". How could a make a grab function that does this (I want to do this because I'm going to use this as the default to a txt/csv etc file. It's a convenience setting.

Here are some unsuccessful attempts (but I want to have a generic grab function):

FUN2 <- function(foo, bar = as.character(substitute(bar))) {
   bar
}

FUN2(mtcars)

#==================

FUN3 <- function(foo, bar) {
    if(missing(bar)) bar <- foo
    as.character(substitute(bar))
}

FUN3(mtcars)

Real life-ish example:

real_example <- function(obj, file = grab(obj)) {
    write.csv(obj, file = sprintf("%s.csv", file))
}
4
  • Feel free to edit or edit title to make this more clear. Commented Sep 21, 2013 at 20:21
  • This question looks very similar: stackoverflow.com/questions/5754367/… Commented Sep 21, 2013 at 20:45
  • @Frank did you get any of those responses to work? Commented Sep 21, 2013 at 20:48
  • 1
    @TylerRinker I haven't tried everything, but this roughly does the same thing: (function(x,y=get_args()))('mtcars') where get_args is from stackoverflow.com/questions/17256834/… Commented Sep 21, 2013 at 20:57

2 Answers 2

6

You could try sys.call to get access to the parent call:

## "which" is the number of the argument of interest
grab <- function(which) {
  ## which + 1, because [1] == name of function/call
  ## and arguments are 2:n
  as.character(sys.call(-1L)[which+1L])
}

FUN <- function(foo, bar = grab(1L)) {
  bar
}

FUN(mtcars)
# "mtcars"
Sign up to request clarification or add additional context in comments.

2 Comments

This is the behavior I am looking for. I'll hold off checking as the answer in case others have a better option (i.e., someone points out something faulty with this).
+1. Yeah, as Tyler says, if there's nothing wrong with doing it this way (instead of passing the name "mtcars" and using get), I might use this, too.
6

How about this?

grab <- function(x) as.character(x[["foo"]])
FUN <- function(foo, bar=grab(match.call())) { bar }

FUN(mtcars)
# [1] "mtcars"

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.