Jornada de Iniciación Científica - Centro Regional de Chiriquí


Tema 2: Gráficos en R - Gráfico de Barras


En este tema veremos el uso del paquete ggplot el cual permite definir gráficos de forma eficiente, elegante y sencilla.
En comparación con los otros gráficos, ggplot2:
• Es más detallado para los gráficos simples.
• Es menos detallado para gráficos complejos o personalizados.
• Los datos deben estar en un objeto tipo data.frame.
• Utiliza un sistema diferente para agregar elementos en diferentes capas ya que utiliza geometría de gráficos.


¿Cuál es la gramática de los gráficos?
El paquete ggplot2 se basa en la gramática de los gráficos (Wilkinson, 2005) y eso reporta varias ventajas respecto a otros gráficos como una estética muy buena o la simplificación en los comandos de gráficos complejos.
Aunque también presenta algunas limitaciones ya que no se pueden realizar gráficos tridimensionales o interactivos.
La idea básica: especificar de forma independiente los bloques de construcción y combinarlos para crear prácticamente cualquier tipo de visualización gráfica que se desee.
Los bloques de construcción de un gráfico incluyen:
• Datos
• Mapeo estético
• Objeto geométrico
• Transformaciones estadísticas
• Escalas
• Sistema de coordenadas
• Ajustes de posición
• Aspecto

#cargar librerias ggplot
#-----------------------------------------
library(ggplot2)

# leer datos de titanic
titanic <- read.csv("titanic.csv")

Significado de las variables del dataframe titanic

survival - Survival (0 = No; 1 = Yes)
class - Passenger Class (1 = 1st; 2 = 2nd; 3 = 3rd)
name - Name
sex - Sex
age - Age
sibsp - Number of Siblings/Spouses Aboard
parch - Number of Parents/Children Aboard
ticket - Ticket Number
fare - Passenger Fare
cabin - Cabin
embarked - Port of Embarkation (C = Cherbourg; Q = Queenstown; S = Southampton)
boat - Lifeboat (if survived)
body - Body number (if did not survive and body was recovered)

Funciones básicas en R para conocer estructura y datos de dataframe

# tipo de objeto de datos
class(titanic)
## [1] "data.frame"
# mostrar los 10 primeros registros del dataFrame
head(titanic)
# mostrar los 5 primeros registros del dataFrame
head(titanic,5)
# Mostrar la estructura del dataFrame y los tipos de datos
str(titanic)
## 'data.frame':    1309 obs. of  14 variables:
##  $ Pclass   : int  1 1 1 1 1 1 1 1 1 1 ...
##  $ Survived : int  1 1 0 0 0 1 1 0 1 0 ...
##  $ Name     : chr  "Allen, Miss. Elisabeth Walton" "Allison, Master. Hudson Trevor" "Allison, Miss. Helen Loraine" "Allison, Mr. Hudson Joshua Creighton" ...
##  $ Sex      : chr  "female" "male" "female" "male" ...
##  $ Age      : num  29 0.917 2 30 25 ...
##  $ Sibsp    : int  0 1 1 1 1 0 1 0 2 0 ...
##  $ Parch    : int  0 2 2 2 2 0 0 0 0 0 ...
##  $ Ticket   : chr  "24160" "113781" "113781" "113781" ...
##  $ Fare     : num  211 152 152 152 152 ...
##  $ Cabin    : chr  "B5" "C22 C26" "C22 C26" "C22 C26" ...
##  $ Embarked : chr  "S" "S" "S" "S" ...
##  $ Boat     : chr  "2" "11" "" "" ...
##  $ body     : int  NA NA NA 135 NA NA NA NA NA 22 ...
##  $ home.dest: chr  "St Louis, MO" "Montreal, PQ / Chesterville, ON" "Montreal, PQ / Chesterville, ON" "Montreal, PQ / Chesterville, ON" ...
#contar el numero de filas del dataFrame
nrow(titanic)
## [1] 1309
#numero de columnas del dataFrame
ncol(titanic)
## [1] 14
#nombre de los atributos o columnas
names(titanic)
##  [1] "Pclass"    "Survived"  "Name"      "Sex"       "Age"       "Sibsp"    
##  [7] "Parch"     "Ticket"    "Fare"      "Cabin"     "Embarked"  "Boat"     
## [13] "body"      "home.dest"
#resumen de los datos del dataFrame
# muestra los tipos de datos, caracteres, numericos, datos vacios
summary(titanic)
##      Pclass         Survived         Name               Sex           
##  Min.   :1.000   Min.   :0.000   Length:1309        Length:1309       
##  1st Qu.:2.000   1st Qu.:0.000   Class :character   Class :character  
##  Median :3.000   Median :0.000   Mode  :character   Mode  :character  
##  Mean   :2.295   Mean   :0.382                                        
##  3rd Qu.:3.000   3rd Qu.:1.000                                        
##  Max.   :3.000   Max.   :1.000                                        
##                                                                       
##       Age              Sibsp            Parch          Ticket         
##  Min.   : 0.1667   Min.   :0.0000   Min.   :0.000   Length:1309       
##  1st Qu.:21.0000   1st Qu.:0.0000   1st Qu.:0.000   Class :character  
##  Median :28.0000   Median :0.0000   Median :0.000   Mode  :character  
##  Mean   :29.8811   Mean   :0.4989   Mean   :0.385                     
##  3rd Qu.:39.0000   3rd Qu.:1.0000   3rd Qu.:0.000                     
##  Max.   :80.0000   Max.   :8.0000   Max.   :9.000                     
##  NA's   :263                                                          
##       Fare            Cabin             Embarked             Boat          
##  Min.   :  0.000   Length:1309        Length:1309        Length:1309       
##  1st Qu.:  7.896   Class :character   Class :character   Class :character  
##  Median : 14.454   Mode  :character   Mode  :character   Mode  :character  
##  Mean   : 33.295                                                           
##  3rd Qu.: 31.275                                                           
##  Max.   :512.329                                                           
##  NA's   :1                                                                 
##       body        home.dest        
##  Min.   :  1.0   Length:1309       
##  1st Qu.: 72.0   Class :character  
##  Median :155.0   Mode  :character  
##  Mean   :160.8                     
##  3rd Qu.:256.0                     
##  Max.   :328.0                     
##  NA's   :1188

