Home > Net >  Is there a way to parse a string in base r legend()?
Is there a way to parse a string in base r legend()?

Time:05-26

I have the following function that I use to write the output of a lm into ggplot graphs:

lm_eqn <- function(df){ # GET EQUATION AND R-SQUARED AS STRING
  m <- lm(y ~ x, df);
  eq <- substitute("Y"[i] == a   b %.% italic("X"[i])*","~~italic(r)^2~"="~r2, 
                   list(a = format(unname(coef(m)[1]), digits = 2),
                        b = format(unname(coef(m)[2]), digits = 2),
                        r2 = format(summary(m)$r.squared, digits = 3)))
  as.character(as.expression(eq));
}

df = data.frame(x=1:100, y=runif(100, 0, 100))

ggplot(data=df, aes(x=x, y=y))  
  geom_smooth(method = "lm")  
  annotate("text", x=50, y=50, label = lm_eqn(df), parse =TRUE)

It works perfectly well inside annotate if I use parse = TRUE. Unfortunately, the same procedure doesn't work in base r legend() because legend() has no parse operator.

m = lm(y ~ x, df)
plot(y ~ x, data=df)
abline(m)
legend("topright", legend = lm_eqn(df))

Is there a way to emulate annotate's behaviour in legend(), preferably using the same function?

enter image description here enter image description here

CodePudding user response:

Just remove as.character from the output of your function:

lm_eqn <- function(df){ # GET EQUATION AND R-SQUARED AS STRING
  m <- lm(y ~ x, df);
  eq <- substitute("Y"[i] == a   b %.% italic("X"[i])*","~~italic(r)^2~"="~r2, 
                   list(a = format(unname(coef(m)[1]), digits = 2),
                        b = format(unname(coef(m)[2]), digits = 2),
                        r2 = format(summary(m)$r.squared, digits = 3)))
  as.expression(eq);
}

m = lm(y ~ x, df)
plot(y ~ x, data=df)
abline(m)
legend("topright", legend = lm_eqn(df))

enter image description here

This will also work in ggplot, you don't even need parse = TRUE

ggplot(data=df, aes(x=x, y=y))  
  geom_smooth(method = "lm")  
  annotate("text", x=75, y=75, label = lm_eqn(df)) 

enter image description here

CodePudding user response:

You should change your lm_eqn function so that it doesn't convert the result into a string at the end. Then it will be fine:

lm_eqn <- function(df){ # GET EQUATION AND R-SQUARED AS EXPRESSION
    m <- lm(y ~ x, df)
    eq <- substitute("Y"[i] == a   b %.% italic("X"[i])*","~~italic(r)^2~"="~r2, 
                                     list(a = format(unname(coef(m)[1]), digits = 2),
                                             b = format(unname(coef(m)[2]), digits = 2),
                                             r2 = format(summary(m)$r.squared, digits = 3)))
    as.expression(eq)
}

df = data.frame(x=1:100, y=runif(100, 0, 100))

m = lm(y ~ x, df)
plot(y ~ x, data=df)
abline(m)
legend("topright", legend = lm_eqn(df))

Created on 2022-05-25 by the reprex package (v2.0.1)

If you can't make changes to lm_eqn, then you could use parse(text = lm_eqn(df)) instead; that's essentially what annotate(parse=TRUE) is doing.

  • Related