2014-12-26 12 views
6

Ich möchte zu einem Histogramm eine Dichtezeile (eine normale Dichte tatsächlich) hinzufügen.Hinzufügen einer Dichtezeile zu einem Histogramm mit Zähldaten in ggplot2

Angenommen, ich habe die folgenden Daten. Ich kann das Histogramm Plot von 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

ich mit einer Dichte Zeile hinzufügen:

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

Aber das ist nicht das, was ich wirklich will, ich möchte, dass diese Dichtezeile an die Zähldaten angepasst wird.

Ich fand einen ähnlichen Beitrag (HERE), der eine Lösung für dieses Problem bot. Aber in meinem Fall hat es nicht funktioniert. Ich brauche einen willkürlichen Expansionsfaktor, um zu bekommen, was ich will. Und das ist gar nicht verallgemeinerbar:

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

Irgendwelche Hinweise, die ich verwenden kann dieses

  • ersten Normalverteilung zu verallgemeinern,
  • dann auf andere Binabmessung,
  • und schließlich zu jeder anderen Verteilung wird sehr hilfreich sein.
+0

Meinten Sie für die beiden Schaubilder die gleiche sein? Sieht so aus, als hättest du das selbe zweimal hochgeladen – arvi1000

+0

Verwende 'fitdistr (...)' im 'MASS'-Paket, um die Distributionen anzupassen. – jlhoward

Antwort

10

Anpassen einer Verteilungsfunktion geschieht nicht durch Magie. Sie müssen es explizit tun. Eine Möglichkeit ist die Verwendung von fitdistr(...) im MASS Paket.

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: Antwort auf Kommentar des OP.

Der Skalierungsfaktor ist binwidth & # x2715; Stichprobenumfang

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

Danke für die Verallgemeinerung zu verschiedenen Distributionen. Mein oberstes Ziel ist es, diese Linien an die Zähldaten anstatt an die Dichte anzupassen. Hast du irgendwelche Erkenntnisse, wie das geht? (Ich möchte dasselbe Diagramm wie das dritte Diagramm des ursprünglichen Beitrags erhalten.) – HBat

+1

Siehe die obigen Änderungen. – jlhoward

+0

Der '0,01'-Wert in der Formel (' 0,01 * nrow (df) * dbeta (x, shape1, shape2) ') ist nicht auf verschiedene binwidths oder sample sizes verallgemeinerbar.Angenommen, ich habe eine Stichprobengröße von 2474 (statt 10000) und 0,03 (statt 0,01). Ich glaube, dass 0,01 die Funktion der Behälterbreite und möglicherweise der Probengröße sein sollte. – HBat

Verwandte Themen