2014-12-26 12 views
6

Desidero aggiungere una linea di densità (in realtà una densità normale) a un istogramma.Aggiunta di una linea di densità a un istogramma con dati di conteggio in ggplot2

Supponiamo di avere i seguenti dati. Posso tracciare l'istogramma per 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

posso aggiungere una linea di densità utilizzando:

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

Ma questo non è quello che in realtà voglio, desidera che questa linea di densità venga adattata ai dati del conteggio.

Ho trovato un post simile (HERE) che offriva una soluzione a questo problema. Ma non ha funzionato nel mio caso. Ho bisogno di un fattore di espansione arbitrario per ottenere ciò che voglio. E questo non è generalizzabile a tutti:

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

eventuali indizi che posso usare per generalizzare questo

  • primo a distribuzione normale,
  • quindi a qualsiasi altro formato bin,
  • e infine a qualsiasi altra distribuzione sarà molto utile.
+0

Forse cercavi per le due immagini del grafico per essere lo stesso? Sembra che tu abbia caricato lo stesso due volte – arvi1000

+0

Usa 'fitdistr (...)' nel pacchetto 'MASS' per adattare le distribuzioni. – jlhoward

risposta

10

Il montaggio di una funzione di distribuzione non avviene per magia. Devi farlo esplicitamente. Un modo è utilizzare fitdistr(...) nel pacchetto 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: Risposta al commento di OP.

Il fattore di scala è binwidth & # x2715; misura di prova.

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

Grazie per la generalizzazione a diverse distribuzioni. Il mio obiettivo ultimo è quello di adattare queste linee ai dati del conteggio anziché alla densità. Hai qualche idea su come farlo? (Voglio ottenere la stessa trama della terza trama del post originale.) – HBat

+1

Vedere le modifiche sopra. – jlhoward

+0

Il valore '0.01' nella formula (' 0.01 * nrow (df) * dbeta (x, shape1, shape2) ') non è generalizzabile a diverse larghezze di lotto o dimensioni del campione.Supponiamo di avere una dimensione del campione 2474 (anziché 10000) e 0,03 (anziché 0,01). Credo che 0,01 dovrebbe essere la funzione della larghezza del contenitore e, eventualmente, della dimensione del campione. – HBat

Problemi correlati