Introducción

“El gráfico simple ha traído más información a la mente del analista de datos que cualquier otro dispositivo”. — John Tukey

Para reconocer cómo es la estructura de los datos y dar una primera mirada a cómo es su comportamiento es necesario la Exploración de los Datos. Esto se realiza de manera numérica, calculando los estadígrafos y con la visualización de los datos a partir de los gráficos.

Primeros pasos

Luego de tratar las bases de datos, reconociendo su estructura, la existencia de datos faltantes, etc, podemos comenzar a realizar la descripción de la/s variable/s.

penguins <- read.csv("penguins_size.csv")
#View(penguins)
head(penguins, n=8)         #Muestra las 8 primeras filas de la tabla
  species    island culmen_length_mm culmen_depth_mm flipper_length_mm
1  Adelie Torgersen             39.1            18.7               181
2  Adelie Torgersen             39.5            17.4               186
3  Adelie Torgersen             40.3            18.0               195
4  Adelie Torgersen               NA              NA                NA
5  Adelie Torgersen             36.7            19.3               193
6  Adelie Torgersen             39.3            20.6               190
7  Adelie Torgersen             38.9            17.8               181
8  Adelie Torgersen             39.2            19.6               195
  body_mass_g    sex
1        3750   MALE
2        3800 FEMALE
3        3250 FEMALE
4          NA   <NA>
5        3450 FEMALE
6        3650   MALE
7        3625 FEMALE
8        4675   MALE
names(penguins); nrow(penguins)
[1] "species"           "island"            "culmen_length_mm" 
[4] "culmen_depth_mm"   "flipper_length_mm" "body_mass_g"      
[7] "sex"              
[1] 344
#Para eliminar las filas con NA
penguins = na.omit(penguins)
penguins$sex[penguins$sex=="."]="MALE"
penguins$species[penguins$species=="Adelie"]="adelia"
penguins$species[penguins$species=="Chinstrap"]="barbijo"
penguins$species[penguins$species=="Gentoo"]="papua"

Medidas de resumen

Una manera de verificar las características de las variables presentes es la base de datos podemos solicitar un resumen de las medidas de posición para cada una de ellas.

names(penguins);dim(penguins)
[1] "species"           "island"            "culmen_length_mm" 
[4] "culmen_depth_mm"   "flipper_length_mm" "body_mass_g"      
[7] "sex"              
[1] 334   7
m_posicion = summary(penguins) ; m_posicion
   species             island          culmen_length_mm culmen_depth_mm
 Length:334         Length:334         Min.   :32.10    Min.   :13.10  
 Class :character   Class :character   1st Qu.:39.50    1st Qu.:15.60  
 Mode  :character   Mode  :character   Median :44.50    Median :17.30  
                                       Mean   :43.99    Mean   :17.16  
                                       3rd Qu.:48.58    3rd Qu.:18.70  
                                       Max.   :59.60    Max.   :21.50  
 flipper_length_mm  body_mass_g       sex           
 Min.   :172       Min.   :2700   Length:334        
 1st Qu.:190       1st Qu.:3550   Class :character  
 Median :197       Median :4050   Mode  :character  
 Mean   :201       Mean   :4209                     
 3rd Qu.:213       3rd Qu.:4794                     
 Max.   :231       Max.   :6300                     

Al observar la salida podemos determinar qué tipo de variable es cada una y si está tomando todos los datos.

Respecto a la variabilidad, contamos con medidas como la varianza, la desviación estándart, el coeficiente de variación, etc. Para su cálculo:

var_CL=var(penguins$culmen_length_mm); var_CL
[1] 29.81729
DE_CL=sd(penguins$culmen_length_mm) #desviacion del largo de culmen
DE_CL
[1] 5.460521
CV_CL=DE_CL/mean(penguins$culmen_length_mm); CV_CL
[1] 0.1241188

Tabla de frecuencias

La tabla de distribución de frecuencias permite visualizar los datos de manera ordenada, de forma que su interpretación sea más rica. Además, es la base para la producción de gráficos. Ellos representan la información de la tabla y hace más fácil la interpretación a través de la observación directa.

