1 Instalación y Configuración de R-STUDIO

Para comenzar a usar R, el primer paso es instalarlo en tu computadora. R es compatible con casi todas las plataformas, incluyendo los sistemas operativos más comunes. Windows, Mac OS X y Linux. Links de descarga para R y RStudio.

RStudio es un entorno de desarrollo integrado (IDE) disponible para R, el cual tiene un buen editor con resaltado de sintaxis, un visor de objetos de R y un gran número de características agradables que están integradas.Ademas, esta dedicado a la computación estadística y gráficos.

1.1 “Mundo” Tidyverse en R-Studio

El Tidyverse es una colección de paquetes del R que permiten preparar, procesar y graficar bases de datos. Se destacan los siguientes:

  • ggplot: permite crear visualizaciones elegantes de los datos de una manera relativamente sencilla.

  • stringr: permite manipular cadenas de caracteres con el fin de realizar sustituciones, detectar duplicados, analizar patrones, etc.

  • tidyr: tiene como objetivo obtener datos ordenados. Destacan funciones como gather para crear factores con base en nombres de columnas y separate para crear factores separando los caracteres de una columna.

  • readr: permite importar y exportar bases de datos en diferentes formatos y tiene implementada la función problems que detecta problemas en nuestras bases.

Para más información visitar la página web:
https://www.tidyverse.org/packages/

1.2 Creación de reportes en R con R Markdown:

2 Conceptos básicos de programación en R:

library(kableExtra)
## Warning: package 'kableExtra' was built under R version 4.3.3
# Crear los datos
comandos <- c("x == y", "x != y", "x > y", "x < y", "x >= y", "x <= y", "&", "|", "!", "isTRUE(A)")
significado <- c("x es igual a y", "x no es igual a y", "x es mayor que y", "x es menor que y",
                 "x es mayor o igual que y", "x es menor o igual que y", "y", "o", "No", "Evalúa si A es cierta")

# Crear el data frame
tabla <- data.frame(Comando = comandos, Significado = significado)

# Visualizar la tabla utilizando kableExtra con mayor ancho
tabla %>%
  kbl(col.names = c("Comando", "Significado"), booktabs = TRUE) %>%
  kable_styling(full_width = TRUE, position = "center", font_size = 24) %>%
  row_spec(0, bold = TRUE, background = "#D3D3D3") %>%
  kable_paper("striped", full_width = F) %>%
  column_spec(1, width = "6cm") %>%  # Ajustar ancho de la primera columna
  column_spec(2, width = "12cm")     # Ajustar ancho de la segunda columna
Comando Significado
x == y x es igual a y
x != y x no es igual a y
x > y x es mayor que y
x < y x es menor que y
x >= y x es mayor o igual que y
x <= y x es menor o igual que y
& y

2.1 Ejemplos de operadores de comparación en R:

# Asignación de valores
a <- 1
b <- 3

# Operaciones y comentarios explicativos

# ¿b es diferente de a?
b != a  # TRUE
## [1] TRUE
# ¿es a igual a b?
isTRUE(a == b)  # FALSE
## [1] FALSE
# Negar que a es menor que b
!(a < b)  # FALSE
## [1] FALSE
# ¿es a menor que b o b menor que a?
(a < b | b < a)  # TRUE
## [1] TRUE
# ¿es a menor o igual a b o b igual a a?
(a <= b & b == a)  # FALSE
## [1] FALSE

2.2 Creación de Objetos

R es un lenguaje orientado a objetos. Los objetos pueden ser usados para guardar valores y pueden madificarse mediante funciones como por ejemplo sumar dos objetos o calcular la media.

X <- 4
Y <- 2

2.2.1 R como calculadora

Puedes usar el programa R como una calculadora, basta con conocer cuáles son los signos y comandos a utilizar para realizar las operaciones. Copia los comandos en tu script de R y ejecútalos para ver los resultados.

#suma
Z <- X +Y

Z
## [1] 6
#multiplicación
2*2
## [1] 4
#división
2/2
## [1] 1
#potencia
4^2
## [1] 16
#raíz cuadrada
sqrt(16)
## [1] 4

2.3 Condicional if-else.

En R, la sintáxis del condicional consiste en:

  • if (A): evalúa si se cumple la condición A.
  • else if (B): si no se cumple la condición o condiciones anteriores, entonces evalúe si se cumple la condición B.
  • else: si no se cumple ninguna de las condiciones anteriores entonces haga lo siguiente.

Ejemplo:

a<-9
 if (a<0){
 print("a es negativo")
 }else if (a>0){
 print("a es positivo")
 }else{
 print("a es igual a cero")
 }
## [1] "a es positivo"

2.4 Bucles for:

Usado para repetir un bloque específico de código, siguiendo una secuencia dada.

suma<-0
 for (i in 1:10){
 suma<-suma+i
 }
 suma
## [1] 55
lista<-c("a","b","c","d")
 for (j in lista){
 print(j)
 }
## [1] "a"
## [1] "b"
## [1] "c"
## [1] "d"
vector<-c(0.1, 0.3,-0.4, 1.5,-2.1)
 for (k in vector){
 print(abs(k))
 }
## [1] 0.1
## [1] 0.3
## [1] 0.4
## [1] 1.5
## [1] 2.1
x1<-cbind(1:3,4:6) # Matriz 1
 x2<-cbind(3:5,4:6) # Matriz 2
 x3<-cbind(5:7,9:11) # Matriz 3
 l1<-list(x1,x2,x3) # Lista de matrices
 for(i in l1){
 print(i)
 }
##      [,1] [,2]
## [1,]    1    4
## [2,]    2    5
## [3,]    3    6
##      [,1] [,2]
## [1,]    3    4
## [2,]    4    5
## [3,]    5    6
##      [,1] [,2]
## [1,]    5    9
## [2,]    6   10
## [3,]    7   11

2.5 Bucles for considerando un next:

# Imprimir solo los impares del 1 al 10
for (i in 1:10) {
  if (i %% 2 == 0) {
    next  # Saltar los números pares
  }
  print(i)  # Imprimir los números impares
}
## [1] 1
## [1] 3
## [1] 5
## [1] 7
## [1] 9

2.6 Bucles while (Condición):

Usado para repetir un bloque específico de código siempre que una condición dada sea verdadera.

a <- 1
while (a < 5) {
  a <- a + 1
  print(a)
}
## [1] 2
## [1] 3
## [1] 4
## [1] 5
a<-1
 b<-3
 while(a<15 &b>0.2){
 a<-a+1
 b<-round(b/2,2)
 print(c(a,b))
 }
## [1] 2.0 1.5
## [1] 3.00 0.75
## [1] 4.00 0.38
## [1] 5.00 0.19

2.7 Bucles repeat:

El bucle repeat funciona igual que el while, pero considera un bucle infinito que se “rompe” con un break.

a <- 1
b <- 3
repeat {
  a <- a + 1
  b <- round(b / 2, 2)
  print(c(a, b))
  if (a > 15 | b < 0.2) {
    break
  }
}
## [1] 2.0 1.5
## [1] 3.00 0.75
## [1] 4.00 0.38
## [1] 5.00 0.19

2.8 Creación de funciones en R.

En una función tenemos tres tipos de elementos:

  1. Argumentos: también conocidos como valores de entrada.

  2. Cuerpo: operaciones que han de realizarse. Se deben localizar entre corchetes.

  3. Resultado: también conocidos como valores de salida y que se ubican en la última expresión que se ejecuta.

Nota: Tratar al máximo de no usar nombres de posibles funciones que ya existen para no entrar en conflictos con los códigos en R.

# Sumar los números impares hasta un m:
 sumar<-function(m){
 sum1<-0
 for (i in 1:m){
 if(!i%%2){
 next
 }else{
 sum1<-sum1+i
 }
 }
 return(sum1)
 }
sumar(5)
## [1] 9
sumar(7)
## [1] 16

Ejemplo de una función en R

 multiplos<-function(a,b,n){
 a1<-vector() #Múltiplos de a menores o iguales a n
 b1<-vector() #Múltiplos de b menores o iguales a n
 ca1<-1
 cb1<-1
 for (i in 1:n){
 if(!i%%a){
 a1[ca1]<-i
 ca1<-ca1+1
 }
 if(!i%%b){
 b1[cb1]<-i
 cb1<-cb1+1
 }else{
 next
 }
 }
 return(list(Multiplos_a=a1,Multiplos_b=b1))
 }
 multiplos(3,5,20) # a=3, b=5, n=20
## $Multiplos_a
## [1]  3  6  9 12 15 18
## 
## $Multiplos_b
## [1]  5 10 15 20
 multiplos(4,7,35) # a=4, b=7, n=35
## $Multiplos_a
## [1]  4  8 12 16 20 24 28 32
## 
## $Multiplos_b
## [1]  7 14 21 28 35

2.9 Guardando y cargando funciones de una forma práctica.

Una forma práctica para guardar y luego utilizar mis funciones de manera práctica consiste en:

  1. Considerar un único archivo .R que contenga todas las funciones que vamos creando.

  2. Utilizar la función source para leer el archivo con mis funciones y poder utilizarlas. Esta función tiene como argumento principal la url de mi computador donde he guardado mi archivo .R que contiene las funciones creadas.

Ejmplo:

# Ejemplo de una función en R
sumar <- function(a, b) {
  return(a + b)
}

restar <- function(a, b) {
  return(a - b)
}

Cargar las funciones desde el archivo

source("ruta/a/tu/archivo/mis_funciones.R")

# Ahora puedes utilizar las funciones cargadas
resultado_suma <- sumar(3, 5)
resultado_resta <- restar(10, 4)

print(resultado_suma)
## [1] 8
print(resultado_resta)
## [1] 6

2.10 Actividad #1

Construir una función llamada filtro en R que haga lo siguiente:

  1. Tenga como entradas un “data frame”, una variable y un valor particular de la variable.

  2. Identifique si la entrada correspondiente de la variable es un nombre o un número de columna.

  3. Arroje como resultado un nuevo “data frame” filtrado por el valor particular de la variable de interés.

  4. Generalizar esta función con varias variables y varias categorías.

3 Bases de datos en R.

3.1 Cargar paquetes

Lo primero que tenemos que hacer es cargar los paquetes que vamos a utilizar para el análisis. En este caso vamos a usar:

library(tidyverse)# Incluye paquetes de importación, visualización entre otros
## ── Attaching core tidyverse packages ──────────────────────── tidyverse 2.0.0 ──
## ✔ dplyr     1.1.4     ✔ readr     2.1.5
## ✔ forcats   1.0.0     ✔ stringr   1.5.1
## ✔ ggplot2   3.5.1     ✔ tibble    3.2.1
## ✔ lubridate 1.9.3     ✔ tidyr     1.3.1
## ✔ purrr     1.0.2     
## ── Conflicts ────────────────────────────────────────── tidyverse_conflicts() ──
## ✖ dplyr::filter()     masks stats::filter()
## ✖ dplyr::group_rows() masks kableExtra::group_rows()
## ✖ dplyr::lag()        masks stats::lag()
## ℹ Use the conflicted package (<http://conflicted.r-lib.org/>) to force all conflicts to become errors
library(dplyr)# Manipulación de Datos
library(ggplot2)# Visualización de datos 
library(readxl)# Importación de datos
require(tibble)# Tablas

Recordar que si no ha instalado estos paquetes debe correr primero el comando: install.packages("nombre del paquete")

3.2 Abrir una Base de R-STUDIO y Resumir**

3.2.1 Cargar base incorporada en R-Studio

R ya incorpora una serie de bases de datos que te pueden resultar de utilidad para empezar a explorar las posibilidades de análisis estadístico que te ofrece este programa.

Como ejemplo vamos a explorara la base de datos llamada “cars”.

# Cargar la base
data(cars)
# Visualizar los encabezados
head(cars)
# Resumir con algunas estadísticas las variables de la base 
summary(cars)
##      speed           dist       
##  Min.   : 4.0   Min.   :  2.00  
##  1st Qu.:12.0   1st Qu.: 26.00  
##  Median :15.0   Median : 36.00  
##  Mean   :15.4   Mean   : 42.98  
##  3rd Qu.:19.0   3rd Qu.: 56.00  
##  Max.   :25.0   Max.   :120.00

3.2.2 Incluir gráficas

Puedes agregar fácilmente gráficos a tu análisis. Por ejemplo:

data(pressure)
head(pressure)
hist(pressure$temperature)

boxplot(pressure$temperature)

3.3 Extensiones.

Dentro de un amplio número de extensiones que se pueden encontrar en bases de datos se encuentran:

Algunos paquetes utilizados para importar y exportar bases de datos en R son:

Algunos paquetes utilizados para importar y exportar bases de datos en R y Python son:

  • utils: permite importar y exportar datos en varios formatos.
  • rgdal: permite importar y exportar datos geoespaciales.
  • readr: permite importar y exportar datos en varios formatos.
  • readxl: Importar datos en formato “Excel”.
  • haven: Importar y exportar datos en “SPSS”, “Stata” y “SAS”.
  • httr: Herramientas para trabajar con URLs y archivos HTTP.
  • rvest: útil para extraer información de las páginas web.
  • xml2: Leer archivos HTML o XML.
  • csv: Importar y exportar datos .csv.
  • pandas: Importar y exportar datos .csv, Excel, SAS, SPSS, html, stata, sql, etc.

Ejemplo: Para los ejemplos de esta sección utilizaremos un dataset que contiene información sobre el Hurto de Motocicletas

https://github.com/Kalbam/Datos/raw/main/Delito_Hurto_Motocicletas.csv

Cargar la base de datos directamente desde GitHub

url <- "https://github.com/Kalbam/Datos/raw/main/Delito_Hurto_Motocicletas.csv"
datos <- read.csv(url)

Otra forma

datos<-read.csv("Delito_Hurto_Motocicletas.csv",
 sep=",",header=TRUE,
 fileEncoding = "UTF-8")

Nombres de variables

names(datos)# nombres de variables
##  [1] "FECHA"         "DEPARTAMENTO"  "MUNICIPIO"     "DIA"          
##  [5] "HORA"          "BARRIO"        "ZONA"          "CLASE.SITIO"  
##  [9] "EDAD"          "GENERO"        "ARMA.EMPLEADA" "MOVIL.AGRESOR"
## [13] "MOVIL.VICTIMA" "MARCA"         "MODELO"        "LINEA"        
## [17] "COLOR"         "ESTADO.CIVIL"  "PROFESIONES"   "ESCOLARIDAD"  
## [21] "CODIGO.DANE"   "X2015"

Dimensiones

dim(datos)
## [1] 27223    22

Categorias de Departamento

