【问题标题】:Using ggplot geom_histogram() with y-log-scale with zero bins使用 ggplot geo_geom_histogram() 和 y-log-scale 零 bin
【发布时间】:2017-06-10 12:52:38
【问题描述】:

我有一组超过 10000 个整数,其值介于 1 到 500 之间。 我想以直方图的形式绘制值,但是,由于只有少数整数的值大于 200,因此我想对 y 轴使用对数刻度。

一个问题出现了,当一个 bin 的计数为零时,因为对数值变为 -infinity。

为了避免这种情况,我想为每个 bin 添加一个伪计数 1。 在标准的 hist()-plot 中,我可以这样做:

hist.data = hist(data, plot=F, breaks=30)
hist.data$counts = log10(hist.data$counts + 1)
plot(hist.data, ...)

但是,我很难找到一种方法来访问 ggplot 中的计数。

有没有一种简单的方法可以做到这一点,或者有其他推荐的方法来处理这个问题?

【问题讨论】:

    标签: r ggplot2 histogram logarithm


    【解决方案1】:

    实现此目的的一种方法是编写您自己的 y 比例转换函数。 ggplot2 使用的转换函数(例如使用scale_y_log10() 时)在scales 包中定义。

    简答

    library(ggplot2)
    library(scales)
    
    mylog10_trans <- function (base = 10) 
    {
      trans <- function(x) log(x + 1, base)
      inv <- function(x) base^x
      trans_new(paste0("log-", format(base)), trans, inv, log_breaks(base = base), 
                domain = c(1e-100, Inf))
    }
    
    ggplot(df, aes(x=x)) + 
      geom_histogram() + 
      scale_y_continuous(trans = "mylog10")
    

    输出

    本图使用的数据:

    df <- data.frame(x=sample(1:100, 10000, replace = TRUE))
    df$x[sample(1:10000, 50)] <- sample(101:500, 50)
    

    解释trans函数

    让我们检查scales::log10_trans;它调用scales::log_trans();现在,scales::log_trans打印为:

    function (base = exp(1)) 
    {
        trans <- function(x) log(x, base)
        inv <- function(x) base^x
        trans_new(paste0("log-", format(base)), trans, inv, log_breaks(base = base), 
            domain = c(1e-100, Inf))
    }
    <environment: namespace:scales>
    

    在上面的答案中,我替换了:

    trans <- function(x) log(x, base)
    

    与:

    trans <- function(x) log(x + 1, base)
    

    【讨论】:

    • 我能否以某种方式避免天平上的计数 0 和 1 相等?
    • 是的,只需将 ifelse(x &gt; 0, log(x, base), 0) 替换为 log(x + 1, base) 即可;查看我的编辑
    • 非常感谢,帮助很大!最后一个问题:我可以以某种方式调整 y 轴标签吗? (因为它们现在在 1、11、1001、...处打勾)
    • 编辑:我使用breaks=c(10-1, 100-1, 1000-1, 10000-1) 在所需位置手动欺骗了一组中断。就我而言,这个解决方案已经足够好了。
    • 现在有scales::log1p_trans() (-> log(x + 1)),可以这样使用:scale_y_continuous(trans = scales::log1p_trans()。另请参阅pseudo_log_trans()
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多