如何在正确的方向上记录变换 R geom_histogram 的 y 轴?
How to log transform the y-axis of R geom_histogram in the right direction?
我忘记了一些非常基本的东西,这可以解释为什么在对 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")
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()
从视觉上看,情节是有道理的。但是,我很难接受 y 轴标签!为什么它们在 log10 转换后如此巨大?
我猜您应该按照此处所述手动转换数据 https://ggplot2-book.org/scales.html#continuous-position-scales:
"Note that there is nothing preventing you from performing the transformation manually. For example, instead of using scale_x_log10() to transform the scale, you could transform the data instead and plot log10(x). The appearance of the geom will be the same, but the tick labels will be different. Specifically, if you use a transformed scale, the axes will be labelled in the original data space; if you transform the data, the axes will be labelled in the transformed space. Regardless of which method you use, the transformation occurs before any statistical summaries. To transform after statistical computation use coord_trans(). See Section 14.1 for more details."
我要反对在对数变换的 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")
在上图中,似乎 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
是的,0 将变为 -Inf
,但至少 y 轴现在是正确的。
编辑:如果你想过滤掉 -Inf
观察结果,scales v1.1.1 包中的一件好事是 oob_censor_any()
函数,如下所示:
scale_y_continuous(trans = "log10", oob = scales::oob_censor_any)
我忘记了一些非常基本的东西,这可以解释为什么在对 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")
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()
从视觉上看,情节是有道理的。但是,我很难接受 y 轴标签!为什么它们在 log10 转换后如此巨大?
我猜您应该按照此处所述手动转换数据 https://ggplot2-book.org/scales.html#continuous-position-scales:
"Note that there is nothing preventing you from performing the transformation manually. For example, instead of using scale_x_log10() to transform the scale, you could transform the data instead and plot log10(x). The appearance of the geom will be the same, but the tick labels will be different. Specifically, if you use a transformed scale, the axes will be labelled in the original data space; if you transform the data, the axes will be labelled in the transformed space. Regardless of which method you use, the transformation occurs before any statistical summaries. To transform after statistical computation use coord_trans(). See Section 14.1 for more details."
我要反对在对数变换的 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")
在上图中,似乎 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
是的,0 将变为 -Inf
,但至少 y 轴现在是正确的。
编辑:如果你想过滤掉 -Inf
观察结果,scales v1.1.1 包中的一件好事是 oob_censor_any()
函数,如下所示:
scale_y_continuous(trans = "log10", oob = scales::oob_censor_any)