table(datos$DEPARTAMENTO)
## 
##                              AMAZONAS          ANTIOQUIA             ARAUCA 
##                 92                 25               6107                196 
##          ATLÁNTICO            BOLÍVAR             BOYACÁ             CALDAS 
##               1254                402                 63                111 
##            CAQUETÁ           CASANARE              CAUCA              CESAR 
##                348                449               1584               1010 
##              CHOCÓ            CÓRDOBA       CUNDINAMARCA            GUAINÍA 
##                318                521               3402                  3 
##            GUAJIRA           GUAVIARE              HUILA          MAGDALENA 
##                852                 27                841                375 
##               META             NARIÑO NORTE DE SANTANDER           PUTUMAYO 
##                854                721               1637                245 
##            QUINDÍO          RISARALDA         SAN ANDRÉS          SANTANDER 
##                155                295                 74                584 
##              SUCRE             TOLIMA              VALLE             VAUPÉS 
##                420                357               3882                  3 
##            VICHADA 
##                 16

Tipos de datos

str(datos)
## 'data.frame':    27223 obs. of  22 variables:
##  $ FECHA        : chr  "01/01/2015 12:00:00 AM" "01/01/2015 12:00:00 AM" "01/01/2015 12:00:00 AM" "01/01/2015 12:00:00 AM" ...
##  $ DEPARTAMENTO : chr  "ANTIOQUIA" "ANTIOQUIA" "ANTIOQUIA" "ANTIOQUIA" ...
##  $ MUNICIPIO    : chr  "CAREPA" "COPACABANA" "EL BAGRE" "MARINILLA" ...
##  $ DIA          : chr  "Jueves" "Jueves" "Jueves" "Jueves" ...
##  $ HORA         : chr  "7:30" "14:45" "4:00" "0:00" ...
##  $ BARRIO       : chr  "PUEBLO NUEVO" "VDA. CABUYAL" "BIJAO" "CENTRO" ...
##  $ ZONA         : chr  "URBANA" "URBANA" "URBANA" "URBANA" ...
##  $ CLASE.SITIO  : chr  "VIAS PUBLICAS" "VIAS PUBLICAS" "VIAS PUBLICAS" "VIAS PUBLICAS" ...
##  $ EDAD         : int  26 22 29 26 61 28 29 39 33 24 ...
##  $ GENERO       : chr  "MASCULINO" "MASCULINO" "FEMENINO" "FEMENINO" ...
##  $ ARMA.EMPLEADA: chr  "LLAVE MAESTRA" "ARMA DE FUEGO" "LLAVE MAESTRA" "LLAVE MAESTRA" ...
##  $ MOVIL.AGRESOR: chr  "A PIE" "PASAJERO MOTOCICLETA" "A PIE" "A PIE" ...
##  $ MOVIL.VICTIMA: chr  "A PIE" "CONDUCTOR MOTOCICLETA" "A PIE" "A PIE" ...
##  $ MARCA        : chr  "YAMAHA" "YAMAHA" "AUTECO" "YAMAHA" ...
##  $ MODELO       : num  2012 2000 2008 1997 2006 ...
##  $ LINEA        : chr  "FZ16" "RX 115" "PLATINO" "DT125" ...
##  $ COLOR        : chr  "NEGRO" "BLANCO" "NEGRO" "AZUL" ...
##  $ ESTADO.CIVIL : chr  "UNION LIBRE" "SOLTERO" "CASADO" "UNION LIBRE" ...
##  $ PROFESIONES  : chr  "POLICIA" "NO REPORTADO" "NO REPORTADO" "NO REPORTADO" ...
##  $ ESCOLARIDAD  : chr  "TECNICO" "SECUNDARIA" "PRIMARIA" "TECNICO" ...
##  $ CODIGO.DANE  : int  5147000 5212000 5250000 5440000 5607000 85010000 85001000 20250000 20001000 20001000 ...
##  $ X2015        : int  1 1 1 1 1 1 1 1 1 1 ...

3.4 Visualizar la base de datos

Se realiza un diagrama de barras para verificar cómo se encuentra la base de datos.

barplot(table(datos$DEPARTAMENTO),las=2)

Se organizan las barras de mayor a menor frecuencia.

barplot(sort(table(datos$DEPARTAMENTO),decreasing=TRUE),
 las=2)

Se realiza un resumen de la variable municipio y luego se visualizan los municipios con frecuencia mayor a 150.

resum_1<-table(datos$MUNICIPIO)
 barplot(sort(resum_1[resum_1>150],decreasing=TRUE),
 las=2)

Visualización de la variable Genero

 barplot(table(datos$GENERO))

resum_2<-table(datos$GENERO)
resum_2
## 
##                  FEMENINO    MASCULINO NO REPORTADO 
##           92         4710        22420            1
names(resum_2)
## [1] ""             "FEMENINO"     "MASCULINO"    "NO REPORTADO"

Se organizan los valores NA de la variable GENERO en a1

a1<-names(resum_2)[1]
a1
## [1] ""

Se guardan todos los valores similares de la base en a2

a2<-which(datos$GENERO==a1)
length(a2)
## [1] 92

Se visualizan los primeros 10 valores NA de la base de datos y se observa que en la fila 81,366,728… 1798 se encuentran NA de la variable GENERO

a2[1:10]
##  [1]   81  366  728  924 1331 1364 1490 1525 1785 1798
datos$FECHA[a2[1]]
## [1] "04/01/2015 12:00:00 AM,VALLE,CALI (CT),Domingo,19:40,OBRERO E9,URBANA,\"DROGUERIAS, FARMACIAS\",36,MASCULINO,LLAVE MAESTRA,A PIE,A PIE,SUZUKI,2009,viva 115,AZUL,UNION LIBRE,NO REPORTADO,SECUNDARIA,76001000,1"
datos$FECHA[a2[2]]
## [1] ",NORTE DE SANTANDER,PAMPLONA,Domingo,0:45,BARRIO EL CAMELLON,URBANA,\"BARES, CANTINAS Y SIMILARES\",27,MASCULINO,LLAVE MAESTRA,A PIE,A PIE,YAMAHA,2003,CRIPTON 110,AZUL,SOLTERO,NO REPORTADO,TECNICO,54518000,1"

3.5 Visualización de la base antes de ser procesada.

kable(datos[70:87,], caption= "Tabla 1: Base de datos, Delito de Hurto de Motocicleta") %>%
  kable_styling(full_width = F) %>%
  column_spec(2, width = "20em") %>%
  scroll_box(width = "900px", height = "450px")
Tabla 1: Base de datos, Delito de Hurto de Motocicleta
FECHA DEPARTAMENTO MUNICIPIO DIA HORA BARRIO ZONA CLASE.SITIO EDAD GENERO ARMA.EMPLEADA MOVIL.AGRESOR MOVIL.VICTIMA MARCA MODELO LINEA COLOR ESTADO.CIVIL PROFESIONES ESCOLARIDAD CODIGO.DANE X2015
70 04/01/2015 12:00:00 AM HUILA HOBO Domingo 12:30 CENTRO URBANA VIAS PUBLICAS 34 MASCULINO LLAVE MAESTRA A PIE A PIE HONDA 1990 LINEA STANDARD AZUL UNION LIBRE NO REPORTADO PRIMARIA 41349000 1
71 04/01/2015 12:00:00 AM MAGDALENA SANTA MARTA (CT) Domingo 13:30 URBANIZACION MARIA CECILIA URBANA VIAS PUBLICAS 23 MASCULINO ARMA DE FUEGO PASAJERO MOTOCICLETA A PIE YAMAHA 2013 FZ16 NEGRO GRAFITO SOLTERO NO REPORTADO SECUNDARIA 47001000 1
72 04/01/2015 12:00:00 AM META FUENTE DE ORO Domingo 8:00 VEREDA PUERTO POVEDA RURAL PLAYA 23 MASCULINO LLAVE MAESTRA A PIE CONDUCTOR MOTOCICLETA BAJAJ 2014 DISCOVER ROJO UNION LIBRE NO REPORTADO PRIMARIA 50287000 1
73 04/01/2015 12:00:00 AM META VILLAVICENCIO (CT) Domingo 1:00 VALLES DE ARAGON URBANA VIAS PUBLICAS 25 MASCULINO LLAVE MAESTRA A PIE A PIE YAMAHA 2015 FZ16 NEGRO SOLTERO NO REPORTADO SECUNDARIA 50001000 1
74 04/01/2015 12:00:00 AM PUTUMAYO MOCOA (CT) Domingo 16:00 OBRERO I URBANA VIAS PUBLICAS 64 MASCULINO CONTUNDENTES A PIE A PIE BAJAJ 2010 DISCOVER AZUL CASADO NO REPORTADO SECUNDARIA 86001000 1
75 04/01/2015 12:00:00 AM RISARALDA PEREIRA (CT) Domingo 15:00 VDA. SAN JOSE RURAL PARQUEADERO 24 MASCULINO LLAVE MAESTRA A PIE A PIE YAMAHA 1997 RX 100 MARRON SOLTERO NO REPORTADO SECUNDARIA 66001000 1
76 04/01/2015 12:00:00 AM SUCRE SINCELEJO (CT) Domingo 11:30 CENTRO URBANA VIAS PUBLICAS 47 MASCULINO LLAVE MAESTRA A PIE CONDUCTOR MOTOCICLETA AUTECO 2014 BOXER NEGRO CASADO NO REPORTADO SECUNDARIA 70001000 1
77 04/01/2015 12:00:00 AM VALLE CALI (CT) Domingo 7:00 UNION DE VIVIENDA POPULAR E16 URBANA FRENTE A RESIDENCIAS - VIA PUBLICA 24 MASCULINO LLAVE MAESTRA A PIE A PIE AKT 2008 AK 100 NEGRO UNION LIBRE NO REPORTADO SECUNDARIA 76001000 1
78 04/01/2015 12:00:00 AM VALLE CALI (CT) Domingo 9:00 SANTA ELENA E10 URBANA VIAS PUBLICAS 33 MASCULINO LLAVE MAESTRA A PIE A PIE TVS 2007 SPORT NEGRO UNION LIBRE NO REPORTADO SECUNDARIA 76001000 1
79 04/01/2015 12:00:00 AM VALLE CALI (CT) Domingo 16:00 VISTAHERMOSA E1 URBANA VIAS PUBLICAS 28 MASCULINO LLAVE MAESTRA A PIE A PIE AUTECO 2011 BOXER BLANCO SOLTERO NO REPORTADO SECUNDARIA 76001000 1
80 04/01/2015 12:00:00 AM VALLE CALI (CT) Domingo 18:00 LA LIBERTAD E10 URBANA VIAS PUBLICAS 31 FEMENINO ARMA DE FUEGO A PIE A PIE YAMAHA 2015 BWS NEGRO UNION LIBRE NO REPORTADO SECUNDARIA 76001000 1
81 04/01/2015 12:00:00 AM,VALLE,CALI (CT),Domingo,19:40,OBRERO E9,URBANA,“DROGUERIAS, FARMACIAS”,36,MASCULINO,LLAVE MAESTRA,A PIE,A PIE,SUZUKI,2009,viva 115,AZUL,UNION LIBRE,NO REPORTADO,SECUNDARIA,76001000,1 NA NA NA NA
82 04/01/2015 12:00:00 AM VALLE CALI (CT) Domingo 20:30 ATANASIO GIRARDOT E8 URBANA VIAS PUBLICAS 34 MASCULINO LLAVE MAESTRA A PIE A PIE HONDA 2013 ECO NEGRO SOLTERO NO REPORTADO SECUNDARIA 76001000 1
83 04/01/2015 12:00:00 AM VALLE CALI (CT) Domingo 22:40 LOS GUAYACANES E5 URBANA VIAS PUBLICAS 21 FEMENINO ARMA DE FUEGO CONDUCTOR MOTOCICLETA CONDUCTOR MOTOCICLETA YAMAHA 2014 CRYPTON 115 AZUL SOLTERO NO REPORTADO SECUNDARIA 76001000 1
84 04/01/2015 12:00:00 AM VALLE TRUJILLO Domingo 0:40 CENTRO URBANA VIAS PUBLICAS 23 MASCULINO LLAVE MAESTRA A PIE A PIE YAMAHA 1996 DT125 BLANCO SOLTERO NO REPORTADO SECUNDARIA 76828000 1
85 05/01/2015 12:00:00 AM ANTIOQUIA ENVIGADO Lunes 22:00 EL DORADO URBANA VIAS PUBLICAS 28 MASCULINO ARMA DE FUEGO PASAJERO MOTOCICLETA CONDUCTOR MOTOCICLETA BMW 2015 RNO REPORTADO1200C ROJO SOLTERO NO REPORTADO SUPERIOR 5266000 1
86 05/01/2015 12:00:00 AM ANTIOQUIA GUARNE Lunes 0:00 SAN FRANCISCO URBANA VIAS PUBLICAS 26 MASCULINO LLAVE MAESTRA A PIE A PIE AUTECO 2014 PULSAR AMARILLO SOLTERO NO REPORTADO SECUNDARIA 5318000 1
87 05/01/2015 12:00:00 AM ANTIOQUIA TURBO Lunes 9:00 CENTRO URBANA VIAS PUBLICAS 33 FEMENINO NO REPORTADO A PIE A PIE BAJAJ 2011 DISCOVER NEGRO CASADO NO REPORTADO SECUNDARIA 5837000 1

3.6 Paquete stringr

El paquete stringr es parte del ecosistema de R y forma parte de la familia de paquetes tidyverse, desarrollado por Hadley Wickham y otros colaboradores. Está diseñado específicamente para facilitar el trabajo con cadenas de texto (strings) en R.

3.7 Principales funcionalidades del paquete stringr

  1. Manipulación de cadenas:
    • Concatenación: Puedes unir múltiples cadenas en una sola.
    • Extracción de subcadenas: Permite extraer partes específicas de una cadena, como un substring.
    • Cambio de mayúsculas y minúsculas: Convertir cadenas a mayúsculas (str_to_upper()) o minúsculas (str_to_lower()).
    • Reemplazo de patrones: Reemplazar partes de una cadena que coinciden con un patrón específico.
  2. Búsqueda y coincidencia de patrones:
    • Patrones regulares (regex): stringr facilita la búsqueda de patrones dentro de cadenas utilizando expresiones regulares, que son una herramienta poderosa para encontrar y manipular texto basado en patrones específicos.
    • Detección de patrones: Funciones como str_detect() permiten identificar si un patrón específico existe dentro de una cadena.
  3. Modificación y limpieza de cadenas:
    • Eliminación de espacios: str_trim() se usa para eliminar espacios en blanco al principio y al final de una cadena.
    • Separación y unión de cadenas: str_split() divide una cadena en partes basadas en un delimitador, y str_c() concatena múltiples cadenas en una sola.
  4. Contar y medir cadenas:
    • Conteo de caracteres: str_length() devuelve el número de caracteres en una cadena.
    • Conteo de ocurrencias: str_count() cuenta cuántas veces un patrón específico aparece en una cadena.
