用小平面绘制 ggplot2 中的分布分位数
Plot quantiles of distribution in ggplot2 with facets
我目前正在从 ggplot 中的多个回归模型中绘制多个不同的一阶差分分布。为了便于解释差异,我想标记每个分布的 2.5% 和 97.5% 百分位数。因为我会做很多图,并且因为数据是按二维(模型和类型)分组的,所以我想在 ggplot 环境中定义和绘制相应的百分位数。使用小平面绘制分布可以让我准确地到达我想要的位置,除了百分位数。我当然可以更手动地执行此操作,但理想情况下我想找到一个我仍然可以使用 facet_grid
的解决方案,因为这让我省去了很多尝试将不同的地块放在一起的麻烦。
下面是一个使用模拟数据的例子:
df.example <- data.frame(model = rep(c("a", "b"), length.out = 500),
type = rep(c("t1", "t2", "t2", "t1"),
length.outh = 250), value = rnorm(1000))
ggplot(df.example, aes(x = value)) +
facet_grid(type ~ model) +
geom_density(aes(fill = model, colour = model))
我试过用两种方法添加分位数。第一个产生错误信息:
ggplot(df.example, aes(x = value)) +
facet_grid(. ~ model) +
geom_density(aes(fill = model, colour = model)) +
geom_vline(aes(x = value), xintercept = quantile(value, probs = c(.025, .975)))
Error in quantile(value, probs = c(0.025, 0.975)) : object 'value' not found
而第二个让我得到了完整变量的分位数,而不是子密度的分位数。也就是说,绘制的分位数对于所有四个密度都是相同的。
ggplot(df.example, aes(x = value)) +
facet_grid(type ~ model) +
geom_density(aes(fill = model, colour = model)) +
geom_vline(xintercept = quantile(df.example$value, probs = c(.025, .975)))
因此我想知道是否有办法在 ggplot2 环境中绘制每个子组的特定分位数?
非常感谢任何意见。
使用 plyr(或 dplyr,data.table)预先计算这些值...
set.seed(1)
# ...
df.q <- ddply(df.example, .(model, type),
summarize, q=quantile(value, c(.025, .975)))
p + geom_vline(aes(xintercept=q), data=df.q)
您可以预先计算分位数。
使用您的示例数据:
library (dplyr)
d2 <- df.example %>%
group_by(model, type) %>%
summarize(lower = quantile(value, probs = .025),
upper = quantile(value, probs = .975))
然后这样画:
ggplot(df.example, aes(x = value)) +
facet_grid(type ~ model) +
geom_density(aes(fill = model, colour = model)) +
geom_vline(data = d2, aes(xintercept = lower)) +
geom_vline(data = d2, aes(xintercept = upper))
好问题。同一问题的更一般版本是:使用分面时如何调用子集数据集上的函数?这似乎是一个非常有用的功能,所以我四处搜索但找不到任何相关信息。
已经给出的答案非常好。另一种选择是使用 multiplot()
作为手动进行分面的方法。
如今,可以将 stat_summary()
与 orientation
选项一起使用
无需预先计算即可获得相同的结果。
为每个面板定义一个虚拟 y
值,以将观察值与
orientation = "y"
。然后使用自定义 fun
来计算向量
stat_summary()
中每个面板的所需分位数。显示结果
作为垂直线,指定 geom = "vline"
及其所需的 xintercept
来自 x
的计算值 xintercept = after_stat(x)
的美学
规范,现在使用 fun
.
计算的结果
library(ggplot2)
set.seed(1)
df.example <- data.frame(
model = rep(c("a", "b"), length.out = 500),
type = rep(c("t1", "t2", "t2", "t1"),
length.outh = 250
), value = rnorm(1000)
)
ggplot(df.example, aes(x = value)) +
facet_grid(type ~ model) +
geom_density(aes(fill = model, colour = model)) +
stat_summary(
geom = "vline",
orientation = "y",
# y is a required aesthetic, so use a dummy value
aes(y = 1, xintercept = after_stat(x)),
fun = function(x) {
quantile(x, probs = c(0.025, 0.975))
}
)
我目前正在从 ggplot 中的多个回归模型中绘制多个不同的一阶差分分布。为了便于解释差异,我想标记每个分布的 2.5% 和 97.5% 百分位数。因为我会做很多图,并且因为数据是按二维(模型和类型)分组的,所以我想在 ggplot 环境中定义和绘制相应的百分位数。使用小平面绘制分布可以让我准确地到达我想要的位置,除了百分位数。我当然可以更手动地执行此操作,但理想情况下我想找到一个我仍然可以使用 facet_grid
的解决方案,因为这让我省去了很多尝试将不同的地块放在一起的麻烦。
下面是一个使用模拟数据的例子:
df.example <- data.frame(model = rep(c("a", "b"), length.out = 500),
type = rep(c("t1", "t2", "t2", "t1"),
length.outh = 250), value = rnorm(1000))
ggplot(df.example, aes(x = value)) +
facet_grid(type ~ model) +
geom_density(aes(fill = model, colour = model))
我试过用两种方法添加分位数。第一个产生错误信息:
ggplot(df.example, aes(x = value)) +
facet_grid(. ~ model) +
geom_density(aes(fill = model, colour = model)) +
geom_vline(aes(x = value), xintercept = quantile(value, probs = c(.025, .975)))
Error in quantile(value, probs = c(0.025, 0.975)) : object 'value' not found
而第二个让我得到了完整变量的分位数,而不是子密度的分位数。也就是说,绘制的分位数对于所有四个密度都是相同的。
ggplot(df.example, aes(x = value)) +
facet_grid(type ~ model) +
geom_density(aes(fill = model, colour = model)) +
geom_vline(xintercept = quantile(df.example$value, probs = c(.025, .975)))
因此我想知道是否有办法在 ggplot2 环境中绘制每个子组的特定分位数?
非常感谢任何意见。
使用 plyr(或 dplyr,data.table)预先计算这些值...
set.seed(1)
# ...
df.q <- ddply(df.example, .(model, type),
summarize, q=quantile(value, c(.025, .975)))
p + geom_vline(aes(xintercept=q), data=df.q)
您可以预先计算分位数。
使用您的示例数据:
library (dplyr)
d2 <- df.example %>%
group_by(model, type) %>%
summarize(lower = quantile(value, probs = .025),
upper = quantile(value, probs = .975))
然后这样画:
ggplot(df.example, aes(x = value)) +
facet_grid(type ~ model) +
geom_density(aes(fill = model, colour = model)) +
geom_vline(data = d2, aes(xintercept = lower)) +
geom_vline(data = d2, aes(xintercept = upper))
好问题。同一问题的更一般版本是:使用分面时如何调用子集数据集上的函数?这似乎是一个非常有用的功能,所以我四处搜索但找不到任何相关信息。
已经给出的答案非常好。另一种选择是使用 multiplot()
作为手动进行分面的方法。
如今,可以将 stat_summary()
与 orientation
选项一起使用
无需预先计算即可获得相同的结果。
为每个面板定义一个虚拟 y
值,以将观察值与
orientation = "y"
。然后使用自定义 fun
来计算向量
stat_summary()
中每个面板的所需分位数。显示结果
作为垂直线,指定 geom = "vline"
及其所需的 xintercept
来自 x
的计算值 xintercept = after_stat(x)
的美学
规范,现在使用 fun
.
library(ggplot2)
set.seed(1)
df.example <- data.frame(
model = rep(c("a", "b"), length.out = 500),
type = rep(c("t1", "t2", "t2", "t1"),
length.outh = 250
), value = rnorm(1000)
)
ggplot(df.example, aes(x = value)) +
facet_grid(type ~ model) +
geom_density(aes(fill = model, colour = model)) +
stat_summary(
geom = "vline",
orientation = "y",
# y is a required aesthetic, so use a dummy value
aes(y = 1, xintercept = after_stat(x)),
fun = function(x) {
quantile(x, probs = c(0.025, 0.975))
}
)