Estructura del paquete ggplot

# Crear el area del gráfico
ggplot()

# Incluir datos del dataFrame Titanic
ggplot(data = titanic)

#Añadir capa aes con (mapeos esteticos) dos ejes X / y
ggplot(data = titanic, mapping = aes(x=Sex))

#Añadir capa de geometria del tipo de gráfico, en este ejemplo una geometría de barra
ggplot(data = titanic, mapping = aes(x=Sex))+
  geom_bar()

Grafico de barra

Conocido como gráfico de barras o gráfico de columnas.

El gráfico de barras clásico utiliza barras horizontales o verticales (gráfico de columnas) para mostrar comparaciones numéricas discretas entre categorías. Un eje del gráfico muestra las categorías específicas que se están comparando y el otro eje representa una escala de valores discretos.

Gráfico con una variable categorica

#Gráfico de pasajeros por sexo (Femenino, Masculino)
ggplot(data = titanic, aes(x=Sex)) +
  geom_bar()

#Gráfico de pasajeros por puerta de embarque (C, Q, S)
ggplot(data = titanic, aes(x=Embarked)) +
  geom_bar()

#Gráfico de pasajeros por clase (1,2,3)
ggplot(titanic, aes(Pclass)) +
  geom_bar()

Gráfico con una variable cuantitativa, discreta o continua

Este tipo de gráfico no es recomendable para mostrar solo variable cuantitativas, mucho menos cuantitativas continuas como la columna “Fare” del data.frame titanic. Aqui mostramos el resultado de su uso de la variable FARE el cual no muestra ningun resultado en la gráfica.

# Pasajeros por Edad (variable continua)
ggplot(titanic, aes(Age)) +
  geom_bar()
## Warning: Removed 263 rows containing non-finite values (stat_count).

#pasajeros por tarifa (variable discreta)
ggplot(titanic, aes(Fare)) +
  geom_bar()
## Warning: Removed 1 rows containing non-finite values (stat_count).


Gráfico con dos variables categoricas

Se utilizan las variables Sex y Pclass, ambas variables categoricas. Al utilizar 2 variables categorias la geometria geom_bar() utiliza de forma predeterminada la estética geom_bar(“stat= count”) aunque no se coloca. Esto envia un error ya que la geometria no puede contar las filas de dos variable a la vez.
Para que este tipo de gráfico funcione entonces se debe utilizar en la geom_bar(stat=‘identity’), para que ggplot no cuente las filas por cada variable.

Estos dos ejemplos enviarian un error.
ggplot(titanic, aes(Sex,Pclass)) +
geom_bar()

Error: stat_count() can only have an x or y aesthetic.

ggplot(titanic, aes(Sex,Pclass)) +
geom_bar(stat= ‘count’)

Esto como si en la geometria colocaramos el valor “stat= count” aunque tambien envia
Error: stat_count() can only have an x or y aesthetic.

