Ajustar una curva de densidad a un histograma en R
¿Existe una función en R que ajuste una curva a un histograma?
Digamos que tienes el siguiente histograma
hist(c(rep(65, times=5), rep(25, times=5), rep(35, times=10), rep(45, times=4)))
Parece normal, pero está torcido. Quiero ajustar una curva normal que esté sesgada para rodear este histograma.
Esta pregunta es bastante básica, pero parece que no puedo encontrar la respuesta para R en Internet.
Si entiendo tu pregunta correctamente, entonces probablemente quieras una estimación de densidad junto con el histograma:
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
Edite mucho tiempo después:
Aquí hay una versión un poco más disfrazada:
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)
junto con el gráfico que produce:
Esto es fácil con 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()
o para imitar el resultado de la solución de Dirk
ggplot(dataset, aes(x = X)) +
geom_histogram(aes(y = ..density..), binwidth = 5) +
geom_density()
Así es como lo hago:
foo <- rnorm(100, mean=1, sd=2)
hist(foo, prob=TRUE)
curve(dnorm(x, mean=mean(foo), sd=sd(foo)), add=TRUE)
Un ejercicio adicional es hacer esto con el paquete ggplot2...
Dirk ha explicado cómo trazar la función de densidad sobre el histograma. Pero a veces es posible que desees optar por la suposición más sólida de una distribución normal sesgada y trazarla en lugar de la densidad. Puede estimar los parámetros de la distribución y trazarlos usando el paquete 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
Esto probablemente funcione mejor con datos que son más asimétricos a lo normal:
Tuve el mismo problema pero la solución de Dirk no pareció funcionar. Recibía este mensaje de advertencia cada vez.
"prob" is not a graphical parameter
Leí ?hist
y descubrí sobrefreq: a logical vector set TRUE by default.
el código que funcionó para mí es
hist(x,freq=FALSE)
lines(density(x),na.rm=TRUE)