如何对R geom_histogram的y轴进行对数变换?

问题描述 投票:0回答:1

我忘记了一些非常基本的东西,这将解释为什么我看到y轴的对数10变换后的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")

enter image description here

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

enter image description here

从视觉上看,这个图是有意义的。然而,我很难接受y轴的标签!为什么对数后的标签如此巨大?为什么经过对数10的变换后,它们会如此巨大?

r ggplot2 histogram
1个回答
2
投票

我将提出一个反对在对数变换的y轴上使用堆叠位置的理由。

考虑以下数据。

df <- data.frame(
  x = c(1, 1),
  y = c(10, 10),
  z = c("A", "B")
)

它只是来自两组的两个相等的观测值,共享一个x位置。如果我们用叠加的柱状图来绘制这个数据,它就会像下面这样。

library(ggplot2)
ggplot(df, aes(x, y, fill = z)) +
  geom_col(position = "stack")

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

ggplot(df, aes(x, y, fill = z)) +
  geom_col(position = "stack") +
  scale_y_continuous(trans = "log10")

在上面的图中,A组的值是10,这是正确的 而B组的值是90,这是不正确的。之所以会出现这种情况,是因为位置调整是在统计变换后发生的,所以没有用 log10(A + B),你会得到 log10(A) + log10(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

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

EDIT: 如果你想过滤出 -Inf 观察,在尺度v1.1.1包中有一个很好的东西是 oob_censor_any() 函数,用法如下。

scale_y_continuous(trans = "log10", oob = scales::oob_censor_any)

0
投票

我猜你应该按照这里的描述手动转换数据。https:/ggplot2-book.orgscales.html#continuous-position-scales。:

"请注意,没有任何东西可以阻止您手动执行转换。例如,您可以不使用 scale_x_log10()来转换比例,而是转换数据并绘制 log10(x)。geom 的外观是一样的,但勾选标签会有所不同。具体来说,如果你使用变换比例尺,坐标轴将在原始数据空间中标注;如果你变换数据,坐标轴将在变换后的空间中标注。无论您使用哪种方法,转换都发生在任何统计汇总之前。要在统计计算后进行变换,请使用 coord_trans()。详见第14.1节。"

© www.soinside.com 2019 - 2024. All rights reserved.