Sesión 1 - Preliminares

Instalando R y R Studio

R fue creado en 1993 por los estadísticos Ross Ihaka y Robert Gentleman de la Universidad de Auckland. Es un lenguaje y entorno de programación. Contiene implementado metodologías en estadística de todas las áreas.

Para decargar y saber más detalles sobre R: https://cran.r-project.org/

R Studio es un IDE de R, esto es, un ambiente gráfico de desarrollo. Para decargar y saber más detalles sobre R Studio: https://www.rstudio.com/products/rstudio/download/#download

Entre las principales opciones de R encontramos:

  • Almacenar y manipular conjuntos de datos en diferentes formatos.
  • Operar objetos de diferentes tipos.
  • Un gran número de herramientas para análisis de datos.
  • Crear gráficos de alta calidad y de fácil manipulación.

Tu turno

  • Descarga e instala el R
  • Descarga e instala el R Studio

R como Calculadora Científica

Operaciones básicas

#2+3
#7*3
#15/3
#21%/%4
#21%%4
#2**3
#2^3
#sqrt(2)
#log(10)
#log(10,base=10)
#exp(1)
#round(sqrt(3),2)
#(1 + (1+1+1)^2)*(1 + 2*(1+1+1))^2

Funciones Trigonometricas

#pi
#sin(pi)
#cos(2*pi)
#tan(3*pi)

Tu turno

Resuelve los siguientes ejercicios:

  • ¿Cuál es el residuo de dividir 2^2022 entre 7?
  • \[\sqrt{(3^{5+7+11})/(2^{13+17})}\]
  • \[log(exp(1993))\]
  • Calcular la secante, cosecante y cotangente del ángulo: \[(5\pi)/4\] Redondea los valores calculados a 3 cifras decimales.

Vectores y asignaciones

R opera sobre estructuras de datos. La más simple de estas son los vectores.

#x <- c(1, 2, 4, 8, 16, 32)
#class(x)
#length(x)
#x[4]
#x[2:5]
#x[-1]
#x[7] <- 64
#x
#y <- c(1, 3, 9, 27, 81, 243, 729)
#z <- cbind(x,y)
#z
#class(z)
abc <- letters
#abc
#class(abc)
length(abc)
## [1] 26
#ABC <- LETTERS
#ABC
#nombre_estudiantes <- c('Ana','Beto','Camilo','Diego','Efrain')
#nombre_estudiantes
#booleano <- c(TRUE,FALSE,TRUE,TRUE,FALSE,FALSE,TRUE,TRUE,TRUE,FALSE,FALSE,FALSE)
#booleano
#class(booleano)

Es posible realizar operaciones sobre vectores:

#sum(x)
#y <- x^2
#y
#sqrt(y)
#log(y)
#z <- seq(6,10)
#z
#u <- seq(1,21,by=2)
#u
#w <- seq(17,2,by=-3)
#w
#x*z
#sum(booleano)
#paste(letters,1:26)
#paste(letters,1:26,sep="")

Tu turno

  • Calcula \[2^a\]

si a es el vector con los primeros cinco números primos.

  • Agrega los siguientes nombres al vector de estudiantes, Federico, Gonzalo y Humberto.

  • Siguiendo el patrón de los valores del vector booleano. Calcula el valor que debe ir en la posición 2022?

  • Defina el vector apellidos_estudiantes con los siguientes valores: González, Peréz, Rodriguez, Garcia, Nieto, Fuentes, Silva y Paz. Finalmente, defina el vector nombre_apellidos_estudiantes concatenando los vectores nombre_estudiantes y apellidos_estudiantes.

La función help

Es posible consultar la documentación de las funciones implementadas en R.

# help(log)
# help(abs)

Operadores de Relación

  • menor que
  • mayor que
  • menor o igual que
  • mayor o igual que
  • igual
  • diferente
# Asignamos a x el valor 8
#x <- 8 
#x
# x es menor que 3?
#x < 3
# x es mayor o igual que 3?
#x >= 3
# x es igual a 3?
#x == 3
# x es distinto de 3?
#x != 3
# CASO: Vectores
# Creamos dos vectores
#y<- 1:5
#z<- 5:1
# Son iguales?
#identical(y,z)
# Vemos los elementos que coinciden
#y == z

Operadores Lógicos

  • Negación
  • Conjunción
  • Disyunción
# Asignamos a y el valor 5
#y <- 5 
#y
# Negamos una expresión 
#!(y < 3)
# Válidez conjunta de dos expresiones
#(x < 10) & (y < 3)

# Válidez conjunta de dos expresiones
#(x < 10) | (y < 3)

# Tablas de Verdad: Conjunción y Disyunción
A <- c(TRUE,TRUE,FALSE,FALSE)
# !A
B <- c(TRUE,FALSE,TRUE,FALSE)
# A y B
#A & B
#tabla_conj <- cbind(A,B,(A & B))
#tabla_conj
# A o B
#A | B
#tabla_disy <- cbind(A,B,(A | B))
#tabla_disy

Tu turno

  • Si P, Q y R son expresiones que pueden tomar sólo dos valores, verdadero ó falso. Construye la tabla de verdad de la expresión \[(!P & Q) | R \]

  • Son iguales los vectores letters y LETTERS?

  • Negar el vector booleano. Luego, calcula el valor que debe ir en la posición 1993?

Scripts

Los scripts son archivos que permiten guardar lo hecho en una sesión de trabajo. Adicionalmente, es posible abrirlos y modificarlos en posteriores sesiones.

Las funciones search y library

Para listar los paquetes instalados junto con una breve descripción:

#library()

Para listar los paquetes cargados en la sesión:

#search()

Instalación y carga de un paquete

Frecuentemente hacemos uso de funciones ó conjuntos de datos que no están en los paquetes core de R. Para instalar un nuevo paquete de la siguiente forma:

#install.packages('modesto')

Si necesitamos instalar una lista de paquetes podemos prodecer de la siguiente forma:

#install.packages(c('sglg','orders','modesto','sregsurvey'))

Para acceder a las funciones ó conjuntos de datos de un paquete ya instalado debemos cargar el paquete:

#library(sglg)

Sesión 2 - Objetos: Manipulación, Lectura y Escritura

Definición y manipulación de Matrices y Arrays

