es.davy.ai

Preguntas y respuestas de programación confiables

¿Tienes una pregunta?

Si tienes alguna pregunta, puedes hacerla a continuación o ingresar lo que estás buscando.

Histograma agrupado con superposición de distribución empírica y/o normal.

Estoy tratando de ver la distribución de frecuencia de una variable en particular. Debido a la gran cantidad de datos, he creado intervalos para un rango de valores y estoy graficando la cantidad de cada intervalo. Quiero poder superponer líneas que representen tanto la distribución empírica vista por mis datos, como lo que se vería en una distribución normal teórica. Puedo lograr esto sin pre-agrupar mis datos o usando ggplot2 haciendo algo como esto:

df <- ggplot2::diamonds
hist(df$price,freq = FALSE)
lines(density(df$price),lwd=3,col="blue")

o con ggplot2 de la siguiente manera:

mean_price <- mean(df$price)
sd_price <- sd(df$price)

ggplot(df, aes(x = price)) +
  geom_histogram(aes(y = ..density..), 
                 bins = 40,  colour = "black", fill = "white") +
  geom_line(aes(y = ..density.., color = 'Empírica'), stat = 'density') +
  stat_function(fun = dnorm, aes(color = 'Normal'),
                args = list(mean = mean_price, sd = sd_price)) +
  scale_colour_manual(name = "Colores", values = c("rojo", "azul"))

pero no puedo descifrar cómo superponer líneas similares en mis datos pre-agrupados:

breaks <- seq(from=min(df$price),to=max(df$price),length.out=11)
price_freq <- cut(df$price,breaks = breaks,right = TRUE,include.lowest = TRUE)
ggplot(data = df,mapping = aes(x=price_freq)) +
  stat_count() +
  theme(axis.text.x = element_text(angle = 270)) 
  # + geom_line(aes(y = ..density.., color = 'Empírica'), stat = 'density') +
  # stat_function(fun = dnorm, aes(color = 'Normal'),
  #               args = list(mean = mean_price, sd = sd_price)) +
  # scale_colour_manual(name = "Colores", values = c("rojo", "azul"))

¿Alguna idea?

Tags:  , ,

Answer

  1. Avatar for davy.ai

    Para superponer líneas tanto para las distribuciones empíricas como teóricas en datos pre-bineados utilizando ggplot2, puedes seguir estos pasos:

    1. Crea un data frame con los rangos de bines y sus frecuencias correspondientes utilizando la función table():
      “`{r}
      price_freq_table <- table(price_freq)
      price_freq_df <- data.frame(price = as.numeric(names(price_freq_table)),
      freq = as.numeric(price_freq_table))

    2. Calcula la densidad empírica utilizando la función `density()` en los datos originales: ```{r} price_density <- density(df$price) price_density_df <- data.frame(price = price_density$x, density = price_density$y)
    1. Calcula la función de densidad normal utilizando dnorm() con la media y desviación estándar de los datos originales:
      “`{r}
      normal_density_df <- data.frame(price = seq(min(df$price), max(df$price), length.out = 100),
      density = dnorm(seq(min(df$price), max(df$price), length.out = 100),
      mean = mean(df$price), sd = sd(df$price)))

    4. Utiliza `geom_col()` para crear el histograma con los bines predefinidos: ```{r} ggplot(data = price_freq_df, aes(x = price, y = freq)) + geom_col(colour = "black", fill = "white") + theme(axis.text.x = element_text(angle = 270))
    1. Superpone las líneas para las distribuciones empírica y normal utilizando geom_line():
      {r}
      ggplot(data = price_freq_df, aes(x = price, y = freq)) +
      geom_col(colour = "black", fill = "white") +
      geom_line(data = price_density_df, aes(x = price, y = density, color = "Empírica")) +
      geom_line(data = normal_density_df, aes(x = price, y = density, color = "Normal")) +
      scale_colour_manual(name = "Distribución", values = c("rojo", "azul")) +
      theme(axis.text.x = element_text(angle = 270))

    Este código producirá un histograma con los bines predefinidos y líneas superpuestas para ambas distribuciones empíricas y teóricas. Puedes ajustar el número de bines y el rango de las funciones de densidad de acuerdo a tus datos.

Comments are closed.