# Se debe utilizar el valor stat='identity' en la geometria 
# Gráfico con las variables Sex, Pclass
ggplot(titanic, aes(Sex,Pclass)) +
  geom_bar(stat='identity')

# Gráfico con las variables  Pclass, Sex
ggplot(titanic, aes(Pclass,Sex)) +
  geom_bar(stat='identity')

Analisis de los dos graficos anteriores (Sex / Pclass)

Si evaluamos el tamaño de las barras en ambos gráficos, la barra FEMALE muestra aproximadamente 1000 pasajeros y la barra MALE aproximadamente 2000 pasajeros, si sumamos el número de pasajeros de ambas barras el total sería 3000, este dato no es correcto, ya que el total de pasajeros del dataFrame titanic es 1309.

¿Cómo podemos verificar que los datos mostrados en un gráfico son correctos y lógicos?

Podemos utilizar tablas de contingencias con variables categóricas.

¿Cuáles son las variables categóricas del dataFrame Titanic?

Podemos utilizar la función str(), que muestra los datos y sus tipos. Una forma de identificar un dato categórico es que sus datos se repiten muchas veces de forma tal que pareciera que pertencen a un grupo.
Ejemplo:
Sex
Pclass
Survived

#Es necesario mostrar la estructura de la tabla para identificar los datos categoricos
str(titanic)
## 'data.frame':    1309 obs. of  14 variables:
##  $ Pclass   : int  1 1 1 1 1 1 1 1 1 1 ...
##  $ Survived : int  1 1 0 0 0 1 1 0 1 0 ...
##  $ Name     : chr  "Allen, Miss. Elisabeth Walton" "Allison, Master. Hudson Trevor" "Allison, Miss. Helen Loraine" "Allison, Mr. Hudson Joshua Creighton" ...
##  $ Sex      : chr  "female" "male" "female" "male" ...
##  $ Age      : num  29 0.917 2 30 25 ...
##  $ Sibsp    : int  0 1 1 1 1 0 1 0 2 0 ...
##  $ Parch    : int  0 2 2 2 2 0 0 0 0 0 ...
##  $ Ticket   : chr  "24160" "113781" "113781" "113781" ...
##  $ Fare     : num  211 152 152 152 152 ...
##  $ Cabin    : chr  "B5" "C22 C26" "C22 C26" "C22 C26" ...
##  $ Embarked : chr  "S" "S" "S" "S" ...
##  $ Boat     : chr  "2" "11" "" "" ...
##  $ body     : int  NA NA NA 135 NA NA NA NA NA 22 ...
##  $ home.dest: chr  "St Louis, MO" "Montreal, PQ / Chesterville, ON" "Montreal, PQ / Chesterville, ON" "Montreal, PQ / Chesterville, ON" ...

¿Qué es una tabla de contingencia?

Son tabla generadas a partir del dataFrame con datos completos (data = titanic) y utilizadas para organizar y resumir datos, especialmente con variables categóricas, las cuales nos pueden ayudar a verificar datos del gráfico.

# Identificar el número de pasajeros por sexo
table(titanic$Sex)
## 
## female   male 
##    466    843
# Identificar el número de pasajeros pasajeros por clase y sexo
table(titanic$Pclass,titanic$Sex)
##    
##     female male
##   1    144  179
##   2    106  171
##   3    216  493

Gráfico de dos variables categoricas, una de ellas agrupa los datos por la estetica de color (SEX)

# 
ggplot(titanic, aes(Pclass, fill=as.factor(Sex))) +
  geom_bar()


Tambien se puede utilizar la estética de color en la geometria con la variable categorica SEX.

ggplot(titanic, aes(Pclass)) +
  geom_bar(aes(fill=as.factor(Sex)))

Gráfico de barras una al lado de la otra utilizando dos variables categóricas.

# grafico de dos variables categoricas agrupadas por color 
ggplot(titanic, aes(Pclass,fill=as.factor(Sex))) +
  geom_bar(position = "dodge")

Añadir nuevas capas al gráfico de barra

Modificar el encabezado de la leyenda del grupo.

ggplot(titanic, aes(Pclass, fill=as.factor(Sex))) +
  geom_bar() +
  guides(fill = guide_legend("Sexo")) 


Modificar las leyendas de los ejes x / y del gráfico.

ggplot(titanic, aes(Pclass, fill=as.factor(Sex))) +
  geom_bar() +
  guides(fill = guide_legend("Sexo")) +  #modificar leyenda
  ylab("N° Pasajeros") + xlab("Numero de Clase")


Insertar Titulo y subtitulo al gráfico.

