1 Importancia de la Estadística en Geología

En geología, la estadística es esencial para interpretar datos geoespaciales, analizar patrones en fenómenos naturales y realizar predicciones sobre eventos como terremotos, erupciones volcánicas o la distribución de recursos minerales. Gracias a las técnicas estadísticas, los geólogos pueden modelar incertidumbre, identificar correlaciones entre variables ambientales y validar hipótesis sobre la evolución del terreno. Esto permite tomar decisiones informadas en exploración, gestión de riesgos y planificación territorial.

Mira este video para entender mejor la utilidad de la estadística en contextos aplicados: Importancia de la estadística en los Geología

2 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.

2.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/

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

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

library(kableExtra)
# 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

3.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

3.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

3.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

3.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"

3.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

3.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

3.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

3.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

3.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

3.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

4 Bases de datos en R.

4.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.2     ✔ tibble    3.2.1
## ✔ lubridate 1.9.4     ✔ tidyr     1.3.1
## ✔ purrr     1.0.4     
## ── 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")

4.2 Abrir una Base de R-STUDIO y Resumir

4.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

4.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)

4.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 ...

4.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"

4.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

4.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.

4.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

4.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

4.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.

4.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.

4.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

4.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)

5 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.

5.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.

5.2 Representación de datos según su Naturaleza

tabla <- data.frame(
  "Naturaleza de la variable" = c("Cualitativa", "", "Cuantitativa", ""),
  "Escala de Medidas" = c("Nominal", "Ordinal", "Intervalo", "Razon"),
  "Frecuencias" = c("Si", "Si", "Agrupadas", ""),
  "Medidas de Localizacion" = c("Moda", "Moda", "Media, Mediana y Moda", ""),
  "Medidas de Dispersion" = c("No", "No", "Si", "Si"),
  "Medidas de Distribucion" = c("No", "No", "Si", "Si"),
  "Graficos" = c("Sectores, Barras", "Sectores, Barras (sin orden)", "Histograma, Tallo y hojas, Cajas y Bigotes, Dispersion.", "")
)

# Create the table with kableExtra
library(knitr)
## Warning: package 'knitr' was built under R version 4.4.2
library(kableExtra)

tabla %>%
  kable("html", align = "c", col.names = c(
    "Naturaleza de la variable", 
    "Escala de Medidas", 
    "Frecuencias", 
    "Medidas de Localizacion", 
    "Medidas de Dispersion", 
    "Medidas de Distribucion", 
    "Graficos"
  )) %>%
  kable_styling(full_width = F, position = "center", bootstrap_options = c("striped", "hover", "condensed", "responsive")) %>%
  row_spec(0, bold = TRUE, background = "#D9E2F1", color = "black") %>%
  row_spec(1:2, background = "white", color = "black") %>%
  row_spec(3:4, background = "#E7E7E7", color = "black")
Naturaleza de la variable Escala de Medidas Frecuencias Medidas de Localizacion Medidas de Dispersion Medidas de Distribucion Graficos
Cualitativa Nominal Si Moda No No Sectores, Barras
Ordinal Si Moda No No Sectores, Barras (sin orden)
Cuantitativa Intervalo Agrupadas Media, Mediana y Moda Si Si Histograma, Tallo y hojas, Cajas y Bigotes, Dispersion.
Razon Si Si

5.3 Presentación y análisis de la Información en estudios Descríptivos.

tabla <- data.frame(
  "Tipo de Tabla" = c(
    "De Frecuencia (Variable Cualitativa)",
    "De Frecuencia (Variable Cuantitativa)",
    "De Asociacion (Dos Variables Cualitativas)",
    "De Asociacion (Una Variable Cualitativa y una Cuantitativa Discreta)",
    "De Asociacion (Una Variable Cualitativa y una Cuantitativa Continua)",
    "De Asociacion (Dos Variables Cuantitativas)"
  ),
  "Tipo de Grafico" = c(
    "- Barras simples\n- Pastel",
    "- Histograma",
    "- Barras compuestas\n- Barras superpuestas",
    "- Barras:\n  * Compuestas\n  * Superpuestas",
    "- Poligono de Frecuencia\n- Box plot (diagrama de cajas y bigotes)",
    "- Diagrama de Puntos"
  ),
  stringsAsFactors = FALSE
)

# Creating the table using kableExtra
tabla %>%
  kable("html", escape = FALSE, align = "l", col.names = c("Tipo de Tabla", "Tipo de Grafico")) %>%
  kable_styling(full_width = F, position = "center", bootstrap_options = c("striped", "hover", "condensed", "responsive")) %>%
  row_spec(0, bold = TRUE, background = "#D9E2F1", color = "black") %>%
  row_spec(c(3, 4), background = "#F2F2F2", color = "black") %>%
  row_spec(c(2, 5), background = "white", color = "black") %>%
  row_spec(c(1, 6), background = "#E7E7E7", color = "black") %>%
  column_spec(1, width = "4cm") %>%
  column_spec(2, width = "6cm")
Tipo de Tabla Tipo de Grafico
De Frecuencia (Variable Cualitativa)
  • Barras simples
  • Pastel
De Frecuencia (Variable Cuantitativa)
  • Histograma