Una matriz es una colección de datos dispuestos en forma rectangular. La clase de los datos puede ser entero, númerica, caracter y lógico. ESte concepto generaliza la idea de vector.

#
Z <- matrix(0,2,2)
Z
##      [,1] [,2]
## [1,]    0    0
## [2,]    0    0
dim(Z)
## [1] 2 2
#
M <- matrix(seq(1:6),3,3)
M
##      [,1] [,2] [,3]
## [1,]    1    4    1
## [2,]    2    5    2
## [3,]    3    6    3
#
N <- matrix(seq(1:6),3,3,byrow = TRUE)
N
##      [,1] [,2] [,3]
## [1,]    1    2    3
## [2,]    4    5    6
## [3,]    1    2    3
# Leer información de una matriz
N[3,]
## [1] 1 2 3
N[,2]
## [1] 2 5 2
N[1:2,]
##      [,1] [,2] [,3]
## [1,]    1    2    3
## [2,]    4    5    6
N[3,2] <- 7
N[,2:3]
##      [,1] [,2]
## [1,]    2    3
## [2,]    5    6
## [3,]    7    3
#
M + N
##      [,1] [,2] [,3]
## [1,]    2    6    4
## [2,]    6   10    8
## [3,]    4   13    6
# 
M*N
##      [,1] [,2] [,3]
## [1,]    1    8    3
## [2,]    8   25   12
## [3,]    3   42    9
#
M%*%N
##      [,1] [,2] [,3]
## [1,]   18   29   30
## [2,]   24   43   42
## [3,]   30   57   54
#
M/M
##      [,1] [,2] [,3]
## [1,]    1    1    1
## [2,]    1    1    1
## [3,]    1    1    1
#
t(N)
##      [,1] [,2] [,3]
## [1,]    1    4    1
## [2,]    2    5    7
## [3,]    3    6    3
#
cbind(M,M)
##      [,1] [,2] [,3] [,4] [,5] [,6]
## [1,]    1    4    1    1    4    1
## [2,]    2    5    2    2    5    2
## [3,]    3    6    3    3    6    3
rbind(N,N)
##      [,1] [,2] [,3]
## [1,]    1    2    3
## [2,]    4    5    6
## [3,]    1    7    3
## [4,]    1    2    3
## [5,]    4    5    6
## [6,]    1    7    3
#
redes <- c("Facebook","Instagram","Youtube","Whattapp")
U <- matrix(c(1,0,1,1,0,0,1,1,1,0,0,0,1,1,1,0,0,0,1,1,0,0,1,0),6,4,dim=list(c(),redes))
U
##      Facebook Instagram Youtube Whattapp
## [1,]        1         1       1        1
## [2,]        0         1       1        1
## [3,]        1         1       1        0
## [4,]        1         0       0        0
## [5,]        0         0       0        1
## [6,]        0         0       0        0
nombre_estudiantes <- c('Ana','Beto','Camilo','Diego','Efrain','Fernanda') 
U <- matrix(c(1,0,1,1,0,0,1,1,1,0,0,0,1,1,1,0,0,0,1,1,0,0,1,0),6,4,dim=list(nombre_estudiantes,redes))
U
##          Facebook Instagram Youtube Whattapp
## Ana             1         1       1        1
## Beto            0         1       1        1
## Camilo          1         1       1        0
## Diego           1         0       0        0
## Efrain          0         0       0        1
## Fernanda        0         0       0        0
#
U%*%t(U)
##          Ana Beto Camilo Diego Efrain Fernanda
## Ana        4    3      3     1      1        0
## Beto       3    3      2     0      1        0
## Camilo     3    2      3     1      0        0
## Diego      1    0      1     1      0        0
## Efrain     1    1      0     0      1        0
## Fernanda   0    0      0     0      0        0

Un arreglo es una colección de datos indexada con una tupla. Este concepto generaliza la idea de matriz.

#
z <- array(seq(1,11,by=2),c(2,3,3))
z
## , , 1
## 
##      [,1] [,2] [,3]
## [1,]    1    5    9
## [2,]    3    7   11
## 
## , , 2
## 
##      [,1] [,2] [,3]
## [1,]    1    5    9
## [2,]    3    7   11
## 
## , , 3
## 
##      [,1] [,2] [,3]
## [1,]    1    5    9
## [2,]    3    7   11
dim(z)
## [1] 2 3 3
#
z[,,1]
##      [,1] [,2] [,3]
## [1,]    1    5    9
## [2,]    3    7   11
z[1,1,3]
## [1] 1
z[,2,2]
## [1] 5 7
notas <- round(runif(18,3,5),1)
notas_cursos <- array(notas,c(3,3,2))
notas_cursos
## , , 1
## 
##      [,1] [,2] [,3]
## [1,]  3.3  4.4  3.4
## [2,]  4.7  3.5  4.9
## [3,]  5.0  4.4  3.5
## 
## , , 2
## 
##      [,1] [,2] [,3]
## [1,]  3.2  4.4  3.7
## [2,]  4.8  4.4  4.5
## [3,]  3.6  3.4  3.4
notas_cursos <- array(notas,c(3,3,2),dimnames=c(list(c(),c(),c('A','B'))))
notas_cursos
## , , A
## 
##      [,1] [,2] [,3]
## [1,]  3.3  4.4  3.4
## [2,]  4.7  3.5  4.9
## [3,]  5.0  4.4  3.5
## 
## , , B
## 
##      [,1] [,2] [,3]
## [1,]  3.2  4.4  3.7
## [2,]  4.8  4.4  4.5
## [3,]  3.6  3.4  3.4

Tu turno

  • Cuál es elemento de la fila 3 y columna 4 de la matriz \[M^5\]

  • Actualiza los perfiles de los estudiantes en la matriz U con los datos de la red social Telegram: \[ c(0,1,0,1,1,1) \]

  • Con base en la matrix U actualizada, cuál(es) son los pares de estudiantes más similares?

  • Las asignaturas en los cursos A y B del arreglo notas_cursos son Cálculo I, Economía y Sicometría. Nombra las columnas de cada curso con estas asignaturas.

Definición y manipulación de Listas y Dataframes

La estructura de datos lista nos permiten almacenar diferentes estructuras de datos. Pudiendo cada una de las subestructuras ser de diferentes dimensiones.

