Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

ggplot2: How to parse a character variable (e.g. x <- ".35") as character, not number, in geom_text label

Tags:

r

ggplot2

I am working on a figure for publication and wish to annotate it with some beta and p values; the style guidelines of my area dictate that these numbers be formatted without leading zeros (e.g., ".003", not "0.003"). I have run into what seems like a Catch-22; I have extracted beta and p values from my models and done some preprocessing to correctly format them so that they are now characters rather than numeric:

fake.beta.vals <- c(".53", ".29", ".14")
fake.p.vals <- c(".034", ".001", ".050")

But, when I try to use these values in my figure, parse = TRUE turns them back into numeric values, losing the formatting I need.

fake.beta.vals <- c(".53", ".29", ".14")
fake.p.vals <- c(".034", ".001", ".050")

p <- ggplot(iris, aes(x = Sepal.Length, y = Sepal.Width))
p <- p + 
  geom_smooth(method = "lm") +
  geom_point() +
  facet_wrap( ~ Species)
p

len <-length(levels(iris$Species))
vars <- data.frame(expand.grid(levels(iris$Species)))
colnames(vars) <- c("Species")
betalabs <- as.data.frame(fake.beta.vals)
plabs <- as.data.frame(fake.p.vals)
dat <- data.frame(
  x = rep(7, len),
  y = rep(4, len),
  vars,
  betalabs,
  plabs)
dat$fake.beta.vals <- as.factor(dat$fake.beta.vals)
dat$fake.p.vals <- as.factor(dat$fake.p.vals)

p <- p +
  geom_text(
    aes(x     = x,
        y     = y,
        label = paste("list(beta ==",
                      fake.beta.vals,
                      ", italic(p) ==",
                      fake.p.vals,
                      ")"),
        group = NULL),
    size  = 5,
    data  = dat,
    parse = TRUE)
p

I have been banging my head against this problem for a while now but adding as.character():

        label = paste("list(beta ==",
                      as.character(fake.beta.vals),
                      ", italic(p) ==",
                      as.character(fake.p.vals),
                      ")"),

Is obviously also cancelled out by parse = TRUE

And adding the function I had previously used to format my values:

statformat <- function(val,z){
  sub("^(-?)0.", "\\1.", sprintf(paste("%.",z,"f", sep = ""), val))
}

Is even worse:

        label = paste("list(beta ==",
                      statformat(fake.beta.vals, 2),
                      ", italic(p) ==",
                      statformat(fake.p.vals, 3),
                      ")"),

And just ends up with a mess.

Help?

like image 467
A Jack Avatar asked Dec 20 '22 23:12

A Jack


1 Answers

Use bquote to create the labels, then coerce to a character representation using deparse

For example

# create a list of labels using bquotw
labs <- Map(.beta = fake.beta.vals, 
            .p = fake.p.vals, 
          f = function(.beta,.p) bquote(list(beta == .(.beta), italic(p) == .(.p))))
# coerce to a character representation for parse=TRUE to work within 
# geom_text
dat <- data.frame(
  x = rep(7, len),
  y = rep(4, len),
  vars,
  labels = sapply(labs,deparse))


p <- ggplot(iris, aes(x = Sepal.Length, y = Sepal.Width)) + 
  geom_smooth(method = "lm") +
  geom_point() +
  facet_wrap( ~ Species) +
  geom_text(data = dat, aes(x=x,y=y,label=labels), parse=TRUE)
p

enter image description here

like image 154
mnel Avatar answered Jan 30 '23 23:01

mnel