De Asociacion (Dos Variables Cualitativas)
  • Barras compuestas
  • Barras superpuestas
  • De Asociacion (Una Variable Cualitativa y una Cuantitativa Discreta)
    • Barras:
    • Compuestas
    • Superpuestas
    De Asociacion (Una Variable Cualitativa y una Cuantitativa Continua)
    • Poligono de Frecuencia
  • Box plot (diagrama de cajas y bigotes)
  • De Asociacion (Dos Variables Cuantitativas)
    • Diagrama de Puntos

    5.4 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.

    5.4.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

    5.4.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

    5.4.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

    5.4.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

    5.4.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

    5.4.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)

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

    #!complete.cases(DATOS)

    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

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

    suppressWarnings(require(Amelia))
    ## Cargando paquete requerido: Amelia
    ## Cargando paquete requerido: Rcpp
    ## ## 
    ## ## Amelia II: Multiple Imputation
    ## ## (Version 1.8.3, built: 2024-11-07)
    ## ## Copyright (C) 2005-2025 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

    5.4.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")

    5.4.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.

    5.4.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

    5.4.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

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

    suppressWarnings(missmap(DATOS))

    5.5 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.

    5.5.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
    ## Cargando paquete requerido: magrittr
    ## 
    ## Adjuntando el paquete: '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

    5.6 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

    5.7 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:

    5.8 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"

    5.8.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
    ## Cargando paquete requerido: janitor
    ## 
    ## Adjuntando el paquete: 'janitor'
    ## The following objects are masked from 'package:stats':
    ## 
    ##     chisq.test, fisher.test
    master %<>% clean_names  # Equivalente a: master <- clean_names(master)

    5.8.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]
    )

    5.8.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"

    5.8.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

    5.9 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"

    5.9.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"

    6 Situación Problema.

    Exploración de la Relación entre la Geología y el Análisis de Datos: Caracterización de Formaciones Geológicas y Propiedades del Suelo

    En un centro de investigación geológica enfocado en el estudio de formaciones rocosas y propiedades del suelo, se recopilan datos geoespaciales y mineralógicos provenientes de diferentes regiones. La base de datos incluye variables como la composición mineral, la densidad de las rocas, la dureza en la escala de Mohs, y características geotécnicas del terreno.

    Utilizando herramientas de análisis de datos y estadísticas geológicas, se busca identificar patrones significativos que permitan comprender mejor la distribución de minerales, la resistencia del terreno y la relación entre diferentes propiedades físicas de los materiales geológicos.

    Este enfoque interdisciplinario entre la geología y la ciencia de datos permite desarrollar modelos predictivos para la exploración de recursos naturales, evaluar la estabilidad del suelo en proyectos de infraestructura y mejorar las estrategias de conservación de los ecosistemas geológicos.

    6.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:

    Investigador <- c("Carlos", "Sofía", "Javier", "Ana", "Fernando", "Elena", "Raúl", "Patricia", "Luis", "Andrea","Keyla")
    
    Edad <- c(32, 31, 32, 35, 30, 45, 32, 33, 41, 33, 34)
    
    Sexo <- c("Masculino", "Femenino", "Masculino", "Femenino", "Masculino", "Femenino", "Masculino", "Femenino", "Masculino", "Femenino", "Femenino")
    
    Especialidad <- c("Petrología", "Geofísica", "Petrología", "Paleontología", "Geoquímica", 
                      "Hidrogeología", "Geoquímica", "Geoquímica", "Hidrogeología", "Hidrogeología", "Hidrogeología")
    
    Región_Trabajo <- c("Amazonía", "Amazonía", "Amazonía", "Caribe", "Llanos", 
                        "Amazonía", "Llanos", "Caribe", "Amazonía", "Llanos","Caribe")
    
    Dureza_Roca <- c(5.2, 6.8, 7.0, 4.5, 6.0, 5.5, 7.2, 4.8, 6.3, 5.9, 10.3)
    
    Contenido_Mineral <- c(55, 72, 60, 45, 68, 50, 75, 48, 62, 53,51)
    
    Densidad_Roca <- c(2.5, 3.1, 2.8, 2.3, 3.0, 2.7, 3.2, 2.4, 2.9, 2.6, 3.8)
    
    Profundidad_Muestra <- c(100, 250, 180, 120, 300, 220, 275, 150, 260, 200,600)
    
    Temperatura_Medida <- c(15, 22, 18, 20, 25, 17, 19, 23, 21, 16,13)
    
    Sismicidad_Registrada <- c(2.1, 3.0, 2.8, 1.5, 3.5, 2.0, 3.8, 1.9, 3.2, 2.4, 3.9)

    Descripción de las Variables:

    Investigador: Nombre del geólogo o investigador.

    Edad: Edad del investigador.

    Sexo: Género del investigador.

    Especialidad: Rama de la geología en la que trabaja.

    Región_Trabajo: Ubicación donde realiza sus estudios.

    Dureza_Roca: Dureza de la roca en la escala de Mohs.

    Contenido_Mineral: Porcentaje de minerales en la muestra analizada.

    Densidad_Roca: Densidad de la roca en g/cm³.

    Profundidad_Muestra: Profundidad a la que se tomó la muestra (en metros).

    Temperatura_Medida: Temperatura registrada en el lugar de la muestra (en °C).

    Sismicidad_Registrada: Nivel de actividad sísmica en la región medida en magnitud.

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

    df <- data.frame(
      Investigador, 
      Edad, 
      Sexo, 
      Especialidad, 
      Región_Trabajo, 
      Dureza_Roca, 
      Contenido_Mineral, 
      Densidad_Roca, 
      Profundidad_Muestra, 
      Temperatura_Medida, 
      Sismicidad_Registrada
    )
    df

    7 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.

    7.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)

    7.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=Investigador, y=Edad)) + 
      geom_bar(stat="identity", fill="steelblue") + 
      labs(title = "Distribución de Edad por Investigador",
           x = "Investigador",
           y = "Edad") +
      theme_minimal() +
      theme(axis.text.x = element_text(angle = 45, hjust = 1))

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

    library(ggplot2)
    
    ggplot(data=df, aes(x=Investigador, y=Edad)) + 
      geom_bar(stat="identity", fill="steelblue") + 
      labs(title = "Distribución de Edad por Investigador",
           x = "Investigador",
           y = "Edad") +
      coord_flip() +  # Invertir el eje para mejor visualización
      theme_minimal()

    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

    library(ggplot2)
    
    ggplot(data=df, aes(x=Investigador, y=Edad)) + 
      geom_bar(stat="identity", width=0.5, fill="steelblue") + 
      labs(title = "Distribución de Edad por Investigador",
           x = "Investigador",
           y = "Edad") +
      theme_minimal() +
      theme(axis.text.x = element_text(angle = 45, hjust = 1))  # Rotar nombres para legibilidad

    library(ggplot2)
    ggplot(data=df, aes(x=Investigador, y=Edad)) + 
      geom_bar(stat="identity", width=0.5, color="blue", fill="green3") + 
      labs(title = "Distribución de Edad por Investigador",
           x = "Investigador",
           y = "Edad") +
      theme_minimal() +
      theme(axis.text.x = element_text(angle = 45, hjust = 1))  # Rotar nombres para legibilidad

    library(ggplot2)
    ggplot(data=df, aes(x=Investigador, y=Edad)) + 
      geom_bar(stat="identity", width=0.8, fill="steelblue") + 
      labs(title = "Distribución de Edad por Investigador",
           x = "Investigador",
           y = "Edad") +
      theme_minimal() +
      theme(axis.text.x = element_text(angle = 45, hjust = 1))  # Rotar nombres para legibilidad

    library(dplyr)
    
    
    Tabla_1 <- df %>%
      dplyr::group_by(Región_Trabajo) %>%                                  
      dplyr::summarise(Total = n()) %>%                                
      dplyr::mutate(Porcentaje = round(Total/sum(Total)*100, 1)) %>%   
      dplyr::arrange(Región_Trabajo)
    
    Tabla_1
    library(ggplot2)
    
    G1 <- ggplot(Tabla_1, aes(x = Región_Trabajo, y = Total)) + 
      geom_bar(width = 0.7, stat="identity",                 
               position = position_dodge(), fill="cyan4") +  
      ylim(c(0, max(Tabla_1$Total) + 2)) +  # Ajusta el límite superior dinámicamente
      labs(x="Región Geológica", y= "Frecuencia \n (Porcentajes)")   +   
      geom_text(aes(label=paste0(Total, " ", "", "(", Porcentaje, "%", ")")),  
                vjust=-0.9, 
                color="black", 
                hjust=0.5,
                position = position_dodge(0.9),  
                angle=0, 
                size=4.5) +   
      theme(axis.text.x = element_text(angle = 45, vjust = 1, hjust=1)) +      
      theme_bw(base_size = 16) +
      facet_wrap(~"Distribución de Regiones Geológicas")
    
    # Mostrar el gráfico
    G1

    7.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)
    library(ggplot2)
    
    ggplot(df, aes(fill = Sexo, y = Edad, x = Región_Trabajo, label = Edad)) +
      geom_bar(position = "dodge", stat = "identity") +
      labs(title = "Distribución de la Región Geológica según la Edad y Sexo",
           x = "Región Geológica",
           y = "Edad",
           fill = "Sexo") +
      theme_minimal() +
      theme(axis.text.x = element_text(angle = 45, hjust = 1))

    library(ggplot2)
    
    ggplot(df, aes(fill = Sexo, x = Región_Trabajo)) +
      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 Región Geológica según el Sexo",
           x = "Región Geológica",
           y = "Frecuencia") +
      scale_fill_manual(values = c("blue2", "pink2"), name = "Sexo", labels = c("Hombre", "Mujer")) +
      theme(legend.position = "right") +
      theme(axis.text.x = element_text(angle = 45, hjust = 1))  # Rotación del eje X
    ## 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.

    7.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..

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

    7.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(ggplot2)
    
    # Crear tabla de resumen
    Tabla_Region <- df %>%
      dplyr::group_by(Región_Trabajo) %>%
      dplyr::summarise(Total = n())
    Tabla_Region
    # Gráfico Circular
    ggplot(Tabla_Region, aes(x = "", y = Total, fill = Región_Trabajo)) +
      geom_bar(stat = "identity", width = 1) +
      coord_polar("y", start = 0) +
      labs(title = "Distribución de Investigadores por Región Geológica") +
      theme_void() +  # Elimina ejes y grillas
      scale_fill_brewer(palette = "Paired")  # Paleta de colores

    Podemos observar, que el gráfico no tiene etiquetas pero ahora se le va agregar.

    library(ggplot2)
    library(dplyr)
    
    Tabla_Region <- df %>%
      dplyr::group_by(Región_Trabajo) %>%
      dplyr::summarise(Total = n()) %>%
      dplyr::mutate(Porcentaje = round(Total / sum(Total) * 100, 1))
    Tabla_Region
    # Gráfico Circular con etiquetas de porcentaje y conteo
    ggplot(Tabla_Region, aes(x = "", y = Total, fill = Región_Trabajo)) +
      geom_bar(stat = "identity", width = 1) +
      coord_polar("y", start = 0) +
      labs(title = "Distribución de Investigadores por Región Geológica") +
      geom_text(aes(label = paste0(Total, " (", Porcentaje, "%)")),
                position = position_stack(vjust = 0.5), size = 4, color = "white") +
      theme_void() +  
      scale_fill_brewer(palette = "Paired") 

    Ahora graficaremos la distribución por sexo.

    # Crear tabla de resumen con porcentaje
    Tabla_Sexo <- df %>%
      dplyr::group_by(Sexo) %>%
      dplyr::summarise(Total = n()) %>%
      dplyr::mutate(Porcentaje = round(Total / sum(Total) * 100, 1))
    Tabla_Sexo
    # Gráfico Circular con etiquetas
    ggplot(Tabla_Sexo, aes(x = "", y = Total, fill = Sexo)) +
      geom_bar(stat = "identity", width = 1) +
      coord_polar("y", start = 0) +
      labs(title = "Distribución de Investigadores por Sexo") +
      geom_text(aes(label = paste0(Total, " (", Porcentaje, "%)")),
                position = position_stack(vjust = 0.5), size = 5, color = "white") +
      theme_void() +
      scale_fill_manual(values = c("blue2", "pink2"))  

    library(ggplot2)
    
    ggplot(df, aes(x = Dureza_Roca, y = Densidad_Roca)) +
      geom_point(color = "blue", size = 3, alpha = 0.7) +  
      geom_smooth(method = "lm", color = "red", se = FALSE) +  
      labs(title = "Relación entre Dureza Mohs y Densidad de la Roca",
           x = "Dureza Mohs",
           y = "Densidad (g/cm³)") +
      theme_minimal()
    ## `geom_smooth()` using formula = 'y ~ x'

    El gráfico de dispersión entre Dureza Mohs y Densidad de la Roca permite analizar la relación entre estas dos propiedades geológicas.

    Correlación positiva: Si los puntos siguen una tendencia ascendente, significa que a mayor dureza, mayor densidad. Esto es común en rocas compactas como el granito o el basalto.

    Correlación negativa: Si los puntos muestran una tendencia descendente, sugiere que a mayor dureza, menor densidad, lo cual es menos común en geología.

    Sin correlación: Si los puntos están dispersos sin un patrón claro, significa que no hay una relación significativa entre la dureza y la densidad.

    ggplot(df, aes(x = Región_Trabajo, y = Densidad_Roca, fill = Región_Trabajo)) +
      geom_boxplot() +
      labs(title = "Distribución de la Densidad de la Roca por Región Geológica",
           x = "Región Geológica",
           y = "Densidad (g/cm³)") +
      theme_minimal() +
      theme(axis.text.x = element_text(angle = 45, hjust = 1))  # Rotar etiquetas

    Cada caja representa la distribución de la densidad en una región geológica. La línea negra dentro de cada caja indica la mediana de la densidad en cada región. Los bigotes muestran el rango donde se encuentra la mayoría de los datos, y cualquier punto fuera de los bigotes representaría valores atípicos (outliers).

    Amazonía (Rojo)

    La mediana de la densidad está alrededor de 2.9 g/cm³, lo que indica una presencia moderada de rocas compactas. La caja no es muy grande, lo que sugiere que la dispersión de densidades es baja, es decir, la mayoría de las muestras tienen valores similares. No hay valores atípicos evidentes, lo que indica que las mediciones son consistentes.

    Caribe (Verde)

    Presenta la mayor variabilidad en la densidad de las rocas, con un rango amplio desde valores bajos hasta altos. Hay una gran diferencia entre la mediana y los valores extremos, lo que sugiere múltiples tipos de formaciones geológicas con diferentes densidades. La parte inferior de la caja está cerca de 2.5 g/cm³, indicando la presencia de rocas sedimentarias menos densas, mientras que la parte superior sugiere presencia de rocas más compactas como calizas o basaltos.

    Llanos (Azul)

    La densidad media es la más alta en comparación con Amazonía y Caribe. La caja es estrecha, lo que sugiere que los datos están menos dispersos y la mayoría de las rocas tienen una densidad similar. La ausencia de valores extremos indica que la distribución de densidades es homogénea en esta región.

    Amazonía tiene una densidad relativamente homogénea, lo que sugiere una composición rocosa consistente.

    Caribe muestra gran variabilidad, lo que sugiere que la región tiene distintos tipos de rocas con densidades muy diferentes.

    Llanos tiene una densidad más estable, lo que podría ser indicativo de un tipo de roca predominante con poca variabilidad en su composición.

    7.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 6 54.5 54.5 54.5 54.5
    Masculino 5 45.5 45.5 100.0 100.0
    Total 11 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  6 5 11
    ##  $ %      : num  54.5 45.5 100
    ##  $ val%   : num  54.5 45.5 100
    ##  $ %cum   : num  54.5 100 100
    ##  $ val%cum: num  54.5 100 100

    7.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(df$Edad))
    x
    32
    31
    32
    35
    30
    45

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

    n_sturges = 1 + log(length(df$Edad))/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(df$Edad) - min(df$Edad)
    w = ceiling(R/n_clases)
    n_sturges = 1 + log(length(df$Edad))/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(df$Edad) - min(df$Edad)
    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(df$Edad), max(df$Edad) + w, by = w)
    bins
    ## [1] 30 33 36 39 42 45 48
    Edades <- cut(df$Edad, bins)
    Freq_table <- transform(table(df$Edad), Rel_Freq=prop.table(Freq), Cum_Freq=cumsum(Freq))
    knitr::kable(Freq_table)
    Var1 Freq Rel_Freq Cum_Freq
    30 1 0.0909091 1
    31 1 0.0909091 2
    32 3 0.2727273 5
    33 2 0.1818182 7
    34 1 0.0909091 8
    35 1 0.0909091 9
    41 1 0.0909091 10
    45 1 0.0909091 11
    str(Freq_table)
    ## 'data.frame':    8 obs. of  4 variables:
    ##  $ Var1    : Factor w/ 8 levels "30","31","32",..: 1 2 3 4 5 6 7 8
    ##  $ Freq    : int  1 1 3 2 1 1 1 1
    ##  $ Rel_Freq: num  0.0909 0.0909 0.2727 0.1818 0.0909 ...
    ##  $ Cum_Freq: int  1 2 5 7 8 9 10 11

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

    df2 <- data.frame(x = Freq_table$Var1, y = Freq_table$Freq)
    knitr::kable(df2)
    x y
    30 1
    31 1
    32 3
    33 2
    34 1
    35 1
    41 1
    45 1
    ggplot(data=df2, aes(x=x, y=y)) +
      geom_bar(stat="identity", color="blue", fill="green") +
      xlab("Rango de Edades") +
      ylab("Frecuencia")

    8 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$Dureza_Roca)
    ##    Min. 1st Qu.  Median    Mean 3rd Qu.    Max. 
    ##   4.500   5.350   6.000   6.318   6.900  10.300

    Del resumen estadístico de la dureza de las rocas en diferentes regiones geológicas, se pueden hacer las siguientes observaciones:

    • La dureza mínima registrada fue de 4.5 g/cm³, lo que sugiere la presencia de rocas menos compactas, posiblemente sedimentarias o con alta porosidad.
    • El primer cuartil (25%) se ubicó en 5.35 g/cm³, lo que indica que el 25% de las muestras tiene una dureza menor o igual a este valor.
    • La mediana (50%) se encuentra en 6.0 g/cm³, lo que sugiere que la mitad de las rocas tienen una dureza inferior a este valor, mientras que la otra mitad presenta valores más elevados.
    • En promedio, las rocas analizadas tienen una dureza de 6.3 g/cm³, lo que refleja la predominancia de materiales compactos, posiblemente ígneas o metamórficas.
    • El tercer cuartil (75%) se ubica en 6.9 g/cm³, lo que indica que el 75% de las muestras tiene una dureza menor o igual a este valor.
    • Finalmente, la dureza máxima registrada fue de 10.3 g/cm³, lo cual podría corresponder a rocas muy compactas o con alto contenido mineral como basaltos densos o rocas metamórficas altamente cristalizadas.
    library(pastecs)
    ## 
    ## Adjuntando el paquete: '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)

    8.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)
    ## Cargando paquete requerido: viridisLite
    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()

    8.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: 13.28927 %

    8.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.

    8.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.2043787

    8.5 Lineamientos para Análisis Exploratorio de Datos (EDA) en RPubs (Primer Corte), plazo máximo por definir:

    En este informe se van a organizar en parejas y van a explorar los enlaces siguientes y seleccionar una base de datos relacionada a su línea de interes:

    1. US Geological Survey (USGS)
    2. OneGeology
    3. PANGAEA Data Publisher for Earth & Environmental Science
    4. NOAA National Centers for Environmental Information (NCEI)
    5. EarthChem Library

    El objetivo es realizar un análisis descriptivo básico de la base de datos seleccionada, basado en tablas de resumen y gráficos. Deben entregar un script .R con los códigos usados.

    8.6 Instrucciones

    Este análisis consiste en:

    1. Contextualizar tanto la base de datos como las variables describiendo en qué consiste cada una de ellas. Explora una de las bases de datos proporcionadas en los enlaces anteriores y selecciona un conjunto de datos para analizar.

    2. Analizar las características de la base de datos. Esta 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.

    8.7 Conclusión

    Al finalizar el análisis, los resultados obtenidos deberán ser discutidos en clase el dia por definir y presentados en el enlace RPubs. Asegúrate de que tu análisis sea completo y bien documentado, incluyendo comentarios en el código que expliquen cada paso del proceso.

    9 Técnicas de Estadística Inferencial en Geológia.

    9.1 Distribuciones Muestrales

    1.Se sabe que el promedio del tamaño de las particulas en una muestra de suelo es de 50 milímetros. Se toma una muestra aleatoria de 20 observaciones, con desviación de 10 milímetros y se desea calcular la probabilida de que el promedio en la muestra de 50 el promedio este por encima de 35

    media_poblacional <- 50  
    desviacion <- 10 
    n <- 20 
    media_muestra <- 45 
    
    # Calcular la t de Student
    t <- (media_muestra - media_poblacional) / (desviacion/ sqrt(n))
    
    
    probabilidad <- pt(t, df = n - 1, lower.tail = FALSE)
    
    
    print(paste("La probabilidad de que el promedio en la muestra esté por encima de 45 mm es:", probabilidad))
    ## [1] "La probabilidad de que el promedio en la muestra esté por encima de 45 mm es: 0.981229725225737"

    2. Se está investigando la resistencia a la compresión de un tipo de roca. Se toma una muestra aleatoria de 30 observaciones y se desea calcular la probabilidad de que la resistencia a la compresión sea mayor a 100.

    Media: 110 Desviación Estándar: 20 Tamaño de la Muestra: 30

    # Calcular la probabilidad de resistencia mayor a 100 MPa
    probabilidad <- pnorm(100, mean = 110, sd = 20, lower.tail = FALSE)
    
    
    print("Probabilidad de resistencia a la compresión mayor a 100 MPa:")
    ## [1] "Probabilidad de resistencia a la compresión mayor a 100 MPa:"
    print(probabilidad)
    ## [1] 0.6914625

    3. Se está estudiando la permeabilidad de dos tipos de suelos en una región geológica. Se toman muestras de cada tipo de suelo y se registran los valores de permeabilidad (centímetros por segundo). Se desea determinar la probabilidad de que la diferencia en la permeabilidad entre los dos tipos de suelo sea menor que la observada.A nivel poblacional no existe diferencia entre las medias de ambos tipos de suelo.

    suelo tipo A: tamaño = 20, media = 0.05, desviación estándar = 0.01 suelo tipo B: tamaño = 25, media = 0.07, desviación estándar = 0.015

    n_A <- 20
    media_A <- 0.05
    desviacion_A <- 0.01
    
    
    n_B <- 25
    media_B <- 0.07
    desviacion_B <- 0.015
    
    
    diferencia_observada <- media_B - media_A
    
    
    diferencia_esperada <- 0
    
    #desviación estándar de la diferencia
    desviacion_diferencia <- sqrt((desviacion_A^2 / n_A) + (desviacion_B^2 / n_B))
    
    #Z
    Z <- (diferencia_observada - diferencia_esperada) / desviacion_diferencia
    
    # probabilidad utilizando la distribución normal estándar
    probabilidad <- pnorm(Z)
    
    
    cat("Probabilidad de que la diferencia en la permeabilidad entre los dos tipos de suelo sea menor que la observada:", probabilidad, "\n")
    ## Probabilidad de que la diferencia en la permeabilidad entre los dos tipos de suelo sea menor que la observada: 1

    4. Se está evaluando la variabilidad en la densidad de una muestra de rocas en una región geológica, la var poblacional es de 1.8. Se toma una muestra de 20 observaciones y se desea determinar la probailidad de que la varianza de la densidad sea menor que 8.

    n <- 20 
    varianza_poblacional <- 1.8 
    varianza_limite <- 8 
    
    
    
    chi_cuadrado <- ((n - 1) * varianza_poblacional) / varianza_limite
    
    probabilidad <- pchisq(chi_cuadrado, df = n-1, lower.tail = TRUE)
    
    
    print(paste("La probabilidad de que la varianza de la densidad sea menor que", varianza_limite, "g/cm³ es:", probabilidad))
    ## [1] "La probabilidad de que la varianza de la densidad sea menor que 8 g/cm³ es: 0.000177034106142528"

    5.Se está comparando la variabilidad en la densidad de dos tipos diferentes de rocas. Se toman dos muestras de 20 y 30 observaciones cada una y se desea calcular la probabilidad de que la razón de varianzas sea menor a la razón observada . Se sabe que las varianzas poblacionales son iguales.

    Desviación Estándar (Muestra 1): 0.5 Tamaño de la Muestra (Muestra 1): 30

    Desviación Estándar (Muestra 2): 0,07 Tamaño de la Muestra (Muestra 1): 30

    # muestra 1
    desviacion_estandar_1 <- 0.05
    n_1 <- 20
    
    #muestra 2
    desviacion_estandar_2 <- 0.07
    n_2 <- 30
    
    #razón de varianzas
    razon_varianzas <- (desviacion_estandar_1^2) / (desviacion_estandar_2^2)
    
    # Definir los grados de libertad para la distribución F
    df1 <- n_1 - 1
    df2 <- n_2 - 1
    
    #probabilidad utilizando la distribución F de Fisher
    probabilidad <- pf(razon_varianzas, df1, df2, lower.tail = TRUE)
    
    
    cat("Probabilidad de que la razón de varianzas sea MENOR a :", probabilidad, "\n")
    ## Probabilidad de que la razón de varianzas sea MENOR a : 0.06463078

    9.2 Situación Problema.

    En América Latina, la geología juega un papel fundamental en el desarrollo económico, especialmente en países como Chile, Perú y Colombia, donde la minería representa una fuente importante de ingresos. Sin embargo, uno de los desafíos más relevantes es la variabilidad de los recursos geológicos y la falta de modelos estadísticos que permitan evaluar con precisión las condiciones del suelo y la distribución de minerales. El uso de intervalos de confianza para la media, diferencia de medias, proporciones, diferencias de proporciones, varianza y razón de varianzas ayuda a reducir la incertidumbre en la caracterización geológica y mejora la toma de decisiones en proyectos de exploración y explotación minera.

    En el ámbito local, se ha recopilado información de diferentes sitios geológicos mediante un muestreo sistemático. La base de datos generada contiene variables como tipo de roca, concentración mineral, densidad, porosidad, permeabilidad y presencia de fallas geológicas en cada sitio de estudio. Con estos datos, geólogos e ingenieros mineros pueden aplicar técnicas estadísticas para analizar la variabilidad geológica y estimar con mayor precisión la calidad y cantidad de los recursos disponibles.

    El uso de análisis estadístico permite:

    • Estimar intervalos de confianza para determinar el rango probable de la concentración mineral en un área determinada.
    • Comparar diferencias de medias entre distintos tipos de roca para evaluar su potencial minero.
    • Analizar proporciones de sitios con presencia de fallas geológicas y su impacto en la estabilidad del suelo.
    • Evaluar la varianza y razón de varianzas para medir la heterogeneidad en la distribución de minerales y otras propiedades físicas.

    Este análisis facilitará la planificación de futuras exploraciones y permitirá mejorar la eficiencia en la gestión de los recursos geológicos.

    Fuente de Datos a utilizar:
    Los datos están disponibles en el siguiente repositorio de GitHub:
    Data Geología - GitHub

    9.3 Descripción de las Variables

    Variable Descripción
    ID_Sitio Identificador único del sitio de muestreo.
    Tipo_Roca Tipo de roca presente en el sitio (Sedimentaria, Ígnea, Metamórfica).
    Concentración_Mineral_% Porcentaje de concentración de un mineral específico en la muestra.
    Densidad_gcm3 Densidad de la roca en gramos por centímetro cúbico (g/cm³).
    Porosidad_% Porcentaje de porosidad de la roca, que indica el volumen de espacios vacíos en relación con el total.
    Permeabilidad_mD Permeabilidad de la roca en milidarcy (mD), que mide la capacidad del fluido para atravesarla.
    Presencia_Falla Indica si hay una falla geológica en el sitio (0: No hay falla, 1: Sí hay falla).
    Potencial_Minero Clasificación del potencial minero del sitio (Bajo, Medio, Alto).
    Tamaño_Muestra Número de muestras recolectadas en el sitio para análisis geológico.

    9.4 Análisis Descríptivo de los Datos

    #install.packages("readxl")  
    library(readxl)
    df3 <- read_excel("data_geologia.xlsx")
    df3
    summary(df3$Concentracion_Mineral_porcentaje)
    ##    Min. 1st Qu.  Median    Mean 3rd Qu.    Max. 
    ##    5.38   24.08   47.19   43.82   59.96   77.98
    ggplot(df3, aes(x = df3$Concentracion_Mineral_porcentaje)) +
      geom_histogram(binwidth = 5, fill = "skyblue", color = "black") +
      theme_minimal() +
      labs(title = "Distribución de la Concentración Mineral", x = "Concentración (%)", y = "Frecuencia")
    ## Warning: Use of `df3$Concentracion_Mineral_porcentaje` is discouraged.
    ## ℹ Use `Concentracion_Mineral_porcentaje` instead.

    ggplot(df3, aes(x = Tipo_Roca, y = Densidad_gcm3, fill = Tipo_Roca)) +
      geom_boxplot() +
      theme_minimal() +
      labs(title = "Densidad de Rocas por Tipo", x = "Tipo de Roca", y = "Densidad (g/cm³)")

    table(df3$Potencial_Minero)
    ## 
    ##  Alto  Bajo Medio 
    ##    21    44    35
    prop.table(table(df3$Presencia_Falla))
    ## 
    ##    0    1 
    ## 0.81 0.19

    9.5 Estimaciones por Intervalos de Confianza

    9.5.0.1 Intervalo de confianza para la Media

    1. Una empresa minera está evaluando la concentración de un mineral en una región específica. Para ello, ha recolectado muestras de distintos sitios y desea estimar un intervalo de confianza del 95% para la concentración media de mineral en la región.

    confianza <- 0.95
    n <- nrow(df3)
    x_barra <- mean(df3$Concentracion_Mineral_porcentaje)
    sd_mineral <- sd(df3$Concentracion_Mineral_porcentaje )
    
    errorest <- sd_mineral / sqrt(n)
    alpha <- 1 - confianza
    z_score <- qnorm(1 - alpha/2)  
    lim_inf <- x_barra - z_score * errorest
    lim_sup <- x_barra + z_score * errorest
    
    
    data.frame(Limite_Inferior = lim_inf, Media = x_barra, Limite_Superior = lim_sup)

    Interpretación: Este intervalo nos indica que estamos 95% seguros de que la verdadera concentración media del mineral en la región está entre los valores obtenidos en el intervalo de confianza.

    9.5.0.2 Intervalo de confianza para la Proporción

    2. En un estudio geológico, se ha determinado que algunos sitios de muestreo presentan fallas geológicas. Con base en los datos recolectados, se desea estimar la proporción de sitios con fallas geológicas en la población total con un nivel de confianza del 95%.

    Para calcular el intervalo de confianza para una proporción, utilizamos la siguiente fórmula:

    \[ IC = \hat{p} \pm Z_{\alpha/2} \cdot \sqrt{\frac{\hat{p} (1 - \hat{p})}{n}} \]

    Donde: - \(\hat{p}\) es la proporción muestral de sitios con fallas geológicas. - \(Z_{\alpha/2}\) es el valor crítico de la distribución normal estándar para un nivel de confianza del 95% (\(Z_{0.025} = 1.96\)). - \(n\) es el tamaño de la muestra. - \(\sqrt{\frac{\hat{p} (1 - \hat{p})}{n}}\) es el error estándar de la proporción.

    total_sites <- nrow(df3)
    num_fallas <- sum(df3$Presencia_Falla)
    p_hat <- num_fallas / total_sites  # Proporción muestral
    
    # Nivel de confianza del 95%
    alpha <- 0.05
    z_value <- qnorm(1 - alpha/2)  # Valor Z para 95%
    
    # Cálculo del error estándar
    se <- sqrt((p_hat * (1 - p_hat)) / total_sites)
    
    # Intervalo de confianza
    lower_bound <- p_hat - z_value * se
    upper_bound <- p_hat + z_value * se
    
    # Mostrar resultado
    intervalo_confianza <- c(lower_bound, upper_bound)
    intervalo_confianza
    ## [1] 0.1131104 0.2668896

    El intervalo de confianza del 95% para la proporción de sitios con fallas geológicas es de 0.1131 a 0.2669. Esto significa que podemos estar seguros en un 95% de que la verdadera proporción de sitios con fallas geológicas en la población se encuentra dentro de este rango.

    # Gráfico de la proporción de sitios con fallas geológicas
    fallas_plot <- df3 %>% 
      group_by(Presencia_Falla) %>% 
      summarise(Count = n()) %>% 
      mutate(Prop = Count / sum(Count))
    
    ggplot(fallas_plot, aes(x = (Presencia_Falla), y = Prop, fill = as.factor(Presencia_Falla))) +
      geom_bar(stat = "identity") +
      scale_fill_manual(values = c("#E69F00", "#56B4E9")) +
      labs(title = "Proporción de Sitios con Falla Geológica",
           x = "Presencia de Falla (0 = No, 1 = Sí)",
           y = "Proporción") +
      theme_minimal()

    Este análisis estadístico nos permite estimar con confianza la proporción de sitios con fallas geológicas en la zona de estudio. Esta información es clave para la planificación geológica y minera, ya que las fallas pueden afectar la estabilidad del terreno y la viabilidad de futuras exploraciones.

    9.5.0.3 Intervalo de confianza de diferencia de Proporciones.

    3.Se quiere comparar la proporción de sitios con fallas geológicas entre dos tipos de roca diferentes: Ígneas y Sedimentarias. Para ello, se calculará un intervalo de confianza del 95% para la diferencia de proporciones y se determinará si hay una diferencia significativa entre estos tipos de roca.

    Para calcular el intervalo de confianza para la diferencia de proporciones, utilizamos la siguiente fórmula:

    \[ IC = (\hat{p}_1 - \hat{p}_2) \pm Z_{\alpha/2} \cdot \sqrt{\frac{\hat{p}_1 (1 - \hat{p}_1)}{n_1} + \frac{\hat{p}_2 (1 - \hat{p}_2)}{n_2}} \]

    Donde: - \(\hat{p}_1\) y \(\hat{p}_2\) son las proporciones muestrales de sitios con fallas en rocas ígneas y sedimentarias, respectivamente. - \(n_1\) y \(n_2\) son los tamaños de muestra de cada tipo de roca. - \(Z_{\alpha/2}\) es el valor crítico de la distribución normal estándar para un nivel de confianza del 95% (\(Z_{0.025} = 1.96\)).

    roca_ignea <- df3 %>% filter(Tipo_Roca == "Ígnea")
    roca_sedimentaria <- df3 %>% filter(Tipo_Roca == "Sedimentaria")
    
    # Definir proporciones y tamaños de muestra
    n1 <- nrow(roca_ignea)
    n2 <- nrow(roca_sedimentaria)
    p1_hat <- sum(roca_ignea$Presencia_Falla) / n1
    p2_hat <- sum(roca_sedimentaria$Presencia_Falla) / n2
    
    # Corrección de continuidad: evitar proporciones 0 o 1
    if (p1_hat == 0) p1_hat <- 0.5 / n1
    if (p1_hat == 1) p1_hat <- (n1 - 0.5) / n1
    if (p2_hat == 0) p2_hat <- 0.5 / n2
    if (p2_hat == 1) p2_hat <- (n2 - 0.5) / n2
    
    # Nivel de confianza del 95%
    alpha <- 0.05
    z_value <- qnorm(1 - alpha/2)  # Valor Z para 95%
    
    # Cálculo del error estándar
    diff_se <- sqrt((p1_hat * (1 - p1_hat)) / n1 + (p2_hat * (1 - p2_hat)) / n2)
    
    # Intervalo de confianza
    lower_bound <- (p1_hat - p2_hat) - z_value * diff_se
    upper_bound <- (p1_hat - p2_hat) + z_value * diff_se
    
    # Mostrar resultado
    intervalo_confianza <- c(lower_bound, upper_bound)
    intervalo_confianza
    ## [1] -0.2008089  0.2103327

    El intervalo de confianza del 95% para la diferencia de proporciones entre sitios con fallas geológicas en rocas ígneas y sedimentarias es de -0.2008 a 0.2103. Si este intervalo incluye el cero, entonces no hay evidencia suficiente para afirmar que la diferencia entre las proporciones es estadísticamente significativa.

    # Gráfico de la proporción de sitios con fallas por tipo de roca
    fallas_plot <- df3 %>% 
      group_by(Tipo_Roca, Presencia_Falla) %>% 
      summarise(Count = n(), .groups = "drop") %>% 
      mutate(Prop = Count / sum(Count, na.rm = TRUE))
    
    ggplot(fallas_plot, aes(x = Tipo_Roca, y = Prop, fill = as.factor(Presencia_Falla))) +
      geom_bar(stat = "identity", position = "dodge") +
      scale_fill_manual(values = c("#E69F00", "#56B4E9"), labels = c("No Falla", "Con Falla")) +
      labs(title = "Proporción de Sitios con Falla por Tipo de Roca",
           x = "Tipo de Roca",
           y = "Proporción",
           fill = "Presencia de Falla") +
      theme_minimal()

    Este análisis permite determinar si la proporción de fallas geológicas varía entre diferentes tipos de roca. Si el intervalo de confianza no contiene el cero, esto indicaría una diferencia significativa en la proporción de fallas entre rocas ígneas y sedimentarias, lo cual puede tener implicaciones importantes en la planificación geológica y minera.

    9.5.0.4 Intervalo de confianza de diferencia de Medias (caso3).

    4. Se desea comparar la densidad media de dos tipos de roca diferentes: Ígneas y Sedimentarias. Para ello, se calculará un intervalo de confianza del 95% para la diferencia de medias y se determinará si existe una diferencia significativa entre estos tipos de roca.

    Para calcular el intervalo de confianza para la diferencia de medias, utilizamos la siguiente fórmula:

    \[ IC = (\bar{X}_1 - \bar{X}_2) \pm t_{\alpha/2, df} \cdot \sqrt{\frac{s_1^2}{n_1} + \frac{s_2^2}{n_2}} \]

    Donde: - \(\bar{X}_1\) y \(\bar{X}_2\) son las medias muestrales de la densidad en rocas ígneas y sedimentarias, respectivamente. - \(s_1^2\) y \(s_2^2\) son las varianzas muestrales de cada tipo de roca. - \(n_1\) y \(n_2\) son los tamaños de muestra de cada tipo de roca. - \(t_{\alpha/2, df}\) es el valor crítico de la distribución t de Student con grados de libertad \(df\).

    Los grados de libertad se calculan con la siguiente fórmula de Welch-Satterthwaite (usada cuando las varianzas son distintas):

    \[ df = \frac{\left( \frac{s_1^2}{n_1} + \frac{s_2^2}{n_2} \right)^2}{\frac{\left( \frac{s_1^2}{n_1} \right)^2}{n_1 - 1} + \frac{\left( \frac{s_2^2}{n_2} \right)^2}{n_2 - 1}} \]

    # Filtrar datos por tipo de roca
    roca_ignea <- df3 %>% filter(Tipo_Roca == "Ígnea")
    roca_sedimentaria <- df3 %>% filter(Tipo_Roca == "Sedimentaria")
    
    # Calcular estadísticas
    n1 <- nrow(roca_ignea)
    n2 <- nrow(roca_sedimentaria)
    mean1 <- mean(roca_ignea$Densidad_gcm3)
    mean2 <- mean(roca_sedimentaria$Densidad_gcm3)
    sd1 <- sd(roca_ignea$Densidad_gcm3)
    sd2 <- sd(roca_sedimentaria$Densidad_gcm3)
    
    # Calcular grados de libertad con la fórmula de Welch-Satterthwaite
    df_welch <- ((sd1^2/n1 + sd2^2/n2)^2) / ((sd1^2/n1)^2 / (n1 - 1) + (sd2^2/n2)^2 / (n2 - 1))
    
    # Nivel de confianza del 95%
    alpha <- 0.05
    t_value <- qt(1 - alpha/2, df = df_welch)  # Valor t para el nivel de confianza
    
    # Calcular el error estándar
    diff_se <- sqrt((sd1^2/n1) + (sd2^2/n2))
    
    # Intervalo de confianza
    lower_bound <- (mean1 - mean2) - t_value * diff_se
    upper_bound <- (mean1 - mean2) + t_value * diff_se
    
    # Mostrar resultado
    intervalo_confianza <- c(lower_bound, upper_bound)
    intervalo_confianza
    ## [1] -0.2509601  0.1454124

    El intervalo de confianza del 95% para la diferencia de medias en densidad entre rocas ígneas y sedimentarias es de -0.251 a 0.1454. Si este intervalo incluye el cero, entonces no hay evidencia suficiente para afirmar que la diferencia entre las medias es estadísticamente significativa.

    # Gráfico de comparación de densidades
    boxplot(Densidad_gcm3 ~ Tipo_Roca, data = df3,
            col = c("#E69F00", "#56B4E9"),
            main = "Comparación de Densidad entre Tipos de Roca",
            xlab = "Tipo de Roca", ylab = "Densidad (g/cm³)")

    Este análisis permite determinar si la densidad media de las rocas ígneas y sedimentarias es significativamente diferente. Si el intervalo de confianza no contiene el cero, esto indicaría una diferencia significativa en la densidad media de estos tipos de roca, lo cual puede tener implicaciones importantes en la exploración y explotación de recursos geológicos.

    9.5.0.5 Intervalo de confianza para la varianza.

    5. En un estudio geológico, se busca analizar la variabilidad de la densidad de las rocas ígneas en una región específica. Para ello, se calculará un intervalo de confianza del 95% para la varianza de la densidad de este tipo de roca.

    Para calcular el intervalo de confianza para la varianza de una población, utilizamos la distribución Chi-cuadrado y la siguiente fórmula:

    \[ IC = \left( \frac{(n-1) s^2}{\chi^2_{1-\alpha/2, n-1}}, \frac{(n-1) s^2}{\chi^2_{\alpha/2, n-1}} \right) \]

    Donde: - \(s^2\) es la varianza muestral de la densidad de las rocas ígneas. - \(n\) es el tamaño de la muestra. - \(\chi^2_{1-\alpha/2, n-1}\) y \(\chi^2_{\alpha/2, n-1}\) son los valores críticos de la distribución Chi-cuadrado con \(n-1\) grados de libertad para los niveles de confianza correspondientes.

    # Filtrar datos para rocas ígneas
    roca_ignea <- df3 %>% filter(Tipo_Roca == "Ígnea")
    
    # Calcular estadísticas
    n <- nrow(roca_ignea)
    var_muestral <- var(roca_ignea$Densidad_gcm3)
    
    # Nivel de confianza del 95%
    alpha <- 0.05
    chi_lower <- qchisq(1 - alpha/2, df = n-1)
    chi_upper <- qchisq(alpha/2, df = n-1)
    
    # Intervalo de confianza
    lower_bound <- (n-1) * var_muestral / chi_lower
    upper_bound <- (n-1) * var_muestral / chi_upper
    
    # Mostrar resultado
    intervalo_confianza <- c(lower_bound, upper_bound)
    intervalo_confianza
    ## [1] 0.08762792 0.24967476

    El intervalo de confianza del 95% para la varianza de la densidad de las rocas ígneas es de 0.0876 a 0.2497. Si este intervalo es amplio, indica una mayor incertidumbre en la variabilidad de la densidad de estas rocas.

    # Histograma de la densidad de las rocas ígneas
    ggplot(roca_ignea, aes(x = Densidad_gcm3)) +
      geom_histogram(binwidth = 0.1, fill = "#56B4E9", color = "black", alpha = 0.7) +
      labs(title = "Distribución de la Densidad de Rocas Ígneas",
           x = "Densidad (g/cm³)",
           y = "Frecuencia") +
      theme_minimal()

    Este análisis permite determinar la incertidumbre en la estimación de la varianza de la densidad de las rocas ígneas. Un intervalo de confianza amplio sugiere una alta variabilidad en los datos, mientras que un intervalo estrecho indica una mayor precisión en la estimación.

    9.5.0.6 Intervalo de confianza para la razón de varianzas.

    6.En un estudio geológico, se busca analizar si la variabilidad en la densidad de las rocas ígneas es significativamente diferente a la de las rocas sedimentarias. Para ello, se calculará un intervalo de confianza del 95% para la razón de varianzas entre estos dos tipos de rocas.

    Para calcular el intervalo de confianza para la razón de varianzas, utilizamos la distribución F de Fisher-Snedecor y la siguiente fórmula:

    \[ IC = \left( \frac{s_1^2}{s_2^2} \right) \cdot \left[ \frac{1}{F_{\alpha/2, n_1-1, n_2-1}}, F_{1-\alpha/2, n_1-1, n_2-1} \right] \]

    Donde: - \(s_1^2\) y \(s_2^2\) son las varianzas muestrales de la densidad en rocas ígneas y sedimentarias, respectivamente. - \(n_1\) y \(n_2\) son los tamaños de muestra de cada tipo de roca. - \(F_{\alpha/2, n_1-1, n_2-1}\) y \(F_{1-\alpha/2, n_1-1, n_2-1}\) son los valores críticos de la distribución F para los grados de libertad correspondientes.

    # Filtrar datos por tipo de roca
    roca_ignea <- df3 %>% filter(Tipo_Roca == "Ígnea")
    roca_sedimentaria <- df3 %>% filter(Tipo_Roca == "Sedimentaria")
    
    # Calcular estadísticas
    n1 <- nrow(roca_ignea)
    n2 <- nrow(roca_sedimentaria)
    var1 <- var(roca_ignea$Densidad_gcm3)
    var2 <- var(roca_sedimentaria$Densidad_gcm3)
    ratio_var <- var1 / var2  # Razón de varianzas
    
    # Nivel de confianza del 95%
    alpha <- 0.05
    f_lower <- qf(alpha/2, df1 = n1-1, df2 = n2-1)
    f_upper <- qf(1 - alpha/2, df1 = n1-1, df2 = n2-1)
    
    # Intervalo de confianza
    lower_bound <- ratio_var / f_upper
    upper_bound <- ratio_var / f_lower
    
    # Mostrar resultado
    intervalo_confianza <- c(lower_bound, upper_bound)
    intervalo_confianza
    ## [1] 0.3734817 1.5563592

    El intervalo de confianza del 95% para la razón de varianzas en densidad entre rocas ígneas y sedimentarias es de 0.3735 a 1.5564. Si este intervalo incluye el valor 1, entonces no hay evidencia suficiente para afirmar que las varianzas son significativamente diferentes.

    # Gráfico de comparación de dispersión
    boxplot(Densidad_gcm3 ~ Tipo_Roca, data = df3,
            col = c("#E69F00", "#56B4E9"),
            main = "Comparación de Varianza en Densidad entre Tipos de Roca",
            xlab = "Tipo de Roca", ylab = "Densidad (g/cm³)")

    Este análisis permite determinar si la variabilidad en la densidad de las rocas ígneas y sedimentarias es significativamente diferente. Si el intervalo de confianza no contiene el valor 1, esto indicaría una diferencia significativa en la dispersión de la densidad entre estos tipos de roca, lo cual puede ser relevante para estudios geológicos y mineros.

    10 Introducción a las Pruebas de Hipótesis

    En geología, las pruebas de hipótesis nos permiten tomar decisiones basadas en datos muestrales sobre fenómenos naturales, como la concentración de minerales, la frecuencia de sismos, o la densidad de suelos.

    La prueba de hipótesis consiste en: 1. Formular una hipótesis nula (\(H_0\)) y una hipótesis alternativa (\(H_1\)). 2. Calcular una estadística de prueba. 3. Comparar el p-valor con un nivel de significancia \(\alpha\). 4. Tomar una decisión: rechazar o no rechazar \(H_0\).

    10.0.1 Fórmula General para la Prueba de Media (Distribución T de Student):

    \[ t = \frac{\bar{x} - \mu_0}{s / \sqrt{n}} \] Donde: - \(\bar{x}\) = media muestral - \(\mu_0\) = valor de referencia de la hipótesis nula - \(s\) = desviación estándar muestral - \(n\) = tamaño de la muestra

    10.1 Ejemplo 1: Exploración de Minerales

    Una compañía minera quiere verificar si la concentración promedio de oro en una veta es mayor que 2.5 gramos por tonelada (g/t). Se toman 10 muestras y se obtiene una media de 2.8 g/t con una desviación estándar de 0.4 g/t.

    • \(H_0: \mu \leq 2.5\) g/t
    • \(H_1: \mu > 2.5\) g/t
    • \(\alpha = 0.05\)
    x_bar <- 2.8
    mu_0 <- 2.5
    s <- 0.4
    n <- 10
    
    
    t_stat <- (x_bar - mu_0) / (s / sqrt(n))
    
    
    df <- n - 1
    p_value <- pt(t_stat, df = df, lower.tail = FALSE)
    
    list(t_stat = round(t_stat, 3), p_value = round(p_value, 4))
    ## $t_stat
    ## [1] 2.372
    ## 
    ## $p_value
    ## [1] 0.0209

    10.2 Prueba de Hipótesis para la Media

    Una compañía minera está evaluando una veta aurífera en una nueva región del país. Históricamente, vetas rentables han mostrado concentraciones de oro superiores a 3.0 g/t. La empresa recolecta una muestra de 12 sitios y encuentra una media de 3.2 g/t con una desviación estándar de 0.5 g/t. ¿Puede afirmarse que esta veta supera el umbral de rentabilidad?

    Planteamiento:

    \(H_0: \mu \leq 3.0\) g/t
    \(H_1: \mu > 3.0\) g/t
    Nivel de significancia: \(\alpha = 0.05\)

    Solución:

    media_muestra <- 3.2
    media_hipotetica <- 3.0
    sd_muestra <- 0.5
    n <- 12
    alpha <- 0.05
    
    t_calculado <- (media_muestra - media_hipotetica) / (sd_muestra / sqrt(n))
    t_critico <- qt(1 - alpha, df = n - 1)
    
    t_calculado
    ## [1] 1.385641
    t_critico
    ## [1] 1.795885
    p_value <- 1 - pt(t_calculado, df = n - 1)
    p_value
    ## [1] 0.09665353

    10.3 2. Prueba para la Proporción

    En una cuenca sedimentaria se han inspeccionado 80 sitios para evaluar la presencia de fracturas geológicas. Se ha identificado que 50 sitios presentan fracturas. Los estudios anteriores sugieren que la proporción esperada de fracturas es del 60%. ¿Es consistente la proporción observada con la proporción histórica?

    Planteamiento:

    \(H_0: p = 0.6\)
    \(H_1: p \neq 0.6\)
    Nivel de significancia: \(\alpha = 0.05\)

    Solución

    1. Datos observados:
      • \(n = 80\)
      • \(x = 50\) sitios con fracturas
      • \(p_{observado} = \frac{50}{80} = 0.625\)
      • \(p_0 = 0.6\)
    2. Cálculo del estadístico de prueba:

    \(Z = \frac{p_{observado} - p_0}{\sqrt{ \frac{p_0(1 - p_0)}{n} }}\)

    # Datos
    n <- 80
    x <- 50
    p_observado <- x / n
    p_hipotetico <- 0.6
    alpha <- 0.05
    
    # Estadístico Z
    z_calculado <- (p_observado - p_hipotetico) / sqrt(p_hipotetico * (1 - p_hipotetico) / n)
    z_critico <- qnorm(1 - alpha / 2)
    
    # p-valor
    p_value <- 2 * (1 - pnorm(abs(z_calculado)))
    
    # Resultados
    z_calculado
    ## [1] 0.4564355
    z_critico
    ## [1] 1.959964
    p_value
    ## [1] 0.6480769

    10.4 3. Prueba para la Varianza

    Un laboratorio geotécnico analiza la variabilidad de la densidad de un tipo de mineral utilizado en la construcción. A partir de una muestra de 15 mediciones, la varianza obtenida es 0.09. Se requiere saber si esta varianza difiere de la especificada por los estándares internacionales, que es 0.04.

    Planteamiento:

    \(H_0: \sigma^2 = 0.04\)
    \(H_1: \sigma^2 \neq 0.04\)
    Nivel de significancia: \(\alpha = 0.05\)

    Solución

    1. Datos observados:
      • \(n = 15\)
      • \(s^2 = 0.09\)
      • \(\sigma_0^2 = 0.04\)
    2. Cálculo del estadístico de prueba:

    \(\chi^2 = \frac{(n - 1) s^2}{\sigma_0^2}\)

    # Datos
    n <- 15
    s2_muestra <- 0.09
    s2_hipotetica <- 0.04
    alpha <- 0.05
    
    # Estadístico Chi-cuadrado
    chi2_calculado <- (n - 1) * s2_muestra / s2_hipotetica
    chi2_critico_inf <- qchisq(alpha / 2, df = n - 1)
    chi2_critico_sup <- qchisq(1 - alpha / 2, df = n - 1)
    
    # Resultados
    chi2_calculado
    ## [1] 31.5
    chi2_critico_inf
    ## [1] 5.628726
    chi2_critico_sup
    ## [1] 26.11895

    10.5 4. Diferencia de Medias

    Se desea comparar la densidad promedio de dos tipos de rocas recolectadas de diferentes regiones tectónicas. Las rocas del Tipo A (región volcánica) presentan una media de 2.7 g/cm³ con desviación estándar de 0.1 g/cm³ (n=20), mientras que las rocas del Tipo B (región sedimentaria) presentan una media de 2.6 g/cm³ con desviación estándar de 0.12 g/cm³ (n=18). ¿Existe una diferencia significativa entre las densidades?

    Planteamiento:

    \(H_0: \mu_1 = \mu_2\)
    \(H_1: \mu_1 \neq \mu_2\)
    Nivel de significancia: \(\alpha = 0.05\)

    Solución

    1. Datos observados:
      • Tipo A: \(\bar{x}_1 = 2.7\), \(s_1 = 0.1\), \(n_1 = 20\)
      • Tipo B: \(\bar{x}_2 = 2.6\), \(s_2 = 0.12\), \(n_2 = 18\)
    2. Cálculo del estadístico de prueba:

    \(T = \frac{\bar{x}_1 - \bar{x}_2}{\sqrt{ \frac{s_1^2}{n_1} + \frac{s_2^2}{n_2} }}\)

    # Datos
    media1 <- 2.7
    media2 <- 2.6
    sd1 <- 0.1
    sd2 <- 0.12
    n1 <- 20
    n2 <- 18
    alpha <- 0.05
    
    # Estadístico T
    se_dif <- sqrt((sd1^2 / n1) + (sd2^2 / n2))
    t_calculado <- (media1 - media2) / se_dif
    df <- min(n1 - 1, n2 - 1)
    t_critico <- qt(1 - alpha / 2, df = df)
    
    # p-valor
    p_value <- 2 * (1 - pt(abs(t_calculado), df = df))
    
    # Resultados
    t_calculado
    ## [1] 2.773501
    t_critico
    ## [1] 2.109816
    p_value
    ## [1] 0.01301038

    10.6 5. Diferencia de Proporciones

    Un estudio regional compara la presencia de fallas geológicas en rocas sedimentarias e ígneas. De 50 sitios en rocas sedimentarias, 30 tienen fallas, y de 40 sitios en rocas ígneas, 20 presentan fallas. ¿Se puede afirmar que la proporción de fallas difiere entre estos dos tipos de rocas?

    Planteamiento:

    \(H_0: p_1 = p_2\)
    \(H_1: p_1 \neq p_2\)
    Nivel de significancia: \(\alpha = 0.05\)

    Solución

    1. Datos observados:
      • Rocas sedimentarias: \(n_1 = 50\), \(x_1 = 30\), \(p_1 = \frac{30}{50} = 0.6\)
      • Rocas ígneas: \(n_2 = 40\), \(x_2 = 20\), \(p_2 = \frac{20}{40} = 0.5\)
    2. Proporción combinada:

    \(p = \frac{x_1 + x_2}{n_1 + n_2} = \frac{30 + 20}{50 + 40} = \frac{50}{90} \approx 0.5556\)

    1. Cálculo del estadístico de prueba:

    \(Z = \frac{p_1 - p_2}{\sqrt{p (1 - p) \left( \frac{1}{n_1} + \frac{1}{n_2} \right)}}\)

    x1 <- 30
    n1 <- 50
    x2 <- 20
    n2 <- 40
    alpha <- 0.05
    
    p1 <- x1 / n1
    p2 <- x2 / n2
    p_pooled <- (x1 + x2) / (n1 + n2)
    
    # Estadístico Z
    se_pooled <- sqrt(p_pooled * (1 - p_pooled) * (1/n1 + 1/n2))
    z_calculado <- (p1 - p2) / se_pooled
    z_critico <- qnorm(1 - alpha / 2)
    
    # p-valor
    p_value <- 2 * (1 - pnorm(abs(z_calculado)))
    
    # Resultados
    z_calculado
    ## [1] 0.9486833
    z_critico
    ## [1] 1.959964
    p_value
    ## [1] 0.3427817

    10.7 6. Razón de Varianzas

    Se estudia la variabilidad de la densidad en rocas de dos formaciones geológicas distintas. En la formación A, la varianza de densidad es 0.09 (n=15), y en la formación B es 0.04 (n=12). Se desea evaluar si la variabilidad de la densidad difiere significativamente entre ambas formaciones.

    Planteamiento:

    \(H_0: \sigma_1^2 = \sigma_2^2\)
    \(H_1: \sigma_1^2 \neq \sigma_2^2\)
    Nivel de significancia: \(\alpha = 0.05\)

    Solución

    1. Datos observados:
      • Formación A: \(s_1^2 = 0.09\), \(n_1 = 15\)
      • Formación B: \(s_2^2 = 0.04\), \(n_2 = 12\)
    2. Cálculo del estadístico de prueba:

    \(F = \frac{s_1^2}{s_2^2}\)

    var1 <- 0.09
    var2 <- 0.04
    n1 <- 15
    n2 <- 12
    alpha <- 0.05
    
    
    F_calculado <- var1 / var2
    F_critico_inf <- qf(alpha / 2, df1 = n1 - 1, df2 = n2 - 1)
    F_critico_sup <- qf(1 - alpha / 2, df1 = n1 - 1, df2 = n2 - 1)
    
    
    F_calculado
    ## [1] 2.25
    F_critico_inf
    ## [1] 0.3231446
    F_critico_sup
    ## [1] 3.35881