#r #ggplot2 #histogram
#r #ggplot2 #гистограмма
Вопрос:
Я пытаюсь составить гистограмму значений плотности и наложить ее на кривую функции плотности (не на оценку плотности).
Используя простой стандартный пример, вот некоторые данные:
x <- rnorm(1000)
Я могу сделать:
q <- qplot( x, geom="histogram")
q stat_function( fun = dnorm )
но это дает масштаб гистограммы по частотам, а не по плотностям. с ..density..
я могу получить правильный масштаб на гистограмме:
q <- qplot( x,..density.., geom="histogram")
q
Но теперь это выдает ошибку:
q stat_function( fun = dnorm )
Есть ли что-то, чего я не вижу?
Другой вопрос, есть ли способ построить кривую функции, например curve()
, но затем не в виде слоя?
Комментарии:
1. Проблема в том, что вы определили глобальную y для своего графика, используя ..density.. внутри
qplot
. Это сбивает с толкуstat_function
. Самым простым решением было бы написатьqplot(x, geom = 'blank') geom_histogram(aes(y = ..density..)) stat_function(fun = dnorm)
. Смотрите мой подробный ответ ниже2. Эквивалентом
curve(dnorm, -4, 4)
было быqplot(x = -4:4, stat = 'function', fun = dnorm, geom = 'line')
3. Ах да, я пробовал это с функцией в качестве первого аргумента, но теперь видите, что пошло не так. Спасибо!
Ответ №1:
Вот так!
# create some data to work with
x = rnorm(1000);
# overlay histogram, empirical density and normal density
p0 = qplot(x, geom = 'blank')
geom_line(aes(y = ..density.., colour = 'Empirical'), stat = 'density')
stat_function(fun = dnorm, aes(colour = 'Normal'))
geom_histogram(aes(y = ..density..), alpha = 0.4)
scale_colour_manual(name = 'Density', values = c('red', 'blue'))
theme(legend.position = c(0.85, 0.85))
print(p0)
Комментарии:
1. P.S. Если вы работаете с реальными данными, обязательно передайте аргументы эмпирического среднего и sd в функцию dnorm, синтаксис см. в справке stat_function.
2. Просто из любопытства: как бы это было сделано с помощью функции ggplot ()? Я едва понял, как работает ggplot (), поэтому я чувствую себя немного странно, используя этот подход для своих материалов.
3. @Jemus42 вы могли бы поменять первую строку на что-то вроде этого «ggplot(data.frame(x), aes(x = x)) »
4. @Jemus42 Почему это? Без передачи mean и sd в args в stat_function я вообще ничего не получаю.
5. Существует проблема с наложением гистограмм и оценок плотности, которая заключается в том, что оценки плотности действительно должны быть сдвинуты на половину ширины ячейки, чтобы получить наиболее точное и эстетически приятное представление. Я так и не смог понять, как это сделать. Есть желающие?
Ответ №2:
Более простая альтернатива ответу Рамната, передающая наблюдаемое среднее значение и стандартное отклонение и использующая ggplot
вместо qplot
:
df <- data.frame(x = rnorm(1000, 2, 2))
# overlay histogram and normal density
ggplot(df, aes(x))
geom_histogram(aes(y = after_stat(density)))
stat_function(
fun = dnorm,
args = list(mean = mean(df$x), sd = sd(df$x)),
lwd = 2,
col = 'red'
)
Комментарии:
1. Это очень удобный ответ, поскольку он предоставляет способ построения гистограммы и кривой плотности, даже если они принадлежат разным распределениям, если это необходимо (как это было для меня). Спасибо!
2. Исходный вопрос касается подгонки кривой плотности, а не конкретно одного гауссова. Если вы хотите понять, почему это решение не работает, попробуйте установить для данных значение
df <- data.frame(x = c(rnorm(1000, 2, 2), rnorm(1000, 12, 2)))
3. @Megatron, Нет, OP запросил «кривую функции плотности (не оценку плотности)» . Так что я все еще думаю, что это правильно. Ваш пример показывает, что функция нормальной плотности в некоторых случаях может не быть хорошим описанием данных, но это не главное.
Ответ №3:
Как насчет использования geom_density()
from ggplot2
? Вот так:
df <- data.frame(x = rnorm(1000, 2, 2))
ggplot(df, aes(x))
geom_histogram(aes(y=..density..)) # scale histogram y
geom_density(col = "red")
Это также работает для мультимодальных распределений, например:
df <- data.frame(x = c(rnorm(1000, 2, 2), rnorm(1000, 12, 2), rnorm(500, -8, 2)))
ggplot(df, aes(x))
geom_histogram(aes(y=..density..)) # scale histogram y
geom_density(col = "red")
Комментарии:
1. Потому что OP запросил «кривую функции плотности (не оценку плотности)» .
geom_density
дает оценку плотности.2. Возможно, это не то, о чем просил OP, но это помогло с тем, что я искал!
3. @Axeman В чем разница между функцией плотности и оценкой плотности?
Ответ №4:
Я пытаюсь получить набор данных iris. Вы должны быть в состоянии видеть нужный вам график в этом простом коде:
ker_graph <- ggplot(iris, aes(x = Sepal.Length))
geom_histogram(aes(y = ..density..),
colour = 1, fill = "white")
geom_density(lwd = 1.2,
linetype = 2,
colour = 2)