#
pais <- c('Argentina', 'Brasil', 'Chile', 'Colombia', 'Ecuador', 'México', 'Perú', 'Venezuela')
poblacion <- c(47,212,19,51,18,126,33,28)
inmunidad <- c(TRUE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, FALSE)
latam <- list(pais = pais, pob = poblacion, inm = inmunidad)
latam
## $pais
## [1] "Argentina" "Brasil"    "Chile"     "Colombia"  "Ecuador"   "México"   
## [7] "Perú"      "Venezuela"
## 
## $pob
## [1]  47 212  19  51  18 126  33  28
## 
## $inm
## [1]  TRUE FALSE FALSE FALSE FALSE FALSE  TRUE FALSE
#
latam$pais
## [1] "Argentina" "Brasil"    "Chile"     "Colombia"  "Ecuador"   "México"   
## [7] "Perú"      "Venezuela"
latam$pob
## [1]  47 212  19  51  18 126  33  28
latam[[1]]
## [1] "Argentina" "Brasil"    "Chile"     "Colombia"  "Ecuador"   "México"   
## [7] "Perú"      "Venezuela"
latam[[2]]
## [1]  47 212  19  51  18 126  33  28
latam$pais[3]
## [1] "Chile"
latam$pais[latam$pob > 40]
## [1] "Argentina" "Brasil"    "Colombia"  "México"

La estructuta de datos data.frame nos permiten almacenar vectores con diferentes tipos datos. Pero, todos deben tener la misma longitud.

pais <- c('Argentina', 'Brasil', 'Chile', 'Colombia', 'Ecuador', 'México', 'Perú')
#latam <- data.frame(pais = pais, pob = poblacion, inm = inmunidad)
#latam
# Todos los vectores deben tener la misma longitud!
latam <- data.frame(pais = pais, pob = poblacion[-8], inm =inmunidad[-8])
latam
##        pais pob   inm
## 1 Argentina  47  TRUE
## 2    Brasil 212 FALSE
## 3     Chile  19 FALSE
## 4  Colombia  51 FALSE
## 5   Ecuador  18 FALSE
## 6    México 126 FALSE
## 7      Perú  33  TRUE
#
latam$pais
## [1] "Argentina" "Brasil"    "Chile"     "Colombia"  "Ecuador"   "México"   
## [7] "Perú"
latam$pob
## [1]  47 212  19  51  18 126  33
latam$inm
## [1]  TRUE FALSE FALSE FALSE FALSE FALSE  TRUE
latam$pais[1]
## [1] "Argentina"
#
subset(latam,select=c(pais,pob))
##        pais pob
## 1 Argentina  47
## 2    Brasil 212
## 3     Chile  19
## 4  Colombia  51
## 5   Ecuador  18
## 6    México 126
## 7      Perú  33
#
subset(latam,inm==TRUE)
##        pais pob  inm
## 1 Argentina  47 TRUE
## 7      Perú  33 TRUE
#
latam$pib <- c(1217,3730,574,959,232,2939,523)
latam
##        pais pob   inm  pib
## 1 Argentina  47  TRUE 1217
## 2    Brasil 212 FALSE 3730
## 3     Chile  19 FALSE  574
## 4  Colombia  51 FALSE  959
## 5   Ecuador  18 FALSE  232
## 6    México 126 FALSE 2939
## 7      Perú  33  TRUE  523
transform(latam,pibpc=round(pib/pob,1))
##        pais pob   inm  pib pibpc
## 1 Argentina  47  TRUE 1217  25.9
## 2    Brasil 212 FALSE 3730  17.6
## 3     Chile  19 FALSE  574  30.2
## 4  Colombia  51 FALSE  959  18.8
## 5   Ecuador  18 FALSE  232  12.9
## 6    México 126 FALSE 2939  23.3
## 7      Perú  33  TRUE  523  15.8

Lectura y escritura de archivos .txt, .csv y xlsx

Para escritura y lectura de archivos de tipo .txt

# Guardamos el archivo *latam* en el archivo *nuevos_datos.txt*
#write.table(latam,"nuevos_datos.txt",sep = "\t")
# Leemos el archivo nuevos_datos.txt 
#datos <- read.table("nuevos_datos.txt", header=TRUE)
#datos

Para escritura y lectura de archivos de tipo .xlsx

# Instalamos y cargamos la biblioteca readxl
#library(readxl)
# Leer archivo .xlsx 
#datos_xlsx <- readxl_excel("nuevos_datos.xlsx")
#datos_xlsx

Para escritura y lectura de archivos de tipo .csv

#datos_csv <- read.csv2("nuevos_datos.csv")
#datos_csv

Sesión 3 - Operadores

Operadores de Control

Podemos usar if o if else para ejecutar un bloque de código sólo si se satisface una condición

# Parque de Atracciones
edades <- c(23,17,19,24,15,20)

if (edades[1] >= 18) print('Puede entrar a la atracción')
## [1] "Puede entrar a la atracción"
if (edades[2] >= 18) print('Puede entrar a la atracción')
#
if (edades[2] >= 18) print('Puede entrar a la atracción') else print('No cumples con la edad mínima')
## [1] "No cumples con la edad mínima"
if (edades[3] >= 18) print('Puede entrar a la atracción') else print('No cumples con la edad mínima')
## [1] "Puede entrar a la atracción"
if (edades[5] >= 18) print('Puede entrar a la atracción') else print('No cumples con la edad mínima')
## [1] "No cumples con la edad mínima"
#
credito <- rep(20,6)
credito
## [1] 20 20 20 20 20 20
if (edades[1] >= 18){ 
  credito[1] <- credito[1] - 4
  print('Puede entrar a la atracción')
}  
## [1] "Puede entrar a la atracción"
credito[1]
## [1] 16
if (edades[2] >= 18){ 
  credito[2] <- credito[2] - 4
  print('Puede entrar a la atracción')
}  
credito[2]
## [1] 20

Estructuras de Repetición

Para repetir la ejecución de un mismo bloque de código podemos usar un for.

