Prefijos SI en las tags del eje ggplot2

A menudo trazo gráficos en GNU R / ggplot para algunas medidas relacionadas con los bytes. Las tags del eje incorporado son números simples o notación científica, es decir 1 megabyte = 1e6. Me gustaría prefijos SI (Kilo = 1e3, Mega = 1e6, Giga = 1e9, etc.) en su lugar, es decir, el eje debería etiquetarse 1.5K, 5K, 1M, 150M, 4G, etc.

Actualmente uso el siguiente código:

si_num  1e6) { chrs <- strsplit(format(x, scientific=12), split="")[[1]]; rem <- chrs[seq(1,length(chrs)-6)]; rem  1e3) { chrs <- strsplit(format(x, scientific=12), split="")[[1]]; rem <- chrs[seq(1,length(chrs)-3)]; rem <- append(rem, "K"); } else { return(x); } return(paste(rem, sep="", collapse="")); } else return(NA); } si_vec <- function(x) { sapply(x, FUN=si_num); } library("ggplot2"); bytes=2^seq(0,20) + rnorm(21, 4, 2); time=bytes/(1e4 + rnorm(21, 100, 3)) + 8; my_data = data.frame(time, bytes); p <- ggplot(data=my_data, aes(x=bytes, y=time)) + geom_point() + geom_line() + scale_x_log10("Message Size [Byte]", labels=si_vec) + scale_y_continuous("Round-Trip-Time [us]"); p; 

Me gustaría saber si esta solución se puede mejorar, ya que la mía requiere mucho código repetitivo en cada gráfico.

Usé la library("sos"); findFn("{SI prefix}") library("sos"); findFn("{SI prefix}") para encontrar el paquete sitools .

Construir datos:

 bytes <- 2^seq(0,20) + rnorm(21, 4, 2) time <- bytes/(1e4 + rnorm(21, 100, 3)) + 8 my_data <- data.frame(time, bytes) 

Cargar paquetes:

 library("sitools") library("ggplot2") 

Crea la ttwig:

 (p <- ggplot(data=my_data, aes(x=bytes, y=time)) + geom_point() + geom_line() + scale_x_log10("Message Size [Byte]", labels=f2si) + scale_y_continuous("Round-Trip-Time [us]")) 

No estoy seguro de cómo se compara esto con tu función, pero al menos alguien más se tomó la molestia de escribirlo ...

Modifiqué un poco el estilo de tu código: el punto y coma al final de las líneas es inofensivo, pero en general es el signo de un codificador MATLAB o C ...

editar : Inicialmente definí una función de formateo genérica

 si_format <- function(...) { function(x) f2si(x,...) } 

siguiendo el formato de (por ejemplo) scales::comma_format , pero eso parece innecesario en este caso, solo parte de la magia más profunda de ggplot2 que no entiendo del todo.

El código del OP da lo que me parece que no es la respuesta correcta: el tic del eje derecho es "1000K" en vez de "1M"; esto se puede solucionar cambiando la prueba >1e6 a >=1e6 . Por otro lado, f2si usa k minúsculas; no sé si se desea K (el ajuste de los resultados en toupper() podría solucionarlo).

Resultados OP ( si_vec ):

enter image description here

Mis resultados ( f2si ):

enter image description here