6 votos

Visualización de la distribución de frecuencias binadas en R

Estoy tratando de representar visualmente la distribución de los apellidos en los Estados Unidos. En concreto, trato de mostrar que la distribución es tal que los nombres más comunes (digamos los 50 primeros) son muy comunes, pero que después desciende rápidamente. La conclusión que espero apoyar es que no es tan significativo diferenciar entre común y menos común entre los nombres que no están en el top X porque todos son una porción muy pequeña de la población.

Tengo la frecuencia observada de todos los apellidos que aparecen más de 100 veces en el censo de 2000.

## Data from the US Census, extracted and CSV re-hosted 
## http://www.census.gov/genealogy/www/data/2000surnames/names.zip
names <- read.csv("http://samswift.org/files/app_c.csv")

Mi intuición fue agrupar la lista clasificada por grupos de 50. Nombres más comunes 1-50, 51-100, ...

sum50 <-  tapply(names$count, (seq_along(names$count)-1) %/% 50, sum)

Así que ahora tenemos la suma de la población con un nombre de los 50 principales, un nombre de los 50 segundos, etc.

Me imaginaba una trama como esta desired plot donde el eje x es el factor ordenado de bins (1-50, 51-100 ..) y el eje y es la suma de la población en ese bin. Creo que es importante que la anchura de las barras escale también con la variable y para que el área del cuadrado transmita la masa de la población.

Así que, pregunta en dos partes realmente (aunque creo que está mal visto)

  1. ¿Cómo podría generar este gráfico en R con los datos proporcionados? Generalmente uso ggplot2, pero no estoy acostumbrado. Intenté usar geom_bar y tratar de establecer el ancho, pero no logré generar nada ni siquiera un poco funcional.

  2. ¿Tienes una idea mejor de cómo visualizar la afirmación que estoy haciendo, o estás en desacuerdo con la afirmación por completo?

9voto

Sven Hohenstein Puntos 3188

Este tipo de gráfico puede generarse con geom_rect .

Sus datos:

names <- read.csv("http://samswift.org/files/app_c.csv")
sum50 <- tapply(names$count, (seq_along(names$count)-1) %/% 50, sum)

En primer lugar, necesitamos variables adicionales:

La suma acumulada:

cum <- rev(cumsum(rev(sum50)))

Poner todo en un marco de datos. Las variables start y stop indican dónde deben empezar y terminar los rectángulos, respectivamente:

data <- data.frame(sum = sum50,
                   names = paste(as.numeric(names(sum50)) * 50 + 1,
                                 as.numeric(names(sum50)) * 50 + 50, sep = "-"),
                   start = c(cum[-1], 0),
                   stop = cum, stringsAsFactors = FALSE)
data$names[nrow(data)] <- paste(as.numeric(names(sum50)[length(sum50)]) * 50 + 1,
                                as.numeric(names(sum50)[length(sum50)]) * 50 + 
                                                          nrow(names) %% 50, sep = "-")

La variable center es el centro entre la posición de inicio y la de parada:

data$center <- (data$stop - data$start)/2 + data$start

Para este ejemplo, utilizo las cinco primeras filas:

data <- data[1:5, ]

Trama:

library(ggplot2)

ggplot(data, aes(xmin = start, xmax = stop, ymin = 0, ymax = sum)) +
  geom_rect(fill = NA, colour = "black") +
  scale_x_reverse("bin", breaks = data$center, labels = data$names) +
  coord_equal() # because we want squares

enter image description here


Esta es la versión basada en el conjunto de datos completo. Debería considerar el uso de sólo un subconjunto de etiquetas del eje x.

enter image description here

i-Ciencias.com

I-Ciencias es una comunidad de estudiantes y amantes de la ciencia en la que puedes resolver tus problemas y dudas.
Puedes consultar las preguntas de otros usuarios, hacer tus propias preguntas o resolver las de los demás.

Powered by:

X