nombres <- c('Ana','Beto','Camilo','Diego','Efrain','Gabriela')
for (i in 1:6){
  if (edades[i] >= 18){ 
    credito[i] <- credito[i] - 4
    mensaje <- paste(nombres[i],'puede entrar a la atracción')
    print(mensaje)
  }
}
## [1] "Ana puede entrar a la atracción"
## [1] "Camilo puede entrar a la atracción"
## [1] "Diego puede entrar a la atracción"
## [1] "Gabriela puede entrar a la atracción"

Para ejecutar repetidamente el mismo bloque de código sólo si una condición es satisfecha usamos el while.

j = 1
credito <- rep(20,6)
nombres <- c('Ana','Beto','Camilo','Diego','Efrain','Gabriela')
while (j <= 6){
    if(edades[j] >= 18){ 
      credito[j] <- credito[j] - 4
      mensaje <- paste(nombres[j],'puede entrar a la atracción')
      print(mensaje)}
    j <- j + 1
}
## [1] "Ana puede entrar a la atracción"
## [1] "Camilo puede entrar a la atracción"
## [1] "Diego puede entrar a la atracción"
## [1] "Gabriela puede entrar a la atracción"
#
i = 1
credito <- rep(20,6)
njugadores <- 0 
while (i <= 6 & njugadores <= 3){
    if(edades[i] >= 18){ 
      credito[i] <- credito[i] - 4
      mensaje <- paste(nombres[i],'puede entrar a la atracción.','Su nuevo credito es: ',credito[i])
      print(mensaje)}
    njugadores <- njugadores + 1  
    i <- i + 1
}
## [1] "Ana puede entrar a la atracción. Su nuevo credito es:  16"
## [1] "Camilo puede entrar a la atracción. Su nuevo credito es:  16"
## [1] "Diego puede entrar a la atracción. Su nuevo credito es:  16"

Tu turno

  • Parque de Atracciones: Construya un bucle que imprima el nombre, el mensaje de bienvenida y el saldo de su tarjeta.

Funciones

sabores <- c('vainilla','chocolate','frutos rojos')
# De cuántas formas podemos servir un helado de tres sabores (sin repetir)?
# Esta situación está relacionada con el problema contar el número de permutaciones de n objetos distintos.
# n: Número de sabores
factorial <- function(n){
             resultado <- 1
             for (i in 2:n){
             resultado <- i*resultado
             }
             return(resultado)
}
factorial(3)
## [1] 6
sabores <- c('vainilla','chocolate','frutos rojos','piña')
factorial(4)
## [1] 24
# Fabrica de Helados
# Un kilo de fruta produce 20 helados  
# n: kilos de fruta
nhelados <- function(n){
             resultados <- n*20
             return(resultados)
}
nhelados(4)
## [1] 80
nhelados(10)
## [1] 200
costof <- function(n){
    costo_total <- 300 + n*0.75
    return(costo_total)
}
costof(0)
## [1] 300
costof(50)
## [1] 337.5

Tu turno

  • Fabrica de Helados: Si los costos fijos mensuales de la fábrica son 300 dólares y el costo de producir un helado es 0.75 dólares. Construya una función que retorne el costo total de producción mensual de n helados.
  • Utilizando los sabores vainilla, chocolate, frutos rojos y piña. Construya un bucle que imprima todos los posibles helados de tres sabores (sin repetir).

Sesión 4 - Estadística Descriptiva

Parte de la Estadística que tiene por objetivos organizar y resumir adecuadamente los conjuntos de datos.

data(iris)
head(iris)
##   Sepal.Length Sepal.Width Petal.Length Petal.Width Species
## 1          5.1         3.5          1.4         0.2  setosa
## 2          4.9         3.0          1.4         0.2  setosa
## 3          4.7         3.2          1.3         0.2  setosa
## 4          4.6         3.1          1.5         0.2  setosa
## 5          5.0         3.6          1.4         0.2  setosa
## 6          5.4         3.9          1.7         0.4  setosa
dim(iris)
## [1] 150   5
tabla_spec <- table(iris$Species)
tabla_spec_prop <- round(prop.table(tabla_spec),2)
tabla_spec_prop
## 
##     setosa versicolor  virginica 
##       0.33       0.33       0.33
iris$Petal.Length
##   [1] 1.4 1.4 1.3 1.5 1.4 1.7 1.4 1.5 1.4 1.5 1.5 1.6 1.4 1.1 1.2 1.5 1.3 1.4
##  [19] 1.7 1.5 1.7 1.5 1.0 1.7 1.9 1.6 1.6 1.5 1.4 1.6 1.6 1.5 1.5 1.4 1.5 1.2
##  [37] 1.3 1.4 1.3 1.5 1.3 1.3 1.3 1.6 1.9 1.4 1.6 1.4 1.5 1.4 4.7 4.5 4.9 4.0
##  [55] 4.6 4.5 4.7 3.3 4.6 3.9 3.5 4.2 4.0 4.7 3.6 4.4 4.5 4.1 4.5 3.9 4.8 4.0
##  [73] 4.9 4.7 4.3 4.4 4.8 5.0 4.5 3.5 3.8 3.7 3.9 5.1 4.5 4.5 4.7 4.4 4.1 4.0
##  [91] 4.4 4.6 4.0 3.3 4.2 4.2 4.2 4.3 3.0 4.1 6.0 5.1 5.9 5.6 5.8 6.6 4.5 6.3
## [109] 5.8 6.1 5.1 5.3 5.5 5.0 5.1 5.3 5.5 6.7 6.9 5.0 5.7 4.9 6.7 4.9 5.7 6.0
## [127] 4.8 4.9 5.6 5.8 6.1 6.4 5.6 5.1 5.6 6.1 5.6 5.5 4.8 5.4 5.6 5.1 5.1 5.9
## [145] 5.7 5.2 5.0 5.2 5.4 5.1
tpetal <- as.character(as.numeric(iris$Petal.Length > 2))
nuevo_iris <- data.frame(iris,tpetal)
head(nuevo_iris)
##   Sepal.Length Sepal.Width Petal.Length Petal.Width Species tpetal
## 1          5.1         3.5          1.4         0.2  setosa      0
## 2          4.9         3.0          1.4         0.2  setosa      0
## 3          4.7         3.2          1.3         0.2  setosa      0
## 4          4.6         3.1          1.5         0.2  setosa      0
## 5          5.0         3.6          1.4         0.2  setosa      0
## 6          5.4         3.9          1.7         0.4  setosa      0
tabla_specie_tpetal<-table(nuevo_iris$Species,nuevo_iris$tpetal)
round(prop.table(tabla_specie_tpetal),3)
##             
##                  0     1
##   setosa     0.333 0.000
##   versicolor 0.000 0.333
##   virginica  0.000 0.333
round(prop.table(tabla_specie_tpetal,2),3)
##             
##                0   1
##   setosa     1.0 0.0
##   versicolor 0.0 0.5
##   virginica  0.0 0.5

