1

I am having difficulty figuring out how to pass an argument through a nested function call to ggplot. An example will help illustrate:

library('tidyverse')

dset <- tibble(
  xvar = 1:5,
  yvar = 6:10
)

plot_inner <- function(.outcome) {

  ggplot(dset, aes(x=xvar)) +
    geom_line(aes_(y=substitute(.outcome)))
}

Now I can call plot_inner(.outcome=yvar) and it will correctly plot a line chart of yvar against xvar. However, the issue arises when I want to nest plot_inner() inside another function:

plot_outer <- function(..outcome) {

  plot_inner(.outcome=..outcome)
}

The intention is to let me call plot_outer() and specify ..outcome as a column of dset which then gets passed through to .outcome in plot_inner() which then gets plotted by ggplot(). But it doesn't work:

> plot_outer(..outcome=yvar)
Error in FUN(X[[i]], ...) : object '..outcome' not found

I've tried various combinations of parse(), eval(), substitute(), and deparse(), but could not figure out how to make this kind of nested function call work.

I also tried an alternative approach:

plot_inner_2 <- function(.outcome) {

  .outcome <- enquo(.outcome)

  dset %>% rename(value = UQ(.outcome)) %>%

    ggplot(aes(xvar, value)) +
      geom_line()
}

With this approach I can call plot_inner_2(.outcome=yvar) and it correctly produces the line chart of yvar against xvar. However, again I run into an error when I try to nest this inside another function and then call the outer function:

plot_outer_2 <- function(..outcome) {

  plot_inner_2(.outcome=..outcome)
}

> plot_outer_2(..outcome=yvar)
 Error: `..outcome` contains unknown variables

Any help would be appreciated. I would prefer a solution along the lines of the first approach I tried, but if anyone has a solution along the lines of the second approach, or some other approach entirely, I would be happy to learn whatever works.

5
  • Are you specifically trying to avoid using strings or tildes when passing the variable to the function argument? Commented Jul 31, 2017 at 22:15
  • @aosmith I would say that needing to use strings or tildes is not ideal, but it could nonetheless be a very good second-best option; if you have a solution in mind that uses strings or tildes I would readily welcome it. Commented Jul 31, 2017 at 22:30
  • This answer might be useful. Commented Jul 31, 2017 at 22:50
  • @aosmith Thank you, following that post you linked to, inside of plot_outer() I wrapped plot_inner() in eval(substitute()) and that seems to have worked. If you'd like to post that as an answer I will mark it as resolved, or if not then I will post it and mark it. Commented Aug 1, 2017 at 4:57
  • You should go ahead and put your solution as answer. Commented Aug 1, 2017 at 14:18

1 Answer 1

0

Following the link in @aosmith's comment, wrapping plot_inner() inside of eval(substitute()) within the plot_outer() function seems to be a solution.

plot_outer <- function(..outcome) {

  eval(substitute(plot_inner(.outcome=..outcome)))
}

Now the call to plot_outer(..outcome=yvar) works as intended, passing yvar through to .outcome in inner_plot() which is then passed to ggplot() and plotted against xvar.

Sign up to request clarification or add additional context in comments.

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.