datos$FECHA[a2[1]] 
## [1] "04/01/2015 12:00:00 AM,VALLE,CALI (CT),Domingo,19:40,OBRERO E9,URBANA,\"DROGUERIAS, FARMACIAS\",36,MASCULINO,LLAVE MAESTRA,A PIE,A PIE,SUZUKI,2009,viva 115,AZUL,UNION LIBRE,NO REPORTADO,SECUNDARIA,76001000,1"
require(stringr)
 str_match(datos$FECHA[a2[1]], '"(.*?)"')[,2]
## [1] "DROGUERIAS, FARMACIAS"
a3<-vector()
 for(i in 1:length(a2)){
 a3[i]<-str_match(datos$FECHA[a2[i]],'"(.*?)"')[,2]
 }
resum3<-summary(as.factor(a3))
 resum3
##        BARES, CANTINAS Y SIMILARES                   CHICO I, II, III 
##                                 37                                  1 
##                 COLEGIOS, ESCUELAS                   COR, LOS ANGELES 
##                                 33                                  1 
##              DROGUERIAS, FARMACIAS HOTELES, RESIDENCIAS, Y SIMILARES. 
##                                  1                                 14 
##              LA ADIELA I,II,III,IV    VDA. QUILCACE, ANTES DEL PUENTE 
##                                  2                                  2 
##                   VIA, PUERTO ASIS 
##                                  1
a31<-str_replace_all(a3,",","-")
 resum4<-summary(as.factor(a31))
 resum4
##        BARES- CANTINAS Y SIMILARES                   CHICO I- II- III 
##                                 37                                  1 
##                 COLEGIOS- ESCUELAS                   COR- LOS ANGELES 
##                                 33                                  1 
##              DROGUERIAS- FARMACIAS HOTELES- RESIDENCIAS- Y SIMILARES. 
##                                  1                                 14 
##              LA ADIELA I-II-III-IV    VDA. QUILCACE- ANTES DEL PUENTE 
##                                  2                                  2 
##                   VIA- PUERTO ASIS 
##                                  1
b1<-str_replace(datos$FECHA[a2[1]],a3[1],a31[1])
 b1
## [1] "04/01/2015 12:00:00 AM,VALLE,CALI (CT),Domingo,19:40,OBRERO E9,URBANA,\"DROGUERIAS- FARMACIAS\",36,MASCULINO,LLAVE MAESTRA,A PIE,A PIE,SUZUKI,2009,viva 115,AZUL,UNION LIBRE,NO REPORTADO,SECUNDARIA,76001000,1"
 b2<-str_replace(b1,'\"','' )
 b2<-str_replace(b2,'\",',',' )
 b2
## [1] "04/01/2015 12:00:00 AM,VALLE,CALI (CT),Domingo,19:40,OBRERO E9,URBANA,DROGUERIAS- FARMACIAS,36,MASCULINO,LLAVE MAESTRA,A PIE,A PIE,SUZUKI,2009,viva 115,AZUL,UNION LIBRE,NO REPORTADO,SECUNDARIA,76001000,1"
 a32<-vector()
 for(i in 1:length(a2)){
 b1<-str_replace(datos$FECHA[a2[i]],a3[i],a31[i])
 b2<-str_replace(b1,'\"','')
 b2<-str_replace(b2,'\",',',' )
 a32[i]<-b2
 }
require(tidyr)
 datos21<-separate(data.frame(a32),a32, sep=",",
 into=colnames(datos))
datos[a2,]<-datos21
datos<-droplevels(datos)
table(datos$GENERO)# DESPUÉS DE PROCESAR LOS DATOS
## 
##     FEMENINO    MASCULINO NO REPORTADO 
##         4728        22494            1

3.8 Visualización de la base despues de ser procesada.

kable(datos[70:87,], caption= "Tabla 1: Base de datos, Delito de Hurto de Motocicleta") %>%
  kable_styling(full_width = F) %>%
  column_spec(2, width = "20em") %>%
  scroll_box(width = "900px", height = "450px")
Tabla 1: Base de datos, Delito de Hurto de Motocicleta
FECHA DEPARTAMENTO MUNICIPIO DIA HORA BARRIO ZONA CLASE.SITIO EDAD GENERO ARMA.EMPLEADA MOVIL.AGRESOR MOVIL.VICTIMA MARCA MODELO LINEA COLOR ESTADO.CIVIL PROFESIONES ESCOLARIDAD CODIGO.DANE X2015
70 04/01/2015 12:00:00 AM HUILA HOBO Domingo 12:30 CENTRO URBANA VIAS PUBLICAS 34 MASCULINO LLAVE MAESTRA A PIE A PIE HONDA 1990 LINEA STANDARD AZUL UNION LIBRE NO REPORTADO PRIMARIA 41349000 1
71 04/01/2015 12:00:00 AM MAGDALENA SANTA MARTA (CT) Domingo 13:30 URBANIZACION MARIA CECILIA URBANA VIAS PUBLICAS 23 MASCULINO ARMA DE FUEGO PASAJERO MOTOCICLETA A PIE YAMAHA 2013 FZ16 NEGRO GRAFITO SOLTERO NO REPORTADO SECUNDARIA 47001000 1
72 04/01/2015 12:00:00 AM META FUENTE DE ORO Domingo 8:00 VEREDA PUERTO POVEDA RURAL PLAYA 23 MASCULINO LLAVE MAESTRA A PIE CONDUCTOR MOTOCICLETA BAJAJ 2014 DISCOVER ROJO UNION LIBRE NO REPORTADO PRIMARIA 50287000 1
73 04/01/2015 12:00:00 AM META VILLAVICENCIO (CT) Domingo 1:00 VALLES DE ARAGON URBANA VIAS PUBLICAS 25 MASCULINO LLAVE MAESTRA A PIE A PIE YAMAHA 2015 FZ16 NEGRO SOLTERO NO REPORTADO SECUNDARIA 50001000 1
74 04/01/2015 12:00:00 AM PUTUMAYO MOCOA (CT) Domingo 16:00 OBRERO I URBANA VIAS PUBLICAS 64 MASCULINO CONTUNDENTES A PIE A PIE BAJAJ 2010 DISCOVER AZUL CASADO NO REPORTADO SECUNDARIA 86001000 1
75 04/01/2015 12:00:00 AM RISARALDA PEREIRA (CT) Domingo 15:00 VDA. SAN JOSE RURAL PARQUEADERO 24 MASCULINO LLAVE MAESTRA A PIE A PIE YAMAHA 1997 RX 100 MARRON SOLTERO NO REPORTADO SECUNDARIA 66001000 1
76 04/01/2015 12:00:00 AM SUCRE SINCELEJO (CT) Domingo 11:30 CENTRO URBANA VIAS PUBLICAS 47 MASCULINO LLAVE MAESTRA A PIE CONDUCTOR MOTOCICLETA AUTECO 2014 BOXER NEGRO CASADO NO REPORTADO SECUNDARIA 70001000 1
77 04/01/2015 12:00:00 AM VALLE CALI (CT) Domingo 7:00 UNION DE VIVIENDA POPULAR E16 URBANA FRENTE A RESIDENCIAS - VIA PUBLICA 24 MASCULINO LLAVE MAESTRA A PIE A PIE AKT 2008 AK 100 NEGRO UNION LIBRE NO REPORTADO SECUNDARIA 76001000 1
78 04/01/2015 12:00:00 AM VALLE CALI (CT) Domingo 9:00 SANTA ELENA E10 URBANA VIAS PUBLICAS 33 MASCULINO LLAVE MAESTRA A PIE A PIE TVS 2007 SPORT NEGRO UNION LIBRE NO REPORTADO SECUNDARIA 76001000 1
79 04/01/2015 12:00:00 AM VALLE CALI (CT) Domingo 16:00 VISTAHERMOSA E1 URBANA VIAS PUBLICAS 28 MASCULINO LLAVE MAESTRA A PIE A PIE AUTECO 2011 BOXER BLANCO SOLTERO NO REPORTADO SECUNDARIA 76001000 1
80 04/01/2015 12:00:00 AM VALLE CALI (CT) Domingo 18:00 LA LIBERTAD E10 URBANA VIAS PUBLICAS 31 FEMENINO ARMA DE FUEGO A PIE A PIE YAMAHA 2015 BWS NEGRO UNION LIBRE NO REPORTADO SECUNDARIA 76001000 1
81 04/01/2015 12:00:00 AM VALLE CALI (CT) Domingo 19:40 OBRERO E9 URBANA DROGUERIAS- FARMACIAS 36 MASCULINO LLAVE MAESTRA A PIE A PIE SUZUKI 2009 viva 115 AZUL UNION LIBRE NO REPORTADO SECUNDARIA 76001000 1
82 04/01/2015 12:00:00 AM VALLE CALI (CT) Domingo 20:30 ATANASIO GIRARDOT E8 URBANA VIAS PUBLICAS 34 MASCULINO LLAVE MAESTRA A PIE A PIE HONDA 2013 ECO NEGRO SOLTERO NO REPORTADO SECUNDARIA 76001000 1
83 04/01/2015 12:00:00 AM VALLE CALI (CT) Domingo 22:40 LOS GUAYACANES E5 URBANA VIAS PUBLICAS 21 FEMENINO ARMA DE FUEGO CONDUCTOR MOTOCICLETA CONDUCTOR MOTOCICLETA YAMAHA 2014 CRYPTON 115 AZUL SOLTERO NO REPORTADO SECUNDARIA 76001000 1
84 04/01/2015 12:00:00 AM VALLE TRUJILLO Domingo 0:40 CENTRO URBANA VIAS PUBLICAS 23 MASCULINO LLAVE MAESTRA A PIE A PIE YAMAHA 1996 DT125 BLANCO SOLTERO NO REPORTADO SECUNDARIA 76828000 1
85 05/01/2015 12:00:00 AM ANTIOQUIA ENVIGADO Lunes 22:00 EL DORADO URBANA VIAS PUBLICAS 28 MASCULINO ARMA DE FUEGO PASAJERO MOTOCICLETA CONDUCTOR MOTOCICLETA BMW 2015 RNO REPORTADO1200C ROJO SOLTERO NO REPORTADO SUPERIOR 5266000 1
86 05/01/2015 12:00:00 AM ANTIOQUIA GUARNE Lunes 0:00 SAN FRANCISCO URBANA VIAS PUBLICAS 26 MASCULINO LLAVE MAESTRA A PIE A PIE AUTECO 2014 PULSAR AMARILLO SOLTERO NO REPORTADO SECUNDARIA 5318000 1
87 05/01/2015 12:00:00 AM ANTIOQUIA TURBO Lunes 9:00 CENTRO URBANA VIAS PUBLICAS 33 FEMENINO NO REPORTADO A PIE A PIE BAJAJ 2011 DISCOVER NEGRO CASADO NO REPORTADO SECUNDARIA 5837000 1

3.9 Paquete readr

El paquete readr es una herramienta esencial en R para la lectura de archivos de datos de manera rápida y eficiente. Forma parte del tidyverse, una colección de paquetes que comparten una filosofía de diseño común y son desarrollados para trabajar juntos de manera armoniosa.

3.9.1 Principales funcionalidades de readr

  1. Lectura de archivos de texto:
    • readr permite la importación de archivos de texto delimitados como CSV (read_csv()), TSV (read_tsv()), y otros formatos similares de manera eficiente y rápida. Utiliza una implementación optimizada en C++ que permite un desempeño superior en comparación con funciones base de R como read.csv().
  2. Conversión automática de tipos:
    • Una de las características más útiles de readr es su capacidad para inferir automáticamente los tipos de datos de cada columna. Esto significa que, al leer un archivo, el paquete detecta si una columna contiene números, fechas, texto, etc., y realiza la conversión adecuada automáticamente.
  3. Lectura perezosa (lazy reading):
    • En lugar de cargar todos los datos en la memoria de una sola vez, readr permite leer y procesar los datos de manera perezosa, lo que es útil para manejar archivos de gran tamaño sin sobrecargar la memoria.
  4. Funciones para otros formatos de archivos:
    • Además de CSV y TSV, readr incluye funciones para leer otros formatos como archivos delimitados por espacios (read_table()), archivos de ancho fijo (read_fwf()), y archivos de datos R (read_rds()).
  5. Facilidad de manejo de errores:
    • El paquete proporciona herramientas para detectar y manejar problemas durante la importación de datos, como valores faltantes o errores de tipo. Esto facilita la limpieza y preparación de datos para su análisis posterior.

3.10 Ejemplos de uso

  1. Lectura de un archivo CSV:
suppressWarnings({
  suppressPackageStartupMessages(library(readr))
  suppressPackageStartupMessages(library(dplyr))
  
  datos2A <- read_csv("Delito_Hurto_Motocicletas.csv",
                      locale = locale(encoding = "UTF-8"),
                      skip_empty_rows = TRUE)
})
## Rows: 27223 Columns: 22
## ── Column specification ────────────────────────────────────────────────────────
## Delimiter: ","
## chr  (17): FECHA, DEPARTAMENTO, MUNICIPIO, DIA, BARRIO, ZONA, CLASE SITIO, G...
## dbl   (4): EDAD, MODELO, CODIGO DANE, 2015
## time  (1): HORA
## 
## ℹ Use `spec()` to retrieve the full column specification for this data.
## ℹ Specify the column types or set `show_col_types = FALSE` to quiet this message.

Al visualizar la base de datos cargada View(datos2A) se observa que la fila 81 presenta problemas.

Con la ayuda de este paquete y su respectiva función problems se identifica el problema de la base de datos, en un solo paso.

probs1 <- problems(datos2A)
probs1
probs1 <- problems(datos2A)

# Ajustar las filas reportadas restando 1, dado que me presento ese problema.
probs1_adjusted <- probs1
probs1_adjusted$row <- probs1$row - 1

El comando names(probs1) se utiliza para mostrar los nombres de las columnas o las variables en el objeto probs1. En este caso, el resultado que se muestra en la salida indica que probs1 es un objeto (probablemente un data frame o lista) que contiene las siguientes variables o columnas:

names(probs1_adjusted)
## [1] "row"      "col"      "expected" "actual"   "file"

Se revelan las salidas con problemas y se verifican que el problema se presenta en las misma filas identificadas manualmente en los pasos anteriores.

probs1_adjusted$row[1:10]# Mostrar las primeras 10 filas con problemas identificadas por probs1
##  [1]   81  366  728  924 1331 1364 1490 1525 1785 1798
a2[1:10] # Obtenido "manualmente"
##  [1]   81  366  728  924 1331 1364 1490 1525 1785 1798