Medidas de Centralidad

Sea \(x_1,x_2,\cdots,x_n\) un conjunto de datos númerico.

Media aritmética

\[ \bar{x} = \frac{1}{n}\sum x_i\]

attach(iris)
mean(Petal.Length)
## [1] 3.758
setosas <- subset(iris,Species=='setosa')
mean(setosas$Petal.Length)
## [1] 1.462
versicolors <- subset(iris,Species=='versicolor')
mean(versicolors$Petal.Length)
## [1] 4.26
mean(Sepal.Length)
## [1] 5.843333
mean(setosas$Sepal.Length)
## [1] 5.006
mean(versicolors$Sepal.Length)
## [1] 5.936

Mediana

Medida de centralidad basada en los datos ordenados de menor a mayor. Su calculo depende de la paridad de n. Si n es par

\[ Med =\frac{1}{2}(x_{(\frac{n}{2})} + x_{(\frac{n}{2} + 1 )}) \]

Si n es impar \[ Med = x_{(\frac{n}{2})} \]

median(Petal.Length)
## [1] 4.35
mean(Petal.Length < 4.35)
## [1] 0.5
mean(Petal.Length > 4.35)
## [1] 0.5
q_2 <- median(Sepal.Length)
round(mean(Sepal.Length < 5.8),2)
## [1] 0.49
round(mean(Sepal.Length > 5.8),2)
## [1] 0.47

Moda

El valor más frecuente en un conjunto de datos. Notese que, un conjunto de datos puede no tener moda o puede tener más de una moda.

# Un ejemplo con una única moda
table(Sepal.Length)
## Sepal.Length
## 4.3 4.4 4.5 4.6 4.7 4.8 4.9   5 5.1 5.2 5.3 5.4 5.5 5.6 5.7 5.8 5.9   6 6.1 6.2 
##   1   3   1   4   2   5   6  10   9   4   1   6   7   6   8   7   3   6   6   4 
## 6.3 6.4 6.5 6.6 6.7 6.8 6.9   7 7.1 7.2 7.3 7.4 7.6 7.7 7.9 
##   9   7   5   2   8   3   4   1   1   3   1   1   1   4   1
max(table(Sepal.Length))
## [1] 10
which.max(table(Sepal.Length))
## 5 
## 8
# Un ejemplo con dos modas
table(Petal.Length)
## Petal.Length
##   1 1.1 1.2 1.3 1.4 1.5 1.6 1.7 1.9   3 3.3 3.5 3.6 3.7 3.8 3.9   4 4.1 4.2 4.3 
##   1   1   2   7  13  13   7   4   2   1   2   2   1   1   1   3   5   3   4   2 
## 4.4 4.5 4.6 4.7 4.8 4.9   5 5.1 5.2 5.3 5.4 5.5 5.6 5.7 5.8 5.9   6 6.1 6.3 6.4 
##   4   8   3   5   4   5   4   8   2   2   2   3   6   3   3   2   2   3   1   1 
## 6.6 6.7 6.9 
##   1   2   1
which.max(table(Petal.Length))
## 1.4 
##   5
# El conjunto de datos, mtcars, del paquete datasets.  
data(mtcars)
str(mtcars)
## 'data.frame':    32 obs. of  11 variables:
##  $ mpg : num  21 21 22.8 21.4 18.7 18.1 14.3 24.4 22.8 19.2 ...
##  $ cyl : num  6 6 4 6 8 6 8 4 4 6 ...
##  $ disp: num  160 160 108 258 360 ...
##  $ hp  : num  110 110 93 110 175 105 245 62 95 123 ...
##  $ drat: num  3.9 3.9 3.85 3.08 3.15 2.76 3.21 3.69 3.92 3.92 ...
##  $ wt  : num  2.62 2.88 2.32 3.21 3.44 ...
##  $ qsec: num  16.5 17 18.6 19.4 17 ...
##  $ vs  : num  0 0 1 1 0 1 0 1 1 1 ...
##  $ am  : num  1 1 1 0 0 0 0 0 0 0 ...
##  $ gear: num  4 4 4 3 3 3 3 4 4 4 ...
##  $ carb: num  4 4 1 1 2 1 4 2 2 4 ...
attach(mtcars)
# Número de cilindros
table(cyl)
## cyl
##  4  6  8 
## 11  7 14
# Número de carburadores
table(carb)
## carb
##  1  2  3  4  6  8 
##  7 10  3 10  1  1
indices <- which.max(table(Sepal.Length))
table(Sepal.Length)[indices]
##  5 
## 10
# sl <- c(mean(Sepal.Length),median(Sepal.Length),---)

Tu turno

  • Construye el data.frame iris_descrito con la media, mediana y moda de cada una de las variables del conjunto de datos iris. Si no aplica una medida en una variable utiliza un valor NA.

  • Construye el data.frame mtcars_descrito con la media, mediana y moda de cada una de las variables del conjunto de datos mtcars. Si no aplica una medida en una variable utiliza un valor NA.

Cuartiles y Percentiles

Los cuartiles son tres valores que dividen al conjunto de datos ordenados en cuatro partes aproximadamente iguales.

  • El primer cuartil, Q1, es un valor que es mayor que una cuarta parte de los datos.
  • El segundo cuartil, Q2, (la mediana), es un valor que es mayor que la mitad de los datos.
  • El tercer cuartil, Q3, es un valor que es mayor que tres cuartas partes de los datos.
q_1 <- quantile(Sepal.Length,p=0.25)
mean(Sepal.Length < q_1)
## [1] 0.2133333
mean(Sepal.Length > q_1)
## [1] 0.7266667
quantile(Sepal.Length,p=0.5)
## 50% 
## 5.8
quantile(Sepal.Length,p=0.75)
## 75% 
## 6.4

