2014-12-26 10 views
6

Chcę dodać linię gęstości (normalny) do gęstości faktycznie histogramu.Dodawanie linii gęstości do histogram z danych liczy się w ggplot2

Załóżmy, że mam następujące dane. mogę wykreślić histogram przez ggplot2:

set.seed(123)  
df <- data.frame(x = rbeta(10000, shape1 = 2, shape2 = 4)) 

ggplot(df, aes(x = x)) + geom_histogram(colour = "black", fill = "white", 
             binwidth = 0.01) 

enter image description here

mogę dodać linię gęstości przy użyciu:

ggplot(df, aes(x = x)) + 
    geom_histogram(aes(y = ..density..),colour = "black", fill = "white", 
       binwidth = 0.01) + 
    stat_function(fun = dnorm, args = list(mean = mean(df$x), sd = sd(df$x))) 

enter image description here

Ale to nie jest to, co faktycznie chcę, ja aby ta linia gęstości była dopasowana do danych liczbowych.

znalazłem podobny post (HERE), który zaproponował rozwiązanie tego problemu. Ale nie zadziałało w moim przypadku. Potrzebuję arbitralnego współczynnika ekspansji, aby uzyskać to, czego chcę. I nie jest to uogólnić na wszystkich:

ef <- 100 # Expansion factor 

ggplot(df, aes(x = x)) + 
    geom_histogram(colour = "black", fill = "white", binwidth = 0.01) + 
    stat_function(fun = function(x, mean, sd, n){ 
    n * dnorm(x = x, mean = mean, sd = sd)}, 
    args = list(mean = mean(df$x), sd = sd(df$x), n = ef)) 

enter image description here

Wszelkie wskazówki, które można używać do uogólnienia tego

  • pierwszy do rozkładu normalnego,
  • następnie do każdej innej wielkości bin,
  • i na końcu do każdej innej dystrybucji będzie bardzo pomocne.
+0

Czy chodziło Ci o dwa obrazy wykres być takie same? Przesłany wygląda ten sam jeden dwukrotnie – arvi1000

+0

Użyj 'fitdistr (...)' 'w pakiecie MASS' celu dopasowania rozkładów. – jlhoward

Odpowiedz

10

Montaż funkcję dystrybucyjną nie zdarza się przez magię. Musisz to zrobić jawnie. Jednym ze sposobów jest użycie pakietu fitdistr(...) w pakiecie MASS.

library(MASS) # for fitsidtr(...) 
# excellent fit (of course...) 
ggplot(df, aes(x = x)) + 
    geom_histogram(aes(y=..density..),colour = "black", fill = "white", binwidth = 0.01)+ 
    stat_function(fun=dbeta,args=fitdistr(df$x,"beta",start=list(shape1=1,shape2=1))$estimate) 

# horrible fit - no surprise here 
ggplot(df, aes(x = x)) + 
    geom_histogram(aes(y=..density..),colour = "black", fill = "white", binwidth = 0.01)+ 
    stat_function(fun=dnorm,args=fitdistr(df$x,"normal")$estimate) 

# mediocre fit - also not surprising... 
ggplot(df, aes(x = x)) + 
    geom_histogram(aes(y=..density..),colour = "black", fill = "white", binwidth = 0.01)+ 
    stat_function(fun=dgamma,args=fitdistr(df$x,"gamma")$estimate) 

EDIT: Odpowiedź na komentarz OP.

Współczynnik skali to binwidth & # x2715; wielkość próbki.

ggplot(df, aes(x = x)) + 
    geom_histogram(colour = "black", fill = "white", binwidth = 0.01)+ 
    stat_function(fun=function(x,shape1,shape2)0.01*nrow(df)*dbeta(x,shape1,shape2), 
       args=fitdistr(df$x,"beta",start=list(shape1=1,shape2=1))$estimate) 

+1

Dziękujemy za uogólnienie dla różnych dystrybucji. Moim ostatecznym celem jest dopasowanie tych linii do danych liczbowych zamiast gęstości. Czy masz jakieś wskazówki, jak to zrobić? (Chcę uzyskać ten sam wykres co trzeci dział oryginalnego wpisu.) – HBat

+1

Zobacz zmiany powyżej. – jlhoward

+0

'0.01' wartość wzorze ('0,01 * nrow (DF) * dbeta (x, shape1, shape2)') nie jest uogólnione różnych binwidths lub próbki rozmiarach.Załóżmy, że mam próbkę o wielkości 2474 (zamiast 10000) i 0,03 (zamiast 0,01). Uważam, że 0.01 powinno być funkcją szerokości bin i ewentualnie wielkości próby. – HBat

Powiązane problemy