Gráfico de barras en R

Usa la función barplot para crear gráficos de barras en R

Cuando una variable toma pocos valores, es común resumir la información con una tabla de frecuencias que se puede representar con un gráfico de barras en R. Este tipo de gráficos se suelen utilizar, por ejemplo, para representar precipitaciones y temperaturas (si añadimos una curva por encima), en lo que se conoce como climogramas. En este artículo vamos a explicar los conceptos básicos de la creación de diagramas de barras en R.

La función barplot() en R

Para crear un gráfico de barras en R, puedes usar la función de R base barplot. En este ejemplo, vamos a crear un diagrama de barras a partir de un data frame. Concretamente vamos a usar el conocido conjunto de datos mtcars.

En primer lugar, carga los datos y crea una tabla para la columna cyl con la función table.

# Cargamos los datos
data(mtcars)
attach(mtcars)

# Tabla de frecuencias
mi_tabla <- table(cyl)
mi_tabla
cyl
 4  6   8
11  7  14

Recuerda que para crear un diagrama de barras en R puedes usar la función barplot y establecer como parámetro la tabla creada anteriormente para mostrar la frecuencia absoluta de los datos.

Sin embargo, si prefieres un gráfico de barras con porcentajes en el eje vertical (la frecuencia relativa), puedes usar la función prop.table y multiplicar el resultado por 100 de la siguiente manera.

# Una fila, dos columnas
par(mfrow = c(1, 2))

# Gráfico de barras de frecuencia absoluta
barplot(mi_tabla, main = "Frequencia absoluta",
        col = rainbow(3))

# Gráfico de barras de frecuencia relativa
barplot(prop.table(mi_tabla) * 100, main = "Frequencia relativa (%)",
        col = rainbow(3))

par(mfrow = c(1, 1))

Frecuencias absolutas y relativas

Ten en cuenta que también puedes crear un diagrama de barras a partir de un factor con la función plot.

plot(factor(mtcars$cyl), col = rainbow(3))

Gráfico de barras con la función plot

Además, por una parte, podríamos agregar curvas sobre el gráfico de barras para representar otra variable, como sucede con la temperatura en el caso de los climogramas.

En este caso vamos a dibujar una línea sobre el gráfico que hemos hecho con nuestra tabla.

barp <- barplot(mi_tabla,                     # Guarda los valores de X que
                main = "Frequencia absoluta", # representan el centro de 
                col = rainbow(3))             # cada barra           
                                                         
lines(barp, c(5, 4, 12), type = "o", lwd = 3)

Añadir líneas para crear un climograma

Asignar un gráfico de barras a una variable almacenará los valores del eje correspondientes al centro de cada barra.

Por otra parte, también podríamos mostrar los números correspondientes a la altura de las barras con la función text de la siguiente manera:

barp <- barplot(mi_tabla, col = rainbow(3), ylim = c(0, 15))
text(barp, mi_tabla + 0.5, labels = mi_tabla)

Gráfico de barras con números representando la frecuencia de cada clase

Por último, podría resultar interesante añadir un grid debajo de las barras del gráfico con la función grid.

barp <- barplot(mi_tabla, col = rainbow(3), ylim = c(0, 15))
grid(nx = NA, ny = NULL, lwd = 1, lty = 1, col = "gray")
barplot(mi_tabla, col = rainbow(3), ylim = c(0, 15), add = TRUE)

Rejilla (grid) en un gráfico de barras en R

Título, etiquetas y colores del gráfico de barras

Al igual que otros gráficos, puedes especificar una amplia variedad de parámetros gráficos, como etiquetas de eje, un título o personalizar los ejes. En el bloque de código anterior personalizamos los colores del diagrama de barras con el parámetro col. Puedes establecer los colores que prefieras con un vector o usar la función rainbow con el número de barras como parámetro como lo hicimos nosotros o usar otras paletas de colores. También puedes cambiar el color del borde de las barras con el argumento border.

barplot(mi_tabla,                               # Datos
        main = "Gráfico de barras",             # Título
        xlab = "Número de cilindros",           # Etiqueta del eje X
        ylab = "Frecuencia",                    # Etiqueta del eje Y
        border = "black",                       # Color del borde de las barras
        col = c("darkgrey", "darkblue", "red")) # Color para cada barra

Gráfico de barras personalizado en R

Cambiar las etiquetas de cada grupo

La etiqueta de cada grupo se puede cambiar con el argumento names.arg. En nuestro ejemplo, los grupos están etiquetados con números, pero podemos cambiarlos escribiendo algo como lo siguiente:

barplot(mi_tabla, names.arg = c("cuatro", "seis", "ocho")) 

Cambiar las etiquetas de los grupos de un un barplot en R

Espacio y ancho de las barras

También se puede modificar el espacio entre barras o el ancho de las barras con los argumentos width y space. Para el espacio entre grupos consulta la sección correspondiente de este tutorial.

par(mfrow = c(1, 2))

# Ancho de las barras (por defecto: width = 1)
barplot(mi_tabla, main = "Cambiar el ancho de las barras",
        col = rainbow(3), width = c(0.4, 0.2, 1))

# Espacio entre las barras
barplot(mi_tabla, main = "Cambiar el espacio entre barras",
        col = rainbow(3), space = c(1, 1.1, 0.1))

par(mfrow = c(1, 1))

Cambiar el ancho o el espacio entre las barras de un barchart en R

El vector space representa el espacio de la barra respecto a la anterior, por lo que el primer elemento no se tendrá en cuenta.

Gráfico de barras a partir de una lista o un data frame

Además, puedes crear un diagrama de barras directamente con las variables de un data frame o incluso una matriz, pero ten en cuenta que la variable debe ser el recuento de algún evento o característica.

En el siguiente ejemplo, contamos el número de vehículos por color y los dibujamos con un gráfico de barras. Usaremos cada color de los coches para colorear las barras correspondientes.

df <- data.frame(ColorCoche = c("rojo", "verde", "blanco", "azul"),
                 num = c(3, 5, 9, 1))
# df <- as.list(df) # Equivalente

barplot(height = df$num, names = df$ColorCoche,
        col = c("red", "green", "white", "blue"))

Barchart a partir de una lista o data frame

Gráfico de barras de una variable continua

En caso de que estés trabajando con una variable continua, deberás usar la función cut para clasificar los datos. De lo contrario, en caso de ausencia de empates, tendrás tantas barras como la longitud del vector y las alturas de las barras serán iguales a 1.

En el siguiente ejemplo, dividiremos nuestros datos de 0 a 45 en pasos de 5 con el argumento breaks.

x <- c(2.1, 8.6, 3.9, 4.4, 4.0, 3.7, 7.6, 3.1, 5.0, 5.5, 20.2, 1.7,
       5.2, 33.7, 9.1, 1.6, 3.1, 5.6, 16.5, 15.8, 5.8, 6.8, 3.3, 40.6)

barplot(table(cut(x, breaks = seq(0, 45, by = 5))))

Gráfico barras en R a partir de una variable continua

Gráfico de barras horizontal en R

Por defecto, los gráficos de barras en R se dibujan verticalmente. Sin embargo, es común representar gráficos de barras horizontales. Puedes rotar 90º el gráfico y crear un gráfico de barras horizontales estableciendo el argumento horiz como TRUE.

barplot(mi_tabla, main = "Gráfico de barras horizontal",
        ylab = "Número de cilindros", xlab = "Frecuencia",
        horiz = TRUE) # Gráfico de barras horizontal

Gráfico de barras horizontal en R con la función barplot

Leyenda del gráfico de barras

Se puede agregar una leyenda a un diagrama de barras en R con el argumento legend.text, donde puedes especificar los nombres que quieres agregar a la leyenda. Ten en cuenta que en RStudio la gráfica resultante puede ser ligeramente diferente, ya que por ejemplo el fondo de la leyenda será blanco en lugar de transparente.

barplot(mi_tabla, xlab = "Número de cilindros",
        col = rainbow(3),
        legend.text = rownames(mi_tabla)) # Leyenda

Añadir leyenda a un gráfico de barras en R con el argumento legend.text

Nótese que, al usar el argumento legend.text, la leyenda puede superponerse al diagrama de barras.

El método más fácil para resolver este problema en este ejemplo es mover la leyenda a la izquierda. Esto se puede lograr con el argumento args.legend, donde puedes establecer parámetros gráficos dentro de una lista. Puedes establecer la posición en top, bottom, topleft, topright, bottomleft y bottomright.

barplot(mi_tabla, xlab = "Número de cilindros",
        col = rainbow(3),
        legend.text = rownames(mi_tabla),
        args.legend = list(x = "top"))

Cambiar posición a la leyenda del diagrama de barras en R

De manera equivalente, se puede lograr el diagrama anterior con la función legend como se muestra en el ejemplo siguiente, con los argumentos legend y fill.