3.11 Se visualizan las distintas variables para observar cómo se encuentran los datos.

Variable Estado Civil

barplot(sort(table(datos$ESTADO.CIVIL),
 decreasing=TRUE),las=2)

Variable Color

barplot(sort(table(datos$COLOR),
 decreasing=TRUE),las=2)

Se muestran solo los primeros 20 colores.

barplot(sort(table(datos$COLOR),
 decreasing = TRUE)[1:20],las=2)

Variable MOVIL.AGRESOR

barplot(sort(table(datos$MOVIL.AGRESOR),
 decreasing = TRUE),las=2)

Variable HORA

barplot(sort(table(datos$HORA),
 decreasing=TRUE)[1:20],las=2)

Se carga el paquete tidyr para manipular un conjunto de datos creado y llamado datos22. Primero, se divide la columna HORA en dos nuevas columnas, HORA1 y MINS1, separando los valores en base al símbolo “:”. Luego, las nuevas columnas se convierten a formato numérico para permitir operaciones matemáticas. Finalmente, se crea una nueva columna HORAS, que representa la hora en formato decimal, sumando la parte de las horas con los minutos divididos entre 60. Este proceso facilita el análisis de las horas al convertirlas en un formato numérico continuo.

 suppressPackageStartupMessages(library(tidyr))
                                
 datos22<-separate(datos,HORA, sep=":",into=c("HORA1","MINS1" ))
                  
 datos22$HORA1<-as.numeric(datos22$HORA1)
 datos22$MINS1<-as.numeric(datos22$MINS1)
 datos22$HORAS<-datos22$HORA1+(datos22$MINS1/60)

Variable HORA, según número de robos.

 require(ggplot2)
 ggplot(datos22,aes(x=HORAS))+
 geom_density(alpha=0.4,fill="blue")

Variable HORA, según número MOVIL AGRESOR, APIE,PASAJERO MOTOCICLETA,CONDUCTORMOTOCICLETA.

datos23<-subset(datos22,subset=(MOVIL.AGRESOR==c("APIE","PASAJERO MOTOCICLETA","CONDUCTOR MOTOCICLETA")))
## Warning in MOVIL.AGRESOR == c("APIE", "PASAJERO MOTOCICLETA", "CONDUCTOR
## MOTOCICLETA"): longitud de objeto mayor no es múltiplo de la longitud de uno
## menor
ggplot(datos23,aes(x=HORAS,fill=MOVIL.AGRESOR))+geom_density(alpha=0.4)

Variable HORA, según número ESTADO CIVIL.

datos24<-subset(datos22,subset=(ESTADO.CIVIL==c("SOLTERO","UNIONLIBRE","CASADO")))
## Warning in ESTADO.CIVIL == c("SOLTERO", "UNIONLIBRE", "CASADO"): longitud de
## objeto mayor no es múltiplo de la longitud de uno menor
 ggplot(datos24,aes(x=HORAS,fill=ESTADO.CIVIL))+geom_density(alpha=0.4)

Variable HORA, según número GENERO.

datos25<-subset(datos22,subset=(GENERO!=c("NO REPORTADO")))
ggplot(datos25,aes(x=HORAS,fill=GENERO))+geom_density(alpha=0.4)

3.12 Actividad práctica #2:

Seleccione alguna de las funciones en R para leer las bases de datos que se encuentran en la cuenta de GitHub. Los archivos de datos que necesita son:

url_DHM <- "https://raw.githubusercontent.com/Kalbam/Datos/main/Delito_Hurto_Automotores.csv"
url_master <- "https://raw.githubusercontent.com/Kalbam/Datos/main/master.csv"

Utilice las funciones de R para explorar estos archivos y analizar su contenido.

  1. Explore posibles problemas leyendo las bases de datos y regístrelos brevemente. Use las funciones head, tail, summary, barplot, etc.

  2. ¿Qué solución propone para resolver dichos problemas y apliquelas?

4 Análisis Exploratorio de Datos

El análisis exploratorio de datos (Ver video) (EDA por sus siglas en inglés) implica el uso de gráficos y visualizaciones para explorar y analizar un conjunto de datos. El objetivo es explorar, investigar y aprender, no confirmar hipótesis estadísticas.

4.1 ¿Cuándo debo utilizarlo?

El análisis exploratorio de datos es una potente herramienta para explorar un conjunto de datos. Incluso cuando su objetivo es efectuar análisis planificados, el EDA puede utilizarse para limpiar datos, para análisis de subgrupos o simplemente para comprender mejor los datos. Un paso inicial importante en cualquier análisis de datos es representar los datos gráficamente.

No gráfico: Calcula estadísticas descriptivas de las variables

Gráfico: Calcula estadísticas de forma gráfica

Univariado: Analiza una sola variable a la vez

Multivariado: Analiza dos o más variables

A su vez, cada uno de esas dividisiones puede subdividirse según los tipos de datos con los que trabajemos: categóricos o numéricos.

4.2 Ejemplo Práctico.

Consideremos nuevamente la base de datos que contiene información acerca de incautaciones de bebidas alcohólicas fraudulentas y de contrabando en cierta ciudad. Puede acceder a la base de datos en el siguiente enlace: BASE_DATOS.xlsx.

url_base_Datos <-"https://raw.github.com/Kalbam/Datos/blob/main/BASE_DATOS.xlsx"

Las variables se describen como:

  • TL: Tipo de licor
  • PI: Precio de incautación. Se refiere al precio de venta en el establecimiento por unidad.
  • GAE: Grados de alcohol en etiqueta.
  • GAQ: Grados de alcohol en prueba química.
  • CE: Cantidad estandarizada. Número de unidades estandarizadas a 750 ml.
require(readxl) 
direccion="BASE_DATOS.xlsx"
DATOS<-read_excel(direccion,sheet="datos")

NOTA: La función read_excel importa un objeto tibble, que es en esencia un data.frame, pero que cuenta con algunas ventajas estéticas en las presentaciones e informes.

4.2.1 caracteristica generales de los datos

Verifiquemos que leímos bien los datos viendo el encabezado y la cola de los datos:

head(DATOS)
tail(DATOS)

Las dimensiones, los nombres de las columnas y la estructura de la base de datos se obtienen con los códigos:

dim(DATOS) # dimensiones de los datos
## [1] 300   5
colnames(DATOS) # Nombres de las columnas o variables
## [1] "TL"  "PI"  "GAE" "GAQ" "CE"
str(DATOS)
## tibble [300 × 5] (S3: tbl_df/tbl/data.frame)
##  $ TL : chr [1:300] "Aguardiente" "Aguardiente" "Aguardiente" "Aguardiente" ...
##  $ PI : num [1:300] 21470 26422 19737 30240 28374 ...
##  $ GAE: num [1:300] 29 29 29 29 38 38 29 38 38 38 ...
##  $ GAQ: num [1:300] 25.1 29 25.3 29 33.5 ...
##  $ CE : num [1:300] 251 262 289 266 232 ...

Otra función que funciona igual a str es glimpse, que hace parte del paquete tibble:

require(tibble)
glimpse(DATOS)
## Rows: 300
## Columns: 5
## $ TL  <chr> "Aguardiente", "Aguardiente", "Aguardiente", "Aguardiente", "Tequi…
## $ PI  <dbl> 21470, 26422, 19737, 30240, 28374, 33601, 33207, 33029, 30964, 309…
## $ GAE <dbl> 29, 29, 29, 29, 38, 38, 29, 38, 38, 38, 29, 29, 29, 35, 29, 38, 29…
## $ GAQ <dbl> 25.143, 29.000, 25.288, 29.000, 33.516, 31.198, 29.000, 33.060, NA…
## $ CE  <dbl> 250.6536, 261.7272, 289.1134, 266.3064, 231.7978, 248.8542, 252.57…
 summary(DATOS)
##       TL                  PI              GAE             GAQ       
##  Length:300         Min.   : 16308   Min.   :29.00   Min.   :24.27  
##  Class :character   1st Qu.: 26682   1st Qu.:29.00   1st Qu.:26.04  
##  Mode  :character   Median : 29390   Median :35.00   Median :30.07  
##                     Mean   : 31846   Mean   :33.54   Mean   :30.74  
##                     3rd Qu.: 32751   3rd Qu.:38.00   3rd Qu.:34.10  
##                     Max.   :430091   Max.   :40.00   Max.   :40.00  
##                     NA's   :5                        NA's   :2      
##        CE       
##  Min.   :  0.0  
##  1st Qu.:239.4  
##  Median :250.3  
##  Mean   :249.6  
##  3rd Qu.:261.7  
##  Max.   :296.5  
##  NA's   :3

4.2.2 Considere el resumen individual de las variables numéricas:

summary(DATOS$PI)
##    Min. 1st Qu.  Median    Mean 3rd Qu.    Max.    NA's 
##   16308   26682   29390   31846   32751  430091       5
summary(DATOS$GAE)
##    Min. 1st Qu.  Median    Mean 3rd Qu.    Max. 
##   29.00   29.00   35.00   33.54   38.00   40.00
summary(DATOS$GAQ)
##    Min. 1st Qu.  Median    Mean 3rd Qu.    Max.    NA's 
##   24.27   26.04   30.07   30.74   34.10   40.00       2

4.2.3 Análisis Descriptivo Individual Variable categórica

Para hacer una tabla de frecuencias de las variables categóricas es necesario transformar primero la variable en factor:

# Se transforma primero en factor
 TL_FACTOR<- as.factor(DATOS$TL)
 # Se obtiene el resumen
 summary(TL_FACTOR)
##  Aguardiente Aguardientre          Ron          Run      Tequila       Whiski 
##          131            1           60            1           85            1 
##       Whisky         NA's 
##           20            1

Otra forma de obtener una tabla de frecuencias para las variables categóricas consiste en utilizar la función table del paquete base, que se carga automáticamente cuando abrimos una sesión del R o del R-Studio:

table(DATOS$TL)
## 
##  Aguardiente Aguardientre          Ron          Run      Tequila       Whiski 
##          131            1           60            1           85            1 
##       Whisky 
##           20

Para extraer los nombres de las categorías de una variable categórica usamos la función labels del paquete base:

unique(DATOS$TL)
## [1] "Aguardiente"  "Tequila"      "Ron"          "Whisky"       "Run"         
## [6] NA             "Whiski"       "Aguardientre"

Reemplazar los nombres de las categorías mal codificadas, utilizamos la función str_replace del paquete stringr y lo guardamos ya corregido directamente en la variable TL de DATOS:

require(stringr)


DATOS$TL <- str_replace(DATOS$TL, "Aguardientre", "Aguardiente")

unique(DATOS$TL)
## [1] "Aguardiente" "Tequila"     "Ron"         "Whisky"      "Run"        
## [6] NA            "Whiski"

Reemplazar los nombres de las categorías mal codificadas, utilizamos la función str_replace del paquete stringr y lo guardamos ya corregido directamente en la variable TL de DATOS:

require(stringr)

reemplazos <- c("Run" = "Ron", "Whiski" = "Whisky")

DATOS$TL <- str_replace_all(DATOS$TL, reemplazos)

unique(DATOS$TL)
## [1] "Aguardiente" "Tequila"     "Ron"         "Whisky"      NA

4.2.4 Identificando valores NA:

is.na(DATOS) # Identifica cuáles valores son NA
##           TL    PI   GAE   GAQ    CE
##   [1,] FALSE FALSE FALSE FALSE FALSE
##   [2,] FALSE FALSE FALSE FALSE FALSE
##   [3,] FALSE FALSE FALSE FALSE FALSE
##   [4,] FALSE FALSE FALSE FALSE FALSE
##   [5,] FALSE FALSE FALSE FALSE FALSE
##   [6,] FALSE FALSE FALSE FALSE FALSE
##   [7,] FALSE FALSE FALSE FALSE FALSE
##   [8,] FALSE FALSE FALSE FALSE FALSE
##   [9,] FALSE FALSE FALSE  TRUE FALSE
##  [10,] FALSE FALSE FALSE FALSE FALSE
##  [11,] FALSE FALSE FALSE FALSE FALSE
##  [12,] FALSE FALSE FALSE FALSE FALSE
##  [13,] FALSE FALSE FALSE FALSE FALSE
##  [14,] FALSE FALSE FALSE FALSE FALSE
##  [15,] FALSE FALSE FALSE FALSE FALSE
##  [16,] FALSE FALSE FALSE FALSE FALSE
##  [17,] FALSE FALSE FALSE FALSE FALSE
##  [18,] FALSE FALSE FALSE FALSE FALSE
##  [19,] FALSE FALSE FALSE FALSE FALSE
##  [20,] FALSE FALSE FALSE FALSE FALSE
##  [21,] FALSE FALSE FALSE FALSE FALSE
##  [22,] FALSE FALSE FALSE FALSE FALSE
##  [23,] FALSE FALSE FALSE FALSE FALSE
##  [24,] FALSE FALSE FALSE FALSE FALSE
##  [25,] FALSE FALSE FALSE FALSE FALSE
##  [26,] FALSE FALSE FALSE FALSE FALSE
##  [27,] FALSE FALSE FALSE FALSE FALSE
##  [28,] FALSE FALSE FALSE FALSE FALSE
##  [29,] FALSE FALSE FALSE FALSE FALSE
##  [30,] FALSE FALSE FALSE FALSE FALSE
##  [31,] FALSE FALSE FALSE FALSE FALSE
##  [32,] FALSE FALSE FALSE FALSE FALSE
##  [33,] FALSE FALSE FALSE FALSE FALSE
##  [34,] FALSE FALSE FALSE FALSE FALSE
##  [35,] FALSE FALSE FALSE FALSE FALSE
##  [36,] FALSE FALSE FALSE FALSE FALSE
##  [37,] FALSE FALSE FALSE FALSE FALSE
##  [38,] FALSE FALSE FALSE FALSE FALSE
##  [39,] FALSE FALSE FALSE FALSE FALSE
##  [40,] FALSE FALSE FALSE FALSE FALSE
##  [41,] FALSE FALSE FALSE FALSE FALSE
##  [42,] FALSE FALSE FALSE FALSE FALSE
##  [43,] FALSE FALSE FALSE FALSE FALSE
##  [44,] FALSE FALSE FALSE FALSE FALSE
##  [45,] FALSE FALSE FALSE FALSE FALSE
##  [46,] FALSE FALSE FALSE FALSE FALSE
##  [47,] FALSE FALSE FALSE FALSE FALSE
##  [48,] FALSE FALSE FALSE FALSE FALSE
##  [49,] FALSE FALSE FALSE FALSE FALSE
##  [50,] FALSE FALSE FALSE FALSE FALSE
##  [51,] FALSE FALSE FALSE FALSE FALSE
##  [52,] FALSE FALSE FALSE FALSE FALSE
##  [53,] FALSE FALSE FALSE FALSE FALSE
##  [54,] FALSE FALSE FALSE FALSE FALSE
##  [55,] FALSE FALSE FALSE FALSE FALSE
##  [56,] FALSE FALSE FALSE FALSE FALSE
##  [57,] FALSE FALSE FALSE FALSE FALSE
##  [58,] FALSE FALSE FALSE FALSE FALSE
##  [59,] FALSE FALSE FALSE FALSE FALSE
##  [60,] FALSE FALSE FALSE FALSE FALSE
##  [61,] FALSE FALSE FALSE FALSE FALSE
##  [62,] FALSE FALSE FALSE FALSE FALSE
##  [63,] FALSE FALSE FALSE FALSE FALSE
##  [64,] FALSE FALSE FALSE FALSE FALSE
##  [65,] FALSE FALSE FALSE FALSE FALSE
##  [66,] FALSE FALSE FALSE FALSE FALSE
##  [67,] FALSE FALSE FALSE FALSE FALSE
##  [68,] FALSE FALSE FALSE FALSE FALSE
##  [69,] FALSE FALSE FALSE FALSE FALSE
##  [70,] FALSE FALSE FALSE FALSE FALSE
##  [71,] FALSE FALSE FALSE FALSE FALSE
##  [72,] FALSE FALSE FALSE FALSE FALSE
##  [73,] FALSE  TRUE FALSE  TRUE FALSE
##  [74,] FALSE FALSE FALSE FALSE FALSE
##  [75,] FALSE FALSE FALSE FALSE FALSE
##  [76,] FALSE FALSE FALSE FALSE FALSE
##  [77,] FALSE FALSE FALSE FALSE FALSE
##  [78,] FALSE FALSE FALSE FALSE FALSE
##  [79,] FALSE FALSE FALSE FALSE FALSE
##  [80,] FALSE FALSE FALSE FALSE FALSE
##  [81,] FALSE FALSE FALSE FALSE FALSE
##  [82,] FALSE FALSE FALSE FALSE FALSE
##  [83,] FALSE FALSE FALSE FALSE FALSE
##  [84,] FALSE FALSE FALSE FALSE FALSE
##  [85,] FALSE FALSE FALSE FALSE FALSE
##  [86,] FALSE FALSE FALSE FALSE FALSE
##  [87,] FALSE FALSE FALSE FALSE FALSE
##  [88,] FALSE FALSE FALSE FALSE FALSE
##  [89,] FALSE FALSE FALSE FALSE FALSE
##  [90,] FALSE FALSE FALSE FALSE FALSE
##  [91,] FALSE  TRUE FALSE FALSE FALSE
##  [92,] FALSE FALSE FALSE FALSE FALSE
##  [93,] FALSE FALSE FALSE FALSE FALSE
##  [94,] FALSE FALSE FALSE FALSE FALSE
##  [95,] FALSE FALSE FALSE FALSE FALSE
##  [96,] FALSE FALSE FALSE FALSE FALSE
##  [97,] FALSE FALSE FALSE FALSE FALSE
##  [98,] FALSE FALSE FALSE FALSE FALSE
##  [99,] FALSE FALSE FALSE FALSE FALSE
## [100,] FALSE FALSE FALSE FALSE FALSE
## [101,] FALSE FALSE FALSE FALSE FALSE
## [102,] FALSE FALSE FALSE FALSE FALSE
## [103,] FALSE FALSE FALSE FALSE FALSE
## [104,] FALSE FALSE FALSE FALSE FALSE
## [105,] FALSE FALSE FALSE FALSE FALSE
## [106,] FALSE FALSE FALSE FALSE FALSE
## [107,] FALSE FALSE FALSE FALSE FALSE
## [108,] FALSE  TRUE FALSE FALSE FALSE
## [109,] FALSE FALSE FALSE FALSE FALSE
## [110,] FALSE FALSE FALSE FALSE FALSE
## [111,] FALSE FALSE FALSE FALSE FALSE
## [112,] FALSE FALSE FALSE FALSE FALSE
## [113,] FALSE FALSE FALSE FALSE FALSE
## [114,] FALSE FALSE FALSE FALSE FALSE
## [115,] FALSE FALSE FALSE FALSE FALSE
## [116,] FALSE FALSE FALSE FALSE FALSE
## [117,]  TRUE FALSE FALSE FALSE FALSE
## [118,] FALSE FALSE FALSE FALSE FALSE
## [119,] FALSE FALSE FALSE FALSE FALSE
## [120,] FALSE FALSE FALSE FALSE FALSE
## [121,] FALSE FALSE FALSE FALSE FALSE
## [122,] FALSE FALSE FALSE FALSE FALSE
## [123,] FALSE FALSE FALSE FALSE FALSE
## [124,] FALSE FALSE FALSE FALSE FALSE
## [125,] FALSE FALSE FALSE FALSE FALSE
## [126,] FALSE FALSE FALSE FALSE FALSE
## [127,] FALSE FALSE FALSE FALSE FALSE
## [128,] FALSE FALSE FALSE FALSE  TRUE
## [129,] FALSE FALSE FALSE FALSE FALSE
## [130,] FALSE FALSE FALSE FALSE FALSE
## [131,] FALSE FALSE FALSE FALSE FALSE
## [132,] FALSE FALSE FALSE FALSE FALSE
## [133,] FALSE FALSE FALSE FALSE FALSE
## [134,] FALSE FALSE FALSE FALSE FALSE
## [135,] FALSE FALSE FALSE FALSE FALSE
## [136,] FALSE FALSE FALSE FALSE FALSE
## [137,] FALSE FALSE FALSE FALSE FALSE
## [138,] FALSE FALSE FALSE FALSE FALSE
## [139,] FALSE FALSE FALSE FALSE  TRUE
## [140,] FALSE FALSE FALSE FALSE FALSE
## [141,] FALSE FALSE FALSE FALSE FALSE
## [142,] FALSE FALSE FALSE FALSE FALSE
## [143,] FALSE FALSE FALSE FALSE FALSE
## [144,] FALSE FALSE FALSE FALSE FALSE
## [145,] FALSE FALSE FALSE FALSE FALSE
## [146,] FALSE FALSE FALSE FALSE FALSE
## [147,] FALSE FALSE FALSE FALSE FALSE
## [148,] FALSE FALSE FALSE FALSE FALSE
## [149,] FALSE FALSE FALSE FALSE FALSE
## [150,] FALSE  TRUE FALSE FALSE  TRUE
## [151,] FALSE FALSE FALSE FALSE FALSE
## [152,] FALSE FALSE FALSE FALSE FALSE
## [153,] FALSE FALSE FALSE FALSE FALSE
## [154,] FALSE FALSE FALSE FALSE FALSE
## [155,] FALSE FALSE FALSE FALSE FALSE
## [156,] FALSE FALSE FALSE FALSE FALSE
## [157,] FALSE FALSE FALSE FALSE FALSE
## [158,] FALSE FALSE FALSE FALSE FALSE
## [159,] FALSE FALSE FALSE FALSE FALSE
## [160,] FALSE FALSE FALSE FALSE FALSE
## [161,] FALSE FALSE FALSE FALSE FALSE
## [162,] FALSE FALSE FALSE FALSE FALSE
## [163,] FALSE FALSE FALSE FALSE FALSE
## [164,] FALSE FALSE FALSE FALSE FALSE
## [165,] FALSE FALSE FALSE FALSE FALSE
## [166,] FALSE FALSE FALSE FALSE FALSE
## [167,] FALSE FALSE FALSE FALSE FALSE
## [168,] FALSE FALSE FALSE FALSE FALSE
## [169,] FALSE FALSE FALSE FALSE FALSE
## [170,] FALSE FALSE FALSE FALSE FALSE
## [171,] FALSE FALSE FALSE FALSE FALSE
## [172,] FALSE FALSE FALSE FALSE FALSE
## [173,] FALSE FALSE FALSE FALSE FALSE
## [174,] FALSE FALSE FALSE FALSE FALSE
## [175,] FALSE  TRUE FALSE FALSE FALSE
## [176,] FALSE FALSE FALSE FALSE FALSE
## [177,] FALSE FALSE FALSE FALSE FALSE
## [178,] FALSE FALSE FALSE FALSE FALSE
## [179,] FALSE FALSE FALSE FALSE FALSE
## [180,] FALSE FALSE FALSE FALSE FALSE
## [181,] FALSE FALSE FALSE FALSE FALSE
## [182,] FALSE FALSE FALSE FALSE FALSE
## [183,] FALSE FALSE FALSE FALSE FALSE
## [184,] FALSE FALSE FALSE FALSE FALSE
## [185,] FALSE FALSE FALSE FALSE FALSE
## [186,] FALSE FALSE FALSE FALSE FALSE
## [187,] FALSE FALSE FALSE FALSE FALSE
## [188,] FALSE FALSE FALSE FALSE FALSE
## [189,] FALSE FALSE FALSE FALSE FALSE
## [190,] FALSE FALSE FALSE FALSE FALSE
## [191,] FALSE FALSE FALSE FALSE FALSE
## [192,] FALSE FALSE FALSE FALSE FALSE
## [193,] FALSE FALSE FALSE FALSE FALSE
## [194,] FALSE FALSE FALSE FALSE FALSE
## [195,] FALSE FALSE FALSE FALSE FALSE
## [196,] FALSE FALSE FALSE FALSE FALSE
## [197,] FALSE FALSE FALSE FALSE FALSE
## [198,] FALSE FALSE FALSE FALSE FALSE
## [199,] FALSE FALSE FALSE FALSE FALSE
## [200,] FALSE FALSE FALSE FALSE FALSE
## [201,] FALSE FALSE FALSE FALSE FALSE
## [202,] FALSE FALSE FALSE FALSE FALSE
## [203,] FALSE FALSE FALSE FALSE FALSE
## [204,] FALSE FALSE FALSE FALSE FALSE
## [205,] FALSE FALSE FALSE FALSE FALSE
## [206,] FALSE FALSE FALSE FALSE FALSE
## [207,] FALSE FALSE FALSE FALSE FALSE
## [208,] FALSE FALSE FALSE FALSE FALSE
## [209,] FALSE FALSE FALSE FALSE FALSE
## [210,] FALSE FALSE FALSE FALSE FALSE
## [211,] FALSE FALSE FALSE FALSE FALSE
## [212,] FALSE FALSE FALSE FALSE FALSE
## [213,] FALSE FALSE FALSE FALSE FALSE
## [214,] FALSE FALSE FALSE FALSE FALSE
## [215,] FALSE FALSE FALSE FALSE FALSE
## [216,] FALSE FALSE FALSE FALSE FALSE
## [217,] FALSE FALSE FALSE FALSE FALSE
## [218,] FALSE FALSE FALSE FALSE FALSE
## [219,] FALSE FALSE FALSE FALSE FALSE
## [220,] FALSE FALSE FALSE FALSE FALSE
## [221,] FALSE FALSE FALSE FALSE FALSE
## [222,] FALSE FALSE FALSE FALSE FALSE
## [223,] FALSE FALSE FALSE FALSE FALSE
## [224,] FALSE FALSE FALSE FALSE FALSE
## [225,] FALSE FALSE FALSE FALSE FALSE
## [226,] FALSE FALSE FALSE FALSE FALSE
## [227,] FALSE FALSE FALSE FALSE FALSE
## [228,] FALSE FALSE FALSE FALSE FALSE
## [229,] FALSE FALSE FALSE FALSE FALSE
## [230,] FALSE FALSE FALSE FALSE FALSE
## [231,] FALSE FALSE FALSE FALSE FALSE
## [232,] FALSE FALSE FALSE FALSE FALSE
## [233,] FALSE FALSE FALSE FALSE FALSE
## [234,] FALSE FALSE FALSE FALSE FALSE
## [235,] FALSE FALSE FALSE FALSE FALSE
## [236,] FALSE FALSE FALSE FALSE FALSE
## [237,] FALSE FALSE FALSE FALSE FALSE
## [238,] FALSE FALSE FALSE FALSE FALSE
## [239,] FALSE FALSE FALSE FALSE FALSE
## [240,] FALSE FALSE FALSE FALSE FALSE
## [241,] FALSE FALSE FALSE FALSE FALSE
## [242,] FALSE FALSE FALSE FALSE FALSE
## [243,] FALSE FALSE FALSE FALSE FALSE
## [244,] FALSE FALSE FALSE FALSE FALSE
## [245,] FALSE FALSE FALSE FALSE FALSE
## [246,] FALSE FALSE FALSE FALSE FALSE
## [247,] FALSE FALSE FALSE FALSE FALSE
## [248,] FALSE FALSE FALSE FALSE FALSE
## [249,] FALSE FALSE FALSE FALSE FALSE
## [250,] FALSE FALSE FALSE FALSE FALSE
## [251,] FALSE FALSE FALSE FALSE FALSE
## [252,] FALSE FALSE FALSE FALSE FALSE
## [253,] FALSE FALSE FALSE FALSE FALSE
## [254,] FALSE FALSE FALSE FALSE FALSE
## [255,] FALSE FALSE FALSE FALSE FALSE
## [256,] FALSE FALSE FALSE FALSE FALSE
## [257,] FALSE FALSE FALSE FALSE FALSE
## [258,] FALSE FALSE FALSE FALSE FALSE
## [259,] FALSE FALSE FALSE FALSE FALSE
## [260,] FALSE FALSE FALSE FALSE FALSE
## [261,] FALSE FALSE FALSE FALSE FALSE
## [262,] FALSE FALSE FALSE FALSE FALSE
## [263,] FALSE FALSE FALSE FALSE FALSE
## [264,] FALSE FALSE FALSE FALSE FALSE
## [265,] FALSE FALSE FALSE FALSE FALSE
## [266,] FALSE FALSE FALSE FALSE FALSE
## [267,] FALSE FALSE FALSE FALSE FALSE
## [268,] FALSE FALSE FALSE FALSE FALSE
## [269,] FALSE FALSE FALSE FALSE FALSE
## [270,] FALSE FALSE FALSE FALSE FALSE
## [271,] FALSE FALSE FALSE FALSE FALSE
## [272,] FALSE FALSE FALSE FALSE FALSE
## [273,] FALSE FALSE FALSE FALSE FALSE
## [274,] FALSE FALSE FALSE FALSE FALSE
## [275,] FALSE FALSE FALSE FALSE FALSE
## [276,] FALSE FALSE FALSE FALSE FALSE
## [277,] FALSE FALSE FALSE FALSE FALSE
## [278,] FALSE FALSE FALSE FALSE FALSE
## [279,] FALSE FALSE FALSE FALSE FALSE
## [280,] FALSE FALSE FALSE FALSE FALSE
## [281,] FALSE FALSE FALSE FALSE FALSE
## [282,] FALSE FALSE FALSE FALSE FALSE
## [283,] FALSE FALSE FALSE FALSE FALSE
## [284,] FALSE FALSE FALSE FALSE FALSE
## [285,] FALSE FALSE FALSE FALSE FALSE
## [286,] FALSE FALSE FALSE FALSE FALSE
## [287,] FALSE FALSE FALSE FALSE FALSE
## [288,] FALSE FALSE FALSE FALSE FALSE
## [289,] FALSE FALSE FALSE FALSE FALSE
## [290,] FALSE FALSE FALSE FALSE FALSE
## [291,] FALSE FALSE FALSE FALSE FALSE
## [292,] FALSE FALSE FALSE FALSE FALSE
## [293,] FALSE FALSE FALSE FALSE FALSE
## [294,] FALSE FALSE FALSE FALSE FALSE
## [295,] FALSE FALSE FALSE FALSE FALSE
## [296,] FALSE FALSE FALSE FALSE FALSE
## [297,] FALSE FALSE FALSE FALSE FALSE
## [298,] FALSE FALSE FALSE FALSE FALSE
## [299,] FALSE FALSE FALSE FALSE FALSE
## [300,] FALSE FALSE FALSE FALSE FALSE
is.na(DATOS$TL) # Identifica cuáles valores son NA en TL
##   [1] FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE
##  [13] FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE
##  [25] FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE
##  [37] FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE
##  [49] FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE
##  [61] FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE
##  [73] FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE
##  [85] FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE
##  [97] FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE
## [109] FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE  TRUE FALSE FALSE FALSE
## [121] FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE
## [133] FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE
## [145] FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE
## [157] FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE
## [169] FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE
## [181] FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE
## [193] FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE
## [205] FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE
## [217] FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE
## [229] FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE
## [241] FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE
## [253] FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE
## [265] FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE
## [277] FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE
## [289] FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE

