Как создать коробочный сюжет с настроенными квантилями в R? - PullRequest
2 голосов
/ 07 июня 2019

Я сейчас имею дело с некоторыми данными и хочу создать коробку, показывающую минимум, 2,5, 25, 50, 70, 75, 97,5 и максимум. На блокпосте также должна быть легенда с линиями разного цвета для представления каждого квантиля. Есть какой-либо способ сделать это? Спасибо за любую помощь.

set.seed(123)
Mydata = sample(x=100:300, size = 500, replace = T)
Mydata = c(Mydata, 1, 500)
boxplot(Mydata)

PS. Я попробовал код, предоставленный @thelatemail, но получил совершенно другую цифру в RStudio. Любое решение этого? Благодарю. enter image description here

Ответы [ 3 ]

3 голосов
/ 07 июня 2019

То, что вы хотите сделать, не может быть легко сгенерировано с помощью каркаса boxplot.

Базовым блокпостом в R является функция boxplot.stats().Давайте запустим это на ваших данных:

boxplot.stats(Mydata)

$stats
[1]   1 152 204 253 300

$n
[1] 502

$conf
[1] 196.8776 211.1224

$out
[1] 500

Вы можете видеть, что $stats возвращается в следующем порядке: нижний усик, 25% квантиль, медиана, 75% квантиль, верхний усик.Сравните с quantile:

quantile(Mydata)

  0%  25%  50%  75% 100% 
   1  152  204  253  500

Если вы используете geom_boxplot() из ggplot2, можно переопределить значения, используемые для поля.Но вы можете нарисовать только те же пять значений: они называются ymin, lower, middle, upper и ymax.

Так, например, если вы хотите, чтобы квантиль 2,5% какlower и 97,5% квантиля как upper, вы можете попробовать:

data.frame(x = 1,
           y0 = min(Mydata),
           y025 = quantile(Mydata, 0.025),
           y50 = median(Mydata),
           y975 = quantile(Mydata, 0.975),
           y100 = max(Mydata)) %>%
  ggplot(df, aes(x)) +
  geom_boxplot(aes(ymin = y0, 
                   lower = y025, 
                   middle = y50, 
                   upper = y975, 
                   ymax = y100),
               stat = "identity")

enter image description here

Однако вы хотели бы прояснить это(возможно, используя метки), что это не «стандартный» блок-график.

Другая идея ggplot2 состоит в том, чтобы использовать geom_jitter для построения точек данных, а затем добавить линии для нужных квантилей, используя geom_hline.Примерно так:

library(tibble)
library(ggplot2)

Mydataq <- quantile(Mydata, probs = c(0.025, 0.25, 0.5, 0.7, 0.75, 0.975)) %>%
  as.data.frame() %>% 
  setNames("value") %>% 
  rownames_to_column(var = "quantile")

Mydataq %>% 
  ggplot() + 
  geom_hline(aes(yintercept = value, color = quantile)) + 
  geom_jitter(data = tibble(x = "Mydata", y = Mydata), 
              aes(x = x, y = y))

enter image description here

2 голосов
/ 07 июня 2019

Просто продолжайте переполнение, используя bxp:

set.seed(123)
Mydata = sample(x=100:300, size = 500, replace = T)
Mydata = c(Mydata, 1, 500)

bp <- boxplot(Mydata, range=0, plot=FALSE)

vals <- c(
  min=min(Mydata),
  quantile(Mydata, c(0.025, 0.25, 0.5, 0.7, 0.75, 0.975)),
  max=max(Mydata)
)

bxp(bp, whisklty=0, staplelty=0)
bp$stats[2:4,] <- c(vals[2], Inf, vals[5])
bxp(bp, whisklty=0, staplelty=0, add=TRUE)
bp$stats[2:4,] <- c(vals[2], Inf, vals[7])
bxp(bp, whisklty=1, staplelty=1, add=TRUE)

enter image description here

2 голосов
/ 07 июня 2019

Вот идея. Возможно, вам придется уточнить это дальше.

#Data
P = c(2.5, 25, 50, 70, 75, 97.5)

#Quantiles
b = quantile(x = Mydata, probs = P/100)

#Custom funtion
dp = function(at, y1, y2, width, ...){
    polygon(x = c(at - width/2, at + width/2, at + width/2, at - width/2),
            y = c(y1, y1, y2, y2), ...)
}

#Parameters
at = 1
width = 0.2

graphics.off()

#Whiskers
plot(x = rep(at, length(Mydata)), y = Mydata, type = "l")
segments(x0 = at - width/2, x1 = at + width/2, y0 = min(Mydata), y1 = min(Mydata))
segments(x0 = at - width/2, x1 = at + width/2, y0 = max(Mydata), y1 = max(Mydata))

#Boxes
sapply(1:ceiling(length(b)/2), function(i) {
    dp(at = at, y1 = b[i], y2 = b[length(b) + 1 - i], width = width * i, col = i)
})
#OR
sapply(1:ceiling(length(b)/2), function(i) {
    segments(x0 = at, x1 = at, y0 = b[i], y1 = b[length(b) + 1 - i],
             lwd = 10 * i, col = i, lend = "butt")
})

enter image description here

...