Líbrerías
library(data.table)
library(dplyr)
library(plyr)
library(ggplot2)
library(naniar)
library(Hmisc)
library(psych)
library(tidyverse)
library(janitor)
library(knitr)
library(pollster)
library(epiDisplay)
library(descr)
library(tidyr)
library(textclean)
library(lubridate)
Importar bases de datos
setwd("C:\\Users\\javaw\\OneDrive - Instituto Tecnologico y de Estudios Superiores de Monterrey\\7mo Semestre\\Reto")
merma<-read.csv("FORM - Merma.csv")
scrap<-read.csv("FORM - Scrap.csv")
carton<-read.csv("FORM - Produccion Carton Completa.csv")
perf<-read.csv("Del Perf.csv")
plan<-read.csv("DP_1.csv")
bajas<-read.csv("RH.csv")
colaboradores<-read.csv("RH2.csv")
Para crear una base de datos final para cada una de las áreas de la empresa FORM hay que considerar lo siguiente:
1.- Cambiar nombres de variables.
2.- Mantener variables relevantes para el análisis.
3.- Hay que limpiar las bases de datos.(Na’s, tipo de variables, errores
ortograficos, entre otros).Además de homogeneizar variables.
merma<-clean_names(merma)
merma<-dplyr::rename(merma, fecha=i_fecha)
colnames(merma)
## [1] "fecha" "mes" "kilos"
scrap<-clean_names(scrap)
scrap<-scrap %>% dplyr::rename(referencia=i_referencia,
ubi_origen=ubicaci_a3n_de_origen,
ubi_desecho=ubicaci_a3n_de_desecho)
colnames(scrap)
## [1] "referencia" "fecha" "producto" "cantidad"
## [5] "unidad_de_medida" "ubi_origen" "ubi_desecho" "estado"
carton<-clean_names(carton)
carton<-carton %>% dplyr::rename(lam_procesadas=laminas_procesadas,
fin_sep_up=fin_inicio_de_sep_up,
inicio_proceso=inicio_de_proceso,
fin_proceso=fin_de_proceso,
fecha=i_fecha)
colnames(carton)
## [1] "fecha" "cliente" "id_form"
## [4] "producto" "piezas_prog" "tmo_min"
## [7] "hr_fin" "estacion_arranque" "lam_procesadas"
## [10] "inicio_sep_up" "fin_sep_up" "inicio_proceso"
## [13] "fin_proceso" "tiempo_calidad" "tiempo_materiales"
## [16] "x"
perf<-clean_names(perf)
colnames(perf)
## [1] "cliente" "vueltas" "fecha" "plan_arrival"
## [5] "real_arrival" "real_departure" "diference"
plan<-clean_names(plan)
plan<-plan %>% dplyr::rename(cliente=i_cliente_planta,
jun_21=junio,
jul_21=julio,
ago_21=agosto,
sep_21=septiembre,
oct_21=octubre,
nov_21=noviembre,
dic_21=diciembre,
oct_22=octubre_22)
colnames(plan)
## [1] "cliente" "proyecto" "id_odoo" "item" "jun_21"
## [6] "jul_21" "ago_21" "sep_21" "oct_21" "nov_21"
## [11] "dic_21" "ene_22" "feb_22" "mar_22" "abr_22"
## [16] "may_22" "jun_22" "jul_22" "ago_22" "sep_22"
## [21] "oct_22" "nov_22" "dic_22" "ene_23" "feb_23"
## [26] "mar_23" "total_meses"
bajas<-clean_names(bajas)
bajas<-bajas %>% dplyr::rename(apellidos=i_apellidos,
fecha_nac=fecha_de_nacimiento,
fecha_alta=fecha_de_alta,
mot_baja=motivo_de_baja,
no_ss=no_seguro_social,
sal_diario_imss=salario_diario_imss,
credito_infonavit=na_credito_infonavit,
lugar_nac=lugar_de_nacimiento,
num_interno=numero_interno,
CP=codigo_postal,
permanencia=x)
colnames(bajas)
## [1] "apellidos" "nombre" "fecha_nac"
## [4] "genero" "rfc" "fecha_alta"
## [7] "mot_baja" "permanencia" "baja"
## [10] "puesto" "departamento" "no_ss"
## [13] "sal_diario_imss" "factor_cred_infonavit" "credito_infonavit"
## [16] "lugar_nac" "curp" "calle"
## [19] "num_interno" "colonia" "CP"
## [22] "municipio" "estado" "estado_civil"
## [25] "tarjeta_cuenta"
colaboradores<-clean_names(colaboradores)
colaboradores<-colaboradores %>% dplyr::rename(no_empleado=i_no_de_empleado,
fecha_nac=fecha_de_nacimiento,
fecha_alta=fecha_de_alta,
"4to_mes"=x4to_mes,
no_ss=no_seguro_social,
sal_diario_imss=salario_diario_imss,
credito_infonavit=na_credito_infonavit,
lugar_nac=lugar_de_nacimiento,
num_interno=numero_interno,
CP=codigo_postal)
colnames(bajas)
## [1] "apellidos" "nombre" "fecha_nac"
## [4] "genero" "rfc" "fecha_alta"
## [7] "mot_baja" "permanencia" "baja"
## [10] "puesto" "departamento" "no_ss"
## [13] "sal_diario_imss" "factor_cred_infonavit" "credito_infonavit"
## [16] "lugar_nac" "curp" "calle"
## [19] "num_interno" "colonia" "CP"
## [22] "municipio" "estado" "estado_civil"
## [25] "tarjeta_cuenta"
En el caso de la base de datos de merma hemos optado por mantener las tres variables, puesto que consideramos que todas son relevantes para el análisis que vamos a realizar.
Para la base de datos de scrap hemos optado por eliminar las variables de unidad de medida, estado y ubicación de desecho, ya que todos los registros tienen el mismo valor en estas variables, es decir todos tienen la misma unidad, la misma ubicación y el mismo estado.
scrap<-dplyr::select(scrap,-c(ubi_desecho, estado, unidad_de_medida))
colnames(scrap)
## [1] "referencia" "fecha" "producto" "cantidad" "ubi_origen"
Para producción de cartón hemos optado por eliminar las columnas de id_form, producto, tiempo_materiales y estación de arranque, ya que consideramos que con el resto de columnas podemos realizar otros calculos, principalmente hacer mediciones de tiempo.
carton<-dplyr::select(carton,-c(id_form, producto, tiempo_materiales, x, estacion_arranque))
colnames(carton)
## [1] "fecha" "cliente" "piezas_prog" "tmo_min"
## [5] "hr_fin" "lam_procesadas" "inicio_sep_up" "fin_sep_up"
## [9] "inicio_proceso" "fin_proceso" "tiempo_calidad"
Para delivery performance hemos optado por mantener todas las columnas.
Para delivery plan por fines de estructura y análisis hemos optado por transformar la base de datos y las columnas de cada mes convertirlas en datos de una sola columna denominada como Mes y los valores pasarlos a otra columna llamada Unidades.
plan<-pivot_longer(plan, cols=5:26, names_to = "mes", values_to = "unidades")
Ya que contamos con la base de datos transformada hemos optado por eliminar la columna de total meses ya que podemos calcular el total de todos los meses por productos posteriormente, y la de id_odoo.
plan<-dplyr::select(plan,-c(total_meses,id_odoo))
Para bajas hemos optado por hacer una transformación a la base de datos y unir los apellidos con el nombre, además de eliminar las columnas de RFC, número de seguro social, factor de crédito infonavit, crédito infonavit, CURP, lugar de nacimiento, calle, numero interno, y tarjeta de cuenta.
bajas<-mutate(bajas,nombre_completo = paste(bajas$nombre, bajas$apellidos, sep=" "))
bajas<-dplyr::select(bajas,-c(rfc, no_ss,factor_cred_infonavit,credito_infonavit,curp,tarjeta_cuenta,apellidos,nombre,lugar_nac,calle,num_interno))
bajas<-bajas[,c(15,1,2,3,4,5,6,7,8,9,10,11,12,13,14)]
colnames(bajas)
## [1] "nombre_completo" "fecha_nac" "genero" "fecha_alta"
## [5] "mot_baja" "permanencia" "baja" "puesto"
## [9] "departamento" "sal_diario_imss" "colonia" "CP"
## [13] "municipio" "estado" "estado_civil"
Para colaboradotes también optamos por unir apellidos con el nombre, además de eliminar las columnas de RFC, número de seguro social, factor de crédito infonavit, crédito infonavit, CURP, lugar de nacimiento, calle, numero interno, y tarjeta de cuenta.
colaboradores<-mutate(colaboradores,nombre_completo = paste(colaboradores$nombre, colaboradores$apellidos, sep=" "))
colaboradores<-dplyr::select(colaboradores,-c(rfc, no_ss,factor_cred_infonavit,credito_infonavit,curp,tarjeta_cuenta,apellidos,nombre,baja,calle,num_interno,lugar_nac,"4to_mes",primer_mes,no_empleado))
colaboradores<-colaboradores[,c(12,1,2,3,4,5,6,7,8,9,10,11)]
El siguiente paso a realizar es la limpieza de las bases de datos (Na’s, tipo de variables, errores ortograficos, entre otros).
Para merma eliminaremos las filas que contienen el total de los meses.
merma<-merma[- grep("Total", merma$mes),]
Así mismo, hay que corroborar que las columnas estén en el formato correcto.
str(merma)
## 'data.frame': 50 obs. of 3 variables:
## $ fecha: chr "11/01/2022" "11/01/2022" "22/01/2022" "22/01/2022" ...
## $ mes : chr "ENERO" "ENERO" "ENERO" "ENERO" ...
## $ kilos: chr "5080" "3810" "2990" "2680" ...
Al observar el tipo de variable, debemos de cambiar fecha a formato de fecha y kilos como entero.
merma$kilos<-as.integer(merma$kilos)
merma$fecha<-as.POSIXct(merma$fecha, format ="%d/%m/%Y")
str(merma)
## 'data.frame': 50 obs. of 3 variables:
## $ fecha: POSIXct, format: "2022-01-11" "2022-01-11" ...
## $ mes : chr "ENERO" "ENERO" "ENERO" "ENERO" ...
## $ kilos: int 5080 3810 2990 2680 3650 4380 3870 3590 3410 3930 ...
Para scrap eliminamos la primer fila que dice agosto.
scrap<-scrap[- grep("agosto", scrap$referencia),]
head(scrap,5)
## referencia fecha
## 2 SP/08731 31/08/2022
## 3 SP/08730 31/08/2022
## 4 SP/08729 31/08/2022
## 5 SP/08728 31/08/2022
## 6 SP/08727 31/08/2022
## producto
## 2 [BACKFRAME 60% CUELLO ARMADO] 18805. 60% Backframe. Cuello Armado.
## 3 [N61506747 CAJA] N61506747. Kit. Caja.
## 4 [N61506729 SEPARADOR] N61506729. Kit. Separador.
## 5 [341332 DIVISOR - U611 & U625] 341332. U611. U625. Divisor Troquelado.
## 6 [DIVISOR ZIGZAG VW CHATTANOOGA] Chattanooga. St1 y St3. Zig Zag Troquelado.
## cantidad ubi_origen
## 2 2 SAB/Calidad/Entrega de PT
## 3 1 SAB/Calidad/Entrega de PT
## 4 1 SAB/Calidad/Entrega de PT
## 5 31 SAB/Pre-Production
## 6 1 SAB/Pre-Production
Así mismo, hay que corroborar que las columnas estén en el formato correcto.
str(scrap)
## 'data.frame': 250 obs. of 5 variables:
## $ referencia: chr "SP/08731" "SP/08730" "SP/08729" "SP/08728" ...
## $ fecha : chr "31/08/2022" "31/08/2022" "31/08/2022" "31/08/2022" ...
## $ producto : chr "[BACKFRAME 60% CUELLO ARMADO] 18805. 60% Backframe. Cuello Armado." "[N61506747 CAJA] N61506747. Kit. Caja." "[N61506729 SEPARADOR] N61506729. Kit. Separador." "[341332 DIVISOR - U611 & U625] 341332. U611. U625. Divisor Troquelado." ...
## $ cantidad : num 2 1 1 31 1 1 1 9 2 1 ...
## $ ubi_origen: chr "SAB/Calidad/Entrega de PT" "SAB/Calidad/Entrega de PT" "SAB/Calidad/Entrega de PT" "SAB/Pre-Production" ...
Al observar el tipo de variable, debemos de cambiar cantidad a entero y fecha con formato de fecha.
scrap$cantidad<-as.integer(scrap$cantidad)
scrap$fecha<-as.POSIXct(scrap$fecha, format ="%d/%m/%Y")
str(scrap)
## 'data.frame': 250 obs. of 5 variables:
## $ referencia: chr "SP/08731" "SP/08730" "SP/08729" "SP/08728" ...
## $ fecha : POSIXct, format: "2022-08-31" "2022-08-31" ...
## $ producto : chr "[BACKFRAME 60% CUELLO ARMADO] 18805. 60% Backframe. Cuello Armado." "[N61506747 CAJA] N61506747. Kit. Caja." "[N61506729 SEPARADOR] N61506729. Kit. Separador." "[341332 DIVISOR - U611 & U625] 341332. U611. U625. Divisor Troquelado." ...
## $ cantidad : int 2 1 1 31 1 1 1 9 2 1 ...
## $ ubi_origen: chr "SAB/Calidad/Entrega de PT" "SAB/Calidad/Entrega de PT" "SAB/Calidad/Entrega de PT" "SAB/Pre-Production" ...
Primero hay que corroborar que las columnas estén en el formato correcto.
str(carton)
## 'data.frame': 5300 obs. of 11 variables:
## $ fecha : chr "15/07/22" "15/07/22" "15/07/22" "15/07/22" ...
## $ cliente : chr "STABILUS 1" "STABILUS 1" "STABILUS 1" "STABILUS 1" ...
## $ piezas_prog : chr "200" "100" "216" "100" ...
## $ tmo_min : chr "20" "15" "20" "10" ...
## $ hr_fin : chr "9:20" "9:35" "9:55" "10:05" ...
## $ lam_procesadas: chr "402" "134" "110" "100" ...
## $ inicio_sep_up : chr "9:05" "10:05" "9:40" "11.20" ...
## $ fin_sep_up : chr "9.10" "10:16" "9:43" "11:26" ...
## $ inicio_proceso: chr "9:12" "10.17" "9:45" "11:30" ...
## $ fin_proceso : chr "10:04" "11:05" "9.57" "11:49" ...
## $ tiempo_calidad: chr "1" "1" "1" "1" ...
Al observar el tipo de variable, debemos de cambiar la fecha con formato de fecha, piezas programadas y laminas procesadas a entero, y las columnas que son de tiempo al formato de hora también.
carton$piezas_prog <-as.integer(carton$piezas_prog)
carton$tmo_min <-as.integer(carton$tmo_min)
carton$hr_fin<-as.POSIXct(carton$hr_fin,format="%H:%M")
carton$hr_fin <- as.ITime(carton$hr_fin)
carton$inicio_sep_up<-as.POSIXct(carton$inicio_sep_up,format="%H:%M")
carton$inicio_sep_up <- as.ITime(carton$inicio_sep_up)
carton$fin_sep_up<-as.POSIXct(carton$fin_sep_up,format="%H:%M")
carton$fin_sep_up <- as.ITime(carton$fin_sep_up)
carton$inicio_proceso<-as.POSIXct(carton$inicio_proceso,format="%H:%M")
carton$inicio_proceso <- as.ITime(carton$inicio_proceso)
carton$fin_proceso<-as.POSIXct(carton$fin_proceso,format="%H:%M")
carton$fin_proceso <- as.ITime(carton$fin_proceso)
str(carton)
## 'data.frame': 5300 obs. of 11 variables:
## $ fecha : chr "15/07/22" "15/07/22" "15/07/22" "15/07/22" ...
## $ cliente : chr "STABILUS 1" "STABILUS 1" "STABILUS 1" "STABILUS 1" ...
## $ piezas_prog : int 200 100 216 100 20 200 100 12 32 500 ...
## $ tmo_min : int 20 15 20 10 10 20 10 10 10 60 ...
## $ hr_fin : 'ITime' int 09:20:00 09:35:00 09:55:00 10:05:00 10:15:00 10:35:00 10:45:00 10:55:00 11:05:00 10:00:00 ...
## $ lam_procesadas: chr "402" "134" "110" "100" ...
## $ inicio_sep_up : 'ITime' int 09:05:00 10:05:00 09:40:00 NA 12:00:00 12:32:00 NA NA 02:44:00 09:00:00 ...
## $ fin_sep_up : 'ITime' int NA 10:16:00 09:43:00 11:26:00 12:05:00 12:34:00 02:16:00 02:29:00 02:47:00 09:11:00 ...
## $ inicio_proceso: 'ITime' int 09:12:00 NA 09:45:00 11:30:00 12:15:00 12:47:00 NA 02:31:00 NA 09:13:00 ...
## $ fin_proceso : 'ITime' int 10:04:00 11:05:00 NA 11:49:00 12:31:00 02:00:00 NA 03:00:00 02:12:00 10:59:00 ...
## $ tiempo_calidad: chr "1" "1" "1" "1" ...
En esta base de datos hay otros elementos a considerar por esto revisaremos cada columna y los registros que la conforman.
Fecha
Con la fecha podemos observar que no hay NA’s, además que nuestros
registros son 59 fechas, que abarcan de mediados de julio hasta mediados
de septiembre. Y hay que cambair el formato a formato de fecha.
carton$fecha <- as.Date(carton$fecha, format ="%d/%m/%y")
str(carton$fecha)
## Date[1:5300], format: "2022-07-15" "2022-07-15" "2022-07-15" "2022-07-15" "2022-07-15" ...
unique(carton$fecha)
## [1] "2022-07-15" "2022-07-16" "2022-07-18" "2022-07-19" "2022-07-20"
## [6] "2022-07-21" "2022-07-22" "2022-07-23" "2022-07-25" "2022-07-26"
## [11] "2022-07-27" "2022-07-28" "2022-07-29" "2022-07-30" "2022-08-01"
## [16] "2022-08-02" "2022-08-03" "2022-08-04" "2022-08-05" "2022-08-06"
## [21] "2022-08-08" "2022-08-09" "2022-08-10" "2022-08-11" "2022-08-12"
## [26] "2022-08-13" "2022-08-15" "2022-08-16" "2022-08-17" "2022-08-18"
## [31] "2022-08-19" "2022-08-20" "2022-08-22" "2022-08-23" "2022-08-24"
## [36] "2022-08-25" "2022-08-26" "2022-08-27" "2022-08-29" "2022-08-30"
## [41] "2022-08-31" "2022-09-01" "2022-09-02" "2022-09-03" "2022-09-05"
## [46] "2022-09-06" "2022-09-07" "2022-09-08" "2022-09-09" "2022-09-10"
## [51] "2022-09-12" "2022-09-13" "2022-09-14" "2022-09-15" "2022-09-16"
## [56] "2022-09-17" "2022-09-19" "2022-09-20" "2022-09-21"
Cliente
Con los clientes podemos observar que hay clientes con NA, otros con
espacios vacíos, y otros que son el mismo pero con error ortográfico,
como es el caso de STABILUS 3 y STABILUS 3. El formato de caracter está
correcto por lo que no hay que hacer modificaciones en eso.
unique(carton$cliente)
## [1] "STABILUS 1" "YANFENG" "TRMX"
## [4] "MERIDIAN LIGHTWEIGHT" "STABILUS 3" "STABILUS 3."
## [7] "HANON SYSTEMS" "VARROC" "VL-017-13939"
## [10] "DENSO" "" "VL-017-14086"
## [13] "HELLA" NA
Por lo tanto, hay que eliminar los registros con clientes con NA y con espacios en blanco, además de cambiar aquellos que tienen de cliente STABILUS 3. a STABILUS 3.
carton <- filter(carton, !is.na(carton$cliente))
carton <- filter(carton,cliente!="")
carton$cliente <- replace(carton$cliente,carton$cliente=="STABILUS 3.","STABILUS 3")
unique(carton$cliente)
## [1] "STABILUS 1" "YANFENG" "TRMX"
## [4] "MERIDIAN LIGHTWEIGHT" "STABILUS 3" "HANON SYSTEMS"
## [7] "VARROC" "VL-017-13939" "DENSO"
## [10] "VL-017-14086" "HELLA"
Inicio de proceso y fin de proceso
Previo a analizar el resto de las columnas primero habremos de eliminar
los registros que estén como NA’s en alguna de estas dos columnas,
puesto que esos registros no sirven para el análisis más adelante. Así
mismo, hay que eliminar los registros que esten como 00:00 también.
carton <- filter(carton, !is.na(carton$inicio_proceso) & !is.na(carton$fin_proceso))
carton <- filter(carton,!inicio_proceso==00:00:00 & !fin_proceso==00:00:00)
sum(is.na(carton$inicio_proceso))
## [1] 0
sum(is.na(carton$fin_proceso))
## [1] 0
Inicio de sep up y fin de sep up
Para estas columnas también eliminaremos los registros con NA o con
00:00 como tiempo.
carton <- filter(carton, !is.na(carton$inicio_sep_up) & !is.na(carton$fin_sep_up))
carton <- filter(carton,!inicio_sep_up==00:00:00 & !fin_sep_up==00:00:00)
sum(is.na(carton$inicio_sep_up))
## [1] 0
sum(is.na(carton$fin_sep_up))
## [1] 0
Piezas Programadas
Hay que eliminar los registros con NA de igual manera. El formato debe
ser de entero, por lo que hay que hacer este cambio.
carton <- filter(carton, !is.na(carton$piezas_prog))
carton$piezas_prog <- as.integer(carton$piezas_prog)
sum(is.na(carton$piezas_prog))
## [1] 0
Laminas procesadas
Para laminas procesadas si bien no tiene NA sus registros no son
consistentes y uniformes en su formato, algunos son numeros enteros,
otros estan divididos por un “/”, otros son alfanúmericos, y otros son 0
o registros vacíos. Eliminaremos aquellos menores a 1, los vaciós y
mantendremos el primer número antes del “/”, y los registros
alfanúmericos aquellos que solo tienen una letra, eliminaremos la letra,
pero aquellos que contengan signos como “=”, o más caracteres serán
eliminados. También el formato debe ser de entero por lo que hay que
hacer esta modificación.
carton <- carton %>% separate(lam_procesadas, c("lam_procesadas", "eliminar"), sep="/")
carton <- dplyr::select(carton,-eliminar)
carton <- carton[- grep("=", carton$lam_procesadas),]
carton <- carton[- grep("A 4 B4", carton$lam_procesadas),]
carton$lam_procesadas <- str_replace(carton$lam_procesadas, "[aeiouLAM=NbBsS]", "")
carton$lam_procesadas <- as.integer(carton$lam_procesadas)
carton <- filter(carton,carton$lam_procesadas>0)
sum(is.na(carton$lam_procesadas))
## [1] 0
unique(carton$lam_procesadas)
## [1] 51 402 501 152 3 202 216 407 212 421 454 350 104 204 203
## [16] 2 24 15 20 31 53 27 405 403 303 102 503 45 63 56
## [31] 57 404 37 46 78 101 9 6 232 406 302 103 210 76 26
## [46] 11 601 28 40 61 398 190 400 86 18 74 287 22 10 38
## [61] 34 135 82 30 8 23 25 97 13 243 148 205 300 67 41
## [76] 242 5 29 50 592 253 206 379 200 35 21 245 124 17 226
## [91] 201 121 218 109 12 4 47 70 110 88 323 324 33 184 73
## [106] 49 84 100 228 91 500 310 839 48 255 1262 36 19 1240 32
## [121] 14 234 219 427 1229 502 105 42 39 415 175 412 231 180 7
## [136] 221 126 16 208 145 52 81 602 90 802 134 79 77 439 163
## [151] 789 600 111 58 328 609 347 161 399 64 384 118 378 370 452
## [166] 752 375 171 44 215 391 376 339 252 772 207 139 197 766 390
## [181] 227 773 194 112 209 688 146 358 408 123 286 60 122 62 410
## [196] 130 322 437 229 187 380 199 120 162 354 247 137 240 236 304
## [211] 136 143 1022 519 608 584 298 154 306 211 65 414 505 396 140
## [226] 66 386 174 165 313 43 114 178 356 196 301 377 54 106 164
## [241] 125 401 274 435 235 108 388 80 127 181 244 220 241 151 117
## [256] 98 382 248 617 385 305 71 141 344 93 409 222 465 250 68
## [271] 315 185 416 312 1 107 133 195 198 128
Tmo_min y hr_final
Estas columnas permaneceran igual sin ajustes en específico. Únicamente
el formato de tmo_min lo dejaremos en entero.
carton$tmo_min <- as.integer(carton$tmo_min)
Tiempo de calidad
Para tiempo de calidad podemos observar que hay registros que no son
enteros, otors que tienen segundos y otros que están vacíos. Los que no
son enteros los dejaremos vacíos, los vacíos van a permanecer y los que
tienen segundos van a ser redondeados al entero más cercano.
carton$tiempo_calidad <- str_replace(carton$tiempo_calidad, "9:47", "9")
carton <- subset(carton, tiempo_calidad!="|")
carton$tiempo_calidad <- as.integer(carton$tiempo_calidad)
unique(carton$tiempo_calidad)
## [1] 1 2 3 4 9 0 5 10 22 8 11 17 NA 7 25 21 6
Para Delivery Performance hay que verificar que las columnas estén en el formato correcto además de identificar valores como Na, valores atípicos, entre otros.
De igual manera iremos revisando columna por columna.
Cliente
Como podemos observar en cliente, solo son 4 clientes, no hay errores
ortográficos y el formato de la columna es el correcto.
unique(perf$cliente)
## [1] "PRINTEL " "MAHLE" "MAGNA" "VARROC"
str(perf$cliente)
## chr [1:2392] "PRINTEL " "MAHLE" "MAHLE" "MAHLE" "MAGNA" "VARROC" "VARROC" ...
sum(is.na(perf$cliente))
## [1] 0
Vueltas
De igual manera en vueltas, solo hay hasta 3 vueltas, y no hay errores
ortográficos o valores atípicos.
unique(perf$vueltas)
## [1] 1 2 3
str(perf$vueltas)
## int [1:2392] 1 1 2 3 1 1 2 3 1 1 ...
sum(is.na(perf$vueltas))
## [1] 0
Fecha
La columna de fecha está como caracter, por lo que hay que hacer el
cambio de formato a fecha. Así mismo, tampoco hay valores faltantes.
perf$fecha <-as.Date(perf$fecha, format ="%d/%m/%Y")
str(perf$fecha)
## Date[1:2392], format: "2021-07-22" "2021-07-22" "2021-07-22" "2021-07-22" "2021-07-22" ...
sum(is.na(perf$fecha))
## [1] 0
Real Arrival y Real Departure
Para estas columnas podemos encontrar que hay valores con 0. Por lo
tanto vamos a eliminar los registros que tengan 0 en estas columnas.
unique(perf$real_arrival)
## [1] 0.00 8.00 9.00 20.00 16.30 16.10 16.00 16.50 18.20 17.00 16.20 17.20
## [13] 16.35 16.05 20.18 16.15 20.05 9.30 9.20 9.15 9.10 15.30 21.00 18.15
## [25] 16.25 16.40 15.36 9.45 15.40 9.06 9.03 9.27 17.35 9.05 15.00 15.10
## [37] 15.20 15.16 15.45 9.35 22.08 9.08 21.05 19.15 20.40 20.15 23.20 11.00
## [49] 23.00 13.00 23.50 14.00 23.15 7.45 13.40 23.30 10.40 22.40 11.37 21.15
## [61] 9.26 6.00 8.05 10.42 20.10 7.30 21.10 8.52 20.30 7.34 7.35 9.12
## [73] 10.05 9.17 19.48 20.20 10.00 8.10 19.20 9.11 8.45 9.50 18.00 9.40
## [85] 18.35 18.40 18.05 18.10 18.50 19.10 9.25 18.30 17.30
unique(perf$real_departure)
## [1] 0.00 8.55 10.00 21.10 18.10 8.50 10.10 21.25 17.20 21.00 16.50 17.00
## [13] 21.15 8.51 9.00 21.05 18.50 9.45 17.05 17.15 19.55 16.55 9.55 18.20
## [25] 10.15 17.25 10.05 18.00 17.40 17.30 9.05 17.45 9.50 17.50 9.40 17.35
## [37] 20.55 10.30 21.20 9.10 10.45 11.05 22.58 10.25 9.15 21.45 9.35 20.50
## [49] 17.58 19.40 17.55 18.25 10.40 10.06 18.31 10.27 19.00 18.30 18.35 10.20
## [61] 19.30 16.45 15.55 16.00 16.10 16.35 21.50 16.40 16.30 9.20 9.25 10.35
## [73] 22.55 17.38 22.10 20.00 10.50 11.35 23.00 22.30 21.40 24.15 12.00 23.50
## [85] 18.08 13.45 24.50 18.40 24.35 14.40 11.15 8.05 12.40 22.50 11.00 12.05
## [97] 24.45 11.55 22.15 10.12 22.00 21.55 21.35 20.45 21.30 9.30 8.40 20.15
## [109] 8.30 9.58 8.34 8.20 20.40 8.35 8.15 11.30 11.20 19.20 6.40 18.45
## [121] 10.55 19.50 20.10 10.24 7.40 19.45 13.10
perf <- filter(perf, perf$real_arrival>0 & perf$real_departure>0)
unique(perf$real_arrival)
## [1] 8.00 9.00 20.00 16.30 16.10 16.00 16.50 18.20 17.00 16.20 17.20 16.35
## [13] 16.05 20.18 16.15 20.05 9.30 9.20 9.15 9.10 15.30 21.00 18.15 16.25
## [25] 16.40 15.36 9.45 15.40 9.06 9.03 9.27 17.35 9.05 15.00 15.10 15.20
## [37] 15.16 15.45 9.35 22.08 9.08 21.05 19.15 20.40 20.15 23.20 11.00 23.00
## [49] 13.00 23.50 14.00 23.15 7.45 13.40 23.30 10.40 22.40 11.37 21.15 9.26
## [61] 6.00 8.05 10.42 20.10 7.30 21.10 8.52 20.30 7.34 7.35 9.12 10.05
## [73] 9.17 19.48 20.20 10.00 8.10 19.20 9.11 8.45 9.50 18.00 9.40 18.35
## [85] 18.40 18.05 18.10 18.50 19.10 9.25 18.30 17.30
unique(perf$real_departure)
## [1] 8.55 10.00 21.10 18.10 8.50 10.10 21.25 17.20 21.00 16.50 17.00 21.15
## [13] 8.51 9.00 21.05 18.50 9.45 17.05 17.15 19.55 16.55 9.55 18.20 10.15
## [25] 17.25 10.05 18.00 17.40 17.30 9.05 17.45 9.50 17.50 9.40 17.35 20.55
## [37] 10.30 21.20 9.10 10.45 11.05 22.58 10.25 9.15 21.45 9.35 20.50 17.58
## [49] 19.40 17.55 18.25 10.40 10.06 18.31 10.27 19.00 18.30 18.35 10.20 19.30
## [61] 16.45 15.55 16.00 16.10 16.35 21.50 16.40 16.30 9.20 9.25 10.35 22.55
## [73] 17.38 22.10 20.00 10.50 11.35 23.00 22.30 21.40 24.15 12.00 23.50 18.08
## [85] 13.45 24.50 18.40 24.35 14.40 11.15 8.05 12.40 22.50 11.00 12.05 24.45
## [97] 11.55 22.15 10.12 22.00 21.55 21.35 20.45 21.30 9.30 8.40 20.15 8.30
## [109] 9.58 8.34 8.20 20.40 8.35 8.15 11.30 11.20 19.20 6.40 18.45 10.55
## [121] 19.50 20.10 10.24 7.40 19.45 13.10
Al hacerlo, los registros de los clientes de VARROC y MAGNA se eliminaron de la base de datos.
Plan Arrival Para Plan Arrival es posible observar que hay registros con 0, estos serán remplazados con el promedio o la mediana de plan arrival por cliente por vuelta, esto con el propósito que sea lo más preciso posible.
unique(perf$plan_arrival)
## [1] 8 9 20 16 0
sum(is.na(perf$plan_arrival))
## [1] 0
Al observar el valor de skewness, podemos observar que el valor es menor a 1 por lo que su distribución nos sugiere que es mejor remplazar con el promedio. Además podemos observar que la mediana es 0 debido a que muchos valores tienen 0 como plan arrival.
describe(perf$plan_arrival)
## vars n mean sd median trimmed mad min max range skew kurtosis se
## X1 1 800 12.86 5.27 9 12.59 1.48 0 20 20 0.42 -1.64 0.19
Para remplazar 0 con el promedio vamos a calcular el promedio por cliente por vuelta.
aggregate(plan_arrival ~ cliente + vueltas, data = perf, mean)
## cliente vueltas plan_arrival
## 1 MAHLE 1 8.00000
## 2 PRINTEL 1 16.00000
## 3 MAHLE 2 9.00000
## 4 MAHLE 3 19.91736
Como queremos remplazar el 0 unicamente en el cliente MAHLE y en la vuelta 3 debemos hacer lo siguiente.
perf <- perf %>% mutate(plan_arrival=ifelse(plan_arrival == 0 | cliente == "MAHLE"| vueltas == 3,20,plan_arrival))
unique(perf$plan_arrival)
## [1] 20 16
Difference
Esta columna se supone es la diferencia que hay entre real arrival y
real departure, sin embargo, podemos observar que no todos los registros
tienen el calculo correcto, e inclusive algunas ni si quiera tienen el
calculo por lo que es necesario modificar esta columna.
perf <- mutate(perf, difference=real_departure-real_arrival)
perf <- dplyr::select(perf,-diference)
head(perf,5)
## cliente vueltas fecha plan_arrival real_arrival real_departure
## 1 MAHLE 1 2021-07-22 20 8.0 8.55
## 2 MAHLE 2 2021-07-22 20 9.0 10.00
## 3 MAHLE 3 2021-07-22 20 20.0 21.10
## 4 PRINTEL 1 2021-07-25 16 16.3 18.10
## 5 MAHLE 1 2021-07-25 20 8.0 8.50
## difference
## 1 0.55
## 2 1.00
## 3 1.10
## 4 1.80
## 5 0.50
Para Delivery Plan también iremos revisando columna por columna.
Cliente Planta
Para Cliente podemos observar que no hay errores ortográficos por lo que
no haremos cambios en esta columna.
unique(plan$cliente)
## [1] "STB3" "STB4" "STB5" "STB6"
## [5] "STB7" "STB8" "STB9" "STB 1"
## [9] "YF RAMOS" "INOAC POLYTEC" "MERIDIAN" "YANFENG sm"
## [13] "YFTO" "YFCF" "YF QRO" "TRMX"
## [17] "DENSO" "SEGROVE" "HANON" "ANTOLIN TOLUCA"
## [21] "ANTOLIN ARTEAGA" "HELLA" "UFI" "ISRI"
## [25] "ABC QUERETARO" "VARROC"
Proyecto
De igual manera para proyecto no haremos cambios a los registros, pues
no encontramos errores de inconsistencia.
unique(plan$proyecto)
Item
De igaul manera con item no haremos modificaciones.
unique(plan$item)
Mes
Para la columna de mes no encontramos errores ortográficos por lo que no
haremos modificaciones.
unique(plan$mes)
## [1] "jun_21" "jul_21" "ago_21" "sep_21" "oct_21" "nov_21" "dic_21" "ene_22"
## [9] "feb_22" "mar_22" "abr_22" "may_22" "jun_22" "jul_22" "ago_22" "sep_22"
## [17] "oct_22" "nov_22" "dic_22" "ene_23" "feb_23" "mar_23"
Unidades
Para unidades optamos por eliminar los registros con 0 unidades, ya que
al convertir los meses en una sola columna, todos aquellos meses donde
no había producción planeada tienen 0.También corroboramos que el
formato de la columna sea el correcto, de entero.
plan <- filter(plan, unidades>0)
str(plan$unidades)
## int [1:972] 140 530 200 150 230 500 200 900 1000 184 ...
Para esta base de datos también iremos revisando columna por columna.
Nombre completo, fecha de nacimiento y fecha de
alta
Estas columnas están correctas, solo hay que convertir a formato de
fecha la fecha de alta y de nacimiento.
bajas$fecha_nac <- as.Date(bajas$fecha_nac, format ="%d/%m/%Y")
str(bajas$fecha_nac)
## Date[1:238], format: "1990-06-24" "1986-07-11" "1999-01-29" "2001-06-11" "1993-01-28" ...
bajas$fecha_alta <- as.Date(bajas$fecha_alta, format ="%d/%m/%Y")
str(bajas$fecha_alta)
## Date[1:238], format: "2020-03-09" "2021-11-09" "2021-11-10" "2021-11-10" "2021-11-18" ...
Género
En la columna de género solo hay un valor vacío, basados en su nombre
completo vamos a asumir que su género es masculino. Así mismo, hay un
registro con lo que parece ser un RFC en lugar del género, basado en el
nombre de esa persona asumiremos que es femenino.
bajas$genero <- replace(bajas$genero,bajas$genero=="","MASCULINO")
bajas$genero <- replace(bajas$genero,bajas$genero=="CAPJ000926597","FEMENINO")
Código Postal
Para el código postal hay que remplazar los registros que tengan el
municipio en lugar del CP por su respectivo CP.
bajas2 <- bajas
bajas2 <- bajas2 %>% mutate(bajas2, CP2=CP)
bajas2 <- bajas2 %>% mutate(bajas2, municipio2=municipio)
bajas2 <- bajas2 %>% mutate(bajas2, estado2=estado)
#Remplazar el municipio por el CP en la columna de CP, tambien remplazar union libre por el CP
bajas2 <- bajas2 %>% mutate(CP=ifelse(CP == "APODACA" | CP == "JUAREZ" | CP == "MONTERREY" | CP == "GUADALUPE" | CP == "RAMOS ARIZPE"| CP == "SAN PDRO COAH"| CP == "PESQUERIA"| CP == "CADEREYTA"| CP == "SAN NICOLAS DE LOS GARZA"| CP == "SALTILLO"| CP == "ZUAZUA"| CP == "CIENEGA DE FLORES"| CP == "NUEVO LEON", estado , CP))
bajas2 <- bajas2 %>% mutate(CP=ifelse(CP == "UNION LIBRE", municipio , CP))
unique(bajas2$CP)
## [1] "66438" "0" "66646" "66640" "66649" "67254" "67114" "66645" ""
## [10] "66644" "66360" "25297" "66648" "67256" "64750" "66670" "66600" "66643"
## [19] "67267" "64764" "67110" "66633" "25902" "27970" "66655" "66647" "66612"
## [28] "64220" "66650" "67486" "67130" "99999" "66673" "67117" "66473" "25019"
## [37] "66634" "67258" "66477" "67113" "67265" "25904" "65776" "67250" "66444"
## [46] "67176" "65580" "67262"
Municipio
En municipio hay que remplazar los registros que tienen el estado por su
respectivo municipio. Además de estandarizar los registros, por ejemplo,
cambiar “SAN NICOLAS DE LOS G” por “SAN NICOLAS DE LOS GARZA”.
#Remplazar el estado por el municipio
bajas2 <- bajas2 %>% mutate(municipio=ifelse(municipio == "NUEVO LEON" | municipio == "Nuevo León" | municipio == "COAHUILA" | municipio == "Coahuila",CP2 , municipio))
bajas2 <- bajas2 %>% mutate(municipio=ifelse(municipio == 66444 , colonia , municipio))
#Cambias SAN NICOLAS DE LOS G x SAN NICOLAS DE LOS GARZA
bajas2$municipio <- replace(bajas2$municipio,bajas2$municipio=="SAN NICOLAS DE LOS G","SAN NICOLAS DE LOS GARZA")
unique(bajas2$municipio)
## [1] "SAN NICOLAS DE LOS GARZA" "PESQUERIA"
## [3] "APODACA" "JUAREZ"
## [5] "GUADALUPE" "RAMOS ARIZPE"
## [7] "MONTERREY" "SAN PDRO COAH"
## [9] "CADEREYTA" "SALTILLO"
## [11] "" "ZUAZUA"
## [13] "CIENEGA DE FLORES"
Estado
En estado hay que remplazar los registros que tienen CP por el estado
correcto. Así mismo, estandarizar los registros, por ejemplo, cambiar
“Nuevo León” por “NUEVO LEON”.
#Remplazar el CP por el estado correcto en la columna de estado
bajas2 <- bajas2 %>% mutate(estado=ifelse(municipio == "SAN NICOLAS DE LOS GARZA" | municipio == "PESQUERIA" | municipio == "APODACA" | municipio == "JUAREZ" | municipio == "GUADALUPE"| municipio == "RAMOS ARIZPE"| municipio == "CADEREYTA"| municipio == "ZUAZUA"| municipio == "CIENEGA DE FLORES"| municipio == "MONTERREY", "NUEVO LEON" , municipio))
bajas2$estado <- replace(bajas2$estado,bajas2$estado=="SAN PDRO COAH","COAHUILA")
bajas2$estado <- replace(bajas2$estado,bajas2$estado=="SALTILLO","COAHUILA")
unique(bajas2$estado)
## [1] "NUEVO LEON" "COAHUILA" ""
Estado Civil
En estado civil hay que estandarizar los registros, por ejemplo, cambiar
“UNIONLIBRE” por “UNION LIBRE”.
bajas2$estado_civil <- replace(bajas2$estado_civil,bajas2$estado_civil=="UNIONLIBRE","UNION LIBRE")
bajas2$estado_civil <- replace(bajas2$estado_civil,bajas2$estado_civil=="Unión libre","UNION LIBRE")
bajas2$estado_civil <- replace(bajas2$estado_civil,bajas2$estado_civil=="Soltero","SOLTERO(A)")
bajas2$estado_civil <- replace(bajas2$estado_civil,bajas2$estado_civil=="Casado","CASADO(A)")
bajas2$estado_civil <- replace(bajas2$estado_civil,bajas2$estado_civil=="CASADA","CASADO(A)")
bajas2$estado_civil <- replace(bajas2$estado_civil,bajas2$estado_civil=="SOLTERA","SOLTERO(A)")
bajas2$estado_civil <- replace(bajas2$estado_civil,bajas2$estado_civil=="DIVORCIADA","DIVORCIADO(A)")
bajas2$estado_civil <- replace(bajas2$estado_civil,bajas2$estado_civil=="CASADO","CASADO(A)")
bajas2$estado_civil <- replace(bajas2$estado_civil,bajas2$estado_civil=="DIVORCIADO","DIVORCIADO(A)")
bajas2$estado_civil <- replace(bajas2$estado_civil,bajas2$estado_civil=="SOLTERO","SOLTERO(A)")
unique(bajas2$estado_civil)
## [1] "SOLTERO(A)" "UNION LIBRE" "CASADO(A)" ""
## [5] "DIVORCIADO(A)"
Puesto Para puesto vamos a unificar aquellos puestos que son similares y que tengan errores ortográficos. Por ejemplo, “AY. GENERAL (MATERIALES)” y “AYUDANTE DE EMBARQUES” pasarlos a “AYUDANTE GENERAL”.
bajas2$puesto <- replace(bajas2$puesto,bajas2$puesto=="AY.GENERAL (MATERIALES)","AYUDANTE GENERAL")
bajas2$puesto <- replace(bajas2$puesto,bajas2$puesto=="AYUDANTE DE EMBARQUES","AYUDANTE GENERAL")
bajas2$puesto <- replace(bajas2$puesto,bajas2$puesto=="AY. GENERAL","AYUDANTE GENERAL")
bajas2$puesto <- replace(bajas2$puesto,bajas2$puesto=="AYUD.EMBARQUES","AYUDANTE GENERAL")
bajas2$puesto <- replace(bajas2$puesto,bajas2$puesto=="AYUDANTE DE SOLDADOR","AYUDANTE GENERAL")
bajas2$puesto <- replace(bajas2$puesto,bajas2$puesto=="AYUDANTE DE MTTO","AYUDANTE GENERAL")
bajas2$puesto <- replace(bajas2$puesto,bajas2$puesto=="AYUDANTE DE SOLDADOR","AYUDANTE GENERAL")
bajas2$puesto <- replace(bajas2$puesto,bajas2$puesto=="AYUDANTE GENERAL DE EMBARQUES","AYUDANTE GENERAL")
bajas2$puesto <- replace(bajas2$puesto,bajas2$puesto=="COSTURERA","COSTURERO(A)")
bajas2$puesto <- replace(bajas2$puesto,bajas2$puesto=="COSTURERO","COSTURERO(A)")
bajas2$puesto <- replace(bajas2$puesto,bajas2$puesto=="INSPECTOR DE CALIDAD","INSPECTOR(A) DE CALIDAD")
bajas2$puesto <- replace(bajas2$puesto,bajas2$puesto=="INSPECTORA DE CALIDAD","INSPECTOR(A) DE CALIDAD")
bajas2$puesto <- replace(bajas2$puesto,bajas2$puesto=="INSPECTOR CALIDAD","INSPECTOR(A) DE CALIDAD")
bajas2$puesto <- replace(bajas2$puesto,bajas2$puesto=="DISEÑO","DISEÑO")
bajas2$puesto <- toupper(bajas2$puesto)
unique(bajas2$puesto)
## [1] "DISEÑO" "AYUDANTE GENERAL"
## [3] "COSTURERO(A)" "RESIDENTE YANFENG"
## [5] "MONTACARGUISTA" "SERVICIO AL CLIENTE"
## [7] "ANALISTA DE NOMINAS /AUX DE R.H." "AUXILIAR DE EMBARQUES"
## [9] "CHOFER" "INSPECTOR(A) DE CALIDAD"
## [11] "MATERIALISTA" "SOLDADOR"
## [13] "FACTURACION" "JEFE DE SEGURIDAD E HIGIENE"
## [15] "MARCADORA" "CORTADOR"
## [17] "LIMPIEZA" "RESIDENTE"
## [19] "GUARDIA DE SEGURIDAD" "ENCARGADA DE CALIDAD"
## [21] "" "PRACTICANTE DE MTTO"
Departamento
Para departamento haremos lo mismo que en puesto.
bajas2$departamento <- replace(bajas2$departamento,bajas2$departamento=="celdas","CELDAS")
bajas2$departamento <- replace(bajas2$departamento,bajas2$departamento=="Celdas","CELDAS")
bajas2$departamento <- replace(bajas2$departamento,bajas2$departamento=="Cedis","CEDIS")
bajas2$departamento <- replace(bajas2$departamento,bajas2$departamento=="Embarques","EMBARQUES")
bajas2$departamento <- replace(bajas2$departamento,bajas2$departamento=="Costura","COSTURA")
bajas2$departamento <- replace(bajas2$departamento,bajas2$departamento=="Paileria","PAILERIA")
bajas2$departamento <- replace(bajas2$departamento,bajas2$departamento=="Stabilus","STABILUS")
bajas2$departamento <- replace(bajas2$departamento,bajas2$departamento=="Troquel","TROQUEL")
bajas2$departamento <- replace(bajas2$departamento,bajas2$departamento=="Mantenimiento FF","MANTENIMIENTO")
bajas2$departamento <- replace(bajas2$departamento,bajas2$departamento=="stabilus","STABILUS")
bajas2$departamento <- replace(bajas2$departamento,bajas2$departamento=="Produccion Cartón MC","PRODUCCION CARTON MC")
bajas2$departamento <- replace(bajas2$departamento,bajas2$departamento=="Produccion Cartón MDL","PRODUCCION CARTON MDL")
bajas2$departamento <- replace(bajas2$departamento,bajas2$departamento=="Producción Retorn","PRODUCCION RETORNO")
bajas2$departamento <- toupper(bajas2$departamento)
unique(bajas2$departamento)
## [1] "ADMINISTRATIVO" "PRODUCCION CARTON MC" "STABILUS"
## [4] "CELDAS" "" "MATERIALES"
## [7] "CEDIS" "PRODUCCION CARTON MDL" "PRODUCCION RETORNO"
## [10] "TROQUEL" "MANTENIMIENTO" "AY.FLEXO"
## [13] "COSTURA" "MARCADORA" "CAJAS"
## [16] "LAMINADO" "CALIDAD" "EMBARQUES"
## [19] "PAILERIA" "EHS" "CORTADORAS"
Motivo de Baja
Para motivo de baja haremos algo diferente, al analizar la base de datos
nos dimos cuenta que muchos de los empleados que tienen muy pocos días,
por ejemplo de 0 días a 10, en lugar de tener como motivo de baja
ABANDONO, tiene FALTAS. Para que el motivo de baja sea las faltas,
debería de existir un periodo establecido sobre el cual se limiten las
faltas. Por ejemplo, cada empleado solo tiene permitidas tanta cantidad
de faltas al mes. Por lo tanto, aquellos empleados que tienen menos de
10 días de permanencia, cambiaremos su motivo de baja de FALTAS a
ABANDONO.
#Remplazamos FALTA POR BAJAS por ABANDONO
bajas2 <- bajas2 %>% mutate(mot_baja=ifelse(permanencia < 10, "ABANDONO" , mot_baja))
#Mantenemos los motivos de baja que no eran FALTA POR BAJAS y tenian permanencia menor de 10 días.
bajas2 <- bajas2 %>% mutate(mot_baja=ifelse(nombre_completo == "JOANA NOHEMI COLUNGA ORTIZ", "RENUNCIA VOLUNTARIA" , mot_baja))
bajas2 <- bajas2 %>% mutate(mot_baja=ifelse(nombre_completo == "ERNESTO GONZALEZ CASTILLO", "RENUNCIA VOLUNTARIA" , mot_baja))
bajas2 <- bajas2 %>% mutate(mot_baja=ifelse(nombre_completo == "MOISES LAUREANI JIMENEZ", "RENUNCIA VOLUNTARIA" , mot_baja))
bajas2 <- bajas2 %>% mutate(mot_baja=ifelse(nombre_completo == "ROCIO OCHOA GONZALEZ", "RENUNCIA VOLUNTARIA" , mot_baja))
bajas2 <- bajas2 %>% mutate(mot_baja=ifelse(nombre_completo == "MARGARITA RIVAS GONZALEZ", "RENUNCIA VOLUNTARIA" , mot_baja))
bajas2 <- bajas2 %>% mutate(mot_baja=ifelse(nombre_completo == "GLORIA FACUNDO MONTOYA", "RENUNCIA VOLUNTARIA" , mot_baja))
Salario Diario del IMSS
Para salario diario hay que asegurarnos que este en el formato correcto,
además de remplazar los valores faltantes e identificar valores atípicos
y definir si hay que remplazarlos.
filter(bajas2,is.na(bajas2$sal_diario_imss))
## nombre_completo fecha_nac genero fecha_alta
## 1 POLETT ADRIANA LOPEZ RUIZ 1988-08-24 FEMENINO 2022-04-04
## 2 ANGEL GUILLERMO PALOMO LOPEZ <NA> MASCULINO <NA>
## mot_baja permanencia baja puesto
## 1 RENUNCIA VOLUNTARIA 18 22/04/2022 JEFE DE SEGURIDAD E HIGIENE
## 2 <NA> NA
## departamento sal_diario_imss colonia CP municipio estado estado_civil CP2
## 1 NA
## 2 NA
## municipio2 estado2
## 1
## 2
describe(bajas2$sal_diario_imss)
## vars n mean sd median trimmed mad min max range skew kurtosis
## X1 1 236 177.96 23.26 180.68 179.14 0 144.45 500 355.55 11.05 152.94
## se
## X1 1.51
Como podemos ver hay dos registros faltantes, para el de Ángel remplazaremos con la mediana, ya que su valor de skewness del salario diario es mayor a 1, indicandonos que es mejor usar la mediana que la media.
summary(bajas2$sal_diario_imss)
## Min. 1st Qu. Median Mean 3rd Qu. Max. NA's
## 144.4 180.7 180.7 178.0 180.7 500.0 2
bajas2 <- bajas2 %>% mutate(sal_diario_imss=ifelse(nombre_completo == "ANGEL GUILLERMO PALOMO LOPEZ", 180.7, sal_diario_imss))
bajas2 <- bajas2 %>% mutate(sal_diario_imss=ifelse(nombre_completo == "POLETT ADRIANA LOPEZ RUIZ", 180.7, sal_diario_imss))
sum(is.na(bajas2$sal_diario_imss))
## [1] 0
Finalmente terminamos de limpiar la base de datos de aquellas columnas que tuvimos que agregar o renombrar.
bajas2 <- dplyr::select(bajas2, -c(CP2,municipio2,estado2))
bajas <- bajas2
colnames(bajas2)
## [1] "nombre_completo" "fecha_nac" "genero" "fecha_alta"
## [5] "mot_baja" "permanencia" "baja" "puesto"
## [9] "departamento" "sal_diario_imss" "colonia" "CP"
## [13] "municipio" "estado" "estado_civil"
Para colaboradores de igual manera revisaremos columna por columna.
Nombre Completo
A nombre completo no le haremos cambios en la base.
Fecha de nacimiento y fecha de alta
Para fecha de nacimiento y fecha de alta nos aseguramos que el formato
este en formato de fecha.
colaboradores$fecha_alta <- as.Date(colaboradores$fecha_alta, format = "%d/%m/%Y")
colaboradores$fecha_nac <- as.Date(colaboradores$fecha_nac, format = "%d/%m/%Y")
Género
Para género identificamos que en la base de datos existen 9 registros
totalmente vacíos, por lo que es necesario eliminar estas filas.
unique(colaboradores$genero)
## [1] "MASCULINO" "FEMENINO"
filter(colaboradores, colaboradores$genero=="")
## [1] nombre_completo fecha_nac genero fecha_alta
## [5] puesto departamento sal_diario_imss colonia
## [9] municipio estado CP estado_civil
## <0 rows> (or 0-length row.names)
colaboradores <- colaboradores[-(114:122),]
Puesto
Para puesto hay que estandarizar los registros, específicamente aquellos
que son el mismo puesto pero están escritos diferente.
colaboradores$puesto <- replace(colaboradores$puesto,colaboradores$puesto=="Supervisor de Máquin","SUPERVISOR(A)")
colaboradores$puesto <- replace(colaboradores$puesto,colaboradores$puesto=="Supervisor de pegado","SUPERVISOR(A)")
colaboradores$puesto <- replace(colaboradores$puesto,colaboradores$puesto=="SUPERVISORA","SUPERVISOR(A)")
colaboradores$puesto <- replace(colaboradores$puesto,colaboradores$puesto=="AY. GENERAL","AYUDANTE GENERAL")
colaboradores$puesto <- replace(colaboradores$puesto,colaboradores$puesto=="AYUDANTE DE MANTENIMIENTO","AYUDANTE GENERAL")
colaboradores$puesto <- replace(colaboradores$puesto,colaboradores$puesto=="CHOFER GESTOR","CHOFER")
colaboradores$puesto <- replace(colaboradores$puesto,colaboradores$puesto=="INSPECTOR DE CALIDAD","INSPECTOR(A) DE CALIDAD")
colaboradores$puesto <- replace(colaboradores$puesto,colaboradores$puesto=="INSPECTORA DE CALIDAD","INSPECTOR(A) DE CALIDAD")
colaboradores$puesto <- replace(colaboradores$puesto,colaboradores$puesto=="Mantenimiento FF","MANTENIMIENTO")
colaboradores$puesto <- toupper(colaboradores$puesto)
unique(colaboradores$puesto)
## [1] "SUPERVISOR(A)" "EXTERNO"
## [3] "CUSTOMER SERVICE INF" "COSTURERA"
## [5] "AYUDANTE GENERAL" "GESTOR"
## [7] "CHOFER" "LIDER"
## [9] "MANTENIMIENTO" "RESIDENTE"
## [11] "LIMPIEZA" "INSPECTOR(A) DE CALIDAD"
## [13] "PINTOR" "SOLDADOR"
## [15] "RECIBO" "ENFERMERA"
## [17] "OP. FLEXO-RANURADORA-REFILADORA" "GUARDIA DE SEGURIDAD"
## [19] "MOZO" "OPERADOR SIERRA"
## [21] "MONTACARGUISTA"
Departamento
Para departamento hay que extandarizar los registros que son el mismo
pero escritos diferentes.
unique(colaboradores$departamento)
## [1] "Produccion Cartón MDL" "Externo" "Produccion Cartón MC"
## [4] "Costura" "Cedis" "Producción Retorn"
## [7] "Costura T2" "Embarques" "EHS"
## [10] "Limpieza" "Calidad" "Paileria"
## [13] "Materiales" "COSTURA" ""
## [16] "Rotativa" "Stabilus" "Troquel"
## [19] "Celdas" "Ay.flexo" "CEDIS"
## [22] "CORTADORAS"
colaboradores$departamento <- replace(colaboradores$departamento,colaboradores$departamento=="Produccion Cartón MDL","PRODUCCIÓN CARTON MDL")
colaboradores$departamento <- replace(colaboradores$departamento,colaboradores$departamento=="Produccion Cartón MC","PRODUCCION CARTON MC")
colaboradores$departamento <- replace(colaboradores$departamento,colaboradores$departamento=="Producción Retorn","PRODUCCION RETORNO")
colaboradores$departamento <- replace(colaboradores$departamento,colaboradores$departamento=="Costura T2","COSTURA")
colaboradores$departamento <- toupper(colaboradores$departamento)
Salario diario del IMSS
Para salario diario del IMSS hay que asegurarnos que el formato esté
correcto. Así mismo, hay que corregir los valores atípicos.
options(scipen = 999)
colaboradores$sal_diario_imss <- as.numeric(colaboradores$sal_diario_imss)
unique(colaboradores$sal_diario_imss)
## [1] 176.72 337.05 4413757.00 260.01 240.75
## [6] 152.86 175.79 144.45 279.61 151.67
## [11] 208.65 240.71 1516728571.00 151.61 180.68
## [16] 181.68 184.68 185.68
str(colaboradores$sal_diario_imss)
## num [1:113] 177 177 177 337 4413757 ...
Para corregir los valores atípicos primero hay que identificarlos. Para remplazar su salario, nos basaremos en puestos similares para asignarles uno similar.
filter(colaboradores, colaboradores$sal_diario_imss > 4413750)
## nombre_completo fecha_nac genero fecha_alta
## 1 YOLANDA LOPEZ RAMOS 1965-09-06 FEMENINO 2014-05-05
## 2 JAIME ERNESTO AGUILERA RODRIGUEZ 1969-02-21 MASCULINO 2020-08-08
## puesto departamento sal_diario_imss colonia
## 1 SUPERVISOR(A) COSTURA 4413757 RINCON DE GALICIA
## 2 AYUDANTE GENERAL PRODUCCION RETORNO 1516728571 LOS PUERTOS 2° SECTOR
## municipio estado CP estado_civil
## 1 APODACA Nuevo León 66620 Soltero
## 2 JUAREZ Nuevo León 67267 Casado
Podemos observar que el puesto de Jaime Ernesto es Ayudante general y que está en el departamento de Producción Retorno. Al observar registros con el mismo puesto y departamento, podemos observar que tres colaboradores tienen un salario de 151.61, y el salario equivocado es de 1516728571.00, por lo que podríamos asumir ha sido un error de dedo y el salario correcto es 151.61, por lo que optamos por remplazarlo por este valor.
colaboradores$sal_diario_imss[colaboradores$nombre_completo == "JAIME ERNESTO AGUILERA RODRIGUEZ"] <- 151.61
El segundo salario equivocado es de 4413757.00. y de YOLANDA LOPEZ RAMOS. Ahora hay que identificar puestos similares en el mismo departamento.
filter(colaboradores, departamento == "COSTURA")
## nombre_completo fecha_nac genero fecha_alta
## 1 YOLANDA LOPEZ RAMOS 1965-09-06 FEMENINO 2014-05-05
## 2 ARACELY PERALTA MARTINEZ 1967-07-01 FEMENINO 2015-08-06
## 3 YOLANDA JUDITH LUNA LOPEZ 1985-08-18 FEMENINO 2017-02-20
## 4 MA DEL CARMEN GARCIA CARRIZALES 1978-02-03 FEMENINO 2020-04-07
## 5 ADELAIDA MENDOZA NAVARRO 1979-12-16 FEMENINO 2020-08-26
## 6 BLANCA OLIVIA BARRON RAMOS 1969-06-29 FEMENINO 2020-08-28
## 7 SOLEDAD ENCARNACION CARDENAS OLMOS 1972-01-22 FEMENINO 2021-04-24
## 8 JOSE ALFREDO VAZQUEZ CEPEDA 1963-08-28 MASCULINO 2021-08-12
## 9 MARCIANA NATIVIDAD MARTINEZ 1967-01-04 FEMENINO 2021-12-06
## puesto departamento sal_diario_imss colonia
## 1 SUPERVISOR(A) COSTURA 4413757.00 RINCON DE GALICIA
## 2 COSTURERA COSTURA 260.01 ALAMOS DEL PARQUE
## 3 COSTURERA COSTURA 152.86 C. H. BLAS CHUMACERO C.T.M
## 4 COSTURERA COSTURA 240.71 PUEBLO NUEVO
## 5 COSTURERA COSTURA 176.72 LOS CANDILES
## 6 COSTURERA COSTURA 176.72 PUEBLO NUEVO
## 7 AYUDANTE GENERAL COSTURA 151.61 PORTAL DE VALLE
## 8 COSTURERA COSTURA 176.72 LA ALIANZA SECTOR C
## 9 COSTURERA COSTURA 176.72 LA JOYA
## municipio estado CP estado_civil
## 1 APODACA Nuevo León 66620 Soltero
## 2 APODACA Nuevo León 66633 Casado
## 3 SAN NICOLAS DE LOS G Nuevo León 66473 Casado
## 4 APODACA Nuevo León 66646 Union Libre
## 5 APODACA Nuevo León 66647 CASADA
## 6 APODACA Nuevo León 66646 Casado
## 7 APODACA NUEVO LEON 66643 CASADA
## 8 MONTERREY NUEVO LEON 64103 DIVORCIADO
## 9 GUADALUPE NUEVO LEON 67160 CASADA
En este caso, es el único registro con ese puesto en el departamento, por lo tanto identificaremos puestos similares pero en diversos departamentos.
filter(colaboradores, puesto == "SUPERVISOR(A)")
## nombre_completo fecha_nac genero fecha_alta puesto
## 1 NICOLAS MARTINEZ DE LOERA 1955-09-10 MASCULINO 2010-07-01 SUPERVISOR(A)
## 2 MARIANA DE LEON MORENO 1979-05-14 FEMENINO 2011-07-01 SUPERVISOR(A)
## 3 MARIA CAZARES MORALES 1990-05-01 FEMENINO 2013-01-30 SUPERVISOR(A)
## 4 YOLANDA LOPEZ RAMOS 1965-09-06 FEMENINO 2014-05-05 SUPERVISOR(A)
## departamento sal_diario_imss colonia municipio
## 1 PRODUCCIÓN CARTON MDL 176.72 UNIDAD LABORAL SAN NICOLAS DE LOS G
## 2 PRODUCCIÓN CARTON MDL 176.72 SANTA TERESITA APODACA
## 3 PRODUCCION CARTON MC 337.05 PUEBLO NUEVO APODACA
## 4 COSTURA 4413757.00 RINCON DE GALICIA APODACA
## estado CP estado_civil
## 1 Nuevo León 66440 Soltero
## 2 Nuevo León 66605 Soltero
## 3 Nuevo León 66649 Casado
## 4 Nuevo León 66620 Soltero
Hemos identificado solo un registro más con el mismo puesto, por lo que optaremos por asignar el mismo salario al registro con el salario elevado.
colaboradores$sal_diario_imss[colaboradores$nombre_completo == "YOLANDA LOPEZ RAMOS"] <- 337.05
unique(colaboradores$sal_diario_imss)
## [1] 176.72 337.05 260.01 240.75 152.86 175.79 144.45 279.61 151.67 208.65
## [11] 240.71 151.61 180.68 181.68 184.68 185.68
Municipio
En municipio hay que estandarizar los registros, por ejemplo, cambiar
“SAN NICOLAS DE LOS G” por “SAN NICOLAS DE LOS GARZA”.
unique(colaboradores$municipio)
## [1] "SAN NICOLAS DE LOS G" "APODACA" "SALTILLO"
## [4] "PESQUERIA" "MONTERREY" "GUADALUPE"
## [7] "JUAREZ" "RAMOS ARIZPE" "CAÑADA BLANCA"
colaboradores$municipio <- replace(colaboradores$municipio,colaboradores$municipio=="SAN NICOLAS DE LOS G","SAN NICOLAS DE LOS GARZA")
colaboradores$municipio <- replace(colaboradores$municipio,colaboradores$municipio=="CAÑADA BLANCA","GUADALUPE")
Estado
En estado hay que estandarizar los registros, por ejemplo, cambiar
“Nuevo León” por “NUEVO LEON”.
colaboradores$estado <- replace(colaboradores$estado,colaboradores$estado=="Nuevo León","NUEVO LEON")
colaboradores$estado <- replace(colaboradores$estado,colaboradores$estado=="GUADALUPE N.L.","NUEVO LEON")
colaboradores$estado <- toupper(colaboradores$estado)
unique(colaboradores$estado)
## [1] "NUEVO LEON" "COAHUILA"
Estado Civil
En estado civil también hay que estandarizar los registros.
unique(colaboradores$estado_civil)
## [1] "Soltero" "Casado" "Unión libre" "Union Libre" "CASADA"
## [6] "UNION LIBRE" "CASADO" "SOLTERA" "DIVORCIADO" "SOLTERO"
## [11] "DIVORCIADA"
colaboradores$estado_civil <- toupper(colaboradores$estado_civil)
colaboradores$estado_civil <- replace(colaboradores$estado_civil,colaboradores$estado_civil=="UNIóN LIBRE","UNION LIBRE")
colaboradores$estado_civil <- replace(colaboradores$estado_civil,colaboradores$estado_civil=="SOLTERO","SOLTERO(A)")
colaboradores$estado_civil <- replace(colaboradores$estado_civil,colaboradores$estado_civil=="CASADO","CASADO(A)")
colaboradores$estado_civil <- replace(colaboradores$estado_civil,colaboradores$estado_civil=="CASADA","CASADO(A)")
colaboradores$estado_civil <- replace(colaboradores$estado_civil,colaboradores$estado_civil=="SOLTERA","SOLTERO(A)")
colaboradores$estado_civil <- replace(colaboradores$estado_civil,colaboradores$estado_civil=="DIVORCIADA","DIVORCIADO(A)")
colaboradores$estado_civil <- replace(colaboradores$estado_civil,colaboradores$estado_civil=="DIVORCIADO","DIVORCIADO(A)")
A continuación se presenta una tabla de estadísticos descriptivos para cada una de las bases de datos y sus respectivos comentarios.
En merma como fecha y mes son datos cualitativos no contienen información descriptiva, sin embargo la variable de kilos si. A continuación podemos identificar que tiene skewness negativo, cercano a -1.
ed_merma <- describe(merma)
ed_merma
## vars n mean sd median trimmed mad min max range skew
## fecha 1 50 NaN NA NA NaN NA Inf -Inf -Inf NA
## mes* 2 50 4.60 2.60 4 4.53 2.97 1 9 8 0.21
## kilos 3 50 3708.52 1023.99 3925 3798.65 541.15 790 6140 5350 -0.94
## kurtosis se
## fecha NA NA
## mes* -1.35 0.37
## kilos 1.65 144.81
hist(merma$kilos)
En Scrap referencia, fecha producto y ubicación de origen son más que nada cualitativas por lo que no tenemos sus datos descriptivos, sin embargo en cantidad sí, a continuación pdoemos encontrar su media, mediana, desviación, estandar y también su distribución, pues tiene skewness positiva alta, indicandonos que en caso de datos faltantes seria mejor remplazar con la mediana que con la media.
ed_scrap <- describe(scrap)
ed_scrap
## vars n mean sd median trimmed mad min max range skew
## referencia* 1 250 125.50 72.31 125.5 125.50 92.66 1 250 249 0.00
## fecha 2 250 NaN NA NA NaN NA Inf -Inf -Inf NA
## producto* 3 250 44.38 24.72 45.0 44.12 25.95 1 95 94 0.01
## cantidad 4 250 6.69 11.85 2.0 3.88 1.48 0 96 96 4.12
## ubi_origen* 5 250 2.48 0.85 3.0 2.60 0.00 1 3 2 -1.10
## kurtosis se
## referencia* -1.21 4.57
## fecha NA NA
## producto* -0.79 1.56
## cantidad 21.13 0.75
## ubi_origen* -0.70 0.05
hist(scrap$cantidad)
En producción de carton tenemos los datos descriptivos principalmente de pizas programas, laminas procesadas, tiempo de calidad y tmo_min. EN todas estas ademas de encontrar su media, mediana y desviación estandar podemos identificar su skewness positiva de nuevo indicando su distribución y como en caso de valores faltantes es mejor remplazar con la mediana.
ed_carton <- describe(carton)
ed_carton
## vars n mean sd median trimmed mad min max
## fecha 1 1486 NaN NA NA NaN NA Inf -Inf
## cliente* 2 1486 6.03 2.39 6.0 5.95 1.48 1 11
## piezas_prog 3 1486 169.96 127.90 184.0 153.67 124.54 1 1500
## tmo_min 4 1477 22.39 13.78 20.0 20.03 7.41 10 120
## hr_fin 5 1469 32241.73 11925.66 36000.0 33834.65 6226.92 3600 46500
## lam_procesadas 6 1486 153.70 141.65 105.5 131.81 130.47 1 1262
## inicio_sep_up 7 1486 30172.53 12770.81 34200.0 31263.53 10007.55 2280 46560
## fin_sep_up 8 1486 30107.00 13005.13 34380.0 31125.18 10585.76 3600 69300
## inicio_proceso 9 1486 29999.27 13061.85 34350.0 31016.22 10585.76 2100 57840
## fin_proceso 10 1486 29503.16 13563.70 34800.0 30462.55 11653.24 2100 57360
## tiempo_calidad 11 1431 1.29 1.50 1.0 1.00 0.00 0 25
## range skew kurtosis se
## fecha -Inf NA NA NA
## cliente* 10 0.34 0.48 0.06
## piezas_prog 1499 1.97 9.97 3.32
## tmo_min 110 2.68 11.01 0.36
## hr_fin 42900 -1.18 0.08 311.15
## lam_procesadas 1261 2.24 9.66 3.67
## inicio_sep_up 44280 -0.75 -0.85 331.29
## fin_sep_up 65700 -0.68 -0.91 337.37
## inicio_proceso 55740 -0.68 -0.97 338.84
## fin_proceso 55260 -0.59 -1.17 351.86
## tiempo_calidad 25 9.21 107.84 0.04
hist(carton$piezas_prog)
hist(carton$lam_procesadas)
hist(carton$tiempo_calidad)
hist(carton$tmo_min)
Para Delivery performance podemos encontrar a continuación sus datos descriptivos, sin embargo hay algunos que no tomamos mucho en consideración por ejemplo, la fecha, vuelta o cliente, y por otro lado tenemos plan arrival, real arrival y real departure que son horas en teoria y difference que es la diferencia en minutos.
ed_perf <- describe(perf)
ed_perf
## vars n mean sd median trimmed mad min max range skew
## cliente* 1 800 1.12 0.32 1.00 1.02 0.00 1.00 2.0 1.00 2.35
## vueltas 2 800 1.91 0.83 2.00 1.89 1.48 1.00 3.0 2.00 0.16
## fecha 3 800 NaN NA NA NaN NA Inf -Inf -Inf NA
## plan_arrival 4 800 19.52 1.29 20.00 19.91 0.00 16.00 20.0 4.00 -2.35
## real_arrival 5 800 12.84 5.21 9.09 12.52 1.62 6.00 23.5 17.50 0.47
## real_departure 6 800 13.88 5.26 10.15 13.57 1.70 6.40 24.5 18.10 0.45
## difference 7 800 1.03 0.83 1.00 1.03 0.03 -14.35 4.4 18.75 -12.42
## kurtosis se
## cliente* 3.54 0.01
## vueltas -1.53 0.03
## fecha NA NA
## plan_arrival 3.54 0.05
## real_arrival -1.58 0.18
## real_departure -1.61 0.19
## difference 220.30 0.03
Con delivery plan muchas de las variables son horas o cualitativas, sin embargo tenemos la variable de unidades, la cual, al igual que en bases anteriores tiene una distribución con skew positiva y alta, por lo que en caso de valores faltantes nos convendría mas remplazar con la mediana que con la media.
ed_plan <- describe(plan)
ed_plan
## vars n mean sd median trimmed mad min max range skew
## cliente* 1 972 17.71 6.87 21.0 18.52 2.97 1 26 25 -1.15
## proyecto* 2 972 46.03 26.24 58.0 46.50 14.83 1 103 102 -0.47
## item* 3 972 100.68 54.76 108.0 101.17 59.30 1 201 200 -0.20
## mes* 4 972 10.05 5.66 10.0 10.01 5.93 1 20 19 -0.03
## unidades 5 972 548.07 2016.47 90.5 176.34 116.38 1 29379 29378 8.56
## kurtosis se
## cliente* -0.19 0.22
## proyecto* -0.49 0.84
## item* -1.12 1.76
## mes* -1.10 0.18
## unidades 89.82 64.68
hist(plan$unidades)
En bajas muchas de las variables son cualitativas por lo que carecen de estadisticos descriptivos, sin embargo, tenemos otra como el salario diario, el cual tiene una distribución con skewness positivo también.
ed_bajas <- describe(bajas)
ed_bajas
## vars n mean sd median trimmed mad min max
## nombre_completo* 1 238 117.54 67.76 116.50 117.43 86.73 1.00 235
## fecha_nac 2 237 NaN NA NA NaN NA Inf -Inf
## genero* 3 238 1.41 0.49 1.00 1.39 0.00 1.00 2
## fecha_alta 4 237 NaN NA NA NaN NA Inf -Inf
## mot_baja* 5 213 2.50 1.28 2.00 2.46 1.48 1.00 5
## permanencia 6 213 79.71 224.98 19.00 31.18 19.27 0.00 1966
## baja* 7 238 46.84 28.59 49.00 47.07 35.58 1.00 96
## puesto* 8 238 6.03 4.93 4.00 4.66 0.00 1.00 22
## departamento* 9 238 10.11 8.11 9.00 9.97 11.86 1.00 21
## sal_diario_imss 10 238 177.99 23.16 180.68 179.16 0.00 144.45 500
## colonia* 11 238 58.43 27.09 73.00 60.30 25.20 1.00 99
## CP* 12 238 26.08 8.66 26.00 26.52 2.97 1.00 48
## municipio* 13 238 3.74 2.77 2.00 3.28 0.00 1.00 13
## estado* 14 238 2.97 0.20 3.00 3.00 0.00 1.00 3
## estado_civil* 15 238 3.66 1.16 4.00 3.72 1.48 1.00 5
## range skew kurtosis se
## nombre_completo* 234.00 0.01 -1.21 4.39
## fecha_nac -Inf NA NA NA
## genero* 1.00 0.36 -1.88 0.03
## fecha_alta -Inf NA NA NA
## mot_baja* 4.00 0.33 -1.39 0.09
## permanencia 1966.00 5.65 35.86 15.42
## baja* 95.00 -0.04 -1.24 1.85
## puesto* 21.00 2.33 4.09 0.32
## departamento* 20.00 0.08 -1.72 0.53
## sal_diario_imss 355.55 11.09 154.20 1.50
## colonia* 98.00 -0.63 -0.88 1.76
## CP* 47.00 -0.52 1.75 0.56
## municipio* 12.00 1.22 0.12 0.18
## estado* 2.00 -8.56 75.40 0.01
## estado_civil* 4.00 -0.55 -1.07 0.08
hist(bajas$sal_diario_imss)
El caso de la base de datos de colaboradores es muy similar al de bajas.
ed_colaboradores <- describe(colaboradores)
ed_colaboradores
## vars n mean sd median trimmed mad min
## nombre_completo* 1 113 57.00 32.76 57.00 57.00 41.51 1.00
## fecha_nac 2 112 NaN NA NA NaN NA Inf
## genero* 3 113 1.46 0.50 1.00 1.45 0.00 1.00
## fecha_alta 4 112 NaN NA NA NaN NA Inf
## puesto* 5 113 4.85 6.64 1.00 3.46 0.00 1.00
## departamento* 6 113 7.73 6.53 7.00 7.25 8.90 1.00
## sal_diario_imss 7 113 180.25 28.60 180.68 176.77 0.00 144.45
## colonia* 8 113 39.42 19.75 47.00 40.07 19.27 1.00
## municipio* 9 113 2.23 1.97 1.00 1.82 0.00 1.00
## estado* 10 113 1.92 0.27 2.00 2.00 0.00 1.00
## CP 11 113 63364.74 11201.89 66646.00 66622.84 4.45 25016.00
## estado_civil* 12 113 2.37 1.17 3.00 2.34 1.48 1.00
## max range skew kurtosis se
## nombre_completo* 113.00 112.0 0.00 -1.23 3.08
## fecha_nac -Inf -Inf NA NA NA
## genero* 2.00 1.0 0.16 -1.99 0.05
## fecha_alta -Inf -Inf NA NA NA
## puesto* 21.00 20.0 1.52 0.67 0.62
## departamento* 19.00 18.0 0.36 -1.47 0.61
## sal_diario_imss 337.05 192.6 3.45 15.39 2.69
## colonia* 73.00 72.0 -0.38 -0.99 1.86
## municipio* 8.00 7.0 1.42 0.74 0.19
## estado* 2.00 1.0 -3.06 7.45 0.03
## CP 67493.00 42477.0 -3.06 7.42 1053.79
## estado_civil* 4.00 3.0 -0.09 -1.59 0.11
hist(colaboradores$sal_diario_imss)
Para merma, nos interesa saber el total de kilos que se producen por mes. Para gráficar el total de kilos de merma por mes primero es necesario obtener la cantidad total de kilos por mes, eso lo hacemos de la siguiente manera.
merma_mes<-aggregate(kilos ~ mes, data = merma, sum) %>% arrange(desc(kilos))
merma_mes
## mes kilos
## 1 AGOSTO 32100
## 2 MAYO 23410
## 3 FEBRERO 22830
## 4 MARZO 22470
## 5 JULIO 19370
## 6 ABRIL 18820
## 7 JUNIO 18280
## 8 ENERO 14560
## 9 SEPTIEMBRE 13586
Una vez que ya tenemos el total por mes podemos graficarlo.
ggplot(merma_mes,aes(x= reorder(mes, -kilos),y=kilos, fill=mes))+
geom_bar(stat="identity")+labs(x="Mes", y="Kilos")+
theme_minimal()+
labs(title="Kilos de merma por mes")+theme(axis.text.x = element_text(angle=65, hjust=1))
### Scrap Para Scrap hemos optado por visualizar un gráfico de barras de
la cantidad y la ubicación de origen.
ggplot(scrap,aes(x= reorder(ubi_origen, -cantidad),y=cantidad, fill=ubi_origen))+
geom_bar(stat="identity")+labs(x="Ubicación de origen", y="Cantidad")+
theme_minimal()+
labs(title="Cantidad por ubicación de origen")+theme(axis.text.x = element_text(angle=65, hjust=1))
La base de datos de producción de cartón solo abarca de los meses de julio a septiembre del 2022, la base de datos de merma incluye más meses pero del mismo año. Hemos graficado la cantidad de piezas programadas por mes en producción de cartón para confirmar si el mes con mayor cantidad de piezas programadas también es el mes con mayor cantidad de kilos de merma.
carton_mes <- carton %>% mutate(mes=format(fecha, "%m"))
carton_mes2<-aggregate(piezas_prog ~ mes, data = carton_mes, sum) %>% arrange(desc(piezas_prog))
ggplot(carton_mes2,aes(x= reorder(mes, -piezas_prog),y=piezas_prog, fill=mes))+
geom_bar(stat="identity")+labs(x="Mes", y="Piezas programadas")+
theme_minimal()+
labs(title="Piezas programadas por mes")+theme(axis.text.x = element_text(angle=65, hjust=1))
Al observar el gráfico de barras podemos confirmar que efectivamente el
mes de agosto, el mes donde más piezas programadas para producción hubo
también fue el mes con mayor cantidad de merma.
Para delivery performance optamos por graficar el retraso que hubo entre el tiempo planeado de llegada con el cliente y el tiempo real. Nos dimos cuenta que el formato de hora variaba de 24 horas a 12 horas por lo que hicimos el cambio para que este correcto. Como podemos ver MAHLE tiene un delay mayor al de PRINTEL.
class(perf$real_arrival)
perf2 <- perf
perf3 <- perf2 %>% mutate(plan_arrival=ifelse(cliente == "MAHLE"| plan_arrival == 20 | real_arrival < 15, 8, plan_arrival))
perf3 <- mutate(perf3, delay=real_arrival-plan_arrival)
perf3 <- aggregate(delay~cliente, data=perf3, mean)
ggplot(perf3,aes(x= cliente,y=delay, fill=cliente))+
geom_bar(stat="identity")+labs(x="Clientes", y="Delay en min")+
theme_minimal()+
labs(title="Delay por cliente")+theme(axis.text.x = element_text(angle=65, hjust=1))
Con Delivery Plan queremos evaluar si el mes donde mayor cantidad de piezas programadas había también era el mes donde mayor producción hubo.
plan_mes<-aggregate(unidades ~ mes, data = plan, sum) %>% arrange(desc(unidades))
ggplot(plan_mes,aes(x= reorder(mes, -unidades),y=unidades, fill=mes))+
geom_bar(stat="identity")+labs(x="Mes", y="Unidades programadas")+
theme_minimal()+
labs(title="Unidades programadas por mes")+theme(axis.text.x = element_text(angle=65, hjust=1))
Al observar el gráfico de barras podemos identificar que el mes en el
que más piezas programadas hubo no fue el mes con mayor producción y
merma.
En esta gráfica de barras se pude observar que el principal motivo de las bajas son las faltas seguidamente de renuncias voluntarias. Es importante mencionar que las personas fueron dadas de bajas a pesar de tener solo una falta, por lo que no se puede realizar un buen diagnóstico sobre las bajas por faltas.
mot_baja <- bajas %>% group_by(mot_baja, genero) %>% tally()
mot_baja
## # A tibble: 11 x 3
## # Groups: mot_baja [6]
## mot_baja genero n
## <chr> <chr> <int>
## 1 ABANDONO FEMENINO 30
## 2 ABANDONO MASCULINO 25
## 3 BAJA POR FALTAS FEMENINO 56
## 4 BAJA POR FALTAS MASCULINO 24
## 5 JUBILACION MASCULINO 1
## 6 RENUNCIA VOLUNTARIA FEMENINO 37
## 7 RENUNCIA VOLUNTARIA MASCULINO 33
## 8 TERMINO DE CONTRATO FEMENINO 6
## 9 TERMINO DE CONTRATO MASCULINO 1
## 10 <NA> FEMENINO 11
## 11 <NA> MASCULINO 14
ggplot(data=mot_baja, aes(x=mot_baja, y=n, fill=genero)) +
geom_bar(stat="identity", position=position_dodge())+theme(axis.text.x = element_text(angle=65, hjust=1))
En esta gráfica de barras podemos observar el sueldo promedio por
puesto y género. Una observación importante es en el puesto de
supervisor/supervisora, ya que las mujeres tienen mayor salario que los
hombres a pesar de realizar el mismo trabajo. Otro puesto en donde la
situación es similar pero el salario no es de mucha diferencia es en el
puesto de costurera/costurero.
Al observar esta gráfica podemos decir que las mujeres ganan más, ya que
a pesar de que realicen el mismo trabajo las mujeres reciben un mayor
sueldo que los hombres.
sueldo_genero_puesto<-aggregate(sal_diario_imss ~ puesto+genero, data = colaboradores, mean)
ggplot(data=sueldo_genero_puesto, aes(x=puesto, y=sal_diario_imss, fill=genero)) +
geom_bar(stat="identity", position=position_dodge())+theme(axis.text.x = element_text(angle=65, hjust=1))
En esta gráfica de boxplot podemos observar la dispersión de kilos de merma por mes. Agosto es el mes con mayor dispersión,por lo que podemos inferir que en este mes es donde hay mayor producción.
ggplot(merma, aes(x=mes, y=kilos)) +
geom_boxplot(color="red", fill="orange", alpha=0.2)
En esta gráfica de boxplot podemos observar la desperation de cantidad de scrap por ubicación de origen. Como se puede observar dónde hay mayor dispersión de scrap es en pre-producción y esto se puede deber a que la empresa utiliza más materiales en esta área de trabajo.
ggplot(scrap, aes(x=ubi_origen, y=cantidad)) +
geom_boxplot(color="red", fill="orange", alpha=0.2)
En esta gráfica podemos observar la dispersión de tiempo de calidad
por cliente de producción de cartón. Existen diferentes motivos por lo
cual se tome mayor tiempo de calidad a ciertos clientes esto puede ser
por:
- cantidad de piezas
- cliente frecuente
- empaque complicado
ggplot(carton, aes(x=cliente, y=tiempo_calidad)) +
geom_boxplot(color="red", fill="orange", alpha=0.2)+theme(axis.text.x = element_text(angle=65, hjust=1))
## Warning: Removed 55 rows containing non-finite values (stat_boxplot).
Al graficar la dispersión de la diferencia entre real arrival y departure arrival vemos que hay mayor variacion en el cliente MAHLE que en PRINTEL.
ggplot(perf, aes(x=cliente, y=difference)) +
geom_boxplot(color="red", fill="orange", alpha=0.2)+theme(axis.text.x = element_text(angle=65, hjust=1))
El boxplot a continuación muestra la dispersión de las unidades programadas por cliente, como podemos ver Hella y TRMX tienen mayor cantidad de unidades programadas y es más dispersa su distribución.
ggplot(plan, aes(x=cliente, y=unidades)) +
geom_boxplot(color="red", fill="orange", alpha=0.2)+theme(axis.text.x = element_text(angle=65, hjust=1))
El siguiente es un boxplot de la permanencia en la empresa en las bajas por genero, por lo general las mujeres duran más en la empresa.
ggplot(bajas, aes(x=genero, y=permanencia)) +
geom_boxplot(color="red", fill="orange", alpha=0.2)+theme(axis.text.x = element_text(angle=65, hjust=1))
## Warning: Removed 25 rows containing non-finite values (stat_boxplot).
Este boxplot muestra la dispersión que hay en el salario diario que reciben los colaboradores por género, la dispersión en mayor en el género femenino, hay mujeres que ganan considerablemente más que los hombres.
ggplot(colaboradores, aes(x=genero, y=sal_diario_imss)) +
geom_boxplot(color="red", fill="orange", alpha=0.2)+theme(axis.text.x = element_text(angle=65, hjust=1))
En el siguiente plot podemos identificar la fecha en la que hubo mayor kilos de merma. A mediados de febrero hubo una gran cantidad de merma, específicamente el 18 de febrero. Podemos observar también que después de cada pico de merma, hay una corrección y la merma disminuye. Esto podría ser por diversos factores como ajustes en la producción, en los cortes, entre otros.
merma_fecha<-aggregate(kilos ~ fecha, data = merma, sum)
ggplot(merma_fecha,aes(x=fecha,y=kilos))+
geom_line()+
labs(title="Kilos por fecha")+ theme(axis.text.x = element_text(angle=65, hjust=1))
Para la producción de cartón vamos a graficar el tiempo en minutos que tomó el proceso. Para esto necesitamos restar el tiempo de inicio de proceso al de fin de proceso.
carton2<-mutate(carton, tiempo_proceso = fin_proceso-inicio_proceso)
carton2 <- filter(carton2, !tiempo_proceso < 0)
Asi mismo, vamos a sacar el promedio de tiempo que toma el proceso por cliente. De esta forma podremos saber cual cliente consume mas tiempo de produccion de Form en el mes de agosto.
prod_cliente<-aggregate(tiempo_proceso ~ cliente, data=carton2, mean)
prod_cliente
## cliente tiempo_proceso
## 1 DENSO 00:20:08
## 2 HANON SYSTEMS 01:23:30
## 3 HELLA 00:12:00
## 4 MERIDIAN LIGHTWEIGHT 00:18:56
## 5 STABILUS 1 00:20:34
## 6 STABILUS 3 00:19:00
## 7 TRMX 00:17:11
## 8 VARROC 00:28:45
## 9 VL-017-13939 00:27:40
## 10 VL-017-14086 00:27:00
## 11 YANFENG 00:32:25
ggplot(prod_cliente,aes(x=cliente,y=tiempo_proceso))+
geom_point()+
labs(title="Tiempo promedio por cliente")+ theme(axis.text.x = element_text(angle=90, hjust=1))
## Don't know how to automatically pick scale for object of type ITime. Defaulting to continuous.
Como podemos ver Hanon Systems, Yen Fang y Varroc son los clientes que
mayor tiempo toma su proceso de producción. Esto puede ser debido a la
complejidad de sus productos o material, sin embargo, hay que prestar
especial atención a la gran diferencia que hay entre Hanon Systems y el
resto de clientes.
En Delivery Plan podemos observar la cantidad de unidades por mes por cliente. Podemos identificar que HELLA en la gran mayoría de las fechas es el cliente con mayor cantidad de unidades planeadas, rara vez es superado por TRMX.
plan_mesycliente <- aggregate(unidades ~ cliente+mes, data=plan, sum)
plan_mesycliente <- plan_mesycliente %>% pivot_wider(names_from = cliente, values_from = unidades)
plan_mesycliente <- dplyr::select(plan_mesycliente, c(mes,"HELLA", "TRMX", "VARROC", "DENSO"))
ggplot(plan_mesycliente, aes(x=mes)) +
geom_point(aes(y = HELLA), color = "darkred") +
geom_point(aes(y = TRMX), color="steelblue", linetype="twodash")+
geom_point(aes(y = VARROC), color = "darkgreen") +
geom_point(aes(y = DENSO), color="darkorange", linetype="twodash")+ theme(axis.text.x = element_text(angle=90, hjust=1))
En estos gráficos de barras podemos identificar los meses donde más bajas hay y donde más ingresos hay, identificando patrones. En las bajas, la mayor cantidad ocurren al inicio del año y posteriormente a mediados pero casi nunca a finales de año. Esto podría deberse a que los colaboradores no quieren estar sin trabajo en fechas donde sus gastos pueden ser mayores como navidad, año nuevo, cierre e inicio de ciclos escolares, entre otros.
En el caso de los ingresos o altas, estas se dan más a mediados de año, muy probablemente FORM haga esto para cubrir las bajas que ocurrieron a inicios y mediados de año. De igual forma, las altas son muy bajas a finales de año, quizás podría deberse a que en estas fechas FORM está cerrando el año, preparando aguinaldos, entre otros costos que tiene por lo que prefiere no contratar nuevos empleados.
bajas$baja <- as.Date(bajas$baja, format ="%d/%m/%Y")
bajas_mes <- bajas %>% mutate(mes_baja=format(baja, "%m"))
bajas_mes <- bajas_mes %>% mutate(mes_alta=format(fecha_alta,"%m"))
bajas_por_mes <- bajas_mes %>% group_by(mes_baja) %>% tally()
altas_por_mes <- bajas_mes %>% group_by(mes_alta) %>% tally()
ggplot(bajas_por_mes,aes(x= reorder(mes_baja,-n),y=n, fill=mes_baja))+
geom_bar(stat="identity")+labs(x="Mes", y="Bajas")+
theme_minimal()+
labs(title="Bajas por mes")+theme(axis.text.x = element_text(angle=65, hjust=1))
ggplot(altas_por_mes,aes(x= reorder(mes_alta,-n),y=n, fill=mes_alta))+
geom_bar(stat="identity")+labs(x="Mes", y="Bajas")+
theme_minimal()+
labs(title="Altas por mes")+theme(axis.text.x = element_text(angle=65, hjust=1))
Graficamos antiguedad por puesto y podemos identificar que los hombres tienen mayor antiguedad en form que las mujeres, además que los unicos puestos donde hay hombres y mujeres son en supervisor(a) y costurera(o). Así mismo que los puestos hay más para hombres que para muejeres.
colaboradores <- mutate(colaboradores, antiguedad=today()-fecha_alta)
antiguedad_puesto <- aggregate(antiguedad ~ puesto+genero, data=colaboradores, mean)
ggplot(data=antiguedad_puesto, aes(x=puesto, y=antiguedad, fill=genero)) +
geom_bar(stat="identity", position=position_dodge())+theme(axis.text.x = element_text(angle=65, hjust=1))
## Don't know how to automatically pick scale for object of type difftime. Defaulting to continuous.
Tenemos las ventas internacionales de autopartes por estado de la república mexicana. Nuestro proosito es encontrar el estado con mayor futuro y volumen de ventas internacionales de autopartes.
ventasi_autopartes <- read.csv("VentasAP.csv")
summary(ventasi_autopartes)
## year id_trimestre trimestre id_estado
## Min. :2014 Min. :20141 Min. :1.000 Min. : 1.00
## 1st Qu.:2016 1st Qu.:20161 1st Qu.:1.000 1st Qu.:10.00
## Median :2018 Median :20181 Median :2.000 Median :17.00
## Mean :2018 Mean :20180 Mean :2.399 Mean :17.37
## 3rd Qu.:2020 3rd Qu.:20201 3rd Qu.:3.000 3rd Qu.:26.00
## Max. :2022 Max. :20222 Max. :4.000 Max. :32.00
## estado id_estado_and_id_trimestre idnueva
## Length:690 Min. : 120141 Length:690
## Class :character 1st Qu.:1020152 Class :character
## Mode :character Median :1720178 Mode :character
## Mean :1756991
## 3rd Qu.:2620172
## Max. :3220222
## ventas_autopartes_trimestre ventas_autopartes_anual eci
## Min. : 10839 Min. : 4382 Min. :-0.9374
## 1st Qu.: 88046463 1st Qu.: 22559574 1st Qu.:-0.4630
## Median : 897579256 Median : 231613702 Median : 0.7088
## Mean :1237565052 Mean : 330709701 Mean : 0.4391
## 3rd Qu.:2151422249 3rd Qu.: 575938509 3rd Qu.: 0.9138
## Max. :4205866546 Max. :1467265578 Max. : 1.7810
## poblacion_ocupada_ensambladora_year exportaciones_anual
## Length:690 Length:690
## Class :character Class :character
## Mode :character Mode :character
##
##
##
## exportaciones_trimestrales iedanual_porestado
## Length:690 Length:690
## Class :character Class :character
## Mode :character Mode :character
##
##
##
En excel realizamos limpieza de datos con: nombres_de_variables, añadir cifrias anuales y unir bases de datos. Esto con la finalidad de realizar una predicción sobre los Estados de la República con el mayor número de ventas internacionales de autopartes en México.
En R, la limpieza que realizaremos será: eliminar registros de los trimestres 2, 3 y 4. Usamos como base el trimestre 1 para juntar las cifras anuales y no repetir registros.
#Filtrar por trimestre
vap_1 <- ventasi_autopartes
vap_1 <- filter(vap_1, trimestre == 1)
vap_1
#Eliminar columnas
vap_2 <- vap_1
vap_2 <- subset(vap_2,select = -c(id_trimestre, trimestre, id_estado, id_estado_and_id_trimestre, idnueva, ventas_autopartes_trimestre, exportaciones_trimestrales))
summary(vap_2)
## year estado ventas_autopartes_anual eci
## Min. :2014 Length:186 Min. : 7241 Min. :-0.9374
## 1st Qu.:2016 Class :character 1st Qu.: 23444726 1st Qu.:-0.4143
## Median :2018 Mode :character Median : 231380284 Median : 0.7088
## Mean :2018 Mean : 330227591 Mean : 0.4587
## 3rd Qu.:2020 3rd Qu.: 557443513 3rd Qu.: 0.9138
## Max. :2022 Max. :1299710425 Max. : 1.7810
## poblacion_ocupada_ensambladora_year exportaciones_anual iedanual_porestado
## Length:186 Length:186 Length:186
## Class :character Class :character Class :character
## Mode :character Mode :character Mode :character
##
##
##
#Cambiar tipos de variable
vap_3 <- vap_2
vap_3$ventas_autopartes_anual <- as.numeric(vap_3$ventas_autopartes_anual)
vap_3$eci <- as.numeric(vap_3$eci)
vap_3$poblacion_ocupada_ensambladora_year <- as.numeric(vap_3$poblacion_ocupada_ensambladora_year)
## Warning: NAs introducidos por coerción
vap_3$exportaciones_anual <- as.numeric(vap_3$exportaciones_anual)
## Warning: NAs introducidos por coerción
vap_3$iedanual_porestado <- as.numeric(vap_3$iedanual_porestado)
## Warning: NAs introducidos por coerción
vap_3$year <- as.numeric(vap_3$year)
vap_3$estado <- as.character(vap_3$estado)
vap_3
vap_4 <- vap_3
vap_4 <- vap_4 %>%
group_by(estado) %>%
summarise(ventas = sum(ventas_autopartes_anual))
vap_4
vap_7 <- vap_3
top_5 <- vap_4 %>%
filter(rank(desc(ventas))<=5)
top_5
Encontrar el top 5 de los estados con mayor numero de ventas internacionales de autopartes y enfocarnos en ellos.
#Eliminar registros de estados no relevantes
nueva <- vap_3
nueva <- filter(nueva, !estado=="Durango")
nueva <- filter(nueva, !estado=="Hidalgo")
nueva <- filter(nueva, !estado=="Jalisco")
nueva <- filter(nueva, !estado=="Estado de Mexico")
nueva <- filter(nueva, !estado=="Morelos")
nueva <- filter(nueva, !estado=="Hidalgo")
nueva <- filter(nueva, !estado=="Quintana Roo")
nueva <- filter(nueva, !estado=="Sonora")
nueva <- filter(nueva, !estado=="Zacatecas")
nueva <- filter(nueva, !estado=="Yucatan")
nueva <- filter(nueva, !estado=="Tlaxcala")
nueva <- filter(nueva, !estado=="Veracruz de Ignacio de la Llave")
nueva <- filter(nueva, !estado=="Colima")
nueva <- filter(nueva, !estado=="Baja California")
nueva <- filter(nueva, !estado=="Chihuaua")
nueva <- filter(nueva, !estado=="Puebla")
nueva <- filter(nueva, !estado=="Aguascalientes")
nueva <- filter(nueva, !estado=="San Luis Potosi")
nueva <- filter(nueva, !estado=="Tamaulipas")
nueva <- filter(nueva, !estado=="Chihuahua")
nueva <- filter(nueva, !estado=="Ciudad de Mexico")
unique(nueva$estado)
Eliminamos tambien a Ciudad de Mexico debido a que es un mercado fuera del que busca FORM.
top_4 <- nueva
top_4
Realizaremos un modelo de regresion lineal para los estados de Coahuila, Guanajuato, Nuevo Leon y Queretaro. Esto nos permitirá evaluar el rumbo de los estados con más ventas internacionales de autopartes.
model1<-lm(ventas_autopartes_anual~eci+poblacion_ocupada_ensambladora_year+exportaciones_anual+iedanual_porestado,data=top_4)
summary(model1)
##
## Call:
## lm(formula = ventas_autopartes_anual ~ eci + poblacion_ocupada_ensambladora_year +
## exportaciones_anual + iedanual_porestado, data = top_4)
##
## Residuals:
## Min 1Q Median 3Q Max
## -200117593 -102191916 11993893 81461056 160068056
##
## Coefficients:
## Estimate Std. Error t value
## (Intercept) 951429657.032634 92629981.493389 10.271
## eci -94939113.056243 56316538.389027 -1.686
## poblacion_ocupada_ensambladora_year -524.951185 3436.193733 -0.153
## exportaciones_anual 0.003336 0.003346 0.997
## iedanual_porestado -0.127185 0.038684 -3.288
## Pr(>|t|)
## (Intercept) 0.0000000000797 ***
## eci 0.10336
## poblacion_ocupada_ensambladora_year 0.87971
## exportaciones_anual 0.32759
## iedanual_porestado 0.00281 **
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
##
## Residual standard error: 114700000 on 27 degrees of freedom
## (4 observations deleted due to missingness)
## Multiple R-squared: 0.4733, Adjusted R-squared: 0.3953
## F-statistic: 6.065 on 4 and 27 DF, p-value: 0.001288
Podemos identificar las variables a utilizar dentro del modelo.
ventas_autopartes_anual: es la variable dependiente que nos ayudará a responder la pregunta principal sobre las ventas por estado.
eci: variable exploratoria para comparar los estados con mayores niveles de ingresos, potencial de crecimiento económico, menor desigualdad de ingresos y menores emisiones.
poblacion_ocupada_ensambladora_year: variable exploratoria que se refiere a las personas dentro del estado que trabajan dierectamente dentro de la industria de autopartes en el respecivo año.
exportaciones_anual: variable exploratoria que se refiere a el número de exportaciones anuales del estado en todas las industrias.
iedanual_porestadol: variable explanatoria que se refiere a la inversion extranjera directa anual del estado, no necesariamente enfocada en la industria automotriz.
model1coahuila<-lm(ventas_autopartes_anual~eci+poblacion_ocupada_ensambladora_year+exportaciones_anual+iedanual_porestado,data=coahuila)
summary(model1coahuila)
##
## Call:
## lm(formula = ventas_autopartes_anual ~ eci + poblacion_ocupada_ensambladora_year +
## exportaciones_anual + iedanual_porestado, data = coahuila)
##
## Residuals:
## 1 2 3 4 5 6 7
## -112098108 -21573011 68781706 17705699 66916376 -25757932 -54147456
## 8
## 60172727
##
## Coefficients: (1 not defined because of singularities)
## Estimate Std. Error t value
## (Intercept) 480278614.114136 431472506.467605 1.113
## eci NA NA NA
## poblacion_ocupada_ensambladora_year 8150.653336 5472.637197 1.489
## exportaciones_anual 0.008748 0.010996 0.796
## iedanual_porestado -0.123249 0.099760 -1.235
## Pr(>|t|)
## (Intercept) 0.328
## eci NA
## poblacion_ocupada_ensambladora_year 0.211
## exportaciones_anual 0.471
## iedanual_porestado 0.284
##
## Residual standard error: 86270000 on 4 degrees of freedom
## (1 observation deleted due to missingness)
## Multiple R-squared: 0.7555, Adjusted R-squared: 0.5722
## F-statistic: 4.12 on 3 and 4 DF, p-value: 0.1025
Coahuila: Adjusted R-squared: 0.5317
model1nuevoleon<-lm(ventas_autopartes_anual~eci+poblacion_ocupada_ensambladora_year+exportaciones_anual+iedanual_porestado,data=nuevoleon)
summary(model1nuevoleon)
##
## Call:
## lm(formula = ventas_autopartes_anual ~ eci + poblacion_ocupada_ensambladora_year +
## exportaciones_anual + iedanual_porestado, data = nuevoleon)
##
## Residuals:
## 1 2 3 4 5 6 7 8
## -27425247 45082342 13143113 34080604 -16783601 -23023827 1501825 -26575210
##
## Coefficients: (1 not defined because of singularities)
## Estimate Std. Error t value
## (Intercept) 994959864.548289 157202606.167140 6.329
## eci NA NA NA
## poblacion_ocupada_ensambladora_year 6949.747308 3018.173156 2.303
## exportaciones_anual -0.015302 0.004382 -3.492
## iedanual_porestado -0.042347 0.023390 -1.810
## Pr(>|t|)
## (Intercept) 0.00319 **
## eci NA
## poblacion_ocupada_ensambladora_year 0.08270 .
## exportaciones_anual 0.02508 *
## iedanual_porestado 0.14447
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
##
## Residual standard error: 37550000 on 4 degrees of freedom
## (1 observation deleted due to missingness)
## Multiple R-squared: 0.7897, Adjusted R-squared: 0.6321
## F-statistic: 5.008 on 3 and 4 DF, p-value: 0.07683
Nuevo Leon: Adjusted R-squared: 0.8242
model1guanajuato<-lm(ventas_autopartes_anual~eci+poblacion_ocupada_ensambladora_year+exportaciones_anual+iedanual_porestado,data=guanajuato)
summary(model1guanajuato)
##
## Call:
## lm(formula = ventas_autopartes_anual ~ eci + poblacion_ocupada_ensambladora_year +
## exportaciones_anual + iedanual_porestado, data = guanajuato)
##
## Residuals:
## 1 2 3 4 5 6 7 8
## -41107653 16667588 6583736 55782925 -20566009 -50526839 9687603 23478649
##
## Coefficients: (1 not defined because of singularities)
## Estimate Std. Error t value
## (Intercept) 320795370.506850 144282624.498742 2.223
## eci NA NA NA
## poblacion_ocupada_ensambladora_year 3953.515522 2548.475105 1.551
## exportaciones_anual 0.013471 0.006916 1.948
## iedanual_porestado 0.049807 0.036810 1.353
## Pr(>|t|)
## (Intercept) 0.0903 .
## eci NA
## poblacion_ocupada_ensambladora_year 0.1958
## exportaciones_anual 0.1233
## iedanual_porestado 0.2474
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
##
## Residual standard error: 46750000 on 4 degrees of freedom
## (1 observation deleted due to missingness)
## Multiple R-squared: 0.7318, Adjusted R-squared: 0.5307
## F-statistic: 3.639 on 3 and 4 DF, p-value: 0.1221
Guanajuato:Adjusted R-squared: 0.5904
model1queretaro<-lm(ventas_autopartes_anual~eci+poblacion_ocupada_ensambladora_year+exportaciones_anual+iedanual_porestado,data=queretaro)
summary(model1queretaro)
##
## Call:
## lm(formula = ventas_autopartes_anual ~ eci + poblacion_ocupada_ensambladora_year +
## exportaciones_anual + iedanual_porestado, data = queretaro)
##
## Residuals:
## 1 2 3 4 5 6 7 8
## -29436644 9131024 37147064 -44654010 -2383969 -15201637 -4223647 49621818
##
## Coefficients: (1 not defined because of singularities)
## Estimate Std. Error t value
## (Intercept) 490168045.45645 201625052.05102 2.431
## eci NA NA NA
## poblacion_ocupada_ensambladora_year 28450.78982 18772.95436 1.516
## exportaciones_anual 0.01420 0.01763 0.805
## iedanual_porestado -0.06691 0.12921 -0.518
## Pr(>|t|)
## (Intercept) 0.0719 .
## eci NA
## poblacion_ocupada_ensambladora_year 0.2042
## exportaciones_anual 0.4659
## iedanual_porestado 0.6319
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
##
## Residual standard error: 41950000 on 4 degrees of freedom
## (1 observation deleted due to missingness)
## Multiple R-squared: 0.7624, Adjusted R-squared: 0.5842
## F-statistic: 4.279 on 3 and 4 DF, p-value: 0.09704
Queretaro: Adjusted R-squared: 0.686
library(jtools)
##
## Attaching package: 'jtools'
## The following object is masked from 'package:epiDisplay':
##
## summ
## The following object is masked from 'package:Hmisc':
##
## %nin%
effect_plot(model1nuevoleon,pred=ventas_autopartes_anual,interval=TRUE)
## Warning in predict.lm(model, newdata = pm, se.fit = interval, interval =
## int.type[1], : prediction from a rank-deficient fit may be misleading
## geom_path: Each group consists of only one observation. Do you need to adjust
## the group aesthetic?
library(tseries) # time series analysis and computational finance
library(forecast) # provides methods and tools for displaying and analyzing univariate time series forecast
library(astsa) # applied statistical time series analysis
options(scipen =999)
plot(nuevoleon$year,nuevoleon$ventas_autopartes_anual, type="l",col="blue", lwd=1.5, xlab ="año",ylab ="Ventas en dolares", main = "Ventas Internacionales de Nuevo Leon en Autopartes ")
lines(nuevoleon$ventas_autopartes_anual,coahuila$ventas_autopartes_anual, col="red",lty=3)
legend("topleft", legend=c("Nuevo Leon", "Coahuila"),
col=c("blue", "red"), lty = 1:2, cex=0.8)
options(scipen =999)
colors <- c("coahuila"="green", "nuevoleon"="orange", "queretaro"="blue", "guanajuato"="red")
ggplot(data=coahuila, aes(x=year, y=ventas_autopartes_anual), color='purple') +
geom_line() +
geom_line(data=nuevoleon, aes(x=year, y=ventas_autopartes_anual), color='orange') +
geom_line() +
geom_line(data=queretaro, aes(x=year, y=ventas_autopartes_anual), color='blue')+
geom_line() +
geom_line(data=guanajuato, aes(x=year, y=ventas_autopartes_anual), color='red')+
scale_colour_manual("",
breaks = c("Coahuila", "Nuevo Leon", "Queretaro", "Guanajuato"),
values = c("green", "orange", "blue", "red"))+
labs(x="Year", y="Total Ventas Dolares")
summary(model1nuevoleon<-arma(nuevoleon$ventas_autopartes_anual,order=c(0,1)))
##
## Call:
## arma(x = nuevoleon$ventas_autopartes_anual, order = c(0, 1))
##
## Model:
## ARMA(0,1)
##
## Residuals:
## Min 1Q Median 3Q Max
## -155651952 -37299724 19338817 44510100 79154505
##
## Coefficient(s):
## Estimate Std. Error t value Pr(>|t|)
## ma1 0.7301 0.3604 2.026 0.0428 *
## intercept 600553057.7170 37703.4591 15928.328 <0.0000000000000002 ***
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
##
## Fit:
## sigma^2 estimated as 5473146058018973, Conditional Sum-of-Squares = 38381860832053096, AIC = 355.69
nuevoleon_forecast<-forecast(model1nuevoleon$fitted,h=5,level=c(95))
## Warning in ets(object, lambda = lambda, biasadj = biasadj,
## allow.multiplicative.trend = allow.multiplicative.trend, : Missing values
## encountered. Using longest contiguous portion of time series
nuevoleon_forecast
## Point Forecast Lo 95 Hi 95
## 10 591345747 488822579 693868916
## 11 591345747 488822579 693868916
## 12 591345747 488822578 693868917
## 13 591345747 488822578 693868917
## 14 591345747 488822577 693868918
Realizando un análisis de la base de datos merma nos dimos cuenta que los meses con mayor producción de merma son los meses de agosto con 32,500 kilos de merma y mayo con 22,700 kilos de merma, en base a esto podemos inferir que en estos meses es donde la empresa FORM tiene mayor producción. De igual manera se identificaron los meses donde la empresa producía menos merma, los cuales fueron los meses de enero con 14,800 kilos de merma y septiembre con 12,400 kilos de merma, por lo que también podemos inferir que en estos meses FORM no tiene mucha producción.
Analizando los resultados de la base de datos Scrap, el cual se refiere a todos los desechos y/o residuos derivados del proceso industrial, se observa que SAB/Pre-Production es el lugar donde más cantidad existe con un valor total de 1500 toneladas.
Las gráficas de dispersión nos indican que con el cliente YANFENG es la vez que más se ha llevado más tiempo de calidad, podemos analizar el tiempo que se llevó a cabo con un empaque y si la producción del mismo ¿es rentable para la empresa? o si lo mejor es no aceptar producir este tipo de producto.
Por otro lado con las series de tiempo, observamos que con Hanon Systems es con quien más se ha tomado tiempo en el proceso. Podemos preguntarnos si es conveniente llevar procesos de producción tan largos con un cliente y evaluar su rentabilidad.
En Delivery Performance hemos podido identificar que MAHLE tiene mayor delay que PRINTEL, por lo que podría decirnos que algo sucede con MAHLE que ocasiona que se retrase más que otros clientes. Habría que tomar medidas correctivas.
Al analizar los resultados, se obtuvo que el mes con más piezas programadas fue Julio de 2022, seguido de Septiembre y Mayo. Además se puede observar una caída significativa de piezas programadas entre el mes de julio a septiembre, ya que en julio hay más de 72,000 piezas programadas y para septiembre ese valor decreció con 10 mil unidades menos.
El principal motivo de las bajas fue por renuncias, este es un dato muy interesante sin embargo no se puede llegar a hacer una buena interpretación ya que muchos de los ex empleados fueron dados de baja solo por faltar un día. El segundo motivo de las bajas fue por renuncia voluntaria y muchas de estas personas no renunciaron sin complir el año en la empresa. Es importante que la empresa recuerde bien la información sobre las bajas y sus motivos para de esta manera generar una buena estrategia en disminuir la rotación de empleados, ya que, la mayoría de los empleados solo dura un año o menos en la empresa.
La persona que más salario tienen son la supervisora mujeres y los de mantenimiento, si FORM necesita un recorte en gastos se fijaría primeramente en estas personas.
El estado de Coahuila se mantiene como el líder en ventas de
autopartes y en el 2022 tuvo un despunte en las ventas.
- Querétaro y Guanajuato siguen manteniendo un crecimiento en el volúmen
de ventas.
- Nuevo León se está recuperando del declive que tuvo en 2018.
- En general la industria en México está creciendo.
Es el proceso de recolección de datos mediante diferentes modelos predictivos y estadísticos con el fin de analizar la situación actual de la empresa para predecir evento, tendencias y comportamientos a futuro que ayuden a determinar la toma de decisiones, reduciendo los riesgos de equivocaciones futuras.
Con Business Intelligence se puede optimizar, evaluar y coordinar las actividades internas de una empresa, mientras que con Business Analytics e ponen en marcha soluciones empresariales con las que satisfacer las necesidades de un negocio.
Se puede decir que el Business Intelligence se preocupa por el qué y el cómo, y el Business Analytics sí se pregunta por qué pasan las cosas para poder predecir futuros comportamientos o tendencias.