4.2.5 Identificando valores NA por columna:

 NAS_TL<-is.na(DATOS$TL) #GuardamosenNAS_TL
 DATOS[NAS_TL,] #FiltramosporlosNASdeTL
NAS_PI<-is.na(DATOS$PI) # Guardamos en NAS_PI
 DATOS[NAS_TL | NAS_PI,] # Filtramos por los NAS de TL y PI

4.2.6 Identificando las filas con al menos un NA:

La función complete.cases del paquete stats nos muestra cuáles filas tienen datos en TODAS sus columnas:

complete.cases(DATOS)
##   [1]  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE FALSE  TRUE  TRUE  TRUE
##  [13]  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE
##  [25]  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE
##  [37]  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE
##  [49]  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE
##  [61]  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE
##  [73] FALSE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE
##  [85]  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE FALSE  TRUE  TRUE  TRUE  TRUE  TRUE
##  [97]  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE FALSE
## [109]  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE FALSE  TRUE  TRUE  TRUE
## [121]  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE FALSE  TRUE  TRUE  TRUE  TRUE
## [133]  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE FALSE  TRUE  TRUE  TRUE  TRUE  TRUE
## [145]  TRUE  TRUE  TRUE  TRUE  TRUE FALSE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE
## [157]  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE
## [169]  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE FALSE  TRUE  TRUE  TRUE  TRUE  TRUE
## [181]  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE
## [193]  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE
## [205]  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE
## [217]  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE
## [229]  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE
## [241]  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE
## [253]  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE
## [265]  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE
## [277]  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE
## [289]  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE

Cuando negamos estos casos completos obtenemos las filas donde hay al menos un valor faltante, es decir,

!complete.cases(DATOS)
##   [1] FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE  TRUE FALSE FALSE FALSE
##  [13] FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE
##  [25] FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE
##  [37] FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE
##  [49] FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE
##  [61] FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE
##  [73]  TRUE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE
##  [85] FALSE FALSE FALSE FALSE FALSE FALSE  TRUE FALSE FALSE FALSE FALSE FALSE
##  [97] FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE  TRUE
## [109] FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE  TRUE FALSE FALSE FALSE
## [121] FALSE FALSE FALSE FALSE FALSE FALSE FALSE  TRUE FALSE FALSE FALSE FALSE
## [133] FALSE FALSE FALSE FALSE FALSE FALSE  TRUE FALSE FALSE FALSE FALSE FALSE
## [145] FALSE FALSE FALSE FALSE FALSE  TRUE FALSE FALSE FALSE FALSE FALSE FALSE
## [157] FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE
## [169] FALSE FALSE FALSE FALSE FALSE FALSE  TRUE FALSE FALSE FALSE FALSE FALSE
## [181] FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE
## [193] FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE
## [205] FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE
## [217] FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE
## [229] FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE
## [241] FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE
## [253] FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE
## [265] FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE
## [277] FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE
## [289] FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE

Guardamos los valores anteriores en un vector para luego filtrar por las filas donde hay al menos un valor NA:

NAS_ALL <- !complete.cases(DATOS)

DATOS[NAS_ALL, ]  # Filas donde hay al menos un valor NA

4.2.7 Gráfica que identifica los NA en cada variable:

suppressWarnings(require(Amelia))
## Loading required package: Amelia
## Loading required package: Rcpp
## ## 
## ## Amelia II: Multiple Imputation
## ## (Version 1.8.2, built: 2024-04-10)
## ## Copyright (C) 2005-2024 James Honaker, Gary King and Matthew Blackwell
## ## Refer to http://gking.harvard.edu/amelia/ for more information
## ##
suppressWarnings(missmap(DATOS))

summary(DATOS)# Analicemos las mediadas de tendencia
##       TL                  PI              GAE             GAQ       
##  Length:300         Min.   : 16308   Min.   :29.00   Min.   :24.27  
##  Class :character   1st Qu.: 26682   1st Qu.:29.00   1st Qu.:26.04  
##  Mode  :character   Median : 29390   Median :35.00   Median :30.07  
##                     Mean   : 31846   Mean   :33.54   Mean   :30.74  
##                     3rd Qu.: 32751   3rd Qu.:38.00   3rd Qu.:34.10  
##                     Max.   :430091   Max.   :40.00   Max.   :40.00  
##                     NA's   :5                        NA's   :2      
##        CE       
##  Min.   :  0.0  
##  1st Qu.:239.4  
##  Median :250.3  
##  Mean   :249.6  
##  3rd Qu.:261.7  
##  Max.   :296.5  
##  NA's   :3

4.2.8 Identificando los valores atípicos:

 par(mfrow=c(1,4))
 boxplot(DATOS$PI,main="PI")
 boxplot(DATOS$GAE,main="GAE")
 boxplot(DATOS$GAQ,main="GAQ")
 boxplot(DATOS$CE,main="CE")

De los gráficos anteriores podemos ver que:

  • La variable PI tiene algunos valores atípicos muy altos.
  • Las variables GAE y GAQ NO presentan valores atípicos muy altos o muy bajos.
  • La variable CE presenta valores atípicos muy bajos.

Filtramos los datos sin los valores atípicos de la variable PI y de la variable CE, filtrando con la función filter del paquete dplyr con el siguiente código:

require(dplyr)
filter(DATOS, PI > 100000)
filter(DATOS, CE < 200)

Reemplazamos los valores atípicos por valores NA (lo cual es equivalente a eliminarlos):

DATOS$PI[DATOS$PI > 100000] <- NA
DATOS$CE[DATOS$CE < 200] <- NA

Repetimos los gráficos boxplot:

par(mfrow=c(1,4))
 boxplot(DATOS$PI,main="PI")
 boxplot(DATOS$GAE,main="GAE")
 boxplot(DATOS$GAQ,main="GAQ")
 boxplot(DATOS$CE,main="CE")

4.2.9 Reemplazando los valores NA de la variable Númerica:

Si se supone que estas variables tienen Distribución normal, se modifican por la Media, de lo contrario seria por la Mediana, como técnica básica de Imputación de datos.

Calculamos la media de las columnas numéricas con la función colMeans del paquete base. Para esto primero excluimos la variable categórica TL que se encuentra en la columna 1:

medias <- colMeans(DATOS[,-1], na.rm = TRUE)
medias
##          PI         GAE         GAQ          CE 
## 29518.52560    33.54000    30.74141   250.49003

El argumento na.rm=TRUE permite calcular las medias de los datos que no son NA.

4.2.10 Verificamos que ya no hay valores NA en las variables numéricas:

Para esto usamos la función replace_na del paquete tidyr:

require(tidyr)  # Cargamos el paquete

# Creamos una lista con los reemplazos:
reemplazos <- list(PI = medias[1], GAE = medias[2], GAQ = medias[3], CE = medias[4])

# Reemplazamos y guardamos en DATOS:
DATOS <- replace_na(DATOS, reemplazos)
summary(DATOS)
##       TL                  PI             GAE             GAQ       
##  Length:300         Min.   :16308   Min.   :29.00   Min.   :24.27  
##  Class :character   1st Qu.:26710   1st Qu.:29.00   1st Qu.:26.04  
##  Mode  :character   Median :29519   Median :35.00   Median :30.22  
##                     Mean   :29519   Mean   :33.54   Mean   :30.74  
##                     3rd Qu.:32459   3rd Qu.:38.00   3rd Qu.:34.07  
##                     Max.   :42022   Max.   :40.00   Max.   :40.00  
##        CE       
##  Min.   :210.9  
##  1st Qu.:239.7  
##  Median :250.5  
##  Mean   :250.5  
##  3rd Qu.:261.5  
##  Max.   :296.5

4.2.11 Reemplazando los valores NA de la variable categórica:

unique(DATOS$TL)
## [1] "Aguardiente" "Tequila"     "Ron"         "Whisky"      NA
FACTOR_TL<-as.factor(DATOS$TL) #Convertimos en factorTL
 FRECUENCIAS_TL<-summary(FACTOR_TL) #Tabla de frecuencias
 barplot(FRECUENCIAS_TL) #Graficamos las frecuencias

Si decidimos reemplazar por el valor más frecuente, lo cual NO es recomendable, lo hacemos con el código:

reemplazos <- list(TL = "Aguardiente")
DATOS <- replace_na(DATOS, reemplazos)

# Verificamos el cambio:
unique(DATOS$TL)
## [1] "Aguardiente" "Tequila"     "Ron"         "Whisky"
 FACTOR_TL<-as.factor(DATOS$TL) #Convertimos enfactor TL
 FRECUENCIAS_TL<-summary(FACTOR_TL) #Tabla de frecuencias
 barplot(FRECUENCIAS_TL) #Graficamos las frecuencias

4.2.12 Finalmente se realiza el esquema de los Datos y se verifica que no se encuentren NAS

suppressWarnings(missmap(DATOS))

4.3 Operadores pipe %>% y %<>%

Los desarrolladores del R-Studio cada vez crean herramientas que buscan simplificar los códigos que utilizamos en R.

Dos herramientas muy útiles son:

  • El operador pipe de continuidad: %>%.
  • Operador pipe de asignación compuesta: %<>%.

Dichos operadores se encuentran en el paquete magrittr.

4.3.1 ¿Cómo podemos usar estos operadores?

La mejor manera de ver el uso de los pipes de continuidad y de asignación compuesta es a través de ejemplos.

Considere que tenemos una variable x que tiene un valor igual a (-3). Queremos aplicar a x:

  • Primero la función valor absoluto;
  • Luego al resultado anterior aplicarle logaritmo natural y;
  • Finalmente al resultado anterior aplicarle raíz cuadrada.
suppressWarnings(require(magrittr)) #Cargamos el paquete
## Loading required package: magrittr
## 
## Attaching package: 'magrittr'
## The following object is masked from 'package:purrr':
## 
##     set_names
## The following object is masked from 'package:tidyr':
## 
##     extract
 x<-(-3)
 r_1<-abs(x) #r_1 es el primer resultado.
 r_2<-log(r_1) #r_2 es el segundo resultado.
 r_3<-sqrt(r_2)#r_3es el tercer y último resultado.
 r_3#Este es el resultado finalque se quería obtener
## [1] 1.048147

En un solo renglón esto podría ser escrito como:

x<-(-3)
 r_3<-sqrt(log(abs(x))) #Las tres funciones se aplican
 r_3
## [1] 1.048147

Ousando el pipe de continuidad %>% sería:

x<-(-3)
 r_3<-x %>%abs %>%log %>%sqrt #Las tres funciones se aplican
 r_3
## [1] 1.048147

Si deseamos reemplazar el valor de x por el resultado final, utilizamos el pipe compuesto %<>%, es decir,

x <- (-3)

x %<>% abs %<>% log %<>% sqrt  # Las tres funciones se aplican

# El valor de x ya no es (-3) sino el resultado final deseado:

x
## [1] 1.048147

4.4 Aplicación práctica #1 de los operadores.

Anteriormente vimos que cómo obtener un gráfico de barra con los códigos:

FACTOR_TL <- as.factor(DATOS$TL)  # Convertimos en factor TL
FRECUENCIAS_TL <- summary(FACTOR_TL)  # Tabla de frecuencias
barplot(FRECUENCIAS_TL)  # Graficamos las frecuencias

Los tres renglones anteriores se pueden resumir con los pipes:

DATOS$TL %>% as.factor %>% summary %>% barplot

4.5 Aplicación práctica #2 de los operadores %>% y %<>% para los nombres de las variables.

En esta sección, utilizaremos operadores para modificar y manejar los nombres de las variables en la base de datos master.csv. Esto es particularmente útil cuando los nombres de las columnas no son intuitivos o contienen caracteres que pueden complicar su manipulación en R.

Consideremos nuevamente la base de datos master.csv:

  • Si leemos con la función read.csv del paquete utils:

4.6 Manejando los nombres de las variables:

En esta sección, utilizaremos operadores para modificar y manejar los nombres de las variables en la base de datos master.csv. Esto es particularmente útil cuando los nombres de las columnas no son intuitivos o contienen caracteres que pueden complicar su manipulación en R.

Consideremos nuevamente la base de datos master.csv:

direccion <- "https://raw.github.com/Kalbam/Datos/blob/main/master.csv"
master<-read_csv("master.csv")
## Rows: 27820 Columns: 12
## ── Column specification ────────────────────────────────────────────────────────
## Delimiter: ","
## chr (5): country, sex, age, country-year, generation
## dbl (6): year, suicides_no, population, suicides/100k pop, HDI for year, gdp...
## num (1): gdp_for_year ($)
## 
## ℹ Use `spec()` to retrieve the full column specification for this data.
## ℹ Specify the column types or set `show_col_types = FALSE` to quiet this message.
master %>% names  # Equivalente a: names(master)
##  [1] "country"            "year"               "sex"               
##  [4] "age"                "suicides_no"        "population"        
##  [7] "suicides/100k pop"  "country-year"       "HDI for year"      
## [10] "gdp_for_year ($)"   "gdp_per_capita ($)" "generation"