El percentil x_p es un valor que divide el conjunto de datos ordenados en dos partes, los menores que x_p y los mayores que x_p. La proporción de valores menores que x_p es aproximadamente p y la proporción de valores mayores que x_p es aproximadamente (1 - p).

quantile(Sepal.Length,p=0.01)
##  1% 
## 4.4
quantile(Sepal.Length,p=0.9)
## 90% 
## 6.9

Tu turno

  • Actualiza el data.frame iris_descrito con el primer cuartil, el segundo cuartil y el tercer cuartil de cada una de las variables del conjunto de datos. Si no aplica una medida en una variable utiliza un valor NA.

  • Actualiza el data.frame mtcars_descrito con el primer cuartil, el segundo cuartil y el tercer cuartil de cada una de las variables del conjunto de datos. Si no aplica una medida en una variable utiliza un valor NA.

Medidas de Variabilidad

Rango

Sea \(x_1,x_2,\cdots,x_n\) un conjunto de datos númerico. Definimos el rango como

\[ r = x_{max} - x_{min}\]

x_min <- min(Sepal.Length)
x_min
## [1] 4.3
x_max <- max(Sepal.Length)
x_max
## [1] 7.9
r <- x_max - x_min
r
## [1] 3.6
range(Sepal.Length)
## [1] 4.3 7.9
r <- range(Sepal.Length)[2] - range(Sepal.Length)[1]
r
## [1] 3.6

Rango intercuartílico

Definimos el rango intercuartílico de los valores \(x_1,x_2,\cdots,x_n\) como \[ r_{IQ} = q_{3} - q_{1}\] con \(q_1, q_3\) los cuartiles 1 y 3, respectivamente.

q_1 <- quantile(Sepal.Length,p=0.25)
q_1
## 25% 
## 5.1
q_3 <- quantile(Sepal.Length,p=0.75)
q_3
## 75% 
## 6.4
r_inter <- q_3 - q_1
r_inter
## 75% 
## 1.3

Varianza y Desviación Estándar

Definimos la varianza de los valores \(x_1,x_2,\cdots,x_n\) como \[ S^2_x = \frac{1}{n}\sum_{i=1}^n (x_i - \bar{x})^2 \]

var(Sepal.Length)
## [1] 0.6856935

Definimos la desviación estándar de los valores \(x_1,x_2,\cdots,x_n\) como \[ S_x = \sqrt \{\frac{1}{n}\sum_{i=1}^n (x_i - \bar{x})^2\} \]

des_est <- sqrt(var(Sepal.Length))
des_est
## [1] 0.8280661
sd(Sepal.Length)
## [1] 0.8280661

Coeficiente de variación de Pearson

Definimos el Coeficiente de variación de los valores \(x_1,x_2,\cdots,x_n\) como \[ CV_x = \frac{ \bar{x}}{S} \]

CV <- mean(Sepal.Length)/sd(Sepal.Length)
CV
## [1] 7.056602
mean(setosas$Sepal.Length)/sd(setosas$Sepal.Length)
## [1] 14.20183
mean(versicolors$Sepal.Length)/sd(versicolors$Sepal.Length)
## [1] 11.50006

Medidas de Forma

Existen varios mecanismos de evaluación la forma de la distribución de una conjunto de datos númericos.

Coeficiente de Asimetría de Pearson

Definimos el coeficiente de asimetría de los valores \(x_1,x_2,\cdots,x_n\) como \[ CAP_x = \frac{ \bar{x} - Med}{S} \]

cap <- (mean(Sepal.Length) - median(Sepal.Length))/sd(Sepal.Length)
cap
## [1] 0.05233076

Coeficiente de Asimetría basado en Cuartiles

Es posible definir un coeficiente de asimetria basado en cuartiles \[ CAQ_x = \frac{Q_3 + Q_1 - 2Med}{R_{IQ}} \] Ambas medidas no tienen unidades de medición, esto es, no dependen de la escala de medición.

Sesgo

dist_sim1 <- runif(300,2,4)
dist_sim2 <- rnorm(300,mean=3,sd=0.3)

#install.packages('moments') 
library(moments)
## Warning: package 'moments' was built under R version 4.1.3
skewness(dist_sim1)
## [1] 0.1792545
skewness(dist_sim2)
## [1] 0.1376623
attach(iris)
## The following objects are masked from iris (pos = 5):
## 
##     Petal.Length, Petal.Width, Sepal.Length, Sepal.Width, Species
skewness(Sepal.Width)
## [1] 0.3157671

Curtosis