barplot(mi_tabla, xlab = "Número de cilindros",
        col = rainbow(3))
legend("top", legend = rownames(mi_tabla), fill = rainbow(3))

Sin embargo, este enfoque solo funciona bien si la leyenda no se superpone a las barras en esas posiciones. Un mejor enfoque es mover la leyenda a la derecha, fuera del gráfico de barras. Puedes hacer esto configurando el argumento inset dentro de una lista pasada como parámetro al argumento args.legend de la siguiente manera.

par(mar = c(5, 5, 4, 10))
barplot(mi_tabla, xlab = "Número de cilindros",
        col = rainbow(3),
        legend.text = rownames(mi_tabla), # Valores de la leyenda
        args.legend = list(x = "topright", inset = c(-0.20, 0))) # Argumentos de la leyenda

Añadir leyenda a un gráfico de barras sin superponerse

También podrías cambiar los límites de los ejes con los argumentos xlim e ylim para gráficos horizontales y verticales, respectivamente, pero ten en cuenta que en este caso el valor que pases dependerá del número y del ancho de las barras. Recuerda que si asignas un barplot a una variable puedes conocer los puntos del eje X que representan el centro de cada barra.

barplot(mi_tabla, xlab = "Número de cilindos",
        col = rainbow(3),
        legend.text = rownames(mi_tabla), xlim = c(0, 4.25))

Otra alternativa para mover la leyenda es ponerla debajo del gráfico de barras con las funciones layout, par y plot.new. Este enfoque es más avanzado que los otros y es posible que debas borrar los parámetros gráficos antes de la ejecución del código para obtener la gráfica correcta, ya que éstos se cambiarán.

# dev.off()
# opar <- par(no.readonly = TRUE)
plot.new()
layout(rbind(1, 2), heights = c(10, 3))
barplot(mi_tabla, xlab = "Número de cilindros",
        col = rainbow(3))

par(mar = c(0, 0, 0, 0))
plot.new()
legend("top", rownames(mi_tabla), lty = 1,
       col = c("red", "green", "blue"), lwd = c(1, 2))
# dev.off()
# on.exit(par(opar))

Agregar leyenda debajo de un gráfico de barras en R

Gráfico de barras agrupadas en R

Una gráfica de barras agrupadas es una gráfica de barras en R con dos o más variables. El gráfico mostrará las barras para cada una de las múltiples variables.

# Convertimos la variable 'am' en factor
am <- factor(am)

# Cambiamos los niveles del factor
levels(am) <- c("Automatica", "Manual")

# Tabla cilindros - tipo de transmisión
tabla_variables <- table(cyl, am)
# tabla_variables <- xtabs(~cyl + am , data = mtcars) # Equivalente

barplot(tabla_variables,
        main = "Gráfico de barras agrupado",
        xlab = "Tipo de transmisión", ylab = "Frecuencia",
        col = c("darkgrey", "darkblue", "red"),
        legend.text = rownames(tabla_variables),
        beside = TRUE) # Barras agrupadas

Crear gráfico de barras por grupos en R

Ten en cuenta que si hubiéramos especificado table(am, cyl) en lugar de table(cyl, am), el eje X representaría el número de cilindros, por lo que habría tres grupos con dos barras cada uno.

Espacio entre grupos

Como revisamos anteriormente, se puede cambiar el espacio entre barras. En el caso de varios grupos, puedes establecer un vector de dos elementos donde el primer elemento es el espacio entre barras de cada grupo (0.4) y el segundo el espacio entre grupos (2.5).

barplot(tabla_variables,
        main = "Espacio entre grupos",
        xlab = "Tipo de transmisión", ylab = "Frecuencia",
        col = c("darkgrey", "darkblue", "red"),
        legend.text = rownames(tabla_variables),
        beside = TRUE,
        space = c(0.4, 2.5)) # Espacio

Cambiar el espacio entre grupos de un barplot

Valores numéricos en grupos

Los gráficos de barras también se pueden usar para resumir una variable en grupos dados por uno o varios factores.

Supón que quieres mostrar la cantidad de cilindros y el tipo de transmisión en función de la potencia media de los automóviles. Puedes utilizar la función tapply para crear la tabla correspondiente:

resumen_datos <- tapply(mtcars$hp, list(cilindros = mtcars$cyl,
                                        transmision = am),
                        FUN = mean, na.rm = TRUE)
resumen_datos
                transmision