4.6.1 Limpiando los nombres de las variables:

Para facilitar la manipulación de las variables en R, es recomendable limpiar los nombres de las columnas, eliminando caracteres especiales y estandarizando el formato. Para esto, utilizaremos la función clean_names del paquete janitor.

suppressWarnings(require(janitor))  # Contiene la función clean_names
## Loading required package: janitor
## 
## Attaching package: 'janitor'
## The following objects are masked from 'package:stats':
## 
##     chisq.test, fisher.test
master %<>% clean_names  # Equivalente a: master <- clean_names(master)

4.6.2 Renombrando las variables:

viejos <- master %>% names
viejos
##  [1] "country"           "year"              "sex"              
##  [4] "age"               "suicides_no"       "population"       
##  [7] "suicides_100k_pop" "country_year"      "hdi_for_year"     
## [10] "gdp_for_year"      "gdp_per_capita"    "generation"
require(dplyr)  # Este paquete contiene la función rename

master %<>% rename(
  pais = viejos[1],
  anio = viejos[2],
  sexo = viejos[3],
  edad = viejos[4],
  num_suic = viejos[5],
  poblacion = viejos[6],
  suic_x100k = viejos[7],
  pais_anio = viejos[8],
  idh_anio = viejos[9],
  pib_anio = viejos[10],
  pib_pcap = viejos[11],
  generacion = viejos[12]
)

4.6.3 Vemos el efecto de los cambios de nombres en las variables:

Después de realizar los cambios en los nombres de las variables, podemos verificar el resultado ejecutando el siguiente código:

master %>% names
##  [1] "pais"       "anio"       "sexo"       "edad"       "num_suic"  
##  [6] "poblacion"  "suic_x100k" "pais_anio"  "idh_anio"   "pib_anio"  
## [11] "pib_pcap"   "generacion"

4.6.4 Estructura de la base de datos:

Para revisar la estructura de la base de datos y entender mejor el tipo de datos que contiene cada columna, utilizamos la función str():

str(master)
## spc_tbl_ [27,820 × 12] (S3: spec_tbl_df/tbl_df/tbl/data.frame)
##  $ pais      : chr [1:27820] "Albania" "Albania" "Albania" "Albania" ...
##  $ anio      : num [1:27820] 1987 1987 1987 1987 1987 ...
##  $ sexo      : chr [1:27820] "male" "male" "female" "male" ...
##  $ edad      : chr [1:27820] "15-24 years" "35-54 years" "15-24 years" "75+ years" ...
##  $ num_suic  : num [1:27820] 21 16 14 1 9 1 6 4 1 0 ...
##  $ poblacion : num [1:27820] 312900 308000 289700 21800 274300 ...
##  $ suic_x100k: num [1:27820] 6.71 5.19 4.83 4.59 3.28 2.81 2.15 1.56 0.73 0 ...
##  $ pais_anio : chr [1:27820] "Albania1987" "Albania1987" "Albania1987" "Albania1987" ...
##  $ idh_anio  : num [1:27820] NA NA NA NA NA NA NA NA NA NA ...
##  $ pib_anio  : num [1:27820] 2.16e+09 2.16e+09 2.16e+09 2.16e+09 2.16e+09 ...
##  $ pib_pcap  : num [1:27820] 796 796 796 796 796 796 796 796 796 796 ...
##  $ generacion: chr [1:27820] "Generation X" "Silent" "Generation X" "G.I. Generation" ...
##  - attr(*, "spec")=
##   .. cols(
##   ..   country = col_character(),
##   ..   year = col_double(),
##   ..   sex = col_character(),
##   ..   age = col_character(),
##   ..   suicides_no = col_double(),
##   ..   population = col_double(),
##   ..   `suicides/100k pop` = col_double(),
##   ..   `country-year` = col_character(),
##   ..   `HDI for year` = col_double(),
##   ..   `gdp_for_year ($)` = col_number(),
##   ..   `gdp_per_capita ($)` = col_double(),
##   ..   generation = col_character()
##   .. )
##  - attr(*, "problems")=<externalptr>

Cuando leemos la base de datos master.csv con la función read.csv tenemos un problema con las comas de la variable PIB por año, lo cual hace que sea reconocida como una variable categórica. Esto lo vemos observando los primeros 5 datos de dicha variable:

master$pib_anio[1:5]
## [1] 2156624900 2156624900 2156624900 2156624900 2156624900

4.7 Manejando los nombres de las variables:

  • Si leemos con la función read_csv del paquete readr:
require(readr)
direccion <- "master.csv"
master <- read_csv(direccion)
## Rows: 27820 Columns: 12
## ── Column specification ────────────────────────────────────────────────────────
## Delimiter: ","
## chr (5): country, sex, age, country-year, generation
## dbl (6): year, suicides_no, population, suicides/100k pop, HDI for year, gdp...
## num (1): gdp_for_year ($)
## 
## ℹ Use `spec()` to retrieve the full column specification for this data.
## ℹ Specify the column types or set `show_col_types = FALSE` to quiet this message.
master %>% names
##  [1] "country"            "year"               "sex"               
##  [4] "age"                "suicides_no"        "population"        
##  [7] "suicides/100k pop"  "country-year"       "HDI for year"      
## [10] "gdp_for_year ($)"   "gdp_per_capita ($)" "generation"

4.7.1 Renombrando las variables:

viejos <- master %>% names
viejos
##  [1] "country"            "year"               "sex"               
##  [4] "age"                "suicides_no"        "population"        
##  [7] "suicides/100k pop"  "country-year"       "HDI for year"      
## [10] "gdp_for_year ($)"   "gdp_per_capita ($)" "generation"

4.8 Actividad Práctica 3 - R:

Considere la base de datos master.csv con respecto a tasas de suicidios mundiales entre 1985 y 2016. La url es:

https://www.kaggle.com/russellyates88/suicide-rates-overview-1985-to-2016

La base de datos Suicide Rates Overview 1985 to 2016 se refiere a lo siguiente:

Existen varias señales correlacionadas con el aumento de las tasas de suicidios mundial, este conjunto de datos fue creado para encontrar este tipo de señales y contiene 27,820 observaciones que aportan información tanto socioeconómica como demográfica de cada país.

Las variables se codificaron como:

  • suicides/100k: suicidios por cada 100 mil habitantes (tasas de suicidio).
  • country: país.
  • year: año.
  • sex: género (male, female).
  • age: edad (grupo de edad).
  • suicides_no: número de suicidios.
  • population: población.
  • country-year: clave compuesta país-año.
  • HDI: índice de desarrollo humano (IDH) por año.
  • gdp_for_year ($): producto interno bruto (PIB) por año.
  • gdp_per_capita: producto interno bruto per capita.
  • generation: generación.

4.8.1 Realice lo siguiente:

  1. Importe la base de datos.
  2. Analice las características de la base de datos. Estas pueden incluir: número de filas, número de columnas, nombres de las variables, tipos de variables, entre otras.
  3. Analice cada una de las variables según su tipo: numéricas y categóricas.
  4. Filtre la base de datos para entender mejor su estructura.
  5. Explore la ayuda de la función table del paquete base y utilícela para explorar la base de datos.
  6. Identifique los valores NA (Not Available) en la base de datos.
  7. Analice la presencia de posibles valores atípicos.
  8. Decida qué hacer con los valores NA.

5 Situación Problema.

Exploración de la Intersección entre la Psicología y la Ciencia de Datos: Comportamiento Humano en Entornos Digitales

En un centro de investigación psicológica enfocado en el comportamiento humano en entornos digitales como redes sociales y plataformas de juegos en línea. Recopilamos datos que incluyen variables demográficas, patrones de uso de redes sociales, datos de juegos en línea y mediciones psicológicas. Utilizamos herramientas de ciencia de datos y análisis estadístico para identificar patrones significativos que ayuden a comprender cómo diferentes factores influyen en el comportamiento en línea y el bienestar psicológico. Este enfoque integrado entre la psicología y la ciencia de datos nos permite desarrollar intervenciones efectivas para mejorar la calidad de vida en línea y promover la salud mental de los usuarios.

5.1 Construcción de una base de datos

A continuación se construirá la primera base de datos a partir de las variables. Para esto, como se observa en los siguientes comandos, se parte por la construcción de 11 variables de 20 casos cada una:

#Creación de las variables: todas tienen la misma cantidad de casos.
Paciente <- c("Mario", "Luis", "Pedro", "Maria", "Sandra", "Erika", "Laura","Luz","Olga")
Edad <- c(18, 20, 20, 17, 19, 22, 22, 22,31)
Sexo <- c("Masculino", "Femenino", "Masculino", "Femenino", "Masculino", "Femenino", "Masculino", "Femenino","Femenino")
Educacion <- c("Universidad", "Secundaria", "Universidad", "Posgrado", "Universidad", "Universidad", "Universidad", "Posgrado","Posgrado")
Ocupacion <- c("Estudiante", "Profesional", "Estudiante", "Profesional", "Estudiante", "Profesional", "Estudiante", "Profesional","Posgrado")
Red_Social_Principal <- c("Instagram", "Facebook", "Instagram", "Twitter", "TikTok", "Instagram", "Facebook", "Instagram","TikTok")
Tiempo_en_Redes_Sociales <- c(2.5, 3.0, 2.0, 2.5, 3.5, 2.2, 2.8, 3.0,2.0)
Horas_Semanales_de_Juego <- c(15, 20, 12, 10, 18, 15, 20, 15,41)
Autoestima <- c(8.2, 6.9, 7.8, 7.0, 8.5, 7.3, 8.0, 7.6,9)
Ansiedad_Social <- c(42, 50, 38, 45, 35, 48, 40, 42,45)
Satisfaccion_con_la_Vida <- c(7.5, 6.9, 8.0, 7.2, 7.8, 6.5, 7.0, 7.3,8)
Estres<- c(2,2,1,3,4,2,1,4,4)

A partir de las variables ya creadas se puede construir una base de datos.

df=data.frame(Paciente, Edad,Sexo,Edad,Educacion, Ocupacion, Red_Social_Principal,Horas_Semanales_de_Juego,Ansiedad_Social,Satisfaccion_con_la_Vida,Estres)
df

6 Representación de datos

La representación de datos se refiere al proceso de presentar la información de manera visual o tabular para facilitar su comprensión, análisis y comunicación. Esta representación puede tomar diversas formas, incluyendo gráficos, tablas, diagramas, mapas y resúmenes estadísticos. El objetivo principal de la representación de datos es convertir datos crudos en información comprensible y significativa.

Aquí hay una descripción de algunas formas comunes de representación de datos:

Gráficos: Los gráficos son representaciones visuales de datos que utilizan diferentes tipos de elementos visuales, como líneas, barras, puntos y áreas, para mostrar la relación entre variables o la distribución de datos. Algunos tipos comunes de gráficos incluyen gráficos de barras, gráficos de líneas, gráficos circulares, histogramas y diagramas de dispersión.

Tablas: Las tablas son representaciones tabulares de datos que organizan la información en filas y columnas. Las tablas son útiles para mostrar datos detallados o para comparar valores entre diferentes categorías o grupos. Pueden incluir valores numéricos, texto descriptivo y otras características.

6.1 Representación en Gráficos.

Para visualizar los datos en formato dataframe puede usar el comando View() o también head() para visualizar las primeras filas en consola.

head(df)

6.1.1 Diagrama de barras

ggplot2 es un sistema para crear gráficos de forma declarativa, basado en la Gramática de los Gráficos. Se deben proporcionar los datos, indicar a ggplot2 cómo asignar las variables a la estética y qué tipo de gráficas utilizar. La función geom_bar() se utiliza para producir gráficos de área 1d: gráficos de barras para x categóricas, e histogramas para y continuas

library(ggplot2)
ggplot(data=df, aes(x=Paciente, y=Edad)) + geom_bar(stat="identity")+labs(title = "Distribución de Edad por Paciente")

El diagrama puede ser dibujado en forma horizontal usando la función coord_flip()

ggplot(data=df, aes(x=Paciente, y=Edad)) + geom_bar(stat="identity")+labs(title = "Distribución de Edad por Paciente")+ coord_flip()

Podemos cambiar el ancho, así como también el color de las barras y bordes. Nótese que se puede hacer una copia de la gráfica en una variable, en este ejemplo en p para que luego pueda ser usada para presentar el grafico o realizar más transformaciones

ggplot(data=df, aes(x=Paciente, y=Edad)) + geom_bar(stat="identity",width=0.5)+labs(title = "Distribución de Edad por Paciente")

ggplot(data=df, aes(x=Paciente, y=Edad)) + geom_bar(stat="identity",width=0.5,color="blue", fill="green3")+labs(title = "Distribución de Edad por Paciente")

ggplot(data=df, aes(x=Paciente, y=Edad)) + geom_bar(stat="identity",width=0.8, fill="steelblue")+labs(title = "Distribución de Edad por Paciente")

#creando tabla de resumen
Tabla_1 <- df %>%
  dplyr::group_by(Red_Social_Principal) %>%                                  
  dplyr::summarise(Total = n()) %>%                                
  dplyr::mutate(Porcentaje = round(Total/sum(Total)*100, 1)) %>%   
  dplyr::arrange(Red_Social_Principal)


"Grafico"
## [1] "Grafico"
G1<-ggplot(Tabla_1, aes(x =Red_Social_Principal, y=Total) ) + 
  geom_bar(width = 0.7,stat="identity",                 
           position = position_dodge(), fill="cyan4") +  
  ylim(c(0,5))+
  #xlim(c(0,300)) +                  
  #ggtitle("Un título") + 
  labs(x="Red Social", y= "Frecuencias \n (Porcentajes)")   +   
  geom_text(aes(label=paste0(Total," ", "", "(", Porcentaje, "%", ")")),  
            vjust=-0.9, 
            color="black", 
            hjust=0.5,
            # define text position and size
            position = position_dodge(0.9),  
            angle=0, 
            size=4.5) +   
  theme(axis.text.x = element_text(angle = 0, vjust = 1, hjust=1)) +      
  theme_bw(base_size = 16) +
  #coord_flip() +                                                         
  facet_wrap(~"Distribución de Tipo de Red Social")
G1

6.1.2 Gráfico de barras agrupado

Un gráfico de barras agrupado muestra un valor numérico para un conjunto de entidades divididas en grupos y subgrupos.

