3

I am working on a shiny app where the user selects which variables might be plotted using ggplot2, however I am completely unsure about the best way to convert character strings (which are the names of the variable to be plotted) in to suitable function arguments.

Consider the following very artificial, working example:

df <- data.frame(gp = factor(rep(letters[1:3], each = 10)),
                 y = rnorm(30))

ggplot(df, aes(x = gp, y = y)) +
   geom_point() + facet_wrap(~gp)

Now, how would I tell ggplot to plot the 'gp' variable on the x axis, if all I have is a character string of the name of the variable?

I have whipped up the following, but is there a simpler and more conventional method? Note the different approaches I use in the aes() and facet_wrap() functions.

x.var <- "gp"

ggplot(df, aes(x=lol <- switch(x.var,"gp"=gp), y = y)) +
   geom_point() + facet_wrap(as.formula(paste("~",x.var)))

Any insight is greatly appreciated!

dcl
  • 929
  • 1
  • 10
  • 22

1 Answers1

5

It would be much better if you used aes_string to specify your x and y variables, instead of x=lol <- switch(x.var,"gp"=gp), i.e. use the following:

ggplot(df, aes_string(x = x.var, y = 'y')) +
  geom_point() + facet_wrap(as.formula(paste("~",x.var)))

Unfortunately, for the facet_wrap function what you have already done is probably the optimal way.

LyzandeR
  • 37,047
  • 12
  • 77
  • 87
  • wow, I didn't know about that function. Thank you. In general though, is there a preferred way to use character strings as function arguments? Say I wanted to dplyr::filter(df,x.var=="a"), where x.var="gp"? – dcl Feb 10 '15 at 11:11
  • 1
    Happy to have helped :). In my opinion, the preferred way is to not use character strings as function arguments wherever possible. In your specific case above it seems extremely weird to use a `text==text` notation but to mean `variable==text`. If you have to do something like that maybe `eval(parse(text='x.var==a'))` might work but I would have to test first. I think it might be better to post as a different question with a reproducible example (like this very good one) so that we can test. – LyzandeR Feb 10 '15 at 11:17
  • Oh, I mean variable==text, but the name of the variable can change, however we have the name of it in string form as x.var="gp". So we would filter on gp=="a" – dcl Feb 10 '15 at 11:22
  • 1
    Interesting case. This is how I thought you would use it. The above might work but I am not sure. I would have to test first. It is an interesting question. Would you please post it as a new one? I would be interested in giving a go to solve it and it would be interesting to see how other people would approach it. (If you do please send me the link of the question here). – LyzandeR Feb 10 '15 at 11:27
  • 1
    this thing worked for me but there might be better ways to do it: `df %>% filter( eval(parse(text="gp == 'a'"),envir=df))` – LyzandeR Feb 10 '15 at 11:34
  • @DCL Good thread although I think it is a duplicate of http://stackoverflow.com/questions/19826352/pass-character-strings-to-ggplot2-within-a-function?rq=1. Regarding your first footnote, I had a recent question about passing arguements with dplyr http://stackoverflow.com/questions/28161349/using-dplyr-within-a-function-grouping-error-with-function-arguments – Michael Bellhouse Feb 11 '15 at 03:23