2012-12-20 106 views
10

我经常在GNU R/ggplot中绘制一些与字节相关的测量图。内置轴标签是简单数字或科学记数法,即1兆字节= 1e6。我想要SI前缀(Kilo = 1e3,Mega = 1e6,Giga = 1e9等),即轴应标记为1.5K,5K,1M,150M,4G等。ggplot2轴标签中的SI前缀

我目前使用以下代码:

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; 

我想知道这个解决方案是否可以改进,因为我的每个图形都需要大量的样板代码。

+0

你可以看看'utils的::: print.object_size' – James

回答

24

我用library("sos"); findFn("{SI prefix}")找到了sitools包。

构造数据:

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

负载包:

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

创建情节:

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

我不知道该怎么比较你的功能,但至少别人去写它的麻烦...

我修改您的代码风格有点 - 在行尾分号是无害的,但一般都是MATLAB或C编码器的标志......

编辑:我最初定义一个通用的格式化功能

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

以下的(如)scales::comma_format的格式,但似乎在这种情况下不必要的 - 只是更深ggplot2魔法,我不完全理解的部分。

OP的代码给了我似乎不太正确的答案:最右边的坐标轴刻度是“1000K”而不是“1M” - 这可以通过将>1e6测试更改为>=1e6来解决。另一方面,f2si使用小写k - 我不知道是否需要K(将结果包含在toupper()中可以解决此问题)。

OP结果(si_vec):

enter image description here

我的结果(f2si):

enter image description here

+1

+1 'SOS'包装,这只是**辉煌**! – Michele