【问题标题】:Creating a log-transformed histogram of multiclass continuous data with ggplot2 and R使用 ggplot2 和 R 创建多类连续数据的对数转换直方图
【发布时间】:2021-08-04 20:47:29
【问题描述】:

我正在使用 R 开发一个研究模型,该模型正在计算大型数据集中三个不同组的异常分数(RMSE 值)。异常分数是一种连续数据类型,并且非常小,在大约 100 万个观测值的总体中范围从大约 1e-04 到 1e-07。

我拥有数据集中每个组标签上每个异常分数分布的所有摘要和描述性统计数据,并且我能够创建一些有用的直方图,显示三个组中的每一个如何在分数。然而,由于分数值的频率差异很大,并且大部分异常分数中的高密度峰值,我需要在直方图中使用对数变换来显示每个分箱观察范围的对数频率计数(y-轴)和分箱得分值(x 轴)的对数转换,以便能够适当地说明数据内的分布并使其更易于理解。

幸运的是,ggplot2 对于创建一些非常有吸引力的双轴对数转换直方图非常有用。

但是,我无法找到一种方法来创建对数转换直方图,以便在同一个直方图中按颜色显示我的三个组中的每一个。我希望它能够看起来像本段下方的直方图,但对 x 轴和 y 轴都使用对数变换。下图在一个直方图中显示了 3 个组,但使用了默认的正常值:

对于日志转换轴值,到目前为止我能做的最好的事情是生成三个单独的直方图,每个组一个:

下面是示例 R 代码,用于说明我在随机生成的示例数据集上遇到的问题以及我目前采用的 ggplot2 方法:

下面的示例 R 代码:

library(ggplot2)
library(dplyr)
library(hrbrthemes)

我创建了一些简单的随机样本数据来生成示例数据集。 这会生成一个名为 d 的示例数据框,其中包含每个观察的 A、B 或 C 类标签 IV。目标变量是每次观察的 anomaly_score 连续值。 该数据框中有 300 行虚拟数据。

DV_score_generator = round(runif(300,0.001,0.999), 3)

d <- data.frame( label = sample( LETTERS[1:3], 300, replace=TRUE, prob=c(0.65, 0.30, 0.05) ), anomaly_score = DV_score_generator)

首先,我使用 ggplot 创建正态分布直方图,该直方图在同一图上按颜色显示所有 3 个组。 请注意,对于这一小组随机样本数据,似乎没有必要使用 x 轴和 y 轴对数变换来显示分布模式,但是对于我更大、更复杂的分数值,它确实会成为一个问题在实际数据的DV中。

p <- d %>%
ggplot( aes(x=anomaly_score, fill=label)) +
geom_histogram( color="#e9ecef", alpha=0.6, position = 'identity') +
scale_fill_manual(values=c("#69b3a2", "blue", "#404080")) +
theme_ipsum() +
labs(fill="")

p

产生这个正常的多类直方图:

创建分组子集。

group_a <- d[ which(d$label =='A'), ]

group_b <- d[ which(d$label =='B'), ]

group_c <- d[ which(d$label =='C'), ]

现在生成一系列双轴对数转换直方图,为数据集中每个不同的标签类生成一个直方图:

# Group A, log transformed

ggplot(group_a, aes(x = anomaly_score)) +
     geom_histogram(aes(y = ..count..), binwidth = 0.05,
     colour = "darkgoldenrod1", fill = "darkgoldenrod2") +
     scale_x_continuous(name = "Log-scale Anomaly Score", trans="log2") +
     scale_y_continuous(trans="log2", name="Log-transformed Frequency Counts") +
     ggtitle("Transformed Anomaly Scores - Group A Only")

A组变换直方图:

# Group B, log transformed

 ggplot(group_b, aes(x = anomaly_score)) +
     geom_histogram(aes(y = ..count..), binwidth = 0.05,
     colour = "green", fill = "darkgreen") +
     scale_x_continuous(name = "Log-scale Anomaly Score", trans="log2") +
     scale_y_continuous(trans="log2", name="Log-transformed Frequency Counts") +
     ggtitle("Transformed Anomaly Scores - Group B Only")

B组变换直方图:

# Group C, log transformed

 ggplot(group_c, aes(x = anomaly_score)) +
     geom_histogram(aes(y = ..count..), binwidth = 0.05,
     colour = "red", fill = "darkred") +
     scale_x_continuous(name = "Log-scale Anomaly Score", trans="log2") +
     scale_y_continuous(trans="log2", name="Log-transformed Frequency Counts") +
     ggtitle("Transformed Anomaly Scores - Group C Only")

C组变换直方图:

结束。

提前谢谢大家!

【问题讨论】:

    标签: r logarithm ggplot2


    【解决方案1】:

    我不太确定您到底遇到了什么问题。建议的策略似乎效果很好;下面的例子:

    library(ggplot2)
    library(dplyr)
    #> 
    #> Attaching package: 'dplyr'
    #> The following objects are masked from 'package:stats':
    #> 
    #>     filter, lag
    #> The following objects are masked from 'package:base':
    #> 
    #>     intersect, setdiff, setequal, union
    
    DV_score_generator = round(runif(300,0.001,0.999), 3)
    
    d <- data.frame( label = sample( LETTERS[1:3], 300, replace=TRUE, prob=c(0.65, 0.30, 0.05) ),
                     anomaly_score = DV_score_generator)
    
    p <- d %>%
      ggplot( aes(x=anomaly_score, fill=label)) +
      geom_histogram( color="#e9ecef", alpha=0.6, position = 'identity') +
      scale_fill_manual(values=c("#69b3a2", "blue", "#404080")) +
      labs(fill="")
    
    p +
      scale_x_continuous(trans = "log2") +
      scale_y_continuous(trans = "log2")
    #> `stat_bin()` using `bins = 30`. Pick better value with `binwidth`.
    #> Warning: Transformation introduced infinite values in continuous y-axis
    

    如果您对 0 显示为负条感到困扰,您可以使用伪对数代替(对数转换将 0 变成 -Inf,这在 ggplot2 中作为面板中最底部的位置具有特殊含义)。

    p + 
      scale_x_continuous(trans = "log2") +
      scale_y_continuous(trans = "pseudo_log")
    #> `stat_bin()` using `bins = 30`. Pick better value with `binwidth`.
    

    reprex package (v2.0.0) 于 2021-08-05 创建

    除此之外,y 轴标题“对数转换的频率计数”可能不适合数据。如果我看到这一点,我可能希望计数被对数转换,因此轴标签 2 可能意味着 2^2 = 4。

    【讨论】:

    • 太棒了!我没有意识到我可以通过使用 p+ 来修改原始的历史图,然后添加 scale_x_continuous(trans = "log2") 函数。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2020-08-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-09-28
    • 2022-11-10
    • 1970-01-01
    相关资源
    最近更新 更多