ggplot(titanic, aes(Pclass, fill=as.factor(Sex))) +
  geom_bar() +
  guides(fill = guide_legend("Sexo")) +  #modificar leyenda
  ylab("N° Pasajeros") + xlab("Numero de Clase")+   # etiquetas x / y
  labs(title="Número de pasajeros por Clase",
       subtitle="Datos del Titanic - 1912") 


Incluir texto de pie de gráfico de la fuente con caption=.

ggplot(titanic, aes(Pclass, fill=as.factor(Sex))) +
  geom_bar() +
  guides(fill = guide_legend("Sexo")) +  #modificar leyenda
  ylab("N° Pasajeros") + xlab("Numero de Clase")+   # etiquetas x / y
  labs(title="Número de pasajeros por Clase",
       subtitle="Datos del Titanic - 1912", caption = "Fuente: www,gist.github.com/michhar/ - titanic.csv") 


Añadir etiquetas de datos. La variable ..count.., cuenta el númeo de filas, stat = ‘count’ es necesario para utilizar la variable count.

ggplot(titanic, aes(Pclass, fill=as.factor(Sex))) +
  geom_bar() +
  guides(fill = guide_legend("Sexo")) +  #modificar leyenda
  ylab("N° Pasajeros") + xlab("Numero de Clase")+   # etiquetas x / y
  labs(title="Número de pasajeros por Clase",
       subtitle="Datos del Titanic - 1912")  +
  geom_text(stat='count', aes(label=..count..))


Modificar la posición de las etiquetas de datos utilizando, position_stack(x,y).

ggplot(titanic, aes(Pclass, fill=as.factor(Sex))) +
  geom_bar() +
  guides(fill = guide_legend("Sexo")) +  #modificar leyenda
  ylab("N° Pasajeros") + xlab("Numero de Clase")+   # etiquetas x / y
  labs(title="Número de pasajeros por Clase",
       subtitle="Datos del Titanic - 1912")  +
  geom_text(position = position_stack(0.5, 0.0), stat='count', aes(label=..count..))


Gráfico de barras una al lado de la otra con dos variables categóricas agrupadas por color utilizando la estetica position = “dodge” .

# 
ggplot(titanic, aes(Pclass,fill=as.factor(Sex))) +
  geom_bar(position = "dodge")


Modificar la position de la leyenda utilizando position = position_dodge(1.0). El 1.0 permite colocar los datos al lado de cada barra.

ggplot(titanic, aes(Pclass, fill=as.factor(Sex))) +
  geom_bar(position = "dodge") +
  guides(fill = guide_legend("Sexo")) +  #modificar leyenda
  ylab("N° Pasajeros") + xlab("Numero de Clase")+   # etiquetas x / y
  labs(title="Número de pasajeros por Clase y Sexo",
       subtitle="Datos del Titanic - 1912")  +
  geom_text(position = position_dodge(1.0), stat='count', aes(label=..count..), vjust=-0.3, hjust=0.5)


Para girar un gráfico completo utilizamos una nueva capa con la función coord_flip().
Solo giran las barras y las etiquetas. Las etiquetas de datos se le debe modificar su posición con vjust y hjust.

ggplot(titanic, aes(Pclass, fill=as.factor(Sex))) +
  geom_bar(position = "dodge") +
  guides(fill = guide_legend("Sexo")) +  #modificar leyenda
  ylab("N° Pasajeros") + xlab("Numero de Clase")+   # etiquetas x / y
  labs(title="Número de pasajeros por Clase y Sexo",
       subtitle="Datos del Titanic - 1912")  +
  geom_text(position = position_dodge(1.0), stat='count', aes(label=..count..), vjust=0.3, hjust=1.5) +
  coord_flip()

Gráficos de barra de los sobrevivientes por sexo

ggplot(titanic, aes(Sex, fill=as.factor(Survived))) +
  geom_bar(position = "dodge") +
  guides(fill = guide_legend("Sobrevivientes")) +  #modificar leyenda
  ylab("N° Pasajeros") + xlab("Sexo")+   # etiquetas x / y
  labs(title="Número de pasajeros por sexo que sobrevivieron",
       subtitle="Datos del Titanic - 1912")  +
  geom_text(position = position_dodge(1.0), stat='count', aes(label=..count..), vjust=-0.3, hjust=0.5)

TIPS 1: Tabla de contingencia

Verificar datos del gráfico con una tabla de contigencia de las variables Sex y Survived utilizando la función table().
Muestra el total de fallecidos y sobrevivientes por sexo.
El número de sobrevivientes es de 500.

# datos de matrix de datos

