Centro de Investigación y Docencia Económicas (CIDE) Región Centro
Manejo de Bases de Datos y Programación (R + STATA)
Actividad 3
Profesor: Dr. Héctor de la Torre Gutiérrez
Laboratorista: EME. Mario Arturo Aguilar López
Actividad 3
Profesor: Dr. Héctor de la Torre Gutiérrez
Laboratorista: EME. Mario Arturo Aguilar López
Ejercicio 1
### Librerías
library(tidyverse)### Lectura y limpieza
rend_raw <- readxl::read_xlsx(here::here("data/class/raw/Rendimiento.xlsx"))
# Se buscan NAs
rend_raw %>%
summarise(across(everything(), ~ sum(is.na(.x)))) %>%
pivot_longer(cols = everything(),
names_to = "Variable",
values_to = "Número de NAs")| Variable | Número de NAs |
|---|---|
| No | 0 |
| Marca | 0 |
| MAKE MODEL | 9 |
| CLASS | 2 |
| ENGINE SIZE (L) | 2 |
| CYLINDERS | 2 |
| TRANSMISSION | 2 |
| FUEL TYPE | 2 |
| CONSUMPTION CITY (L/100 KM) | 2 |
| CONSUMPTION HIGHWAY (L/100 KM) | 2 |
| CONSUMPTION COMBINED (L/100 KM) | 2 |
| $ PER YEAR | 10 |
| CO2 EMISSIONS (g/km) | 2 |
| CO2 RATING | 2 |
Limpieza
Reemplazo de NAs
# Se reemplazan los NAs por 0
rend_clean <- rend_raw %>%
mutate(across(where(is.numeric), ~ replace_na(., 0))) %>%
mutate(across(where(is.character), ~ replace_na(., "0")))
# Se verifica que no exista ningún NA
rend_clean %>%
summarise(across(everything(), ~ sum(is.na(.x)))) %>%
pivot_longer(cols = everything(),
names_to = "Variable",
values_to = "Número de NAs")| Variable | Número de NAs |
|---|---|
| No | 0 |
| Marca | 0 |
| MAKE MODEL | 0 |
| CLASS | 0 |
| ENGINE SIZE (L) | 0 |
| CYLINDERS | 0 |
| TRANSMISSION | 0 |
| FUEL TYPE | 0 |
| CONSUMPTION CITY (L/100 KM) | 0 |
| CONSUMPTION HIGHWAY (L/100 KM) | 0 |
| CONSUMPTION COMBINED (L/100 KM) | 0 |
| $ PER YEAR | 0 |
| CO2 EMISSIONS (g/km) | 0 |
| CO2 RATING | 0 |
Coerción de tipo de variable
Data <- readxl::read_excel(here::here("data/class/raw/Rendimiento.xlsx"),
col_types = c("numeric", "text", "text",
"text", "numeric", "numeric", "text",
"text", "numeric", "numeric", "numeric",
"numeric", "numeric", "numeric"))
NAVals2 <- data.frame(apply(is.na(Data), 2, sum))
names(NAVals2) = c('ValFaltantes')
print(NAVals2)## ValFaltantes
## No 0
## Marca 0
## MAKE MODEL 9
## CLASS 2
## ENGINE SIZE (L) 2
## CYLINDERS 2
## TRANSMISSION 2
## FUEL TYPE 2
## CONSUMPTION CITY (L/100 KM) 2
## CONSUMPTION HIGHWAY (L/100 KM) 2
## CONSUMPTION COMBINED (L/100 KM) 2
## $ PER YEAR 10
## CO2 EMISSIONS (g/km) 2
## CO2 RATING 2
Como podemos ver el número de NAs no cambió.
Búsqueda y reemplazo de valores repetidos
# valores repetidos
rend_clean %>%
select(-No) %>%
duplicated() %>%
sum(. == TRUE)## [1] 0
No hay observaciones repetidas.
Auto que recomendaría a Fernanda Esquinca
# Se filtra por tamaño de motor y tipo de combustible
rend_fer <- rend_clean %>%
filter(CLASS != "0",
`ENGINE SIZE (L)` < 2 &
`FUEL TYPE` != "Z")
# Se calcula la media de consumo combinado
media_consumo <- mean(rend_fer$`CONSUMPTION COMBINED (L/100 KM)`)
# Se hace el histograma antes de filtrar por la media
p1 <- rend_fer %>%
ggplot() +
geom_histogram(aes(`CONSUMPTION COMBINED (L/100 KM)`), bins = 28, color = "orange", fill = "orange", alpha = 0.5) +
geom_vline(aes(xintercept = media_consumo, color = "Media de\nconsumo\ncombinado"), linetype = "dashed", size = 1) +
scale_x_continuous(breaks = scales::pretty_breaks(n = 5)) +
scale_color_manual(name = "", values = c("Media de\nconsumo\ncombinado" = "black")) +
theme_minimal() +
labs(title = "Consumo combinado de\nlos autos seleccionados",
subtitle = glue::glue("n = {nrow(rend_fer)}"),
x = "L/100 km",
y = "Frecuencia")
# Se filtra por la media
rend_fer <- rend_fer %>%
filter(`CONSUMPTION COMBINED (L/100 KM)` <= media_consumo)
# Se hace el histograma después de filtrar por la media de consumo
p2 <- rend_fer %>%
ggplot() +
geom_histogram(aes(`CONSUMPTION COMBINED (L/100 KM)`), bins = 17, color = "blue", fill = "blue", alpha = 0.5) +
geom_vline(aes(xintercept = as.numeric(rend_fer[which(rend_fer$`MAKE MODEL` == "CIVIC SEDAN"), "CONSUMPTION COMBINED (L/100 KM)"]), color = "Civic\nSedan"), linetype = "dashed", size = 1) +
scale_x_continuous(breaks = scales::pretty_breaks(n = 5)) +
scale_color_manual(name = "", values = c("Civic\nSedan" = "green")) +
theme_minimal() +
labs(title = "Consumo combinado de\nlos autos seleccionados\npor debajo de la media",
subtitle = glue::glue("n = {nrow(rend_fer)}"),
x = "L/100 km",
y = "Frecuencia")
# Se grafica
ggpubr::ggarrange(p1, p2, ncol = 2)| No | Marca | MAKE MODEL | CLASS | ENGINE SIZE (L) | CYLINDERS | TRANSMISSION | FUEL TYPE | CONSUMPTION CITY (L/100 KM) | CONSUMPTION HIGHWAY (L/100 KM) | CONSUMPTION COMBINED (L/100 KM) | $ PER YEAR | CO2 EMISSIONS (g/km) | CO2 RATING |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 102 | CHEVROLET | CRUZE | C | 1.4 | 4 | AS6 | X | 7.8 | 5.6 | 6.8 | 1482 | 159 | 8 |
| 103 | CHEVROLET | CRUZE | C | 1.4 | 4 | M6 | X | 8.2 | 5.8 | 7.1 | 1548 | 167 | 8 |
| 104 | CHEVROLET | CRUZE PREMIER | C | 1.4 | 4 | AS6 | X | 7.8 | 5.9 | 6.9 | 1504 | 160 | 8 |
| 166 | HONDA | CIVIC COUPE | C | 1.5 | 4 | AV | X | 7.5 | 5.6 | 6.7 | 1461 | 155 | 8 |
| 169 | HONDA | CIVIC SEDAN | M | 1.5 | 4 | AV | X | 7.6 | 5.5 | 6.7 | 1461 | 157 | 8 |
| 172 | HONDA | CR-Z | T | 1.5 | 4 | AV7 | X | 7.0 | 6.4 | 6.8 | 1482 | 157 | 8 |
| 173 | HONDA | CR-Z | T | 1.5 | 4 | M6 | X | 7.9 | 6.5 | 7.3 | 1591 | 169 | 8 |
| 174 | HONDA | FIT | WS | 1.5 | 4 | AV | X | 7.0 | 5.7 | 6.4 | 1395 | 150 | 8 |
| 175 | HONDA | FIT | WS | 1.5 | 4 | AV7 | X | 7.3 | 6.1 | 6.8 | 1482 | 158 | 8 |
| 280 | NISSAN | SENTRA | M | 1.8 | 4 | AV | X | 8.0 | 6.1 | 7.2 | 1570 | 167 | 8 |
| 282 | NISSAN | VERSA | M | 1.6 | 4 | AV | X | 7.5 | 6.0 | 6.8 | 1482 | 161 | 8 |
| 317 | SCION | iM | M | 1.8 | 4 | AV7 | X | 8.3 | 6.3 | 7.4 | 1613 | 173 | 8 |
| 341 | TOYOTA | COROLLA | M | 1.8 | 4 | AV | X | 8.2 | 6.2 | 7.3 | 1591 | 171 | 8 |
| 342 | TOYOTA | COROLLA | M | 1.8 | 4 | AV7 | X | 7.9 | 6.1 | 7.1 | 1548 | 166 | 8 |
| 343 | TOYOTA | COROLLA | M | 1.8 | 4 | M6 | X | 8.4 | 6.4 | 7.5 | 1635 | 174 | 8 |
| 344 | TOYOTA | COROLLA LE ECO (1-mode) | M | 1.8 | 4 | AV | X | 7.7 | 5.6 | 6.8 | 1482 | 160 | 8 |
| 345 | TOYOTA | COROLLA LE ECO (2-mode) | M | 1.8 | 4 | AV | X | 7.7 | 6.0 | 6.9 | 1504 | 162 | 8 |
El auto que le recomendaría a mi amiga Fernanda sería el Honda Civic Sedan porque dado que reside en Rincón de Romos su uso del automóvil contemplaría recorridos en ciudad y en carretera, por esta razón, la variable de decisión fue el consumo combinado, ya que este auto cuenta con un consumo de 6.7 litros por cada 100 kilómetros, lo cual, para el tamaño del auto (Medio) es un consumo bastante bueno y se encuentra casi un litro por debajo de la media de todos los autos candidatos que le permitirá ahorrar una cantidad de dinero comparado con otros autos. Aunque el hecho de que sea soltera permitiría elegir un auto más pequeño, considero que un auto sedan como el Civic es una opción que no tendrá que reemplazar en mucho tiempo y que puede satisfacer necesidades futuras de espacio, por ejemplo, en el caso de que Fernanda forme una familia.
Para encontrar a los autos candidatos, lo primero fue filtrar por tamaño de motor que fuera menor a 2.0 litros, ya que Fernanda no necesitaría tanto poder para sus tareas diarias. En segundo lugar fue filtrar los autos que no necesitaran de combustible premium. Por último, de los autos restantes que eran 28, se contempló solo a aquellos que tuvieran un consumo combinado por debajo de la media de los 28 autos candidatos, la cual era de aproximadamente 7.5 litros por cads 100 kilómetros, lo que resultó en una muestra de 17 autos. Esta última comparación es la que se muestra en los histogramas.
Ejercicio 2
Lectura de los datos
Se utiliza la librería tabulizer para extraer la tabla del pdf “Actividad_cide”.
datos_act <- tabulizer::extract_tables(here::here("./Actividad_cide.pdf"), output = "data.frame")
datos_act_raw <- datos_act[[2]]Estandarizar variable sexo
En este caso se decide estandarizar con “H” para hombre y “M” para mujer.
# Se obtienen los valores únicos de la codificación
unique(datos_act_raw$sexo)## [1] "hombre" "mujer" "Femenino" "masculino" "mascuino" "Masculino"
## [7] "H" "M"
# Se reemplazan por H para hombre y M para mujer
for(i in 1:nrow(datos_act_raw)){
if(datos_act_raw$sexo[i] %in% c("hombre" , "masculino", "mascuino", "Masculino")){
datos_act_raw$sexo[i] <- "H"
}
if(datos_act_raw$sexo[i] %in% c("mujer" , "Femenino")){
datos_act_raw$sexo[i] <- "M"
}
else {
next
}
}| x |
|---|
| H |
| H |
| H |
| H |
| H |
| M |
| M |
| M |
| H |
| M |
| M |
| H |
| H |
| H |
| H |
| H |
| M |
| M |
| H |
| M |
| M |
| H |
| H |
| H |
| H |
| M |
| M |
| M |
| M |
| M |
| H |
| H |
| M |
| H |
| H |
| H |
| M |
| M |
| M |
| H |
Estimación del ingreso
Segun los datos de la pagina https://mx.talent.com/salary los salarios para los empleos de la lista son los siguientes:
salarios = data.frame(
"Enfermeria" = c(7000, 8250),
"obrero" = c(5050, 4574),
"mtro" = c(6500, 7072),
"abogado" = c(9750, 7719),
"politico" = c(7800, 9000)
)Creamos la función.
sal = function(prof, gen){
if(gen == 'H'){g = 2}
if(gen == 'M'){g = 1}
p = match(prof, names(salarios))
return(salarios[g,p])
}La aplicamos en los datos.
for (i in 1:length(datos_act_raw$empleo)) {
datos_act_raw$ingreso[i] = sal(datos_act_raw$empleo[i], datos_act_raw$sexo[i])
}| obs | encuestador | sexo | empleo | ingreso | edad | altura | peso |
|---|---|---|---|---|---|---|---|
| 1 | arturo | H | Enfermeria | 8250 | 51 | 150.5 | 64.0 |
| 2 | arturo | H | obrero | 4574 | 33 | 155.7 | 62.0 |
| 3 | arturo | H | mtro | 7072 | 47 | 170.8 | 76.0 |
| 4 | arturo | H | obrero | 4574 | 38 | 166.0 | 67.0 |
| 5 | arturo | H | abogado | 7719 | 46 | 192.5 | 90.0 |
| 6 | arturo | M | mtro | 6500 | 47 | 171.7 | 80.0 |
| 7 | arturo | M | obrero | 5050 | 55 | 164.8 | 75.0 |
| 8 | arturo | M | Enfermeria | 7000 | 40 | 173.0 | 65.0 |
| 9 | arturo | H | politico | 9000 | 57 | 179.8 | 83.0 |
| 10 | arturo | M | abogado | 9750 | NA | 166.3 | 68.0 |
| 11 | jessica | M | mtro | 6500 | 56 | 168.5 | 62.0 |
| 12 | jessica | H | obrero | 4574 | 47 | 175.0 | 79.0 |
| 13 | jessica | H | mtro | 7072 | 36 | 155.8 | 65.0 |
| 14 | jessica | H | mtro | 7072 | 51 | 188.0 | 88.0 |
| 15 | jessica | H | mtro | 7072 | 41 | 188.3 | 74.0 |
| 16 | jessica | H | abogado | 7719 | 26 | 160.0 | 63.0 |
| 17 | jessica | M | obrero | 5050 | 52 | 179.4 | 86.0 |
| 18 | jessica | M | abogado | 9750 | 55 | 176.4 | 81.0 |
| 19 | jessica | H | Enfermeria | 8250 | 42 | 180.2 | 88.0 |
| 20 | jessica | M | abogado | 9750 | 40 | 188.3 | 95.0 |
| 21 | susy | M | abogado | 9750 | 52 | 165.2 | 68.0 |
| 22 | susy | H | obrero | 4574 | 62 | 166.0 | 76.0 |
| 23 | susy | H | obrero | 4574 | 49 | 166.0 | 70.0 |
| 24 | susy | H | Enfermeria | 8250 | 49 | 168.4 | 63.0 |
| 25 | susy | H | obrero | 4574 | 58 | 186.3 | 83.0 |
| 26 | susy | M | obrero | 5050 | 64 | 176.3 | 70.0 |
| 27 | susy | M | obrero | 5050 | 49 | 184.3 | 75.0 |
| 28 | susy | M | obrero | 5050 | 39 | 173.6 | 80.0 |
| 29 | susy | M | politico | 7800 | 70 | 166.0 | 66.0 |
| 30 | susy | M | abogado | 9750 | 44 | 181.3 | 76.0 |
| 31 | pedro | H | obrero | 4574 | 47 | 160.4 | 68.0 |
| 32 | pedro | H | mtro | 7072 | 40 | 183.3 | 76.0 |
| 33 | pedro | M | Enfermeria | 7000 | 34 | 164.5 | NA |
| 34 | pedro | H | Enfermeria | 8250 | 44 | 178.4 | 78.0 |
| 35 | pedro | H | Enfermeria | 8250 | 49 | 191.7 | 80.0 |
| 36 | pedro | H | obrero | 4574 | 33 | 168.0 | 73.0 |
| 37 | pedro | M | obrero | 5050 | 45 | 155.9 | 54.3 |
| 38 | pedro | M | mtro | 6500 | 49 | 188.0 | NA |
| 39 | pedro | M | obrero | 5050 | 46 | 186.0 | 88.0 |
| 40 | pedro | H | obrero | 4574 | 80 | 178.6 | 83.0 |
Estimación del peso
Se utiliza la siguiente fórmula para calcular el vector de estimaciones puntuales:
\[b = (X^TX)^{-1}X^Ty\]
datos_act_peso <- datos_act_raw %>%
filter(!is.na(peso))
y_peso <- as.matrix(datos_act_peso$peso) # y
x_altura <- as.matrix(datos_act_peso["altura"]) # X
t_x_altura <- t(x_altura) # matriz traspuesta X^t
# vector de estimaciones puntuales
b <- (solve(t_x_altura%*%x_altura))%*%(t_x_altura%*%y_peso)
# Se estima el peso en las observaciones donde se tiene NA
peso_na <- which(is.na(datos_act_raw$peso))
datos_act_raw[peso_na, ]## obs encuestador sexo empleo ingreso edad altura peso
## 33 33 pedro M Enfermeria 7000 34 164.5 NA
## 38 38 pedro M mtro 6500 49 188.0 NA
for(i in which(is.na(datos_act_raw$peso))){
datos_act_raw$peso[i] <- datos_act_raw$altura[i]*b
}| obs | encuestador | sexo | empleo | ingreso | edad | altura | peso | |
|---|---|---|---|---|---|---|---|---|
| 33 | 33 | pedro | M | Enfermeria | 7000 | 34 | 164.5 | 71.05027 |
| 38 | 38 | pedro | M | mtro | 6500 | 49 | 188.0 | 81.20031 |
Las observaciones 33 y 38 fueron a las que se les estimó el peso. Con un estimador \(b\) de 0.432, se obtuvo un peso estimado de 71.05 y 81.2 kilos respectivamente.
La recta de regresión sería:
\[\hat{peso} = 0.432\ altura\]
Ejercicio 3
Sea \(X\) una variable aleatoria Binomial(\(n\), \(p\)) y \(Y\) una variable binomial condicionada en \(X\); esto es, (\(Y|X=x\)) tiene una distribución binomial (\(X + 1\), \(q\)).
a. Hacer la función masa de probabilidad conjunto \(X\), \(Y\) cuando \(n = 5\), \(p = 0.5\) y \(q = 0.5\).
Considerando que una probabilidad condicional de \(Y\) dado \(X = x\) es:
\[f_{Y|X}(y|x) = \frac{f(x,y)}{f_X(x)}\] donde \(f(x,y)\) es la función de probabilidad conjunta y \(f_X(x)\) es la función de probabilidad marginal de \(X\).
Se parte de la función marginal y condicional para encontrar la función de probabilidad conjunta:
\[f(x,y) = f_X(x)f_{Y|X}(y|x)\]
Se crea la función marginal y condicional con los valores de los parámetros dados (\(n = 5\), \(p = 0.5\) y \(q = 0.5\)):
# función de probabilidad conjunta de X y Y
f_x_y <- function(x, n = 5, p = 0.5){
# Parámetros de Y|X
q <- 1 - p
n_y <- x + 1
# Marginal de X
f_x <- choose(n, x)*(p^x)*((1-p)^(n-x))
y <- c(0:n_y)
# Bucle for para calcular los valores de y
f_y_cond_x <- c()
for(i in y){
f_y_cond_x <- c(f_y_cond_x, choose(n_y, i)*(q^n_y)*((1-q)^(n_y-i)))
}
# Producto de la marginal de X y la condicional de Y|X
f_x * f_y_cond_x
}Se crea la tabla con la probabilidad conjunta:
x_vals <- c(0, 0, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 3, 4, 4, 4, 4, 4, 4, 5, 5, 5, 5, 5, 5, 5)
y_vals <- c(0, 1, 0, 1, 2, 0, 1, 2, 3, 0, 1, 2, 3, 4, 0, 1, 2, 3, 4, 5, 0, 1, 2, 3, 4, 5, 6)
conjunta_x_y <- unlist(sapply(0:5, f_x_y))
tabla_conjunta_x_y <- data.frame(x = x_vals,
y = y_vals,
"P(X)*P(Y|X)" = conjunta_x_y)| x | y | P.X..P.Y.X. |
|---|---|---|
| 0 | 0 | 0.0078125 |
| 0 | 1 | 0.0156250 |
| 1 | 0 | 0.0097656 |
| 1 | 1 | 0.0390625 |
| 1 | 2 | 0.0390625 |
| 2 | 0 | 0.0048828 |
| 2 | 1 | 0.0292969 |
| 2 | 2 | 0.0585938 |
| 2 | 3 | 0.0390625 |
| 3 | 0 | 0.0012207 |
| 3 | 1 | 0.0097656 |
| 3 | 2 | 0.0292969 |
| 3 | 3 | 0.0390625 |
| 3 | 4 | 0.0195312 |
| 4 | 0 | 0.0001526 |
| 4 | 1 | 0.0015259 |
| 4 | 2 | 0.0061035 |
| 4 | 3 | 0.0122070 |
| 4 | 4 | 0.0122070 |
| 4 | 5 | 0.0048828 |
| 5 | 0 | 0.0000076 |
| 5 | 1 | 0.0000916 |
| 5 | 2 | 0.0004578 |
| 5 | 3 | 0.0012207 |
| 5 | 4 | 0.0018311 |
| 5 | 5 | 0.0014648 |
| 5 | 6 | 0.0004883 |
b. Proporcione la función masa de probabilidad para \(Y\).
Ahora en el caso de una condicional de \(X\) dado \(Y\):
\[f_{X|Y}(x|y) = \frac{f(x,y)}{f_Y(y)}\]
Se puede obtener la marginal de \(Y\):
\[f_Y(y) = \frac{f(x,y)}{f_{X|Y}(x|y)}\]