考虑来自
depth
数据的 diamonds
变量的密度直方图。
dat0 <- ggplot2::diamonds %>% select(depth)
gg0 <- ggplot(dat0, aes(x = depth)) +
scale_x_continuous(limits = c(30, 90), expand = c(0,0), breaks = seq(30,90,10)) +
scale_y_continuous(limits = c(0, 20000), expand = c(0,0), trans = modulus_trans(0.3)) +
geom_histogram(bins = 100)
使用
scales::modulus_trans()
,可以轻松变换 x 轴以将刻度向左 (gg1) 或向右 (gg2) 收紧。
gg1 <- ggplot(dat0, aes(x = depth)) +
scale_x_continuous(limits = c(30, 90), expand = c(0,0), breaks = seq(30,90,10),
trans = modulus_trans(2.8)) +
scale_y_continuous(limits = c(0, 20000), expand = c(0,0), trans = modulus_trans(0.3)) +
geom_histogram(bins = 100)
gg2 <- ggplot(dat0, aes(x = depth)) +
scale_x_continuous(limits = c(30, 90), expand = c(0,0), breaks = seq(30,90,10),
trans = modulus_trans(-1)) +
scale_y_continuous(limits = c(0, 20000), expand = c(0,0), trans = modulus_trans(0.3)) +
geom_histogram(bins = 100)
但是如何变换 x 尺度以收紧密度峰值的两侧(位于
depth
= 62),同时保持理想地调整 p
(来自 modulus_trans()
函数的变换指数 λ)的可能性双方独立?也许是一个天真的问题,但是两个 modulus_trans()
组合在 trans_new()
函数中是否可能?
如果没有,可以使用什么其他类型的变换来放大密度峰值,同时将其保持在初始位置?
感谢您的帮助和建议
我将在这里创建一个自定义转换,它将您的中心值作为参数,并在您使用简单的差值求幂远离该值时平滑地减小间距。您也可以使用
strength
参数控制强度:
squish_trans <- function(x, strength) {
trans_new("squish",
transform = function(.x) {
val <- .x - x
val <- abs(val)^(1/strength) * sign(val)
mean(x) + val
},
inverse = function(.x) {
val <- .x - x
val <- abs(val)^strength * sign(val)
mean(x) + val
})
}
测试,强度为1.5我们得到
ggplot(ggplot2::diamonds, aes(x = depth)) +
scale_x_continuous(limits = c(30, 90), expand = c(0,0),
breaks = seq(30,90,10),
trans = squish_trans(62, 1.5)) +
scale_y_continuous(limits = c(0, 20000), expand = c(0,0),
trans = modulus_trans(0.3)) +
geom_histogram(breaks = 1:100) +
theme_gray(16)
或者使用更温和的
strength = 1.2
设置,我们得到
请注意,我已指定直方图在 1 到 100 之间的所有整数处断开;否则,箱位置将更改为沿着新比例的固定间隔,从而在较高强度下产生奇怪的效果。