table(titanic$Sex, titanic$Survived)
##         
##            0   1
##   female 127 339
##   male   682 161


Datos de sobreviviente por sexo en decimales y porcentaje. El porcentaje de sobrevivientes es del 38.2%.

#tabla de contingencia asignada a una variable 
matrix <-table(titanic$Sex, titanic$Survived)
matrix
##         
##            0   1
##   female 127 339
##   male   682 161
# datos en decimales utilizando función prop.table()
prop.table(matrix) 
##         
##                   0          1
##   female 0.09702063 0.25897632
##   male   0.52100840 0.12299465
# datos en porcentaje multiplicando por 100
prop.table(matrix)  *100
##         
##                  0         1
##   female  9.702063 25.897632
##   male   52.100840 12.299465
# datos de porcentaje redondeados utilizando función round()
porcentaje <- round(prop.table(matrix)  *100,1)
porcentaje
##         
##             0    1
##   female  9.7 25.9
##   male   52.1 12.3

¿Cual sería el número de sobrevivientes por sexo, según clase?

En este ejemplo, la pregunta esta relacionada a unir 3 variables categóricas, Survived, Sex y Pclass, sin embargo, solo se pueden utilizar dos variables categoricas para el grráfico de barras.
Lo que hacemos es integrar una nueva variable utilizando la capa de facetas facet_wrap(variable), para separar los gráficos de sobrevivientes por sexo.

ggplot(titanic, aes(Sex, fill=as.factor(Survived))) +
  geom_bar(position = "dodge") +
  guides(fill = guide_legend("Clase")) +  #modificar leyenda
  ylab("N° Pasajeros") + xlab("Sexo")+   # etiquetas x / y
  labs(title="Número de pasajeros por sexo que sobrevivieron según clase",
       subtitle="Datos del Titanic - 1912")  +
  geom_text(position = position_dodge(1.0), stat='count', aes(label=..count..), vjust=-0.3, hjust=0.5) +
  facet_wrap(~Pclass)

Verificar datos del gráfico con una tabla de contingenia

Utilizamos la función table con las tres variables categoricas.

table(titanic$Sex, titanic$Survived, titanic$Pclass)
## , ,  = 1
## 
##         
##            0   1
##   female   5 139
##   male   118  61
## 
## , ,  = 2
## 
##         
##            0   1
##   female  12  94
##   male   146  25
## 
## , ,  = 3
## 
##         
##            0   1
##   female 110 106
##   male   418  75


Aunque se pueden leer los datos de sobrevicientes por sexo según clase, es un poco complejo, por la forma en que se estructuran los datos.

TIPS 2: Tabla de contingencia avanzada - función ftable()

Para utilizar 3 o más variables en tablas de contingencia utilizamos la función ftable(). La forma de estructurar los resultados de las tabla de contingencia resulta más legible y ordenada, lo cual corresponde a los mismos datos del gráfico.

ftable(titanic$Sex, titanic$Survived, titanic$Pclass)
##             1   2   3
##                      
## female 0    5  12 110
##        1  139  94 106
## male   0  118 146 418
##        1   61  25  75
ggplot(titanic, aes(Sex, fill=as.factor(Survived))) +
  geom_bar(position = "dodge") +
  guides(fill = guide_legend("Clase")) +  
  ylab("N° Pasajeros") + xlab("Sexo")+   
  labs(title="Número de pasajeros por sexo que sobrevivieron según clase",
       subtitle="Datos del Titanic - 1912")  +
  geom_text(position = position_dodge(1.0), stat='count', aes(label=..count..), vjust=-0.3, hjust=0.5) +
  facet_wrap(~Pclass)

Análisis de los Gráficos con apoyo de las tablas de contingencias.

Según datos y gráfico de barra, de los 1309 pasajeros del Titanic, el 38.2% de los pasajeros sobrevivio, siendo 339 mujeres y 161 hombre. De los fallecidos el 52.1% eran hombres, 418 estaban en la clase 3. EL grupo de Primera clase fue el grupo con un mayor número de sobrevivientes con 136 y el de tercera clase el grupo con más fallecidos con 528 lo que corresponde al 40.3% de los pasajeros.



PRÁCTICA 1: ¿Cuál es el número de sobrevivientes por Clase?

Crear un gráfico de barra agrupadas por color.
Mostrar etiquetas de datos.

PRÁCTICA 2: ¿Cuál es el número de pasajeros por puerta de embarque y Sexo que sobrevivieron?

Crear un gráfico de barra una al lado de la otra agrupadas por color.
Mostrar etiquetas de datos.
Modifique las etiquetas de ejes X / Y. Coloque un título al gráfico.