4
votes

I'm an R/ggplot newbie switching over from MatLab.

I would like to create a function using ggplot with linear regression equation printed on the graph (which is discussed in Adding Regression Line Equation and R2 on graph). But here, I am trying to build a function with it but wasn't successful.

I kept getting an error - "Error in eval(expr, envir, enclos) : object 'label' not found".

One workaround is to define "label" variable outside of the function but I just don't understand why this doesn't work.

Can anyone explain why?

df <- data.frame(x = c(1:100))
df$y <- 2 + 3 * df$x + rnorm(100, sd = 40)

f <- function(DS, x, y, z) {
    label <- z
    print(label)

    ggplot(DS, aes(x=x, y=y)) + 
        geom_point() +
        labs(y=y) +
        labs(title=y) +
        xlim(0,5)+
        ylim(0,5)+
        geom_smooth(method="lm", se=FALSE)+
        geom_text (aes(x=1, y=4, label=label))
}

f(df, x, y, "aaa") #execution line  
1

1 Answers

5
votes

See the following code:

library(ggplot2)
df <- data.frame(x = c(1:100))
df$y <- 2 + 3 * df$x + rnorm(100, sd = 40)
f <- function(DS, x, y, z) {
  label.df = data.frame(x=1, y=4, label=z)
  ggplot(DS, aes_string(x=x, y=y)) + 
    geom_point() +
    labs(y=y) +
    labs(title=y) +
    geom_smooth(method="lm", se=FALSE)+
    geom_text (aes(x=x, y=y, label=label), label.df)
}

f(df, "x", "y", "aaa") 

There were a few fixes about your code:

  • The data you are using in geom_text is the same you have defined in ggplot() unless you change it. Here I have created a temporary data.frame for this purpose called label.df.
  • The xlim() and ylim() functions were filtering most of your data points, since the range of x and y are much larger than the limits you defined in the original code.
  • When you want to pass the names of the columns of your data.frame to be used for displaying the graph it would be easier to pass their names as strings (i.e. "x"). This way, the aes() function is also changed to aes_string().

Here is the result: enter image description here

Edit Thanks to @Gregor, a simpler version would be:

f <- function(DS, x, y, z) {
   ggplot(DS, aes_string(x=x, y=y)) + 
    geom_point() +
    labs(y=y) +
    labs(title=y) +
    geom_smooth(method="lm", se=FALSE)+
    annotate(geom="text", x=1, y=4, label=z)
}