#r #ggplot2 #kernel-density
#r #ggplot2 #ядро-плотность
Вопрос:
Когда я строю плотности с помощью ggplot, кажется, что границы очень неправильные. Я вижу, что geom_density
и другие функции позволяют указывать различные ядра плотности, но ни одна из них, похоже, не устраняет проблему.
Как правильно отображать плотности вокруг границ с помощью ggplot?
В качестве примера давайте построим распределение Хи-квадрат с 2 степенями свободы. Используя встроенные плотности вероятности:
library(ggplot2)
u = seq(0, 2, by=0.01)
v = dchisq(u, df=2)
df = data.frame(x=u, p=v)
p = ggplot(df)
geom_line(aes(x=x, y=p), size=1)
theme_classic()
coord_cartesian(xlim=c(0, 2), ylim=c(0, 0.5))
show(p)
Мы получаем ожидаемый график:
Теперь давайте попробуем смоделировать это и построить эмпирическое распределение:
library(ggplot2)
u = rchisq(10000, df=2)
df = data.frame(x=u)
p = ggplot(df)
geom_density(aes(x=x))
theme_classic()
coord_cartesian(xlim=c(0, 2))
show(p)
Мы получаем неверный график:
Мы можем попытаться визуализировать фактическое распределение:
library(ggplot2, dplyr, tidyr)
u = rchisq(10000, df=2)
df = data.frame(x=u)
p = ggplot(df)
geom_point(aes(x=x, y=0.5), position=position_jitter(height=0.2), shape='.', alpha=1)
theme_classic()
coord_cartesian(xlim=c(0, 2), ylim=c(0, 1))
show(p)
И это, кажется, выглядит правильно, в отличие от графика плотности:
Похоже, проблема связана с ядрами, и geom_density
позволяет использовать разные ядра. Но на самом деле они не решают проблему предела. Например, приведенный выше код с triangular
выглядит примерно так же:
Вот представление о том, что я ожидаю увидеть (конечно, мне нужна плотность, а не гистограмма):
library(ggplot2)
u = rchisq(10000, df=2)
df = data.frame(x=u)
p = ggplot(df)
geom_histogram(aes(x=x), center=0.1, binwidth=0.2, fill='white', color='black')
theme_classic()
coord_cartesian(xlim=c(0, 2))
show(p)
Комментарии:
1. Я немного смущен вашим использованием
geom_violin
— обычно он используется там, где вы использовали бы boxplot, например, показывающий распределение по нескольким дискретным категориям. Когда я запускаю код, я также получаю то, что выглядит иначе, чем изображение, которое вы опубликовали.2. @Marius Я просто по ошибке вставил неправильный код, чувак. Нет необходимости в лекции по статистике.
Ответ №1:
Обычные методы плотности ядра сталкиваются с проблемами, когда существует ограничение, такое как в этом случае для плотности с поддержкой только выше нуля. Обычной рекомендацией для решения этой проблемы было использование пакета logspline:
install.packages("logspline")
library(logspline)
png(); fit <- logspline(rchisq(10000, 3))
plot(fit) ; dev.off()
Если это необходимо было сделать в среде ggplot2, существует функция dlogspline:
densdf <- data.frame( y=dlogspline(seq(0,12,length=1000), fit),
x=seq(0,12,length=1000))
ggplot(densdf, aes(y=y,x=x)) geom_line()
Возможно, вы настаивали на графике с 2 степенями свободы?
Комментарии:
1. Это выглядит еще менее точным, чем график плотности в моем вопросе.
2. Я построил распределение с тремя степенями свободы. Вы построили единицу с 2.