He logrado encontrar en línea cómo la superposición de una curva normal de un histograma en R, pero me gustaría conservar la normal «frecuencia» del eje y de un histograma. Ver a dos segmentos de código a continuación y observe cómo en el segundo, el eje y es reemplazado con «densidad». ¿Cómo puedo evitar que el eje y como «frecuencia», como es en la primera parcela.

COMO UN BONO: me gustaría marcar la SD regiones (hasta 3 SD) en la curva de densidad así. ¿Cómo puedo hacer esto? Traté de abline, pero la línea se extiende a la parte superior de la gráfica y se ve feo.

g = d$mydata
hist(g)

Superposición de la curva normal para el histograma en R

g = d$mydata
m<-mean(g)
std<-sqrt(var(g))
hist(g, density=20, breaks=20, prob=TRUE, 
     xlab="x-variable", ylim=c(0, 2), 
     main="normal curve over histogram")
curve(dnorm(x, mean=m, sd=std), 
      col="darkblue", lwd=2, add=TRUE, yaxt="n")

Superposición de la curva normal para el histograma en R

Ver cómo en la imagen de arriba, el eje y es que la «densidad». Me gustaría conseguir que para ser «frecuencia».

  • Usted puede lograr esto mediante la aplicación de la estrategia establecidos en esta respuesta
  • Aunque debo añadir que la interpretación de la «Frecuencia» para el continuo de la curva de densidad va a ser muy claro.
  • Entiendo, y estoy bien con eso. El enlace que me dio funciona muy bien, excepto que no se da una distribución normal, sino más bien una curva de densidad que tiene varios puntos de inflexión. Me gustaría conseguir un normal como en el gráfico anterior. Alguna idea?
  • sólo comentar para asegurarse de que usted vea mi edición, que tanto aplicar mi método a una densidad normal en lugar de un arbitrario de la densidad y agregar líneas en las desviaciones estándar.
  • Yo lo hice, muchas gracias!
  • Consulte aquí para una ggplot2 opción.
  • Hola a Todos, alguien Ha hecho el anterior ggplot si es así sería posible actualización de la respuesta o me dirija a uno con una descripción del conjunto de datos. Gracias de antemano !

InformationsquelleAutor StanLe | 2013-11-19

