r - Formatting ggplot2 axis labels with commas (and K? MM?) if I already have a y-scale -


i trying format cost , revenue (both in thousands) , impressions (in millions) data ggplot graph's y-axis labels.

my plot runs 31 days ago 'yesterday' , uses min , max values on period ylim(c(min,max)) option. showing cost example,

library(ggplot2) library(ttr)  set.seed(1984)  #make series start <- as.date('2016-01-01') end <- sys.date()  days <- as.numeric(end - start)  #make cost , moving averages cost <- rnorm(days, mean = 45400, sd = 11640) date <- seq.date(from = start, = end - 1, = 'day')  cost_7 <- sma(cost, 7) cost_30 <- sma(cost, 30)  df <- data.frame(date = date, cost = cost, cost_7 = cost_7, cost_30 = cost_30)   # set parameters window left <- end - 31 right <- end - 1  # plot series ggplot(df, aes(x = date, y = cost))+ geom_line(lwd = 0.5) + geom_line(aes(y = cost_7), col = 'red', linetype = 3, lwd = 1) + geom_line(aes(y = cost_30), col = 'blue', linetype = 5, lwd = 0.75) + xlim(c(left, right)) +  ylim(c(min(df$cost[df$date > left]), max(df$cost[df$date > left]))) + xlab("") 

ggplot output

i a) represent thousands , millions on y-axis commas, , b) numbers abbreviated , 'k' thousands or 'mm' millions. realize b) may tall order, a) cannot accomplished

ggplot(...) + ... + ylim(c(min, max)) + scale_y_continuous(labels = comma)

because following error thrown:

## scale 'y' present. adding scale 'y', ## replace existing scale. 

i have tried putting scale_y_continuous(labels = comma) section after geom_line()layer (which throws error above) or @ end of ggplot layers, overrides limits in ylim call , throws error above, anyway.

any ideas?

for comma formatting, need include scales library label=comma. "error" discussed warning, because used both ylim , scale_y_continuous. second call overrides first. can instead set limits , specify comma-separated labels in single call scale_y_continuous:

library(scales)  ggplot(df, aes(x = date, y = cost))+   geom_line(lwd = 0.5) +   geom_line(aes(y = cost_7), col = 'red', linetype = 3, lwd = 1) +   geom_line(aes(y = cost_30), col = 'blue', linetype = 5, lwd = 0.75) +   xlim(c(left, right)) +    xlab("") +   scale_y_continuous(label=comma, limits=c(min(df$cost[df$date > left]),                                             max(df$cost[df$date > left]))) 

another option melt data long format before plotting, reduces amount of code needed , streamlines aesthetic mappings:

library(reshape2)  ggplot(melt(df, id.var="date"),         aes(x = date, y = value, color=variable, linetype=variable))+   geom_line() +   xlim(c(left, right)) +    labs(x="", y="cost") +   scale_y_continuous(label=comma, limits=c(min(df$cost[df$date > left]),                                             max(df$cost[df$date > left]))) 

either way, put y values in terms of thousands or millions divide y values 1,000 or 1,000,000. i've used dollar_format() below, think you'll need divide appropriate power of ten if use unit_format (per @joran's suggestion). example:

div=1000  ggplot(melt(df, id.var="date"),         aes(x = date, y = value/div, color=variable, linetype=variable))+   geom_line() +   xlim(c(left, right)) +    labs(x="", y="cost (thousands)") +   scale_y_continuous(label=dollar_format(),                      limits=c(min(df$cost[df$date > left]),                                max(df$cost[df$date > left]))/div) 

use scale_color_manual , scale_linetype_manual set custom colors , linetypes, if desired.

enter image description here