Para realizar la tabla de frecuencias, se utiliza la función table del paquete base de R. En nuestro caso:

FA = table(penguins$species) ; FA

 adelia barbijo   papua 
    146      68     120 

Nota: Se pueden cambiar los nombres comunes de las especies por aquellos en lengua española: adelie es adelia, chinstrap por barbijo y gentoo por papua.

Sólo obtendremos las frecuencias absolutas para cada categoría. También nos interesan las frecuencias relativas, ya que nos permiten poder comparar muestras diferentes:

FR = prop.table(table(penguins$species)) ; FR

   adelia   barbijo     papua 
0.4371257 0.2035928 0.3592814 

Para la presentación de la tabla, podemos utilizar lo que ya vimos:

Tabla1 = cbind(FA,FR)
round(Tabla1,2)
         FA   FR
adelia  146 0.44
barbijo  68 0.20
papua   120 0.36
Tabla1=as.data.frame(Tabla1)
Tabla1
         FA        FR
adelia  146 0.4371257
barbijo  68 0.2035928
papua   120 0.3592814

Tabla de contingencia

Cuando tenemos que presentar las frecuencias de dos variables cualitativas:

Tabla2 <- table(penguins$species,penguins$sex)
Tabla2
         
          FEMALE MALE
  adelia      73   73
  barbijo     34   34
  papua       58   62
#crea tabla con recuento de casos

Tabla2 = addmargins(Tabla2)
Tabla2#agrega los totales marginales
         
          FEMALE MALE Sum
  adelia      73   73 146
  barbijo     34   34  68
  papua       58   62 120
  Sum        165  169 334

Variables cuantitativas

En el caso de que tengamos una gran cantidad de datos, podremos realizar la tabla de frecuencias de dos maneras: a) semiautomático y b)automático.

a) Semiautomático

Sabemos que existen diferentes métodos para calcular el número de intervalos, amplitudes, etc. Para construir los intervalos de clase podemos utilizar la regla de Sturges, que nos proporciona un número adecuado de intervalos en función del rango de los datos (ver help(nclass.Sturges); de modo alternativo podría utilizarse la regla de Scott o la de Freedman-Diaconis). Una vez que hemos decidido el número de intervalos, generamos una secuencia de valores con los límites de cada intervalo y utilizamos la función cut() para que nos construya una nueva variable que recodifica la variable en dichos intervalos. Tomaremos el caso de largo de culmen (mm)

range(penguins$culmen_length_mm, na.rm=TRUE)  #Al incluir el na.rm solicito que no se tengan en cuenta los NA
[1] 32.1 59.6
nclass.Sturges(penguins$culmen_length_mm)     #Número de intervalos
[1] 10
lim = seq(32.1,59.6,length=9)
round(lim,2)
[1] 32.10 35.54 38.98 42.41 45.85 49.29 52.73 56.16 59.60
# Construcción de los intervalos mediante la función cut():
inter_CL=cut(penguins$culmen_length_mm,breaks=seq(32.1,59.6,length=9),include.lowest=TRUE) 

Por último construimos la tabla de frecuencias de esta variable:

FA_CL = table(inter_CL)
FR_CL = prop.table(table(inter_CL))

Tabla3 = cbind(FA_CL,FR_CL)
round(Tabla3,2)
            FA_CL FR_CL
[32.1,35.5]    15  0.04
(35.5,39]      60  0.18
(39,42.4]      64  0.19
(42.4,45.9]    58  0.17
(45.9,49.3]    66  0.20
(49.3,52.7]    61  0.18
(52.7,56.2]     8  0.02
(56.2,59.6]     2  0.01
b)Automático
library(fdth)

Attaching package: 'fdth'
The following objects are masked from 'package:stats':

    sd, var
TF=fdt(penguins$culmen_length_mm,
       breaks="Sturges") # calcula la distribución de frecuencias utilizando la regla Sturges

TF$table
    Class limits  f          rf      rf(%)  cf     cf(%)
