5

I have following simple function but its ggplot command does not work. The command works all right when given from command line:

> testfn <- function(gdf, first, second){          
   library(ggplot2) 
   print(ggplot(gdf, aes(first, second)) + geom_point()) 
}                                                                                              
>
> testfn(mydataf, vnum1, vnum2)   
    Error in eval(expr, envir, enclos) : object 'second' not found
> 
> ggplot(mydataf, aes(vnum1, vnum2)) + geom_point()

>  (plots graph without any error)

I tried to use aes_string instead of aes; and also using x=first, y=second. Things improve and one point is plotted! X and Y axes show numbers related to that point as the label. Only the first row is being plotted. Where is the problem. Thanks for your help.

smci
  • 32,567
  • 20
  • 113
  • 146
rnso
  • 23,686
  • 25
  • 112
  • 234
  • Show us `dim(gdf)`. How many points do you think your x,y-series have? Also show us `dput(gdf)`, or at least truncate out a snippet of the x,y-series of say length 10. – smci Apr 30 '14 at 08:15
  • Ah. On the command-line, `ggplot(gdf, aes(first, second))` would work fine. But inside your function, you're also passing in `first,second` as string variables. So yes you would need `aes_string(first,second)` inside your function testfn, since you're now passing variable names indirectly, through the string-variables `first,second`. – smci Apr 30 '14 at 08:17
  • I strongly recommend you get your `ggplot()` command working on the command-line, before you then try to wrap it inside a function. Make your debugging life easy. Don't try to solve five problems at once. – smci Apr 30 '14 at 08:19
  • 1
    Putting quotes around variable names while calling the function, i.e. testfn(mydataf, "vnum1", "vnum2" , works well. Earlier I was trying testfn(mydataf, vnum1, vnum2) which did not work. Thanks for your comments. – rnso Apr 30 '14 at 09:12
  • I posted my above suggestions as an answer. – smci Apr 30 '14 at 09:18

2 Answers2

4

So the aes_string version works fine for me.

# set-up and sample data
library(ggplot2) 
set.seed(1)
mydataf <- data.frame(vnum1=rnorm(10), 
                      vnum2=rnorm(10))
# aes_string version called with characters
testfn <- function(gdf, first, second){            
  print(ggplot(gdf, aes_string(x=first, y=second)) + geom_point()) 
}                                                                                              
# aes_string version called with variables
testfn2 <- function(gdf, first, second){  
  print(ggplot(gdf, aes_string(x=deparse(substitute(first)), 
                               y=deparse(substitute(second)))) + 
          geom_point())
}     
# 3 times the same plot
ggplot(mydataf, aes(vnum1, vnum2)) + geom_point()
testfn(mydataf, "vnum1", "vnum2")   
testfn2(mydataf, vnum1, vnum2)   
shadow
  • 21,823
  • 4
  • 63
  • 77
  • The command testfn(mydataf, "vnum1", "vnum2") works all right. I was not quoting the names of variable. Thanks. – rnso Apr 30 '14 at 09:10
4

(As per my initial suggestion and your confirmation)

It was about how you were trying to pass string arguments of variable names into your fn.

  • on the command-line, ggplot(gdf, aes(first, second)) would work fine
  • but inside your function, you're also passing in first,second as string variables. So yes you would now need aes_string(first,second) inside your function testfn, since you're now passing variable names indirectly, through the string-variables first,second.
  • also since the variable-names first,second are strings, yes you do need to quote them when you call the fn. (I'm not sure what language mechanism ggplot's aes() uses to not need strings, but whatever. Use quotes.)
  • see also the quote() command in R
smci
  • 32,567
  • 20
  • 113
  • 146