2013-11-19 3 views
43

Мне удалось найти онлайн, как наложить нормальную кривую на гистограмму в R, но я хотел бы сохранить нормальную «частоту» оси y гистограммы. См. Два сегмента кода ниже и обратите внимание, как во втором, ось y заменяется на «плотность». Как я могу сохранить эту ось y как «частоту», как это происходит в первом сюжете.Наложение нормальной кривой на гистограмму в R

КАК БОНУС: Я хотел бы также отметить области SD (до 3 SD) на кривой плотности. Как я могу это сделать? Я пробовал abline, но линия простирается до вершины графика и выглядит уродливой.

g = d$mydata 
hist(g) 

enter image description here

g = d$mydata 
    m<-mean(g) 
    std<-sqrt(var(g)) 
    hist(g, density=20, breaks=20, prob=TRUE, 
     xlab="x-variable", ylim=c(0, 2), 
     main="normal curve over histogram") 
    curve(dnorm(x, mean=m, sd=std), 
      col="darkblue", lwd=2, add=TRUE, yaxt="n") 

enter image description here

Посмотрите, как на изображении выше, у-ось "плотность". Я бы хотел, чтобы это была «частота».

+2

Вы можете достичь этого путем применения стратегия, изложенная в [этом ответе] (http://stackoverflow.com/questions/13960896/add-density-lines-to-histogram-and-cumulative-histogram/13961565#13961565) –

+0

Хотя я должен добавить, что интерпретация «Частота» для кривой непрерывной плотности wi будет действительно непонятно. –

+0

Я понимаю, и все в порядке. Ссылка, которую вы мне дали, отлично работает, за исключением того, что она не дает нормального распределения, а представляет собой кривую плотности, которая имеет несколько точек перегиба. Я хотел бы получить нормальное, как в сюжете выше. Есть идеи? – StanLe

ответ

37

Вот хороший простой способ я нашел:

h <- hist(g, breaks = 10, density = 10, 
      col = "lightgray", xlab = "Accuracy", main = "Overall") 
xfit <- seq(min(g), max(g), length = 40) 
yfit <- dnorm(xfit, mean = mean(g), sd = sd(g)) 
yfit <- yfit * diff(h$mids[1:2]) * length(g) 

lines(xfit, yfit, col = "black", lwd = 2) 
+0

Ницца! Вы также можете использовать 'freq = FALSE' в' hist', чтобы избавиться от масштабирования 'yfit'. –

+4

Какова значимость использования h $ mids [1: 2] вместо всего вектора? – Zach

+0

Я считаю, что значение h $ mids [1: 2] заключается в том, что оно используется для вычисления размера бункеров. Поскольку они имеют одинаковый размер, найти разницу между двумя первыми дает нам это. Это не обязательно делать, если диапазон каждого бункера равен 1. – dpwrussell

20

Вам просто нужно найти правильный множитель, который может быть легко вычислен из hist объекта.

myhist <- hist(mtcars$mpg) 
multiplier <- myhist$counts/myhist$density 
mydensity <- density(mtcars$mpg) 
mydensity$y <- mydensity$y * multiplier[1] 

plot(myhist) 
lines(mydensity) 

enter image description here

Более полная версия, с нормальной плотностью и линий на каждом стандартное отклонение от среднего (в том числе среднего):

myhist <- hist(mtcars$mpg) 
multiplier <- myhist$counts/myhist$density 
mydensity <- density(mtcars$mpg) 
mydensity$y <- mydensity$y * multiplier[1] 

plot(myhist) 
lines(mydensity) 

myx <- seq(min(mtcars$mpg), max(mtcars$mpg), length.out= 100) 
mymean <- mean(mtcars$mpg) 
mysd <- sd(mtcars$mpg) 

normal <- dnorm(x = myx, mean = mymean, sd = mysd) 
lines(myx, normal * multiplier[1], col = "blue", lwd = 2) 

sd_x <- seq(mymean - 3 * mysd, mymean + 3 * mysd, by = mysd) 
sd_y <- dnorm(x = sd_x, mean = mymean, sd = mysd) * multiplier[1] 

segments(x0 = sd_x, y0= 0, x1 = sd_x, y1 = sd_y, col = "firebrick4", lwd = 2) 
Смежные вопросы