I could not reproduce your behavior. See this:
df <- data.frame(x=runif(100), y=(runif(100)-1/2)/1e8) p <- ggplot(df, aes(x, y)) + geom_point() p + scale_y_continuous(labels=f2si)

I also found another similar function if you don't like the label "0 n":
format_si <- function(...) { # Based on code by Ben Tupper # https://stat.ethz.ch/pipermail/r-help/2012-January/299804.html function(x) { limits <- c(1e-24, 1e-21, 1e-18, 1e-15, 1e-12, 1e-9, 1e-6, 1e-3, 1e0, 1e3, 1e6, 1e9, 1e12, 1e15, 1e18, 1e21, 1e24) prefix <- c("y", "z", "a", "f", "p", "n", "Β΅", "m", " ", "k", "M", "G", "T", "P", "E", "Z", "Y") # Vector with array indices according to position in intervals i <- findInterval(abs(x), limits) # Set prefix to " " for very small values < 1e-24 i <- ifelse(i==0, which(limits == 1e0), i) paste(format(round(x/limits[i], 1), trim=TRUE, scientific=FALSE, ...), prefix[i]) } } p + scale_y_continuous(labels=format_si())
