如何在正确的方向上对 R geom_histogram 的 y 轴进行对数变换?

Ant*_*ash 3 r histogram ggplot2

我忘记了一些非常基本的东西,这可以解释为什么我在 y 轴的 log10 变换后看到非常膨胀的 y 值。

我有以下堆叠的 ggplot + geom_histogram。

ggTherapy <- ggplot(genderTherapyDF, aes(freq, fill=name)) +
 geom_histogram(data=genderTherapyDF, binwidth = 1, alpha=0.5, color="black") + theme_bw() +
 theme(legend.position="none", axis.title = element_text(size=14), legend.text = element_text(size=14), axis.text.y = element_text(size=12, angle=45), axis.text.x = element_text(size=12), legend.background = element_rect(fill="transparent")) +
 ylab("No. of patients") + xlab("Events") + labs(fill="") +  ggtitle("Therapy")
Run Code Online (Sandbox Code Playgroud)

在此输入图像描述

y 值是真实的,正是我所期望的。然而,它是如此倾斜,以至于肉眼看来,我发现这非常令人不满意。我宁愿看到一个转变的情节。

我尝试对 x 进行变换,很快就意识到沿分箱轴进行变换非常难以解释。所以我变换了 y 轴上的频率:

ggTherapy <- ggplot(genderTherapyDF, aes(freq, fill=name)) +
 geom_histogram(data=genderTherapyDF, binwidth = 1, alpha=0.5, color="black") + theme_bw() +
 theme(legend.position="none", axis.title = element_text(size=14), legend.text = element_text(size=14), axis.text.y = element_text(size=12, angle=45), axis.text.x = element_text(size=12), legend.background = element_rect(fill="transparent")) +
 ylab("No. of patients") + xlab("Events") + labs(fill="") +  ggtitle("Therapy") +
scale_y_log10()
Run Code Online (Sandbox Code Playgroud)

在此输入图像描述

从视觉上看,情节是有道理的。然而,我很难接受 y 轴标签!为什么经过 log10 变换后它们会如此巨大?

teu*_*and 5

我将反对在对数转换的 y 轴上使用堆叠位置。

考虑以下数据。

df <- data.frame(
  x = c(1, 1),
  y = c(10, 10),
  z = c("A", "B")
)
Run Code Online (Sandbox Code Playgroud)

它只是来自共享 x 位置的两个组的两个相等的观察结果。如果我们将其绘制在堆积条形图中,它将如下所示:

library(ggplot2)
ggplot(df, aes(x, y, fill = z)) +
  geom_col(position = "stack")
Run Code Online (Sandbox Code Playgroud)

这正是您所期望的。然而,如果我们现在变换 y 轴,我们会得到以下结果:

ggplot(df, aes(x, y, fill = z)) +
  geom_col(position = "stack") +
  scale_y_continuous(trans = "log10")
Run Code Online (Sandbox Code Playgroud)

在上图中,B 组的值似乎是 10,这是正确的,而 A 组的值是 90,这是不正确的。发生这种情况的原因是因为位置调整是在统计转换之后发生的,因此log10(A + B)您得到的不是log10(A) + log10(B),而是 ,与 相同log10(A * B),作为顶部高度。

相反,如果您计划变换 y 轴,我建议不要堆叠直方图,而是使用填充的 alpha 将它们分开。下面的例子:

df <- data.frame(
  x = c(rnorm(100, 1), rnorm(100, 2)),
  z = rep(c("A", "B"), each = 100)
)

ggplot(df, aes(x, fill = z)) +
  geom_histogram(position = "identity", alpha = 0.5) +
  scale_y_continuous(trans = "log10")
#> `stat_bin()` using `bins = 30`. Pick better value with `binwidth`.
#> Warning: Transformation introduced infinite values in continuous y-axis
Run Code Online (Sandbox Code Playgroud)

是的,0 会变成-Inf,但至少 y 轴现在是正确的。

编辑:如果您想过滤掉-Inf观察结果,scales v1.1.1 包中的一件好事是oob_censor_any()使用如下函数:

scale_y_continuous(trans = "log10", oob = scales::oob_censor_any)
Run Code Online (Sandbox Code Playgroud)