web-dev-qa-db-fra.com

Adapter une courbe de densité à un histogramme en R

Existe-t-il une fonction dans R qui adapte une courbe à un histogramme?

Disons que vous avez l'histogramme suivant

hist(c(rep(65, times=5), rep(25, times=5), rep(35, times=10), rep(45, times=4)))

Cela semble normal, mais il est biaisé. Je veux ajuster une courbe normale qui est asymétrique pour entourer cet histogramme.

Cette question est plutôt basique, mais je n'arrive pas à trouver la réponse à R sur Internet.

83
user5243421

Si je comprends bien votre question, vous voudrez probablement une estimation de la densité avec l'histogramme:

X <- c(rep(65, times=5), rep(25, times=5), rep(35, times=10), rep(45, times=4))
hist(X, prob=TRUE)            # prob=TRUE for probabilities not counts
lines(density(X))             # add a density estimate with defaults
lines(density(X, adjust=2), lty="dotted")   # add another "smoother" density

Modifier longtemps après:

Voici une version légèrement plus habillée:

X <- c(rep(65, times=5), rep(25, times=5), rep(35, times=10), rep(45, times=4))
hist(X, prob=TRUE, col="grey")# prob=TRUE for probabilities not counts
lines(density(X), col="blue", lwd=2) # add a density estimate with defaults
lines(density(X, adjust=2), lty="dotted", col="darkgreen", lwd=2) 

avec le graphique qu'il produit:

enter image description here

148
Dirk Eddelbuettel

Une telle chose est facile avec ggplot2

library(ggplot2)
dataset <- data.frame(X = c(rep(65, times=5), rep(25, times=5), 
                            rep(35, times=10), rep(45, times=4)))
ggplot(dataset, aes(x = X)) + 
  geom_histogram(aes(y = ..density..)) + 
  geom_density()

ou imiter le résultat de la solution de Dirk

ggplot(dataset, aes(x = X)) + 
  geom_histogram(aes(y = ..density..), binwidth = 5) + 
  geom_density()
29
Thierry

Voici comment je le fais:

foo <- rnorm(100, mean=1, sd=2)
hist(foo, prob=TRUE)
curve(dnorm(x, mean=mean(foo), sd=sd(foo)), add=TRUE)

Un exercice bonus consiste à faire ceci avec le paquet ggplot2 ...

26
John Johnson

Dirk a expliqué comment tracer la fonction de densité sur l'histogramme. Mais parfois, vous voudrez peut-être adopter l'hypothèse plus forte d'une distribution normale asymétrique et l'intrigue au lieu de la densité. Vous pouvez estimer les paramètres de la distribution et la représenter à l’aide du paquet sn :

> sn.mle(y=c(rep(65, times=5), rep(25, times=5), rep(35, times=10), rep(45, times=4)))
$call
sn.mle(y = c(rep(65, times = 5), rep(25, times = 5), rep(35, 
    times = 10), rep(45, times = 4)))

$cp
    mean     s.d. skewness 
41.46228 12.47892  0.99527 

Skew-normal distributed data plot

Cela fonctionne probablement mieux sur des données plus asymétriques:

Another skew-normal plot

11
fmark

J'ai eu le même problème mais la solution de Dirk n'a pas semblé fonctionner. Je recevais ce message d'avertissement à chaque fois

"prob" is not a graphical parameter

J'ai lu ?hist Et trouvé environ freq: a logical vector set TRUE by default.

le code qui a fonctionné pour moi est

hist(x,freq=FALSE)
lines(density(x),na.rm=TRUE)
2
Matias Andina