dist_sim2
##   [1] 2.848765 3.191054 2.963674 3.168860 2.743617 3.227867 3.463678 3.001469
##   [9] 2.862609 2.798650 2.919715 2.852658 2.779278 2.992049 3.024974 2.926409
##  [17] 2.694882 2.765839 2.828953 2.777550 2.970729 2.474447 2.435852 2.981316
##  [25] 3.013137 3.382710 2.507145 2.816003 3.128654 2.893322 2.872289 2.692753
##  [33] 2.842469 2.938580 2.893401 3.734335 2.605784 2.758408 2.585095 3.294856
##  [41] 2.637664 3.406038 3.059829 3.154566 3.158248 2.664252 2.841379 2.878701
##  [49] 2.584871 2.881164 2.947417 2.835585 3.337947 2.533991 3.030719 2.739163
##  [57] 2.758252 2.821394 3.206983 2.994464 2.718721 3.914972 3.275218 3.023019
##  [65] 3.249274 2.839884 2.994629 2.700136 2.878439 3.354181 2.671973 3.793124
##  [73] 3.222042 2.878988 2.702975 3.113417 2.308614 3.010928 2.959465 2.739179
##  [81] 3.108470 3.033257 2.910584 3.453483 2.763404 2.900760 2.540385 3.225535
##  [89] 2.881582 3.369262 2.883443 2.903252 2.862023 3.499301 3.213031 3.031227
##  [97] 3.285057 2.896178 3.136335 3.469496 3.172559 2.856348 3.564462 3.506645
## [105] 3.031896 2.153102 2.742057 2.661507 2.329922 3.089891 3.033471 3.360820
## [113] 3.306941 3.296247 3.737552 3.515090 2.897430 2.714843 2.753259 2.890094
## [121] 3.231620 2.887997 3.196361 2.803696 3.513101 3.164382 2.568422 2.883578
## [129] 3.006122 3.065776 2.918426 3.092502 2.895044 2.326964 3.449305 2.749104
## [137] 2.992374 2.626411 3.002283 2.973627 2.496844 2.622100 3.069941 2.851031
## [145] 2.380807 2.997621 2.370279 3.237731 2.930775 3.288617 3.047838 3.151377
## [153] 2.647904 3.710144 3.446407 3.241057 3.051879 3.025495 2.891555 2.484224
## [161] 2.993074 3.226321 3.381486 2.710685 2.903702 3.059317 2.695639 2.825180
## [169] 2.977937 2.821011 3.679989 3.042365 2.887116 3.130130 3.331116 2.773256
## [177] 2.713191 2.640911 2.868529 3.348930 2.935010 3.025018 2.938490 2.697212
## [185] 2.799026 2.891505 2.967370 3.508417 3.093867 2.571382 2.662124 2.896389
## [193] 2.591147 3.242266 2.558532 2.565470 3.194967 3.026261 2.852793 3.227155
## [201] 3.186320 2.929721 2.927215 3.464555 3.012469 2.228792 2.716201 3.083357
## [209] 3.280961 3.052155 3.082362 2.373582 3.266353 3.133255 2.810871 3.237494
## [217] 2.945061 2.412989 3.083188 2.576094 2.892797 3.315469 2.721089 2.233328
## [225] 2.449561 3.046703 2.719292 2.703583 3.013372 2.579667 2.836788 2.940909
## [233] 3.130922 2.660389 3.172639 3.141218 3.432345 3.366582 2.717097 2.981680
## [241] 3.296320 2.891160 2.987806 2.875501 2.870132 3.186500 3.243778 3.445879
## [249] 2.697010 2.790259 3.321663 3.321820 2.772526 3.321563 3.119029 3.542541
## [257] 3.325488 2.650436 3.146137 3.425287 3.020004 2.822097 2.862129 2.995249
## [265] 3.386678 2.928160 2.377758 2.815120 2.659916 2.845610 3.185171 2.998989
## [273] 2.784636 3.382319 3.137082 2.474308 2.887891 2.888258 2.953870 3.041218
## [281] 3.103044 2.713037 3.121854 2.820992 3.526654 3.356909 3.235152 2.847666
## [289] 3.289018 3.112634 2.803123 3.558364 3.558258 3.141649 2.475574 3.208793
## [297] 3.352041 2.478534 2.894845 2.542436
# La función 'kurtosis' está en el paquete 'moments' 
kurtosis(dist_sim2)
## [1] 3.027629
# La kurtosis de la variable es cercana a la kurtosis de la distribución normal
kurtosis(Sepal.Width)
## [1] 3.180976

Sesión 5 - Visualizacion

Barplots

Gráfico construido con base en la frecuencia absoluta de cada una de las categorias de una variable categórica ó categórizada.

data(mtcars)
attach(mtcars)
## The following objects are masked from mtcars (pos = 5):
## 
##     am, carb, cyl, disp, drat, gear, hp, mpg, qsec, vs, wt
# 
tabla_cyl <- table(cyl)
tabla_cyl
## cyl
##  4  6  8 
## 11  7 14
barplot(tabla_cyl)

barplot(sort(tabla_cyl,decreasing = TRUE))

barplot(sort(tabla_cyl,decreasing = TRUE), xlab = "Categoria",  ylab = "Frecuencia Absoluta", main = "Cilindraje")

barplot(sort(tabla_cyl), horiz = TRUE , ylab="Categoria", xlab ="Frecuencia Absoluta", main = "Cilindraje")

# Categorizando Longitud de Sepalo
Sepal.Length
##   [1] 5.1 4.9 4.7 4.6 5.0 5.4 4.6 5.0 4.4 4.9 5.4 4.8 4.8 4.3 5.8 5.7 5.4 5.1
##  [19] 5.7 5.1 5.4 5.1 4.6 5.1 4.8 5.0 5.0 5.2 5.2 4.7 4.8 5.4 5.2 5.5 4.9 5.0
##  [37] 5.5 4.9 4.4 5.1 5.0 4.5 4.4 5.0 5.1 4.8 5.1 4.6 5.3 5.0 7.0 6.4 6.9 5.5
##  [55] 6.5 5.7 6.3 4.9 6.6 5.2 5.0 5.9 6.0 6.1 5.6 6.7 5.6 5.8 6.2 5.6 5.9 6.1
##  [73] 6.3 6.1 6.4 6.6 6.8 6.7 6.0 5.7 5.5 5.5 5.8 6.0 5.4 6.0 6.7 6.3 5.6 5.5
##  [91] 5.5 6.1 5.8 5.0 5.6 5.7 5.7 6.2 5.1 5.7 6.3 5.8 7.1 6.3 6.5 7.6 4.9 7.3
## [109] 6.7 7.2 6.5 6.4 6.8 5.7 5.8 6.4 6.5 7.7 7.7 6.0 6.9 5.6 7.7 6.3 6.7 7.2
## [127] 6.2 6.1 6.4 7.2 7.4 7.9 6.4 6.3 6.1 7.7 6.3 6.4 6.0 6.9 6.7 6.9 5.8 6.8
## [145] 6.7 6.7 6.3 6.5 6.2 5.9
x_33 <- quantile(Sepal.Length,p=0.33)
x_33
## 33% 
## 5.4
x_66 <- quantile(Sepal.Length,p=0.66)
x_66
##   66% 
## 6.234
sl_cat <- vector()
for(i in 1:150){
  if(Sepal.Length[i] < x_33) sl_cat[i] <- "P"
  else if ( Sepal.Length[i] < x_66) sl_cat[i] <- "M"
  else sl_cat[i] <- "G"
}
sl_cat
##   [1] "P" "P" "P" "P" "P" "M" "P" "P" "P" "P" "M" "P" "P" "P" "M" "M" "M" "P"
##  [19] "M" "P" "M" "P" "P" "P" "P" "P" "P" "P" "P" "P" "P" "M" "P" "M" "P" "P"
##  [37] "M" "P" "P" "P" "P" "P" "P" "P" "P" "P" "P" "P" "P" "P" "G" "G" "G" "M"
##  [55] "G" "M" "G" "P" "G" "P" "P" "M" "M" "M" "M" "G" "M" "M" "M" "M" "M" "M"
##  [73] "G" "M" "G" "G" "G" "G" "M" "M" "M" "M" "M" "M" "M" "M" "G" "G" "M" "M"
##  [91] "M" "M" "M" "P" "M" "M" "M" "M" "P" "M" "G" "M" "G" "G" "G" "G" "P" "G"
## [109] "G" "G" "G" "G" "G" "M" "M" "G" "G" "G" "G" "M" "G" "M" "G" "G" "G" "G"
## [127] "M" "M" "G" "G" "G" "G" "G" "G" "M" "G" "G" "G" "M" "G" "G" "G" "M" "G"
## [145] "G" "G" "G" "G" "M" "M"
tabla_sl_cat <- table(sl_cat)
tabla_sl_cat
## sl_cat
##  G  M  P 
## 51 53 46
tabla_spec_sl_cat <- table(sl_cat,Species)
tabla_spec_sl_cat
##       Species
## sl_cat setosa versicolor virginica
##      G      0         14        37
##      M     10         31        12
##      P     40          5         1
tc_spec_sl <- as.matrix(tabla_spec_sl_cat)
barplot(height=tc_spec_sl, beside = TRUE, col = c(1,3,4),legend.text = c('G','M','P'))

