Estoy tratando de hacer un gráfico de barras donde la barra más grande estaría más cerca del eje y y la barra más corta estaría más lejos. Así que esto es algo así como la tabla que tengo
Name Position
1 James Goalkeeper
2 Frank Goalkeeper
3 Jean Defense
4 Steve Defense
5 John Defense
6 Tim Striker
Así que estoy tratando de construir un gráfico de barras que muestre el número de jugadores según la posición.
p <- ggplot(theTable, aes(x = Position)) + geom_bar(binwidth = 1)
pero el gráfico muestra la barra del portero primero, luego la defensa, y finalmente la del delantero. Me gustaría que el gráfico se ordene de modo que la barra de defensa esté más cerca del eje y, la del portero y finalmente la del delantero. Gracias
ggplot2
, no el OPRespuestas:
La clave para ordenar es establecer los niveles del factor en el orden que desee. No se requiere un factor ordenado; la información adicional en un factor ordenado no es necesaria y si estos datos se están utilizando en algún modelo estadístico, podría producirse una parametrización incorrecta: los contrastes polinómicos no son adecuados para datos nominales como este.
En el sentido más general, simplemente necesitamos establecer los niveles de factores para que estén en el orden deseado. Si no se especifica, los niveles de un factor se ordenarán alfabéticamente. También puede especificar el orden de nivel dentro de la llamada al factor como se indicó anteriormente, y también son posibles otras formas.
fuente
within
, no hay necesidad de usartheTable$Position
, y podría hacerlosort(-table(...))
para disminuir el orden.-
que usa, ya que es mucho más fácil obtener la intención dedecreasing = TRUE
notar-
el resto del código.levels(theTable$Position) <- c(...)
conduce a un comportamiento no deseado donde las entradas reales del marco de datos se reordenan, y no solo los niveles del factor. Ver esta pregunta . ¿Tal vez deberías modificar o eliminar esas líneas?levels<-
. Voy a editar esa parte, al menos tentativamente.levels<-()
hoy. Esto es algo de hace 8 años y no puedo recordar si las cosas eran diferentes en ese momento o si simplemente estaba equivocado, pero de todos modos, ¡está mal y debería borrarse! ¡Gracias!@GavinSimpson:
reorder
es una solución poderosa y efectiva para esto:fuente
ggplot(theTable,aes(x=reorder(Position,Position,length))+geom_bar()
Utilizando
scale_x_discrete (limits = ...)
para especificar el orden de las barras.fuente
Creo que las soluciones ya proporcionadas son demasiado detalladas. Una forma más concisa de hacer un diagrama de barras ordenado por frecuencia con ggplot es
Es similar a lo que sugirió Alex Brown, pero un poco más corto y funciona sin una definición de función cualquiera.
Actualizar
Creo que mi solución anterior era buena en ese momento, pero hoy en día prefiero usar
forcats::fct_infreq
los niveles de factor de clasificación por frecuencia:fuente
Como
reorder()
en la respuesta de Alex Brown, también podríamos usarforcats::fct_reorder()
. Básicamente, ordenará los factores especificados en el primer argumento, de acuerdo con los valores en el segundo argumento después de aplicar una función específica (predeterminado = mediana, que es lo que usamos aquí ya que solo tenemos un valor por nivel de factor).Es una pena que en la pregunta del OP, el orden requerido también sea alfabético, ya que ese es el orden de clasificación predeterminado cuando crea factores, por lo que ocultará lo que esta función está haciendo realmente. Para que quede más claro, reemplazaré "Portero" con "Zoalkeeper".
fuente
Un simple reordenamiento de factores basado en dplyr puede resolver este problema:
fuente
Solo necesita especificar que la
Position
columna sea un factor ordenado donde los niveles están ordenados por sus cuentas:(Tenga en cuenta que
table(Position)
produce un conteo de frecuencia de laPosition
columna).Luego, su
ggplot
función mostrará las barras en orden decreciente de conteo. No sé si hay una opcióngeom_bar
para hacer esto sin tener que crear explícitamente un factor ordenado.fuente
reorder()
de que la biblioteca de estadísticas realiza la misma tarea.reorder()
en este caso? El factor que requiere reordenamiento necesita ser reordenado por alguna función de sí mismo y estoy luchando por ver una buena manera de hacerlo.with(theTable, reorder(Position, as.character(Position), function(x) sum(duplicated(x))))
es de una manera, y de otra,with(theTable, reorder(Position, as.character(Position), function(x) as.numeric(table(x))))
pero estos son igual de complicados ...sort
lugar deorder
reorder
es hábil para hacerlo. Estoy de acuerdo con esta pregunta de que se necesita algo más complicado. Perdón por la confusion.Además de forcats :: fct_infreq, mencionado por @HolgerBrandl, hay forcats :: fct_rev, que invierte el orden del factor.
fuente
Estoy de acuerdo con zach en que contar dentro de dplyr es la mejor solución. He encontrado que esta es la versión más corta:
Esto también será significativamente más rápido que reordenar los niveles de factor de antemano ya que el conteo se realiza en dplyr, no en ggplot o usando
table
.fuente
Si las columnas del gráfico provienen de una variable numérica como en el marco de datos a continuación, puede usar una solución más simple:
El signo menos antes de la variable de clasificación (-Qty) controla la dirección de clasificación (ascendente / descendente)
Aquí hay algunos datos para probar:
Cuando encontré este hilo, esa fue la respuesta que estaba buscando. Espero que sea útil para otros.
fuente
Otra alternativa usando reordenar para ordenar los niveles de un factor. En orden ascendente (n) o descendente (-n) según el recuento. Muy similar a la que utiliza
fct_reorder
desde elforcats
paquete:Orden descendiente
Orden ascendente
Marco de datos:
fuente
Como solo estamos viendo la distribución de una sola variable ("Posición") en lugar de mirar la relación entre dos variables , entonces quizás un histograma sería la gráfica más apropiada. ggplot tiene geom_histogram () que lo hace fácil:
Usando geom_histogram ():
Creo que geom_histogram ( ) es un poco peculiar ya que trata los datos continuos y discretos de manera diferente.
Para datos continuos , puede usar geom_histogram () sin parámetros. Por ejemplo, si agregamos un vector numérico "Puntaje" ...
y use geom_histogram () en la variable "Score" ...
Para datos discretos como "Posición" tenemos que especificar una estadística calculada calculada por la estética para dar el valor y para la altura de las barras usando
stat = "count"
:Nota: Curiosa y confusamente, también puede usar
stat = "count"
datos continuos y creo que proporciona un gráfico más estéticamente agradable.Ediciones : Respuesta extendida en respuesta a las útiles sugerencias de DebanjanB .
fuente
Me pareció muy molesto que
ggplot2
no ofrezca una solución 'automática' para esto. Por eso creé labar_chart()
función enggcharts
.Por defecto
bar_chart()
ordena las barras y muestra un diagrama horizontal. Para cambiar ese conjuntohorizontal = FALSE
. Además,bar_chart()
elimina el desagradable 'espacio' entre las barras y el eje.fuente