schneider_41042
schneider_41042

Reputation: 21

Write mutliple mathematical symbols via bquote in R

I am having trouble placing more than one mathematical symbol via bquote in the scale_color_manual call of ggplot. As an example, I am trying to create a legend that has pvalues labeled and described in a plot. For instance:

plot.1 <- ggplot(data, aes(x=x, y=y, color=pvalues))+
geom_hline(yintercept=0.00, linetype='dotted', col = 'grey', size=1.0)+
geom_pointrange(aes(ymin=Lower, ymax=Upper)
ylab("Regression Coefficient")+
scale_color_manual(values=c("Strong" = "#fde725",
                          "Moderate" = "#21918c",
                          "Weak" = "#440154",
                          "Absent" = "lightgrey"),
                 labels=c(bquote("Strong (" <= " 0.05)"),
                          bquote("Moderate (0.05" < beta <= " 0.10)"),
                          bquote("Weak (" > " 0.10)"), 
                          "Absent"))+
theme_bw()

The less than or equal to sign works for "Strong" but I get this error message with "Moderate."

Error: unexpected '<=' in: "labels=c(bquote("Strong (" <= " 0.05)"),
                            bquote("Moderate (0.05" < beta <="

I am sure the answer is simple but I have not been able to find a bquote vignette or pdf anywhere, just little tidbits sprinkled across stackoverflow.

Upvotes: 1

Views: 43

Answers (1)

jpsmith
jpsmith

Reputation: 17174

I agree, for me support for bquote is notoriously hard to find.

bquote() is best used when you want to construct an expression that contains both fixed text and dynamic values that are drawn from the environment (i.e., if the mild/moderate/severe thresholds changed based on the data). In this vein, I wouldn't recommend using it for these purposes (see below)

For completeness, though, if you want to use bquote in this exact way, the reason you are getting this error is the way R reads mathematical functions like <, >, >=, etc. Using these as-is makes R attempt immediate evaluation of the <= operator (and similar, i.e., its looking for something less than or equal to the LHS of the equality).cSince you want them in an expression, backticks (`) are required to treat these symbols (<, <=, and >) as names or expressions - backticks explicitly tell R to interpret them as symbols rather than an actual operator.

So, if you really want to use bquote here, you will need to use backticks (`) and tilde separators.

# sample data 
data <- data.frame(
  x = c(1, 2, 3, 4, 5),
  y = c(-0.250920, 0.901429, 0.463988, 0.197317, -0.687963),
  pvalues = c("Weak", "Strong", "Moderate", "Absent", "Absent"),
  Lower = c(-0.472429, 0.767324, 0.350978, -0.092460, -0.981089),
  Upper = c(0.042997, 1.156455, 0.751888, 0.476282, -0.468383)
)

library(ggplot2) 

ggplot(data, aes(x = x, y = y, color = pvalues, ymin = Lower, 
                 ymax = Upper)) +
  geom_hline(yintercept = 0.00, linetype = 'dotted', col = 'grey', size = 1.0) +
  geom_point() +
  geom_pointrange() +
  ylab("Regression Coefficient") +
  scale_color_manual(values=c("Strong" = "#fde725",
                              "Moderate" = "#21918c",
                              "Weak" = "#440154",
                              "Absent" = "lightgrey"),
                     labels=c(bquote("Strong (" ~ `<=` ~ " 0.05)"),
                              bquote("Moderate (0.05" ~ `<` ~ beta ~ `<=` ~ " 0.10)"),
                              bquote("Weak (" ~ `>` ~ " 0.10)"),
                              "Absent"))+
  theme_bw()

However, in this application you just want static text (i.e., the values for the p values that define moderate, severe, etc do not change). I would argue that you dont need bquote at all if they are just labels, and can just use text - plugging in "\u03b2" for the beta symbol:

ggplot(data, aes(x = x, y = y, color = pvalues, ymin = Lower, 
                 ymax = Upper)) +
  geom_hline(yintercept = 0.00, linetype = 'dotted', col = 'grey', size = 1.0) +
  geom_point() +
  geom_pointrange() +
  ylab("Regression Coefficient") +
  scale_color_manual(values = c("Strong" = "#fde725",
                              "Moderate" = "#21918c",
                              "Weak" = "#440154",
                              "Absent" = "lightgrey"),
                     labels = c("Strong (<=0.05)",
                              "Moderate (0.05 < \u03b2 <= 0.10)",
                              "Weak (>0.10)",
                              "Absent")) +
  theme_bw()

Both of these return the same plot: enter image description here

As @baobab notes in the comments, you may also want to use unicode for the less than/greater than symbols. For convenience, they are below:

"\u2265"
# [1] "≥"

"\u2264"
# [1] "≤"

Upvotes: 2

Related Questions