Pizzas

Al igual que el gráfico de barras, un gráfico de pizza es construido con base en la frecuencia absoluta de cada una de las categorias de una variable categórica ó categórizada.

# Diagrama simple
nombre_cat <- attr(tabla_cyl,"dimnames")$cyl
pie(tabla_cyl)

pie(tabla_cyl, labels = nombre_cat, main="Diagrama Cilindraje", col = c(1,3,4))

# Incluyendo porcentajes
pct <- 100*round(prop.table(tabla_cyl),2)
pct
## cyl
##  4  6  8 
## 34 22 44
nombre_cat_pct <- paste(nombre_cat,pct,sep = " (")
nombre_cat_pct <- paste(nombre_cat_pct,"%)",sep="")
nombre_cat_pct
## [1] "4 (34%)" "6 (22%)" "8 (44%)"
pie(tabla_cyl,labels=nombre_cat_pct, main="Diagrama Cilindraje", col= c(1,3,4))

Histogramas

Gráfico construido con base en la Frecuencia Absoluta ó Probabilidad de una muestra \(x_1,x_2,\cdots,x_n\). Para su construcción es necesario definir un conjunto de intervalos que cubren el todo rango de la muestra.

#
range(Sepal.Length)
## [1] 4.3 7.9
dim(iris)[1]
## [1] 150
# Frecuencia Absoluta
hist(Sepal.Length, xlab = "Longitud de Sepalo", main = "")

hist_sl <- hist(Sepal.Length, xlab = "Long. de Sepalo", main = "")

hist_sl$breaks
## [1] 4.0 4.5 5.0 5.5 6.0 6.5 7.0 7.5 8.0
hist_sl$counts
## [1]  5 27 27 30 31 18  6  6
# Probabilidad
hist(Sepal.Length, xlab = "Longitud de Sepalo", main = "", freq = FALSE)

hist_sl_f <- hist(Sepal.Length, xlab = "Long. Sepalo", main = "", freq = FALSE)

delta = 0.5
round(delta*hist_sl_f$density,2)
## [1] 0.03 0.18 0.18 0.20 0.21 0.12 0.04 0.04
150*delta
## [1] 75
# Por defecto R se usa 'Sturges'
hist_sl <- hist(Sepal.Length, xlab = "Longitud de Sepalo", main = "", freq = FALSE, breaks = 'Scott')

hist_sl$breaks
## [1] 4.0 4.5 5.0 5.5 6.0 6.5 7.0 7.5 8.0
hist(Sepal.Length, xlab = "Longitud de Sepalo", main = "", freq = FALSE, breaks = 'FD')
hist_sl$breaks
## [1] 4.0 4.5 5.0 5.5 6.0 6.5 7.0 7.5 8.0

Para una discusión acerca de las ventajas y desventajas de estos métodos ver: https://robjhyndman.com/papers/sturges.pdf

Boxplots

Gráfico construido con base en los quartiles de la muestra \(x_1,x_2,\cdots,x_n\)

# mpg vs Cyl
boxplot(mpg,main="Millas/Galón")

boxplot(mpg~cyl,data=mtcars, main="Millas", xlab="Cilindros", ylab="Millas/Galón", col=4)

# mpg vs hp_cat
median(hp)
## [1] 123
hp_cat <- as.factor(as.numeric(hp < 123))
nuevo_mtcars <- data.frame(mtcars,hp_cat)
boxplot(mpg~hp_cat,data=nuevo_mtcars, main="Millas", xlab="Potencia", ylab="Millas/Galón", col="darkgreen")

Múltiples gráficos

Es posible construir un gráfico compuesto de multiples subgráficos.

data(iris)
data(mtcars)
attach(iris)
## The following objects are masked from iris (pos = 4):
## 
##     Petal.Length, Petal.Width, Sepal.Length, Sepal.Width, Species
## The following objects are masked from iris (pos = 7):
## 
##     Petal.Length, Petal.Width, Sepal.Length, Sepal.Width, Species
attach(mtcars)
## The following objects are masked from mtcars (pos = 4):
## 
##     am, carb, cyl, disp, drat, gear, hp, mpg, qsec, vs, wt
## The following objects are masked from mtcars (pos = 7):
## 
##     am, carb, cyl, disp, drat, gear, hp, mpg, qsec, vs, wt
par(mfrow=c(1,2))
hist(Petal.Length)
hist(Sepal.Length)

par(mfrow=c(2,2))
plot(Petal.Length,Sepal.Length)
plot(Petal.Width,Sepal.Width)
par(mfcol=c(2,3))

#
pairs(~Petal.Length + Sepal.Length + Petal.Width + Sepal.Width)

pairs(~mpg + disp  + hp + drat + wt  + qsec)

Sesión 6 - Probabilidad