En los siguientes ejercicios que vamos a realizar espero les sirva de mucha ayuda, son unos ejercicios muy sencillos los cuales te van ayudar a y espero te siva de mucho en R.
Vamos a tratar sobre los graficos 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 de 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))
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))
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,
main = "Frequencia absoluta",
col = rainbow(3))
lines(barp, c(5, 4, 12), type = "o", lwd = 3)
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)
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)
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
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"))
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
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))
El vector space representa el espacio de la barra respecto a la anterior, por lo que el primer elemento no se trendrá 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"))
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 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
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
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"))
De manera equivalente, se puede lograr el diagrama anterior con la función legend de la siguiente manera, 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
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))
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
Nótese 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
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)))
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))
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)
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")
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)
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 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)
## Warning: package 'ggplot2' was built under R version 4.1.3
##
## Attaching package: 'ggplot2'
## The following object is masked from 'mtcars':
##
## mpg
df <- as.data.frame(mi_tabla)
ggplot(data = df, aes(x = cyl, y = Freq)) +
geom_bar(stat = "identity")
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
Histograma en
¿Cómo hacer un histograma en R? La función hist
Para explicar los pasos para crear un histograma en R, vamos a utilizar los siguientes datos, que representan las distancia (en yardas) que recorre una pelota de golf después de ser golpeada.
distancia <- c(241.1, 284.4, 220.2, 272.4, 271.1, 268.3,
291.6, 241.6, 286.1, 285.9, 259.6, 299.6,
253.1, 239.6, 277.8, 263.8, 267.2, 272.6,
283.4, 234.5, 260.4, 264.2, 295.1, 276.4,
263.1, 251.4, 264.0, 269.2, 281.0, 283.2)
Puedes dibujar un histograma en R con la función hist. Por defecto, la función creará un histograma de frecuencias.
hist(distancia, main = "Histograma de frecuencias", # Frecuencia
ylab = "Frecuencia")
Sin embargo, si estableces el argumento prob como TRUE, obtendrás un histograma de densidad.
hist(distancia, prob = TRUE, main = "Histograma de densidad", # Densidad
ylab = "Densidad")
Además, puedes añadir un grid al histograma con la función grid de la siguiente manera.
hist(distancia, prob = TRUE, ylab = "Densidad", main = "Grid")
grid(nx = NA, ny = NULL, lty = 2, col = "gray", lwd = 1)
hist(distancia, prob = TRUE, add = TRUE, col = "white")
Ten en cuenta que hay que dibujar dos veces el histograma para que el grid salga por debajo de las barras en lugar de por encima.
Desde R 4.0.0 los histogramas son grises por defecto, no blancos.
Cambiar el color del histograma
Ahora que ya sabes crear un histograma en R, también puedes personalizarlo. Si quieres cambiar el color de las barras puede establecer el parámetro col al color que prefieras. Al igual que sucede con cualquier otro gráfico en R, puedes personalizar muchas características del gráfico, como el título, los ejes, el tamaño de fuente, la escala de los ejes, …
hist(distancia, main = "Cambiar color", ylab = "Frecuencia", col = "lightblue")
El argumento breaks
Los histogramas son muy útiles para representar la distribución subyacente de los datos si el número de barras o clases se selecciona correctamente. Sin embargo, la selección del número de barras (o el ancho de las barras) puede ser complicada:
1.Pocas clases agruparán demasiado las observaciones.
2.Con demasiadas clases habrá pocas observaciones en cada una de ellas aumentando la variabilidad del gráfico obtenido.
Hay varias reglas para determinar el número de barras. En R, el método de Sturges se usa por defecto. Si quieres cambiar el número de barras, pasa al argumento breaks el número de clases que quieras.
par(mfrow = c(1, 3))
hist(distancia, breaks = 2, main = "Pocas clases", ylab = "Frecuencia")
hist(distancia, breaks = 50, main = "Demasiadas clases", ylab = "Frecuencia")
hist(distancia, main = "Método de Sturges", ylab = "Frecuencia")
par(mfrow = c(1, 1))
También puedes usar el método plug-in (Wand, 1995) implementando en la librería KernSmooth para seleccionar el ancho de las barras del histograma:
# Método plug-in
# install.packages("KernSmooth")
library(KernSmooth)
## KernSmooth 2.23 loaded
## Copyright M. P. Wand 1997-2009
ancho_barras <- dpih(distancia)
nbarras <- seq(min(distancia) - ancho_barras,
max(distancia) + ancho_barras, by = ancho_barras)
hist(distancia, breaks = nbarras, main = "Plug-in", ylab = "Frecuencia")
Histograma en R con dos variables
Establecer el argumento add como TRUE permite añadir un histograma sobre otro gráfico. Como ejemplo, puedes crear un histograma en R por grupo con el código del siguiente bloque:
set.seed(1)
x <- rnorm(1000) # Primer grupo
y <- rnorm(1000, 1) # Segundo grupo
hist(x, main = "Dos variables", ylab = "Frecuencia")
hist(y, add = TRUE, col = rgb(1, 0, 0, alpha = 0.5))
La función rgb permite establecer colores en canal RGB. El argumento alpha determina la transparencia. De hecho, cuando se combinan gráficos es una buena idea añadir colores con transparencia para no ocultar las representaciones entre si.
Histograma con curva normal
Para dibujar una curva normal sobre un histograma, puede usar las funciones dnorm y lines de la siguiente manera:
hist(distancia, prob = TRUE,
main = "Histograma con curva normal", ylab = "Densidad")
x <- seq(min(distancia), max(distancia), length = 40)
f <- dnorm(x, mean = mean(distancia), sd = sd(distancia))
lines(x, f, col = "red", lwd = 2)
Añadir curva de densidad a un histograma en R
Para agregar una curva de densidad sobre un histograma, puedes usar la función lines para trazar la curva y la función density para calcular una estimación no paramétrica (tipo núcleo) de la distribución.
hist(distancia, freq = FALSE, main = "Curva densidad", ylab = "Densidad")
lines(density(distancia), lwd = 2, col = 'red')
La selección de ventana para ajustar las densidades no paramétricas es un área de intensa investigación. Además, ten en cuenta que por defecto, la función density usa un núcleo gaussiano. Para obtener más información, ejecuta ?density.
Vamos a unir los códigos anteriores dentro de una función para crear automáticamente un histograma con curvas normales y de densidad.
histDenNorm <- function (x, ...) {
hist(x, ...) # Histograma
lines(density(x), col = "blue", lwd = 2) # Densidad
x2 <- seq(min(x), max(x), length = 40)
f <- dnorm(x2, mean(x), sd(x))
lines(x2, f, col = "red", lwd = 2) # Normal
legend("topright", c("Histograma", "Densidad", "Normal"), box.lty = 0,
lty = 1, col = c("black", "blue", "red"), lwd = c(1, 2, 2))
}
Ahora puedes verificar el comportamiento de la función anterior con datos de muestra.
set.seed(1)
# Datos normales
x <- rnorm(n = 5000, mean = 110, sd = 5)
# Datos exponenciales
y <- rexp(n = 3000, rate = 1)
par(mfcol = c(1, 2))
histDenNorm(x, prob = TRUE, main = "Histograma de X")
histDenNorm(y, prob = TRUE, main = "Histograma de Y")
par(mfcol = c(1, 1))
Histograma y boxplot en R
Se puede agregar un diagrama de caja sobre un histograma escribiendo par(new = TRUE) entre los códigos de los dos gráficos.
hist(distancia, probability = TRUE, ylab = "", main = "",
col = rgb(1, 0, 0, alpha = 0.5), axes = FALSE)
axis(1) # Añade el eje horizontal
par(new = TRUE)
boxplot(distancia, horizontal = TRUE, axes = FALSE,
lwd = 2, col = rgb(0, 0, 0, alpha = 0.2))
También puedes agregar la curva normal o de densidad a la gráfica anterior.
Histograma en R con ggplot2
Para crear un histograma con el paquete ggplot2, debes usar las funciones ggplot + geom_histogram y pasar los datos como data frame. En el argumento aes debes especificar el nombre de la variable del data frame.
# install.packages("ggplot2")
library(ggplot2)
ggplot(data.frame(distancia), aes(x = distancia)) +
geom_histogram(color = "gray", fill = "white")
## `stat_bin()` using `bins = 30`. Pick better value with `binwidth`.
Este gráfico devolverá un mensaje advirtiéndote de que el histograma se calculó utilizando 30 clases. Esto se debe a que, de manera predeterminada, ggplot no utiliza el método de Sturges.
Ahora vamos a calcular el número de barras con el método Sturges como lo hace la función hist y establecerlo con el argumento breaks. Ten en cuenta que también puedes establecer el argumento binwidth si lo prefieres.
# Calculando el número de barras como la función hist()
nbreaks <- pretty(range(distancia), n = nclass.Sturges(distancia),
min.n = 1)
ggplot(data.frame(distancia), aes(x = distancia)) +
geom_histogram(breaks = nbreaks, color = "gray", fill = "white")
Como puedes ver, el siguiente gráfico es igual al primer histograma.
En ggplot2 también puedes agregar la curva de densidad con la función geom_density. Además, si quieres rellenar el área debajo de la curva, puedes indicar en el argumento fill el color que prefieras y en el argumento alpha el grado de transparencia del color. Ten en cuenta que necesitas establecer un nuevo aes dentro del geom_histogram de la siguiente manera:
ggplot(data.frame(distancia), aes(x = distancia)) +
geom_histogram(aes(y = ..density..), breaks = nbreaks,
color = "gray", fill = "white") +
geom_density(fill = "black", alpha = 0.2)