cilindros  Automatica   Manual
        4   84.66667   81.8750
        6  115.25000  131.6667
        8  194.16667  299.5000

Ahora puedes crear el diagrama de barras correspondiente en R:

par(mar = c(5, 5, 4, 10))

barplot(resumen_datos, xlab = "Tipo de transmisión",
        main = "Media CV",
        col = rainbow(3),
        beside = TRUE,
        legend.text = rownames(resumen_datos),
        args.legend = list(title = "Cilindros", x = "topright",
                           inset = c(-0.20, 0)))

Resumen numérico por grupo

Gráfico de barras en R con barras de error

Por defecto, no puedes crear un diagrama de barras con barras de error. Sin embargo, la siguiente función te permitirá crear un diagrama de barras totalmente personalizable con barras de error estándar:

# Argumentos:
# x: un único factor
# y: un vector numérico
# ...: argumentos adicionales para ser pasados a la función barplot

barplot.error <- function(x, y, ...) {
    mod <- lm(y ~ x)
    reps <- sqrt(length(y)/length(levels(x)))
    sem <- sigma(mod)/reps
    means <- tapply(y, x, mean)
    upper <- max(means) + sem
    lev <- levels(x)
    barpl <- barplot(means, ...)
    invisible(sapply(1:length(barpl), function(i) arrows(barpl[i], means[i] + sem,
              barpl[i], means[i] - sem, angle = 90, code = 3, length = 0.08)))
}

# Llamamos a la función
barplot.error(factor(mtcars$cyl), mtcars$hp, col = rainbow(3), ylim = c(0, 250))

Añadir barras de error

Aunque puedes agregar barras de error a un diagrama de barras en R, cabe destacar que un diagrama de caja por grupo podría ser un mejor enfoque para resumir los datos en este escenario.

Gráfico de barras apiladas en R

Un gráfico de barras apiladas es como un diagrama de barras agrupado, pero la frecuencia de las variables está apilada. Este tipo de diagrama de barras se creará de forma predeterminada al pasar como argumento una tabla con dos o más variables, ya que el argumento beside por defecto es FALSE.

barplot(tabla_variables,
        main = "Gráfico de barras apilado",
        xlab = "Tipo de transmisión", ylab = "Frecuencia",
        col = c("darkgrey", "darkblue", "red"),
        legend.text = rownames(tabla_variables),
        beside = FALSE) # Barras apiladas (opción por defecto)

Barras apiladas en R

Relacionado con los gráficos de barras apiladas, existen implementaciones similares, como el diagrama de espinas o spineplot y el gráfico de mosaico o mosaicplot. Este tipo de gráficos se pueden crear con las funciones spineplot y mosaicplot del paquete graphics.

El diagrama de tipo mosaico permite visualizar datos de dos o más variables cuantitativas, donde el área de cada rectángulo representa la proporción de esa variable en cada grupo.

# install.packages("graphics")
library(graphics)

mosaicplot(tabla_variables, main = "Mosaico")

Gráfico de mosaico en R

El diagrama de espina es un caso especial de un diagrama de mosaico y es una generalización del diagrama de barras apilado. En este caso, a diferencia de los gráficos de barras apiladas, cada barra suma uno.

spineplot(tabla_variables)

Gráfico de espina en R

Ten cuenta que, por defecto, los ejes se intercambian con respecto al diagrama de barras apiladas que creamos en la sección anterior. Puedes crear el gráfico equivalente transponiendo la tabla de frecuencias con la función t.

spineplot(t(tabla_variables))

Gráfico de espinas vertical

Gráfico de barras en R con ggplot2

El paquete ggplot2 es una biblioteca gráfica de R muy conocida. Puedes crear un diagrama de barras con esta biblioteca convirtiendo los datos en data frame y usando las funciones ggplot y geom_bar. En el argumento aes debes pasar los nombres de las variables del data frame, en x la variable categórica y en y la numérica.

# install.packages("ggplot2")
library(ggplot2)

df <- as.data.frame(mi_tabla)

ggplot(data = df, aes(x = cyl, y = Freq)) +
       geom_bar(stat = "identity")

Crear diagrama de barras en R con ggplot2

Gráfico de barras horizontal en ggplot2

En caso de que quieras rotar el diagrama de barras anterior, puedes usar la función coord_flip de la siguiente manera:

ggplot(data = df, aes(x = cyl, y = Freq)) +
       geom_bar(stat = "identity") +
       coord_flip() # Barras horizontales

Crear gráfico de barras horizontal con ggplot2