簡體   English   中英

在 ggplot2 中用 facets 繪制分布的分位數

[英]Plot quantiles of distribution in ggplot2 with facets

我目前正在從 ggplot 中的許多回歸模型繪制許多不同的一階差分分布。 為了便於解釋差異,我想標記每個分布的 2.5% 和 97.5% 百分位數。 由於我將繪制相當多的圖,並且由於數據按二維(模型和類型)分組,因此我想在 ggplot 環境中定義和繪制相應的百分位數。 使用 facets 繪制分布可以讓我准確地到達我想要的地方,除了百分位數。 我當然可以更多地手動執行此操作,但理想情況下,我希望找到一個仍然可以使用facet_grid的解決方案,因為這讓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()作為手動進行刻面的方法。

現在,可以使用帶有orientation選項的stat_summary()來獲得相同的結果,而無需預先計算。

為每個面板定義一個虛擬y值以將觀察結果與orientation = "y"一起分組。 然后使用自定義fun.data函數為stat_summary()每個面板返回所需分位數的數據框。 要將結果顯示為垂直線,請在美學規范中使用xintercept = stat(x)從計算的x值中指定geom = "vline"及其所需的xintercept

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(
    # y is a required aesthetic, so use a dummy value
    aes(y = 1, xintercept = stat(x)),
    fun.data = function(x) {
      data.frame(
        y = quantile(x, probs = c(0.025, 0.975))
      )
    },
    geom = "vline",
    orientation = "y"
  )

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM