2012-12-20 14 views
10

Często wykreślam wykresy w GNU R/ggplot dla niektórych pomiarów związanych z bajtami. Wbudowane etykiety osi są albo zwykłymi liczbami, albo notacją naukową, tj. 1 Megabajt = 1e6. Chciałbym zamiast tego prefiksy SI (Kilo = 1e3, Mega = 1e6, Giga = 1e9, itp.), Tj. Oś powinna być oznaczona 1,5K, 5K, 1M, 150M, 4G itd.Przedrostki SI w etykietach osi ggplot2

Obecnie używam następującego kodu:

si_num <- function (x) { 

    if (!is.na(x)) { 
    if (x > 1e6) { 
     chrs <- strsplit(format(x, scientific=12), split="")[[1]]; 
     rem <- chrs[seq(1,length(chrs)-6)]; 
     rem <- append(rem, "M"); 
    } 

    else if (x > 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; 

Chciałbym wiedzieć, czy to rozwiązanie może zostać ulepszone, ponieważ mój wymaga wiele kodu na każdym wykresie.

+0

Można spojrzeć na 'utils ::: print.object_size' – James

Odpowiedz

24

Użyłem library("sos"); findFn("{SI prefix}"), aby znaleźć pakiet sitools.

Construct Data:

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

pakiety obciążenie:

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

Tworzenie działki:

(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]")) 

nie jestem pewien jak to porównać do funkcji, ale przynajmniej ktoś inny zadał sobie trud napisania go ...

zmodyfikowałem swój styl Kod trochę - średników na końcach linii są nieszkodliwe, ale są zwykle oznaką MATLAB lub C kodera ...

edit: początkowo zdefiniowano funkcję formatowania rodzajowe

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

po formacie (np) scales::comma_format, ale to wydaje się zbędne w tym przypadku - po prostu częścią głębszej ggplot2 magii, że nie w pełni zrozumieć.

Kod OP daje odpowiedź, która wydaje mi się być nie do końca właściwą odpowiedzią: tyłem prawej osi jest "1000K" zamiast "1M" - można to naprawić, zmieniając test >1e6 na >=1e6. Z drugiej strony, f2si używa małej litery k - nie wiem, czy potrzebna jest K (zawijanie wyników w toupper() może to naprawić).

Wyniki OP (si_vec):

enter image description here

Moje wyniki (f2si):

enter image description here

+1

+1 dla Pakiet 'SOS', po prostu ** genialny ** !!! – Michele

Powiązane problemy