1  [31.78,34.62)  8 0.023952096  2.3952096   8   2.39521
2  [34.62,37.46) 38 0.113772455 11.3772455  46  13.77246
3   [37.46,40.3) 56 0.167664671 16.7664671 102  30.53892
4   [40.3,43.15) 48 0.143712575 14.3712575 150  44.91018
5  [43.15,45.99) 48 0.143712575 14.3712575 198  59.28144
6  [45.99,48.83) 57 0.170658683 17.0658683 255  76.34731
7  [48.83,51.67) 59 0.176646707 17.6646707 314  94.01198
8  [51.67,54.51) 15 0.044910180  4.4910180 329  98.50299
9  [54.51,57.35)  3 0.008982036  0.8982036 332  99.40120
10  [57.35,60.2)  2 0.005988024  0.5988024 334 100.00000

Esta función nos brinda una tabla con los calculos de la distribución de frecuencias. Donde: - f= frecuencia absoluta - rf= frecuencia relativa - rf(%) frecuencia relativa porcentual - cf= frecuencia acumulada - cf(%)=frecuencia acumulada porcentual

Para cambiar la cantidad de intervalos agregamos el argumento k y la guardamos en un objeto

TF_CL<-fdt(penguins$culmen_length_mm, #la guardamos en un objeto
        k=9,
        breaks="Sturges")
Tabla4=TF_CL$table
Tabla4
   Class limits  f          rf      rf(%)  cf     cf(%)
1 [31.78,34.94)  8 0.023952096  2.3952096   8   2.39521
2 [34.94,38.09) 50 0.149700599 14.9700599  58  17.36527
3 [38.09,41.25) 65 0.194610778 19.4610778 123  36.82635
4 [41.25,44.41) 43 0.128742515 12.8742515 166  49.70060
5 [44.41,47.57) 70 0.209580838 20.9580838 236  70.65868
6 [47.57,50.72) 62 0.185628743 18.5628743 298  89.22156
7 [50.72,53.88) 29 0.086826347  8.6826347 327  97.90419
8 [53.88,57.04)  5 0.014970060  1.4970060 332  99.40120
9  [57.04,60.2)  2 0.005988024  0.5988024 334 100.00000

Visualización de datos

Para graficar los datos utilizaremos, en principio, plot que es el paquete base de R. También presentamos el paquete ggplot2 que es más potente y tiene más opciones.

Gráficos con R

#library(plotly)

#Diagrama circular
pie(table(penguins$species))

pie(table(penguins$species),
    sub = "Distribución de los pingüinos según su especie",
    col = c("red","pink","orange"))

#Diagrama de barras
barplot(table(penguins$species),
        sub = "Distribución de los pingüinos según su especie",
        col = c("purple","blue2","green3","cyan"))

#Histograma

hist(penguins$culmen_length_mm,
     main="Histograma de los pingüinos según el largo de culmen",
     xlab="largo de culmen (mm)",
     xlim=c(30,60),
     ylab="Frecuencia absoluta",
     col = "green3",
     breaks=lim)

#### Diagrama de cajas
boxplot(penguins$culmen_length_mm,
        horizontal=TRUE,
        col="purple",
        main="Boxplot")

Hacerlo horizontal horizontal=TRUE

Ponerle color col=“orange”

# Por grupos ~
boxplot(penguins$culmen_length_mm~penguins$species,
        ylab ="largo culmen (mm)",
        xlab="Especie",
        sub="Boxplot del largode culmen (mm) de pingüinos según la especie",
        horizontal=FALSE,
        col =  c("orange","blue4","pink"))

Para más detalles del uso, herramientas, etc. de la función plot se pueden dirigir a la página https://r-coder.com/plot-en-r/

Gráficos con ggplo2

La librería ggplot2 es un paquete de visualización de datos para el lenguaje R que implementa lo que se conoce como la “Gramática de los Gráficos”, que no es más que una representación esquemática y en capas de lo que se dibuja en dichos gráficos, como pueden ser los marcos y los ejes, el texto de los mismos, los títulos, así como, por supuesto, los datos o la información que se grafica, el tipo de gráfico que se utiliza, los colores, los símbolos y tamaños, entre otros. Haremos uso de algunos de los conjuntos de datos incluidos por defecto en R para mostrar el cómo se construyen las gráficas deseadas según el caso, la manera de representarlos y en la sintaxis que ggplot2 emplea. Primeramente es necesario la instalación del paquete y la habilitación de la librería:

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