3 Comentarios

  1. 47

    Aquí está una manera fácil de encontrar:

    h <- hist(g, breaks = 10, density = 10,
              col = "lightgray", xlab = "Accuracy", main = "Overall") 
    xfit <- seq(min(g), max(g), length = 40) 
    yfit <- dnorm(xfit, mean = mean(g), sd = sd(g)) 
    yfit <- yfit * diff(h$mids[1:2]) * length(g) 
    
    lines(xfit, yfit, col = "black", lwd = 2)
    • Bueno! También puede utilizar freq = FALSE en hist para deshacerse de la escala de yfit.
    • ¿Qué es el significante de uso de h$mids[1:2] en lugar de todo el vector?
    • Creo que el significado de h$mids[1:2] es sólo que se utiliza para calcular el tamaño de los recipientes. Como todos ellos son del mismo tamaño, la búsqueda de la diferencia entre los dos primeros nos da esto. Esto no sería necesario si el rango de cada bin fue de 1.
    • Sería agradable si este ejemplo de código se puede ejecutar por otros.
    • Vea a continuación la respuesta de una aplicación. Se envuelve alrededor de las existentes hist() función.
    • El yfit * diff(h$mids[1:2]) * length(g) debe ser omitido cuando el uso de densidades (hist(..., density = TRUE)). Además, para las fechas en las que usted debe utilizar la transformación numérica de yfit: as.double(yfit) * diff(h$mids[1:2]) * length(g). Acabo de encontrar hoy en día. He implementado las correcciones en mi respuesta (que es una implementación de la suya).

  2. 27

    Usted sólo tiene que encontrar el derecho multiplicador, que puede ser fácilmente calculada a partir de la hist objeto.

    myhist <- hist(mtcars$mpg)
    multiplier <- myhist$counts / myhist$density
    mydensity <- density(mtcars$mpg)
    mydensity$y <- mydensity$y * multiplier[1]
    
    plot(myhist)
    lines(mydensity)

    Superposición de la curva normal para el histograma en R

    Una versión más completa, con una densidad normal y las líneas en cada una desviación estándar de distancia de la media (incluyendo la media):

    myhist <- hist(mtcars$mpg)
    multiplier <- myhist$counts / myhist$density
    mydensity <- density(mtcars$mpg)
    mydensity$y <- mydensity$y * multiplier[1]
    
    plot(myhist)
    lines(mydensity)
    
    myx <- seq(min(mtcars$mpg), max(mtcars$mpg), length.out= 100)
    mymean <- mean(mtcars$mpg)
    mysd <- sd(mtcars$mpg)
    
    normal <- dnorm(x = myx, mean = mymean, sd = mysd)
    lines(myx, normal * multiplier[1], col = "blue", lwd = 2)
    
    sd_x <- seq(mymean - 3 * mysd, mymean + 3 * mysd, by = mysd)
    sd_y <- dnorm(x = sd_x, mean = mymean, sd = mysd) * multiplier[1]
    
    segments(x0 = sd_x, y0= 0, x1 = sd_x, y1 = sd_y, col = "firebrick4", lwd = 2)
  3. 2

    Esta es una aplicación de la citada StanLe el anwer, también la fijación el caso de que su respuesta iba a producir ninguna curva cuando el uso de densidades.

    Esta sustituye a la existente, pero oculto hist.default() función, que sólo añade la normalcurve parámetro (cuyo valor por defecto es TRUE).

    Las tres primeras líneas son para apoyar roxygen2 para la construcción de paquetes.

    #' @noRd
    #' @exportMethod hist.default
    #' @export
    hist.default <- function(x,
    breaks = "Sturges",
    freq = NULL,
    include.lowest = TRUE,
    normalcurve = TRUE,
    right = TRUE,
    density = NULL,
    angle = 45,
    col = NULL,
    border = NULL,
    main = paste("Histogram of", xname),
    ylim = NULL,
    xlab = xname,
    ylab = NULL,
    axes = TRUE,
    plot = TRUE,
    labels = FALSE,
    warn.unused = TRUE,
    ...)  {
    # https://stackoverflow.com/a/20078645/4575331
    xname <- paste(deparse(substitute(x), 500), collapse = "\n")
    suppressWarnings(
    h <- graphics::hist.default(
    x = x,
    breaks = breaks,
    freq = freq,
    include.lowest = include.lowest,
    right = right,
    density = density,
    angle = angle,
    col = col,
    border = border,
    main = main,
    ylim = ylim,
    xlab = xlab,
    ylab = ylab,
    axes = axes,
    plot = plot,
    labels = labels,
    warn.unused = warn.unused,
    ...
    )
    )
    if (normalcurve == TRUE & plot == TRUE) {
    x <- x[!is.na(x)]
    xfit <- seq(min(x), max(x), length = 40)
    yfit <- dnorm(xfit, mean = mean(x), sd = sd(x))
    if (isTRUE(freq) | (is.null(freq) & is.null(density))) {
    yfit <- yfit * diff(h$mids[1:2]) * length(x)
    }
    lines(xfit, yfit, col = "black", lwd = 2)
    }
    if (plot == TRUE) {
    invisible(h)
    } else {
    h
    }
    }

    Ejemplo rápido:

    hist(g)

    Superposición de la curva normal para el histograma en R

    Para las fechas es un poco diferente. Referencia:

    #' @noRd
    #' @exportMethod hist.Date
    #' @export
    hist.Date <- function(x,
    breaks = "months",
    format = "%b",
    normalcurve = TRUE,
    xlab = xname,
    plot = TRUE,
    freq = NULL,
    density = NULL,
    start.on.monday = TRUE,
    right = TRUE,
    ...)  {
    # https://stackoverflow.com/a/20078645/4575331
    xname <- paste(deparse(substitute(x), 500), collapse = "\n")
    suppressWarnings(
    h <- graphics:::hist.Date(
    x = x,
    breaks = breaks,
    format = format,
    freq = freq,
    density = density,
    start.on.monday = start.on.monday,
    right = right,
    xlab = xlab,
    plot = plot,
    ...
    )
    )
    if (normalcurve == TRUE & plot == TRUE) {
    x <- x[!is.na(x)]
    xfit <- seq(min(x), max(x), length = 40)
    yfit <- dnorm(xfit, mean = mean(x), sd = sd(x))
    if (isTRUE(freq) | (is.null(freq) & is.null(density))) {
    yfit <- as.double(yfit) * diff(h$mids[1:2]) * length(x)
    }
    lines(xfit, yfit, col = "black", lwd = 2)
    }
    if (plot == TRUE) {
    invisible(h)
    } else {
    h
    }
    }

Dejar respuesta

Please enter your comment!
Please enter your name here