2

Feel I am making a very dumb mistake here.. as I've done this before on another project (maybe luck?)

Goal is to construct several graphs in ggplot via use of a function. I eventually want all the graphs displayed on a single page, etc...

Here is an example of a single ggplot that works:

if (require("ggplot2") == FALSE) install.packages("ggplot2")

data_df = data.frame(matrix(rnorm(200), nrow=20))
time=1:nrow(data_df)

ggplot(data=data_df, aes(x=time, y=data_df[,1])) + 
        geom_point(alpha=1/4) + 
        ggtitle(deparse(substitute(data_df[1])))

Note there are other functions that will be called within this that will change based on the dataframe column called. I followed another working example I had made, but this just gives me an error. I feel like I'm making an elementary mistake but can't put my finger on it!

if (require("ggplot2") == FALSE) install.packages("ggplot2")

data_df = data.frame(matrix(rnorm(200), nrow=20))
time=1:nrow(data_df)

graphit <- function(sample_num){
        ggplot(data=data_df, aes(x=time, y=data_df[,sample_num])) + 
                geom_point(alpha=1/4) + 
                ggtitle(deparse(substitute(data_df[sample_num])))
}

graphit(1)

#Error in `[.data.frame`(data_df, , sample_num) : 
#  object 'sample_num' not found

Thanks for any help.

tastycanofmalk
  • 628
  • 7
  • 23

2 Answers2

8

You're doing several things wrong.

First, everything specified inside aes() should be columns in your data frame. Do not reference separate vectors, or redundantly call columns via data_df[,1]. The whole point of specifying data = data_df is that then everything inside aes() is evaluated within that data frame.

Second, to write functions to create ggplots on different columns based on arguments, you should be using aes_string so that you can pass the aesthetic mappings as characters explicitly and avoid problems with non-standard evaluation.

Similarly, I would not rely on deparse(substitute()) for the plot title. Use some other variable built into the data frame, or some other data structure.

For instance, I would do something more like this:

data_df = data.frame(matrix(rnorm(200), nrow=20))
time=1:nrow(data_df)
data_df$time <- time

graphit <- function(data,column){
    ggplot(data=data, aes_string(x="time", y=column)) + 
        geom_point(alpha=1/4) + 
        ggtitle(column)
}

graphit(data_df,"X1")
joran
  • 169,992
  • 32
  • 429
  • 468
  • thanks so much. i did finally get the code working thanks to your explanation. i'm sure i'll reference this answer in the future – tastycanofmalk Jun 13 '14 at 14:34
1

Can't comment due to rep count. Joran's solution (and advice on ggplot2) is highly recommended.

Here is a highly not recommended hack that will get your code to work. Add this line as the first line of your function.

assign(x = "sample_num", value = sample_num, envir=.GlobalEnv)

Alternative synthax for the same code above is sample_num <<- sample_num.

The issue you are facing is an scoping issue. sample_num exists only within the graphit() environment and is not defined within the ggplot() environment.

Vlo
  • 3,168
  • 13
  • 27