Formato de la función ggplot2

Veremos los mismos gráficos que planteamos anteriormente para que se observen las diferencias.

Gráfico de barras y circular No hay un gráfico específico en la función geom para construir un gráfico de torta en ggplot2. El truco es construir un diagrama de barras y usar coord_polar para hacerlo circular. Esta es la razón por la que la función pie() descrita anteriormente es probablemente una mejor alternativa. Por este motivo primero veremos la construcción de un gráfico de barras y luego el circular. ggplot2 permite construir barplot gracias a la función geom_bar() . Los siguientes ejemplos pueden guiarnos a través de los conceptos básicos de esta herramienta:

ggplot(data=penguins,aes(x=as.factor(species)))+
  geom_bar()+
  xlab("Especie de pingüino")+
  ylab("N° de pingüinos")+
  ggtitle ("Distribución de pingüinos según su especie")

ggplot(data=penguins,aes(x="",y=species,fill=species))+
  geom_bar(stat = "identity",width=1)+
  ggtitle ("Distribucion de pinguinos segun su especie")+
  coord_polar("y",start=0)+
  theme_void()

Histograma Es muy importante tener en cuenta la amplitud de los intervalos, por ende el número de ellos. Esto afecta mucho a la apariencia del histograma y puede ayudar a la interpretación de la información a obtener.

library(tidyverse)
── Attaching packages ─────────────────────────────────────── tidyverse 1.3.2 ──
✔ tibble  3.1.8      ✔ dplyr   1.0.10
✔ tidyr   1.2.1      ✔ stringr 1.4.1 
✔ readr   2.1.2      ✔ forcats 0.5.2 
✔ purrr   0.3.4      
── Conflicts ────────────────────────────────────────── tidyverse_conflicts() ──
✖ dplyr::filter() masks stats::filter()
✖ dplyr::lag()    masks stats::lag()
library(hrbrthemes)
NOTE: Either Arial Narrow or Roboto Condensed fonts are required to use these themes.
      Please use hrbrthemes::import_roboto_condensed() to install Roboto Condensed and
      if Arial Narrow is not on your system, please see https://bit.ly/arialnarrow
ggplot(penguins, aes(x=culmen_length_mm)) +
    geom_histogram(binwidth = 3.5, fill="#69b3a2", color="#e9ecef") +
    theme_ipsum() +
  xlab("largo de culmen(mm)")+
  ylab("N° pinguinos")+
    theme(plot.title = element_text(size=15))+
  ggtitle("distribución de pinguinos de acuerdo al largo de culem (mm)")

Diagrama de caja (boxplot) Existen muchas ventajas a la hora de interpretar la información de los boxplot. Nos dan idea de la distribución en forma y en variabilidad de los datos y de la amplitud del recorrido de los mismos.

library(ggplot2)
ggplot(data = penguins, aes(x = "", y = culmen_length_mm)) +
  stat_boxplot(geom = "errorbar", width = 0.2) +     #Bigotes
  geom_boxplot(fill = "#4271AE",outlier.colour = "red", alpha = 0.9) +
  ggtitle("Boxplot a partir de un vector") +
  xlab("")+
  coord_flip() # Boxplot horizontal

En nuestro estudio tenemos 3 especies de pingüino, por lo que nos interesa conocer si existen diferencias entre ellas:

ggplot(data = penguins, aes(x = species, y = culmen_length_mm)) +
  stat_boxplot(geom = "errorbar",width = 0.2) +
  geom_boxplot(fill = "#4271AE", colour = "#1F3552", alpha = 0.9, outlier.colour = "red") +
  scale_y_continuous(name = "Largo de culmen (mm)") +
  scale_x_discrete(name = " ") + 
  ggtitle(" ") +
  theme(axis.line = element_line(colour = "black",size = 0.25))

En el gráfico se observan que existen diferencias en el largo de culmen pero se deben evaluar inferencialmente para emitir una conclusión sobre las mismas.