paxton
paxton

Reputation: 91

How do I modify labels produced by scales package?

graphs

So I'm making pyramid visualizations. I'm using scale_y_continuous(labels = scales::label_number_si(accuracy = 0.1)) to produce the labels. However, I want to get rid of the negative sign on the female section of the graph.

I think the best way to keep the SI suffixes, but remove the negative sign is to modify the labels output by label_number_si, but labels = abs(label_number_si()) gives the following error: Error in abs: non-numeric argument to mathematical function

Any insight is appreciated.

EDIT: Use demo_continuous(c(-1e10,1e10), label = label_number_si()) labels should look as they do below EXCEPT that negative numbers should not have a "-" in front

enter image description here

Upvotes: 3

Views: 614

Answers (1)

Jon Spring
Jon Spring

Reputation: 66775

I bet there's a simpler way to do this but I haven't figured it out yet.

Here's an example that replicates your question's result using the normal scales::label_number_si:

ggplot(data = data.frame(x = 1000*c(-5:-1, 1:5),
                         type = rep(1:2, each = 5))) +
  geom_col(aes(x,abs(x),fill = type), orientation = "y") +
  scale_x_continuous(labels = scales::label_number_si()) +
  facet_wrap(~type, scales = "free_x")

enter image description here

We could make a custom version of scales::label_number_si which makes them absolute values in the last step. To make this, I used command-click (Mac OS X) on the function name to see the underlying function's code, and then just pasted that into a new function definition with minor modifications.

label_number_si_abs <- function (accuracy = 1, unit = NULL, sep = NULL, ...) 
{
  sep <- if (is.null(unit)) 
    ""
  else " "
  function(x) {
    breaks <- c(0, 10^c(K = 3, M = 6, B = 9, T = 12))
    n_suffix <- cut(abs(x), breaks = c(unname(breaks), Inf), 
                    labels = c(names(breaks)), right = FALSE)
    n_suffix[is.na(n_suffix)] <- ""
    suffix <- paste0(sep, n_suffix, unit)
    scale <- 1/breaks[n_suffix]
    scale[which(scale %in% c(Inf, NA))] <- 1
    scales::number(abs(x), accuracy = accuracy, scale = unname(scale), 
           suffix = suffix, ...)
  }
}

We could replace with the custom function to get abs value labels:

ggplot(data = data.frame(x = 1000*c(-5:-1, 1:5),
                         type = rep(1:2, each = 5))) +
  geom_col(aes(x,abs(x),fill = type), orientation = "y") +
  scale_x_continuous(labels = label_number_si_abs()) +
  facet_wrap(~type, scales = "free_x")

enter image description here

Upvotes: 3

Related Questions