如何在 R 中创建带有自定义分位数的箱线图?
How to create a boxplot with customized quantiles in R?
我现在正在处理一些数据,我想制作一个显示最小值、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 中得到了一个完全不同的数字。对此有什么解决办法吗?谢谢。
这是一个主意。您可能需要进一步完善它。
#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")
})
使用箱线图框架无法轻松生成您想做的事情。
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
returns 的顺序是:下晶须、25% 分位数、中位数、75% 分位数、上晶须。与 quantile
比较:
quantile(Mydata)
0% 25% 50% 75% 100%
1 152 204 253 500
如果您使用 ggplot2
中的 geom_boxplot()
,则可以重新定义用于框的值。但是您只能绘制相同的五个值:它们称为 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")
但是,您需要明确(可能使用标签)这不是 "standard" 箱线图。
另一个 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))
使用 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)
基本 R 解决方案:如果您只想更改部分箱线图,这里将 25% 和 75% 分位数更改为 0.125、0.9 分位数:
set.seed(12345)
myData <- c(-4, rnorm(10), 2, 3)
bp <- boxplot(myData)
bp <- boxplot(myData, range=1.5, plot=FALSE)
bxp(bp)#, whisklty=0, staplelty=0)
bp$stats[c(2, 4), ] <- quantile(x = myData, probs = c(0.125, 0.9))
bxp(bp, whisklty=1, staplelty=1, boxfill = "lightgray", add=TRUE)
看起来和原来的一样,只是盒子变了。
我现在正在处理一些数据,我想制作一个显示最小值、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 中得到了一个完全不同的数字。对此有什么解决办法吗?谢谢。
这是一个主意。您可能需要进一步完善它。
#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")
})
使用箱线图框架无法轻松生成您想做的事情。
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
returns 的顺序是:下晶须、25% 分位数、中位数、75% 分位数、上晶须。与 quantile
比较:
quantile(Mydata)
0% 25% 50% 75% 100%
1 152 204 253 500
如果您使用 ggplot2
中的 geom_boxplot()
,则可以重新定义用于框的值。但是您只能绘制相同的五个值:它们称为 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")
但是,您需要明确(可能使用标签)这不是 "standard" 箱线图。
另一个 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))
使用 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)
基本 R 解决方案:如果您只想更改部分箱线图,这里将 25% 和 75% 分位数更改为 0.125、0.9 分位数:
set.seed(12345)
myData <- c(-4, rnorm(10), 2, 3)
bp <- boxplot(myData)
bp <- boxplot(myData, range=1.5, plot=FALSE)
bxp(bp)#, whisklty=0, staplelty=0)
bp$stats[c(2, 4), ] <- quantile(x = myData, probs = c(0.125, 0.9))
bxp(bp, whisklty=1, staplelty=1, boxfill = "lightgray", add=TRUE)
看起来和原来的一样,只是盒子变了。