“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.
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"
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
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
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
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.
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
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
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.
#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/
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.