Построение нормального и биномиального распределения на одном участке - PullRequest
1 голос
/ 05 марта 2020

Как видно из названия, я пытаюсь построить нормальное распределение и биномиальное распределение на одном графике, используя R. Моя попытка может быть замечена ниже, есть ли какая-то причина, почему мое нормальное распределение выглядит таким странным? Я дважды проверил среднее значение и стандартное отклонение, и все выглядит хорошо.

enter image description here

n <- 151
p <- 0.2409

dev <- 4
mu <- n*p
sigma <- sqrt(n*p*(1 - p))

xmin <- round(max(mu - dev*sigma,0));
xmax <- round(min(mu + dev*sigma,n))
x <- seq(xmin, xmax)
y <- dbinom(x,n,p)

barplot(y, 
     col = 'lightblue',
     names.arg = x,
     main = 'Binomial distribution, n=151, p=.803')

range <- seq(mu - dev*sigma, mu + dev*sigma, 0.01)
height <- dnorm(range, mean = mu, sd = sigma) 
lines(range, height, col = 'red', lwd = 3)

Ответы [ 3 ]

3 голосов
/ 05 марта 2020

barplot - просто неправильная функция для вашего случая. Или, если вы действительно хотите его использовать, вам нужно перенастроить оси X между barplot и lines

. По умолчанию для barplot стоит поставить каждое значение height на * 1008. *

head(c(barplot(y, plot = FALSE)))
# [1] 0.7 1.9 3.1 4.3 5.5 6.7

Это можно изменить, выбрав space и width или комбинацию обоих

head(c(barplot(y, plot = FALSE, space = 0)))
# [1] 0.5 1.5 2.5 3.5 4.5 5.5

head(c(barplot(y, plot = FALSE, space = 0, width = 3)))
# [1]  1.5  4.5  7.5 10.5 13.5 16.5

Вы можете просто использовать plot, чтобы избежать таких вещей

n <- 151
p <- 0.2409

dev <- 4
mu <- n*p
sigma <- sqrt(n*p*(1 - p))

xmin <- round(max(mu - dev*sigma,0));
xmax <- round(min(mu + dev*sigma,n))
x <- seq(xmin, xmax)
y <- dbinom(x,n,p)

plot(x, y, type = 'h', lwd = 10, lend = 3, col = 'lightblue',
     ann = FALSE, las = 1, bty = 'l', yaxs = 'i', ylim = c(0, 0.08))
title(main = sprintf('Binomial distribution, n=%s, p=%.3f', n, p))
lines(x, dnorm(x, mean = mu, sd = sigma), col = 'red', lwd = 7)

xx <- seq(min(x), max(x), length.out = 1000)
lines(xx, dnorm(xx, mean = mu, sd = sigma), col = 'white')

enter image description here

«Стержни» на этом рисунке зависят от вашего выбора lwd и размеров вашего устройства, но если вам нужно более точное управление что, вы можете использовать rect, который требует немного больше работы.

w <- 0.75
plot(x, y, type = 'n', ann = FALSE, las = 1, bty = 'l', yaxs = 'i', ylim = c(0, 0.08))
rect(x - w / 2, 0, x + w / 2, y, col = 'lightblue')
lines(xx, dnorm(xx, mean = mu, sd = sigma), col = 'red', lwd = 3)
title(main = sprintf('Binomial distribution, n=%s, p=%.3f', n, p))

enter image description here

2 голосов
/ 05 марта 2020

Вы можете использовать пакет ggplot2

library(ggplot2)

n <- 151
p <- 0.2409
mean <- n*p
sd <-   sqrt(n*p*(1-p))
binwidth <-   0.005


xmin <- round(max(mu - dev*sigma,0));
xmax <- round(min(mu + dev*sigma,n))
x <- seq(xmin, xmax)
y <- dbinom(x,n,p)

df <- cbind.data.frame(x, y)

ggplot(df, aes(x = x, y = y)) +
  geom_bar(stat="identity", fill = 'dodgerblue3')+
  labs(title = "Binomial distribution, n=151, p=.803",
       x = "",
       y = "") +
  theme_minimal()+
  # Create normal curve, akousting for number of observations and binwidth
  stat_function( 
    fun = function(x, mean, sd, n, bw){ 
      dnorm(x = x, mean = mean, sd = sd)
    }, col = "red", size=I(1.4),  
    args = c(mean = mean, sd = sd, n = n, bw = binwidth))

enter image description here

0 голосов
/ 05 марта 2020

Вы можете сделать это, используя пакет ggplot2 (я был удивлен нормальным распределением, но замена geom_line на geom_point убедила меня в том, что имеет эту форму (слишком высокая дисперсия?)):

n <- 151
p <- 0.2409

dev <- 4
mu <- n*p
sigma <- sqrt(n*p*(1 - p))

xmin <- round(max(mu - dev*sigma,0));
xmax <- round(min(mu + dev*sigma,n))

x <- seq(xmin, xmax)
y <- dbinom(x,n,p)

z <- dnorm(x = qnorm(p = seq(0,1, length.out = length(x)), mean = mu, sd = sigma), mean = mu, sd = sigma)

library(magrittr)
library(ggplot2)
data.frame(x, y, z) %>% 
    ggplot(aes(x = x)) +
    geom_col(aes(y = y)) +
    geom_line(aes(x = x, y = z, colour = "red"),
          show.legend = FALSE)

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...