El conjunto de datos para el presente ejemplo proporciona 3 columnas: el valor numérico (value), y 2 variables categóricas. En el llamada aes(), x es (categ), y el subgrupo (categ) se da al argumento fill. En la función geom_bar(), debe especificarse position=“dodge” para que las barras estén una al lado de la otra.

  • El siguiente llamado es utilizado para el gráfico de barras agrupado
head(df)
ggplot(df, aes(fill = Sexo, y = Edad, x = Red_Social_Principal, label = Edad)) +
  geom_bar(position = "dodge", stat = "identity") +
  labs(title = "Distribución de la Red Social según la Edad y Sexo",
       x = "Red Social Principal",
       y = "Edad",
       fill = "Sexo")  

ggplot(df, aes(fill = Sexo, x = Red_Social_Principal)) +
  geom_bar(position = "stack") +
  geom_text(stat = 'count', aes(label = ..count..), position = position_stack(vjust = 0.5), size = 3, color = "black") +
  labs(title = "Distribución de la Red Social según el Sexo",
       x = "Red Social Principal",
       y = "Frecuencia") +
  scale_fill_manual(values = c("blue2", "pink2"), name = "Sexo", labels = c("Hombre", "Mujer")) +
  theme(legend.position = "right")  # Ubicación de la leyenda 
## Warning: The dot-dot notation (`..count..`) was deprecated in ggplot2 3.4.0.
## ℹ Please use `after_stat(count)` instead.
## This warning is displayed once every 8 hours.
## Call `lifecycle::last_lifecycle_warnings()` to see where this warning was
## generated.

6.1.3 Histograma

Los histogramas son útiles para representar la distribución de variables continuas como Edad, Tiempo en Redes Sociales y Horas Semanales de Juego. Cada barra del histograma muestra la frecuencia de los datos..

ggplot(data = df, aes(x = Edad)) +
  geom_histogram(binwidth = 1, fill = "skyblue", color = "black", alpha = 0.8) +
  labs(title = "Histograma de Edades",
       x = "Edad",
       y = "Frecuencia")

6.1.4 Gráfico Circular

ggplot2 no ofrece ningún geom específica para construir diagramas circulares (piecharts). El truco es el siguiente: El marco de datos de entrada tiene 2 columnas: los nombres de los grupos (group here) y su valor (value here), se construye un gráfico de barras apilado con una sola barra utilizando la función geom_bar(), luego se hace circular con coord_polar()

library(magrittr)
library(dplyr)

#Tabla resumen
Tabla_2 <- df %>% 
  group_by(Sexo) %>% # Variable a ser transformada
  count() %>% 
  ungroup() %>% 
  mutate(Porcentaje = `n` / sum(`n`)) %>% 
  arrange(Porcentaje) %>%
  mutate(etiquetas = scales::percent(Porcentaje))

#Grafico #2
require(scales)
## Loading required package: scales
## 
## Attaching package: 'scales'
## The following object is masked from 'package:purrr':
## 
##     discard
## The following object is masked from 'package:readr':
## 
##     col_factor
ggplot(Tabla_2, aes(x = "", y = Porcentaje, fill = Sexo)) +
  geom_col(color = "black") +
  geom_label(aes(label = etiquetas),
             position = position_stack(vjust = 0.5),
             show.legend = FALSE) +
  guides(fill = guide_legend(title = "Distribución de Pacientes según el Sexo")) + scale_color_gradient() +
  coord_polar(theta = "y") + ggtitle ("")

  #theme_void() 

6.2 Representación en Tablas

La libreria questionr de R contiene la función freq la cual genera y formatea tablas de frecuencia simples a partir de una variable o una tabla, con porcentajes y opciones de formato. El resultado es un objeto de la clase data.frame.

library(questionr)

Tabla_Sexo <- questionr::freq(Sexo, cum = TRUE, sort = "dec", total = TRUE)
knitr::kable(Tabla_Sexo)
n % val% %cum val%cum
Femenino 5 55.6 55.6 55.6 55.6
Masculino 4 44.4 44.4 100.0 100.0
Total 9 100.0 100.0 100.0 100.0

La tabla puede ordenarse opcionalmente en frecuencia descendente, y funciona bien con kable. Si deseamos ver la estructura de la tabla generada por freq() utilizamos la función str()

str(Tabla_Sexo) 
## Classes 'freqtab' and 'data.frame':  3 obs. of  5 variables:
##  $ n      : num  5 4 9
##  $ %      : num  55.6 44.4 100
##  $ val%   : num  55.6 44.4 100
##  $ %cum   : num  55.6 100 100
##  $ val%cum: num  55.6 100 100

6.2.1 Tabla de frecuencias agrupada

Para realizar una tabla de frecuencias agrupada utilizaremos en este ejemplo la Regla de Sturges, en la que el número de clases es obtenido por medio de: \(c=1+ln(N)/ln(2)\) donde \(N\) representa el número total de datos. Consideremos el Ejemplo 23 de los apuntes, en el que se representan las edades de un conjunto de estudiantes.

Ejemplo: Se tienen las siguientes edades de algunos estudiantes

edades <- c(22, 19, 16, 13, 18, 15, 20, 14, 15, 16,
          15, 16, 20, 13, 15, 18, 15, 13, 18, 15)
knitr::kable(head(edades))
x
22
19
16
13
18
15

Encontremos el número de clases usando la regla de Sturges

n_sturges = 1 + log(length(edades))/log(2)
n_sturgesc = ceiling(n_sturges)
n_sturgesf = floor(n_sturges)

n_clases = 0
if (n_sturgesc%%2 == 0) {
  n_clases = n_sturgesf
} else {
  n_clases = n_sturgesc
}
R = max(edades) - min(edades)
w = ceiling(R/n_clases)

Calculemos ahora nuestra tabla de frecuencias con número de clases n_clases. Primero creamos una lista de fronteras de clases bins y luego agrupamos los datos basados en estas

bins <- seq(min(edades), max(edades) + w, by = w)
bins
## [1] 13 15 17 19 21 23
Edades <- cut(edades, bins)
Freq_table <- transform(table(Edades), Rel_Freq=prop.table(Freq), Cum_Freq=cumsum(Freq))
knitr::kable(Freq_table)
Edades Freq Rel_Freq Cum_Freq
(13,15] 7 0.4117647 7
(15,17] 3 0.1764706 10
(17,19] 4 0.2352941 14
(19,21] 2 0.1176471 16
(21,23] 1 0.0588235 17
str(Freq_table)
## 'data.frame':    5 obs. of  4 variables:
##  $ Edades  : Factor w/ 5 levels "(13,15]","(15,17]",..: 1 2 3 4 5
##  $ Freq    : int  7 3 4 2 1
##  $ Rel_Freq: num  0.4118 0.1765 0.2353 0.1176 0.0588
##  $ Cum_Freq: int  7 10 14 16 17

Podemos también crear un histograma para la tabla de frecuencias agrupada

df2 <- data.frame(x = Freq_table$Edades, y = Freq_table$Freq)
knitr::kable(df2)
x y
(13,15] 7
(15,17] 3
(17,19] 4
(19,21] 2
(21,23] 1
ggplot(data=df2, aes(x=x, y=y)) +
  geom_bar(stat="identity", color="blue", fill="green") +
  xlab("Rango de Edades") +
  ylab("Frecuencia")

7 Análisis Estadístico

Una función multiuso muy útil en R es summary(X), donde X puede ser uno de cualquier número de objetos, incluyendo conjuntos de datos, variables y modelos lineales, por nombrar algunos. Cuando se utiliza, el comando proporciona datos de resumen relacionados con el objeto individual que se introdujo en él. Así, la función de resumen tiene diferentes resultados dependiendo del tipo de objeto que tome como argumento. Además de ser ampliamente aplicable, este método es valioso porque a menudo proporciona exactamente lo que se necesita en términos de estadísticas de resumen.

Usando la función summary() podemos obtener estadísticos de interes y valores de posición:

summary(df$Horas_Semanales_de_Juego)
##    Min. 1st Qu.  Median    Mean 3rd Qu.    Max. 
##   10.00   15.00   15.00   18.44   20.00   41.00

Del anterior resultado se puede observar que la hora mínima en el juego fue de 10, el 25% se ubicó en 15 horas indicando que dedicaron 15 o menor o igual a 15, al igual que el 50%, en promedio dedicaron 18,4 horas de juego, el 75% dedicó menos o igual que 20 horas y la hora que más dedicaron fue de 41.

Por otro lado, se puede notar la función summary() no nos entrega todos los estadísticos de interés, para solucionar esto podemos hacer uso de la librería, pastecs y la función stat.desc(), como se muestra a continuación.

library(pastecs)
## Warning: package 'pastecs' was built under R version 4.3.3
## 
## Attaching package: 'pastecs'
## The following object is masked from 'package:magrittr':
## 
##     extract
## The following objects are masked from 'package:dplyr':
## 
##     first, last
## The following object is masked from 'package:tidyr':
## 
##     extract
stat.desc(df)

7.1 Caja y extensión

Los gráficos de caja (box plots), también conocidos como diagramas de cajas y bigotes, son una representación gráfica que permite resumir las características principales de los datos (posición, dispersión, asimetría, …) e identificar la presencia de valores atípicos. En esta sección revisaremos cómo hacer box plots en R base y en ggplot2.

Utilizando boxplot() R base

boxplot(df$Edad, horizontal=TRUE, col='steelblue')

Usando geom_boxplot() de la librería ggplot2

library(tidyverse)
library(hrbrthemes)
library(viridis)
## Loading required package: viridisLite
## 
## Attaching package: 'viridis'
## The following object is masked from 'package:scales':
## 
##     viridis_pal
df %>% 
  ggplot(aes(x = "", y = Edad)) +
  geom_boxplot(color = "black", fill = "yellow2", alpha = 0.5) +
  theme_ipsum() +
  theme(legend.position = "none", plot.title = element_text(size = 11)) +
  ggtitle("Distribución de las Edades") +
  coord_flip()

ggplot(df, aes(x = Sexo, y = Edad, fill = Sexo)) +
  geom_boxplot() +
  labs(title = "Diagrama de Edades según el Sexo",
       x = "Sexo", y = "Edades") +
  scale_fill_manual(values = c("lightblue", "pink")) +
  theme_minimal()

7.2 Coeficiente de Variación

El coeficiente de variación (CV) es una medida estadística que se utiliza para evaluar la variabilidad relativa de una muestra o población en relación con su media. Se calcula como la desviación estándar de los datos dividida por la media, y se expresa como un porcentaje multiplicado por 100 para facilitar su interpretación.

El CV es útil cuando se comparan distribuciones de datos con diferentes escalas o unidades, ya que normaliza la variabilidad en relación con la magnitud de los datos. Esto permite realizar comparaciones más significativas entre diferentes conjuntos de datos.

\[CV = \left( \frac{\text{Desviación Estándar}}{\text{Media}} \right) \times 100\]

Ahora vamos a hallar el coeficiente de variación de la variable Edad.

media <- mean(df$Edad)
desviacion <- sd(df$Edad)
coef_variacion <- (desviacion / media) * 100
cat("El coeficiente de variación es:", coef_variacion, "%\n")
## El coeficiente de variación es: 19.25285 %

7.3 Asimetría

El coeficiente de asimetría de Pearson es que es una medida estandarizada de la asimetría de una distribución de datos. Se calcula como el tercer momento estandarizado de la distribución, es decir, la diferencia promedio al cubo entre los datos y la media, dividida por la desviación estándar al cubo. Si el coeficiente de asimetría de Pearson es cero, la distribución es simétrica. Si es positivo, la cola de la distribución está en el lado derecho, y si es negativo, la cola está en el lado izquierdo. Esto proporciona información sobre la forma y dirección de la asimetría en la distribución de datos.

\[\text{Coeficiente de Asimetría de Pearson} = \frac{E[(X - \mu)^3]}{\sigma^3}\]

Como el coefiente de asmetría de Pearson es mayo que cero, indica que la edad presenta distribución asimetrica hacia la derecha.

7.4 Medidas de la curtosis

La curtosis es una medida estadística que describe la forma de la distribución de los datos en relación con una distribución normal estándar. La curtosis es una medida de la “picudez” de la distribución, es decir, cuán puntiaguda o aplanada es en comparación con una distribución normal.

\[\text{Curtosis} = \frac{1}{n} \sum_{i=1}^{n} \left(\frac{x_i - \bar{x}}{s}\right)^4 - 3\]

Platicúrtica: Una distribución platicúrtica es aquella que tiene un exceso de curtosis negativo en comparación con la distribución normal estándar (cuyo exceso de curtosis es 0). Esto significa que la distribución tiene colas más ligeras y es más aplanada en comparación con la distribución normal. En una distribución platicúrtica, los valores se concentran más cerca de la media y hay menos valores extremos en comparación con una distribución normal.

Mesocúrtica: Una distribución mesocúrtica es aquella que tiene un exceso de curtosis igual a 0, es decir, su forma es similar a la de una distribución normal estándar. Esto significa que la distribución tiene una cantidad “normal” de picos y colas, y su forma se asemeja a una campana simétrica.

Leptocúrtica: Una distribución leptocúrtica es aquella que tiene un exceso de curtosis positivo en comparación con la distribución normal estándar. Esto significa que la distribución tiene colas más pesadas y es más puntiaguda en comparación con la distribución normal. En una distribución leptocúrtica, los valores tienden a agruparse más cerca de la media y hay más valores extremos en comparación con una distribución normal.

curtosis <- kurtosis(df$Edad)
cat("La curtosis de la muestra es:", curtosis, "\n")
## La curtosis de la muestra es: 0.8255815

7.5 Trabajo 1(EDA) - Para realizar en R:

Realice un análisis descriptivo básico de la base de datos basado en tablas de resumen y en gráficos Accidentalidad_en_Barranquilla.csv . Deben entregar un script .R con los códigos usados.

Este análisis puede consistir en:

  1. Contextualizar tanto la base de datos como las variables describiendo en qué consiste cada una de ellas. La base de datos está en el sitio web:
    https://www.datos.gov.co/Transporte/Accidentalidad-en-Barranquilla/yb9r-2dsi

  2. Analizar las características de la base de datos. Estas pueden incluir: número de filas, número de columnas, nombres de las variables, tipos de variables, entre otros.

  3. Analizar cada una de las variables según su tipo: numéricas y categóricas.

  4. Filtrar la base de datos para entender mejor su estructura. Aplique filtros en al menos cinco oportunidades.

  5. Utilice la función table para explorar la base de datos.

  6. Identifique los valores NA (Not Available) en la base de datos.

  7. Analice la presencia de posibles valores atípicos.

  8. Comente cada uno de los resultados obtenidos.