class: center, middle, inverse, title-slide .title[ # Seminario de Instrumentos Computacionales ] .subtitle[ ## R - Clase 5 ] .author[ ### Cristian Bonavida ] --- <style> p.caption { font-size: 0.6em; } </style> <style> div.remark-slide-content { padding: 1em; /*default is 1em 4em*/ } .dataTables_wrapper { font-size: .5em; } </style> <style> pre { white-space: pre !important; overflow-y: auto !important; max-height: 45vh !important; } </style> <style type="text/css"> .remark-code, .remark-inline-code { background: #f0f0f0; } .remark-code { font-size: 18px; } .huge .remark-code { /*Change made here*/ font-size: 125% !important; } .inter .remark-code { /*Change made here*/ font-size: 85% !important; } .mid .remark-code { /*Change made here*/ font-size: 75% !important; } .tiny .remark-code { /*Change made here*/ font-size: 70% !important; } </style> --- ## Programación En esta clase vamos a ver algunos conceptos y fundamentos propios de la programación en R -- Aprender algunas estructuras lógicas y sentencias condicionales es muy útil, para **replicar** facilmente un mismo trabajo -- Ahora que ya sabemos cómo cargar datos, limpiarlos, transformarlos, realizar estimaciones y graficar, veamos cómo podemos **sistematizar** esas tareas, en procesos mas generales -- Pueden pensar que una vez que aprendimos a trabajar con datos y producir información con ellos, ahora queremos aprender **cómo hacerlo a escala** de forma eficiente. --- ## Programación La hoja de ruta será la siguiente: Veremos tres elementos que nos permiten programar en R - For Loops - Sentencias Condicionales - Funciones propias -- El objetivo es introducir cada uno desde una aplicación practica hipotética y ver cómo se relacionan entre sí -- Y luego explorar algunas aplicaciones al trabajo con datos --- ## For loops El loop es la estructura que comúnmente conocemos como **bucle** -- La utilizamos cuando queremos **repetir** una operación o acción *n* cantidad de veces, sobre distintos elementos. <br> -- Los bucles tienen una estructura simple y la idea es: **para cada** elemento en un objeto : **realizá** la siguiente operación <br> -- Si sabemos como escribir cada una de estas partes, sabremos cómo escribir un loop. --- ## For loops Al igual que en la mayoría de los lenguajes los bucles se inician con un `for()`, donde escribimos la primer parte: - **para cada** elemento en un objeto = `for( x in objeto)` <br> -- La segunda parte va encerrada entre llaves `{}` - **realizá** la siguiente operación = `{ definir operación }` -- --- ## For loops Veamos cómo funciona. Escribamos 5 números impares, el bucle debe tomar cada elemento del objeto e imprimir el mensaje "el elemento x es impar" Cada vez que el bucle toma un elemento particular, decimos que ocurre una **iteración**, o más facil, **una vuelta** -- . Estas son cada una de las veces que se repite la acción -- ```r numeros <- c(1,3,5,7,9) for (numero in numeros) { print(numero %+% " es un número impar") } ``` ``` ## [1] "1 es un número impar" ## [1] "3 es un número impar" ## [1] "5 es un número impar" ## [1] "7 es un número impar" ## [1] "9 es un número impar" ``` -- En este caso tenemos 5 iteraciones, porque son 5 los elementos del objeto *numeros* --- ## For loops El objeto puede ser un vector, que a priori, puede contener todo tipo de elementos -- Probemos hacerlo sobre una lista de *strings* y pidamosle que en cada iteración nos devuelva la cantidad de caracteres con al función `nchar()` -- Algo que sabemos cómo hacer para un elemento en particular, lo repetimos de manera estandarizada ```r mi_vector <- c("esta_frase_es_larga", "esta_corta", "R", "programming") for (i in mi_vector) { x <- nchar(i) print(x %+% " caracter/es tiene " %+% i) } ``` ``` ## [1] "19 caracter/es tiene esta_frase_es_larga" ## [1] "10 caracter/es tiene esta_corta" ## [1] "1 caracter/es tiene R" ## [1] "11 caracter/es tiene programming" ``` --- ## For loops Existe otra manera en la que podemos iterara sobre un conjunto de elementos. -- Ya hemos aprendido que podemos llamar a cada elemento indexandolo por su posición -- Entonces iterar desde un número hasta otro, implica que podemos acceder en cada iteración, al elemento que se encuentra en esa posición: -- ```r mi_vector <- c("esta_frase_es_larga", "esta_corta", "R", "programming") for (i in 1:4) { x <- nchar(mi_vector[i]) print(x %+% " caracter/es tiene " %+% mi_vector[i]) } ``` ``` ## [1] "19 caracter/es tiene esta_frase_es_larga" ## [1] "10 caracter/es tiene esta_corta" ## [1] "1 caracter/es tiene R" ## [1] "11 caracter/es tiene programming" ``` --- ## For loops Notar que la lógica sigue siendo la misma: para cada elemento de un objeto realizar algo. -- Solo cambia la forma en que accedemos a ese elemento. -- Ya veremos en qué contexto nos conviene mas uno u otro --- ## Sentencias condicionales Pero muchas veces, lo que necesitamos no es realizar siempre **una misma operación** para todos los elementos, Sino queremos poder **evaluar** si ese elemento cumple alguna condición, y **en función de** eso optar por una acción u otra -- Por ejemplo, si iteramos sobre una lista de *strings* de nombres, y queremos saludar a cada persona, con lo que aprendimos de loops haríamos alg como: -- ```r nombre <- c("Cristian", "Sandra", "Micaela", "Armando", "Hector") for (i in nombre) { print("Hola Estimado: " %+% i) } ``` ``` ## [1] "Hola Estimado: Cristian" ## [1] "Hola Estimado: Sandra" ## [1] "Hola Estimado: Micaela" ## [1] "Hola Estimado: Armando" ## [1] "Hola Estimado: Hector" ``` --- ## Sentencias condicionales Pero nuestro output no es muy adecuado. "Estimado" por default en masculino no parece la mejor forma de hacerlo.. Refinemos un poco esto para ser mas inclusivos -- ¿Qué se les ocurre? Supongamos que sabemos el genero con el que se autopercibe la persona -- Necesitamos poder evaluar en cada caso cómo desea ser considerada la persona y en consecuencia imprimir un saludo adecuado -- Lo que necesitamos es una sentencia condicional: *"si se da este caso, hace esto"* -- Lo que necesitamos es un `if` -- --- ## Sentencias condicionales .inter[ ```r nombre <- c("Cristian", "Sandra", "Micaela", "Armando", "Hector") percep <- c("H", "F", "I", "X", "H", "F") for (i in 1:5){ if(percep[i] == "H"){ print("Hola Estimado: " %+% nombre[i]) } } ``` ``` ## [1] "Hola Estimado: Cristian" ## [1] "Hola Estimado: Hector" ``` ] <br> Al igual que el `for()` el alcance del `if()` está determinado por las llaves `{}` -- El paréntesis por su parte indica la condición a cumplir --- ## Sentencias condicionales Si bien personalizamos el saludo, seguimos haciendo diferencias puesto que solo saludamos a los hombres -- Necesitamos agregar **otra condicion** -- Necesitamos agregar un `else` .inter[ ```r for (i in 1:5){ if(percep[i] == "H"){ print("Hola Estimado: " %+% nombre[i]) } else{ print("Hola Estimada: " %+% nombre[i]) } } ``` ``` ## [1] "Hola Estimado: Cristian" ## [1] "Hola Estimada: Sandra" ## [1] "Hola Estimada: Micaela" ## [1] "Hola Estimada: Armando" ## [1] "Hola Estimado: Hector" ``` ] --- ## Sentencias condicionales Pero estamos asumiendo que todos los que no son hombres, son mujeres. Tenemos que encontrar alguna manera de contemplar géneros no binarios para poder para incluirlos Veamos como el `else if()` nos puede ayudar con esto: .mid[ ```r for (i in 1:5){ if(percep[i] == "H"){ print("Hola EstimadO: " %+% nombre[i]) } else if(percep[i] == "F"){ print("Hola Estimada: " %+% nombre[i]) } else{ print("Hola Estimade: " %+% nombre[i]) } } ``` ``` ## [1] "Hola EstimadO: Cristian" ## [1] "Hola Estimada: Sandra" ## [1] "Hola Estimade: Micaela" ## [1] "Hola Estimade: Armando" ## [1] "Hola EstimadO: Hector" ``` ] --- ## Sentencias condicionales Mucho mejor! -- Repasemos la lógica detrás de nuestro bucle - `if` -- Si ocurre tal caso --> entonces realizar esto -- - `else if` -- Si ocurre tal otro caso --> entonces realizar esto otro -- - `else` -- En cualquier otro caso --> entonces realizar esto --- ## Sentencias condicionales Ahora mejoremos también nuestro código. Justamente la idea de programar secuencias en R es que puedan servirnos para la mayor cantidad de casos posibles. Es decir que puedan ser lo más generales posibles -- Si tenemos códigos demasiado específicos, tendremos que modificarlos constantemente. <br> Por ejemplo si se agregara una persona más, ahora tenemos que cambiar la función para que tome valores de 1 a 6. Es mucho mejor R solo detecte cuantas iteraciones se precisan ```r nombre[6] <- "Fede" percep[6] <- "I" ``` -- En este caso la forma de hacerlo indicándolo que vaya de 1 hasta el largo del vector, con `length(vector)` --- ## Sentencias condicionales ```r for (i in 1:length(nombre)){ if(percep[i] == "F"){ print("Hola Estimada: " %+% nombre[i]) } else if(percep[i] == "H"){ print("Hola Estimado: " %+% nombre[i]) } else{ print("Hola Estimade: " %+% nombre[i]) } } ``` ``` ## [1] "Hola Estimado: Cristian" ## [1] "Hola Estimada: Sandra" ## [1] "Hola Estimade: Micaela" ## [1] "Hola Estimade: Armando" ## [1] "Hola Estimado: Hector" ## [1] "Hola Estimade: Fede" ``` --- ## For loops y condicionales Buen trabajo! Aumentemos ahora levemente la complejidad Supongamos ahora que están a cargo de un pub, y reciben una lista de invitados con estos datos junto con la edad de las personas y deben determinar quienes pueden entrar -- Debemos **imponer una condición** sobre la edad de estas personas para saber si son mayores de edad para ingresar (el género por supuesto que no debe influir en las chances de ingresar o no) -- Tenemos dos posibilidades: - Si es mayor a 18 --> Ingresa - Si es menor a 18 --> No Ingresa Y queremos indicar el caso para cada persona, es decir si X persona entra o no --- ## For loops y condicionales .inter[ ```r nombre <- c("Cristian", "Sandra", "Micaela", "Armando", "Hector", "Fatima") edad <- c(18, 19, 17, 21, 16, 19) for (i in 1:length(edad)){ if(edad[i] >= 18){ x <- "Ingresa" } else{ x <- "No Ingresa" } print(paste(nombre[i], x, sep = ": ")) } ``` ``` ## [1] "Cristian: Ingresa" ## [1] "Sandra: Ingresa" ## [1] "Micaela: No Ingresa" ## [1] "Armando: Ingresa" ## [1] "Hector: No Ingresa" ## [1] "Fatima: Ingresa" ``` ] --- ## For loops y condicionales Bien ahora tienen una restricción adicional, el local tienen un máximo de 50 personas, entonces no deben dejar ingresar a mas personas una vez alcanzada la capacidad máxima -- Prescindamos de los nombres por practicidad e identifiquemos a los candidatos a entrar en base a un id, que puede ser el orden en el cual se inscribieron en la lista de entradas. -- Evaluamos si pueden entrar en base a la edad y cuando alcancemos la cantidad de 50 dictaminemos que no pueden entrar mas -- Supongamos que tienen 100 postulantes y con una edad que aletoriamente puede ser de entre 17 y 25 --- ## For loops y condicionales .tiny[ ```r id <- seq(1:100) edad <- sample(17:25, 100, TRUE) cupos = 50 for (i in 1:length(edad)){ if(edad[i] >= 18){ print("El ID: " %+% id[i] %+% " Ingresa") cupos = cupos - 1 } else{ print("El ID: " %+% id[i] %+% " NO Ingresa") } if(cupos==0){ print ("Se alcanzó la capacidad máxima del local") break } } ``` ] --- ## For loops y condicionales Y nuestro output es el siguiente: .tiny[ ``` ## [1] "El ID: 1 NO Ingresa" ## [1] "El ID: 2 Ingresa" ## [1] "El ID: 3 Ingresa" ## [1] "El ID: 4 Ingresa" ## [1] "El ID: 5 Ingresa" ## [1] "El ID: 6 Ingresa" ## [1] "El ID: 7 Ingresa" ## [1] "El ID: 8 Ingresa" ## [1] "El ID: 9 Ingresa" ## [1] "El ID: 10 Ingresa" ## [1] "El ID: 11 NO Ingresa" ## [1] "El ID: 12 Ingresa" ## [1] "El ID: 13 Ingresa" ## [1] "El ID: 14 Ingresa" ## [1] "El ID: 15 Ingresa" ## [1] "El ID: 16 Ingresa" ## [1] "El ID: 17 Ingresa" ## [1] "El ID: 18 Ingresa" ## [1] "El ID: 19 Ingresa" ## [1] "El ID: 20 Ingresa" ## [1] "El ID: 21 Ingresa" ## [1] "El ID: 22 Ingresa" ## [1] "El ID: 23 Ingresa" ## [1] "El ID: 24 Ingresa" ## [1] "El ID: 25 NO Ingresa" ## [1] "El ID: 26 Ingresa" ## [1] "El ID: 27 Ingresa" ## [1] "El ID: 28 Ingresa" ## [1] "El ID: 29 NO Ingresa" ## [1] "El ID: 30 Ingresa" ## [1] "El ID: 31 Ingresa" ## [1] "El ID: 32 Ingresa" ## [1] "El ID: 33 Ingresa" ## [1] "El ID: 34 Ingresa" ## [1] "El ID: 35 NO Ingresa" ## [1] "El ID: 36 Ingresa" ## [1] "El ID: 37 Ingresa" ## [1] "El ID: 38 Ingresa" ## [1] "El ID: 39 NO Ingresa" ## [1] "El ID: 40 Ingresa" ## [1] "El ID: 41 Ingresa" ## [1] "El ID: 42 Ingresa" ## [1] "El ID: 43 Ingresa" ## [1] "El ID: 44 Ingresa" ## [1] "El ID: 45 Ingresa" ## [1] "El ID: 46 Ingresa" ## [1] "El ID: 47 Ingresa" ## [1] "El ID: 48 Ingresa" ## [1] "El ID: 49 Ingresa" ## [1] "El ID: 50 Ingresa" ## [1] "El ID: 51 Ingresa" ## [1] "El ID: 52 Ingresa" ## [1] "El ID: 53 Ingresa" ## [1] "El ID: 54 NO Ingresa" ## [1] "El ID: 55 Ingresa" ## [1] "El ID: 56 Ingresa" ## [1] "El ID: 57 Ingresa" ## [1] "Se alcanzó la capacidad máxima del local" ``` ] --- ## For loops y condicionales Notemos dos cosas importantes de nuestra función -- Por una lado el objeto *count*, que comenzó con valor de 50 y que cada vez que se evaluaba un candidato +18 restaba en un 1 su valor. Los contadores son muy útiles dentro de los bucles, ya que nos ayudan en múltiples casos. En cada iteración podemos incrementarlos o restarlos. -- Lo segundo a notar es la función `break`, su proposito es simple, cortar el loop, finalizarlo. Cuando ya no había mas lugar disponible dejamos de evaluar candidatos --- ## For loops y condicionales Bien, ya podemos determinar rápidamente y sin trabajo manual, quienes pueden ingresar a la fiesta -- Pero notemos que siempre estuvimos tomando un vector, iterando sobre sus elementos e imprimiendo los resultados. -- Supongamos ahora que lo que reciben es una planilla, un dataframe con estos vectores pero como columnas. -- Su tarea es agregar un **nueva columna** donde en cada fila quede registrado si entra o no a la fiesta -- Tenemos que pasar de imprimir los resultados a guardarlos en una columna ¿cómo hacemos? --- ## For loops y condicionales Podemos hacerlo con la lógica de antes. Solo tenemos que recordar algunos conceptos de la clase 1 -- Antes estábamos indexando un vector para acceder a cada elemento. Ahora debemos recordar como acceder a cada elemento de una columna de un data frame Debemos pasar de - `edad[i]` a - `df$edad[i]` -- Adicional mente vamos a necesitar crear una columna como vacía y luego ir llenando el registro en cada iteración en base a la edad del candidato en esa fila --- ## For loops y condicionales .inter[ ```r id <- seq(1:100) edad <- sample(17:25, 100, TRUE) candidatos <- data_frame(id, edad) candidatos$status <- NA cupos = 50 for (i in id){ if(candidatos$edad[i]>=18 & cupos>0){ cupos = cupos - 1 candidatos$status[i] <- "Ingresa" } else{ candidatos$status[i] <- "NO Ingresa" } if (cupos==0) { print ("El punto de corte es el id " %+% i) cupos = (-1) } } ``` ``` ## [1] "El punto de corte es el id 56" ``` ] --- ## For loops y condicionales La función nos avisa en qué momento se llena el local y genera este df como resultado <div style="border: 1px solid #ddd; padding: 0px; overflow-y: scroll; height:450px; overflow-x: scroll; width:100%; "><table class="table table-condensed table-responsive" style="font-size: 13px; margin-left: auto; margin-right: auto;"> <thead> <tr> <th style="text-align:right;position: sticky; top:0; background-color: #FFFFFF;"> id </th> <th style="text-align:right;position: sticky; top:0; background-color: #FFFFFF;"> edad </th> <th style="text-align:left;position: sticky; top:0; background-color: #FFFFFF;"> status </th> </tr> </thead> <tbody> <tr> <td style="text-align:right;"> 1 </td> <td style="text-align:right;"> 23 </td> <td style="text-align:left;"> Ingresa </td> </tr> <tr> <td style="text-align:right;"> 2 </td> <td style="text-align:right;"> 18 </td> <td style="text-align:left;"> Ingresa </td> </tr> <tr> <td style="text-align:right;"> 3 </td> <td style="text-align:right;"> 20 </td> <td style="text-align:left;"> Ingresa </td> </tr> <tr> <td style="text-align:right;"> 4 </td> <td style="text-align:right;"> 22 </td> <td style="text-align:left;"> Ingresa </td> </tr> <tr> <td style="text-align:right;"> 5 </td> <td style="text-align:right;"> 19 </td> <td style="text-align:left;"> Ingresa </td> </tr> <tr> <td style="text-align:right;"> 6 </td> <td style="text-align:right;"> 19 </td> <td style="text-align:left;"> Ingresa </td> </tr> <tr> <td style="text-align:right;"> 7 </td> <td style="text-align:right;"> 24 </td> <td style="text-align:left;"> Ingresa </td> </tr> <tr> <td style="text-align:right;"> 8 </td> <td style="text-align:right;"> 23 </td> <td style="text-align:left;"> Ingresa </td> </tr> <tr> <td style="text-align:right;"> 9 </td> <td style="text-align:right;"> 24 </td> <td style="text-align:left;"> Ingresa </td> </tr> <tr> <td style="text-align:right;"> 10 </td> <td style="text-align:right;"> 18 </td> <td style="text-align:left;"> Ingresa </td> </tr> <tr> <td style="text-align:right;"> 11 </td> <td style="text-align:right;"> 23 </td> <td style="text-align:left;"> Ingresa </td> </tr> <tr> <td style="text-align:right;"> 12 </td> <td style="text-align:right;"> 19 </td> <td style="text-align:left;"> Ingresa </td> </tr> <tr> <td style="text-align:right;"> 13 </td> <td style="text-align:right;"> 24 </td> <td style="text-align:left;"> Ingresa </td> </tr> <tr> <td style="text-align:right;"> 14 </td> <td style="text-align:right;"> 22 </td> <td style="text-align:left;"> Ingresa </td> </tr> <tr> <td style="text-align:right;"> 15 </td> <td style="text-align:right;"> 17 </td> <td style="text-align:left;"> NO Ingresa </td> </tr> <tr> <td style="text-align:right;"> 16 </td> <td style="text-align:right;"> 18 </td> <td style="text-align:left;"> Ingresa </td> </tr> <tr> <td style="text-align:right;"> 17 </td> <td style="text-align:right;"> 23 </td> <td style="text-align:left;"> Ingresa </td> </tr> <tr> <td style="text-align:right;"> 18 </td> <td style="text-align:right;"> 20 </td> <td style="text-align:left;"> Ingresa </td> </tr> <tr> <td style="text-align:right;"> 19 </td> <td style="text-align:right;"> 24 </td> <td style="text-align:left;"> Ingresa </td> </tr> <tr> <td style="text-align:right;"> 20 </td> <td style="text-align:right;"> 24 </td> <td style="text-align:left;"> Ingresa </td> </tr> <tr> <td style="text-align:right;"> 21 </td> <td style="text-align:right;"> 22 </td> <td style="text-align:left;"> Ingresa </td> </tr> <tr> <td style="text-align:right;"> 22 </td> <td style="text-align:right;"> 18 </td> <td style="text-align:left;"> Ingresa </td> </tr> <tr> <td style="text-align:right;"> 23 </td> <td style="text-align:right;"> 22 </td> <td style="text-align:left;"> Ingresa </td> </tr> <tr> <td style="text-align:right;"> 24 </td> <td style="text-align:right;"> 25 </td> <td style="text-align:left;"> Ingresa </td> </tr> <tr> <td style="text-align:right;"> 25 </td> <td style="text-align:right;"> 21 </td> <td style="text-align:left;"> Ingresa </td> </tr> <tr> <td style="text-align:right;"> 26 </td> <td style="text-align:right;"> 22 </td> <td style="text-align:left;"> Ingresa </td> </tr> <tr> <td style="text-align:right;"> 27 </td> <td style="text-align:right;"> 17 </td> <td style="text-align:left;"> NO Ingresa </td> </tr> <tr> <td style="text-align:right;"> 28 </td> <td style="text-align:right;"> 20 </td> <td style="text-align:left;"> Ingresa </td> </tr> <tr> <td style="text-align:right;"> 29 </td> <td style="text-align:right;"> 22 </td> <td style="text-align:left;"> Ingresa </td> </tr> <tr> <td style="text-align:right;"> 30 </td> <td style="text-align:right;"> 21 </td> <td style="text-align:left;"> Ingresa </td> </tr> <tr> <td style="text-align:right;"> 31 </td> <td style="text-align:right;"> 22 </td> <td style="text-align:left;"> Ingresa </td> </tr> <tr> <td style="text-align:right;"> 32 </td> <td style="text-align:right;"> 25 </td> <td style="text-align:left;"> Ingresa </td> </tr> <tr> <td style="text-align:right;"> 33 </td> <td style="text-align:right;"> 24 </td> <td style="text-align:left;"> Ingresa </td> </tr> <tr> <td style="text-align:right;"> 34 </td> <td style="text-align:right;"> 22 </td> <td style="text-align:left;"> Ingresa </td> </tr> <tr> <td style="text-align:right;"> 35 </td> <td style="text-align:right;"> 18 </td> <td style="text-align:left;"> Ingresa </td> </tr> <tr> <td style="text-align:right;"> 36 </td> <td style="text-align:right;"> 24 </td> <td style="text-align:left;"> Ingresa </td> </tr> <tr> <td style="text-align:right;"> 37 </td> <td style="text-align:right;"> 22 </td> <td style="text-align:left;"> Ingresa </td> </tr> <tr> <td style="text-align:right;"> 38 </td> <td style="text-align:right;"> 24 </td> <td style="text-align:left;"> Ingresa </td> </tr> <tr> <td style="text-align:right;"> 39 </td> <td style="text-align:right;"> 18 </td> <td style="text-align:left;"> Ingresa </td> </tr> <tr> <td style="text-align:right;"> 40 </td> <td style="text-align:right;"> 18 </td> <td style="text-align:left;"> Ingresa </td> </tr> <tr> <td style="text-align:right;"> 41 </td> <td style="text-align:right;"> 19 </td> <td style="text-align:left;"> Ingresa </td> </tr> <tr> <td style="text-align:right;"> 42 </td> <td style="text-align:right;"> 17 </td> <td style="text-align:left;"> NO Ingresa </td> </tr> <tr> <td style="text-align:right;"> 43 </td> <td style="text-align:right;"> 18 </td> <td style="text-align:left;"> Ingresa </td> </tr> <tr> <td style="text-align:right;"> 44 </td> <td style="text-align:right;"> 24 </td> <td style="text-align:left;"> Ingresa </td> </tr> <tr> <td style="text-align:right;"> 45 </td> <td style="text-align:right;"> 25 </td> <td style="text-align:left;"> Ingresa </td> </tr> <tr> <td style="text-align:right;"> 46 </td> <td style="text-align:right;"> 20 </td> <td style="text-align:left;"> Ingresa </td> </tr> <tr> <td style="text-align:right;"> 47 </td> <td style="text-align:right;"> 20 </td> <td style="text-align:left;"> Ingresa </td> </tr> <tr> <td style="text-align:right;"> 48 </td> <td style="text-align:right;"> 25 </td> <td style="text-align:left;"> Ingresa </td> </tr> <tr> <td style="text-align:right;"> 49 </td> <td style="text-align:right;"> 17 </td> <td style="text-align:left;"> NO Ingresa </td> </tr> <tr> <td style="text-align:right;"> 50 </td> <td style="text-align:right;"> 17 </td> <td style="text-align:left;"> NO Ingresa </td> </tr> <tr> <td style="text-align:right;"> 51 </td> <td style="text-align:right;"> 22 </td> <td style="text-align:left;"> Ingresa </td> </tr> <tr> <td style="text-align:right;"> 52 </td> <td style="text-align:right;"> 21 </td> <td style="text-align:left;"> Ingresa </td> </tr> <tr> <td style="text-align:right;"> 53 </td> <td style="text-align:right;"> 19 </td> <td style="text-align:left;"> Ingresa </td> </tr> <tr> <td style="text-align:right;"> 54 </td> <td style="text-align:right;"> 25 </td> <td style="text-align:left;"> Ingresa </td> </tr> <tr> <td style="text-align:right;"> 55 </td> <td style="text-align:right;"> 17 </td> <td style="text-align:left;"> NO Ingresa </td> </tr> <tr> <td style="text-align:right;"> 56 </td> <td style="text-align:right;"> 23 </td> <td style="text-align:left;"> Ingresa </td> </tr> <tr> <td style="text-align:right;"> 57 </td> <td style="text-align:right;"> 21 </td> <td style="text-align:left;"> NO Ingresa </td> </tr> <tr> <td style="text-align:right;"> 58 </td> <td style="text-align:right;"> 19 </td> <td style="text-align:left;"> NO Ingresa </td> </tr> <tr> <td style="text-align:right;"> 59 </td> <td style="text-align:right;"> 20 </td> <td style="text-align:left;"> NO Ingresa </td> </tr> <tr> <td style="text-align:right;"> 60 </td> <td style="text-align:right;"> 25 </td> <td style="text-align:left;"> NO Ingresa </td> </tr> <tr> <td style="text-align:right;"> 61 </td> <td style="text-align:right;"> 25 </td> <td style="text-align:left;"> NO Ingresa </td> </tr> <tr> <td style="text-align:right;"> 62 </td> <td style="text-align:right;"> 23 </td> <td style="text-align:left;"> NO Ingresa </td> </tr> <tr> <td style="text-align:right;"> 63 </td> <td style="text-align:right;"> 17 </td> <td style="text-align:left;"> NO Ingresa </td> </tr> <tr> <td style="text-align:right;"> 64 </td> <td style="text-align:right;"> 18 </td> <td style="text-align:left;"> NO Ingresa </td> </tr> <tr> <td style="text-align:right;"> 65 </td> <td style="text-align:right;"> 20 </td> <td style="text-align:left;"> NO Ingresa </td> </tr> <tr> <td style="text-align:right;"> 66 </td> <td style="text-align:right;"> 17 </td> <td style="text-align:left;"> NO Ingresa </td> </tr> <tr> <td style="text-align:right;"> 67 </td> <td style="text-align:right;"> 24 </td> <td style="text-align:left;"> NO Ingresa </td> </tr> <tr> <td style="text-align:right;"> 68 </td> <td style="text-align:right;"> 22 </td> <td style="text-align:left;"> NO Ingresa </td> </tr> <tr> <td style="text-align:right;"> 69 </td> <td style="text-align:right;"> 17 </td> <td style="text-align:left;"> NO Ingresa </td> </tr> <tr> <td style="text-align:right;"> 70 </td> <td style="text-align:right;"> 24 </td> <td style="text-align:left;"> NO Ingresa </td> </tr> <tr> <td style="text-align:right;"> 71 </td> <td style="text-align:right;"> 25 </td> <td style="text-align:left;"> NO Ingresa </td> </tr> <tr> <td style="text-align:right;"> 72 </td> <td style="text-align:right;"> 19 </td> <td style="text-align:left;"> NO Ingresa </td> </tr> <tr> <td style="text-align:right;"> 73 </td> <td style="text-align:right;"> 18 </td> <td style="text-align:left;"> NO Ingresa </td> </tr> <tr> <td style="text-align:right;"> 74 </td> <td style="text-align:right;"> 19 </td> <td style="text-align:left;"> NO Ingresa </td> </tr> <tr> <td style="text-align:right;"> 75 </td> <td style="text-align:right;"> 24 </td> <td style="text-align:left;"> NO Ingresa </td> </tr> <tr> <td style="text-align:right;"> 76 </td> <td style="text-align:right;"> 19 </td> <td style="text-align:left;"> NO Ingresa </td> </tr> <tr> <td style="text-align:right;"> 77 </td> <td style="text-align:right;"> 18 </td> <td style="text-align:left;"> NO Ingresa </td> </tr> <tr> <td style="text-align:right;"> 78 </td> <td style="text-align:right;"> 25 </td> <td style="text-align:left;"> NO Ingresa </td> </tr> <tr> <td style="text-align:right;"> 79 </td> <td style="text-align:right;"> 18 </td> <td style="text-align:left;"> NO Ingresa </td> </tr> <tr> <td style="text-align:right;"> 80 </td> <td style="text-align:right;"> 21 </td> <td style="text-align:left;"> NO Ingresa </td> </tr> <tr> <td style="text-align:right;"> 81 </td> <td style="text-align:right;"> 22 </td> <td style="text-align:left;"> NO Ingresa </td> </tr> <tr> <td style="text-align:right;"> 82 </td> <td style="text-align:right;"> 19 </td> <td style="text-align:left;"> NO Ingresa </td> </tr> <tr> <td style="text-align:right;"> 83 </td> <td style="text-align:right;"> 17 </td> <td style="text-align:left;"> NO Ingresa </td> </tr> <tr> <td style="text-align:right;"> 84 </td> <td style="text-align:right;"> 25 </td> <td style="text-align:left;"> NO Ingresa </td> </tr> <tr> <td style="text-align:right;"> 85 </td> <td style="text-align:right;"> 18 </td> <td style="text-align:left;"> NO Ingresa </td> </tr> <tr> <td style="text-align:right;"> 86 </td> <td style="text-align:right;"> 17 </td> <td style="text-align:left;"> NO Ingresa </td> </tr> <tr> <td style="text-align:right;"> 87 </td> <td style="text-align:right;"> 19 </td> <td style="text-align:left;"> NO Ingresa </td> </tr> <tr> <td style="text-align:right;"> 88 </td> <td style="text-align:right;"> 25 </td> <td style="text-align:left;"> NO Ingresa </td> </tr> <tr> <td style="text-align:right;"> 89 </td> <td style="text-align:right;"> 20 </td> <td style="text-align:left;"> NO Ingresa </td> </tr> <tr> <td style="text-align:right;"> 90 </td> <td style="text-align:right;"> 25 </td> <td style="text-align:left;"> NO Ingresa </td> </tr> <tr> <td style="text-align:right;"> 91 </td> <td style="text-align:right;"> 24 </td> <td style="text-align:left;"> NO Ingresa </td> </tr> <tr> <td style="text-align:right;"> 92 </td> <td style="text-align:right;"> 25 </td> <td style="text-align:left;"> NO Ingresa </td> </tr> <tr> <td style="text-align:right;"> 93 </td> <td style="text-align:right;"> 23 </td> <td style="text-align:left;"> NO Ingresa </td> </tr> <tr> <td style="text-align:right;"> 94 </td> <td style="text-align:right;"> 20 </td> <td style="text-align:left;"> NO Ingresa </td> </tr> <tr> <td style="text-align:right;"> 95 </td> <td style="text-align:right;"> 23 </td> <td style="text-align:left;"> NO Ingresa </td> </tr> <tr> <td style="text-align:right;"> 96 </td> <td style="text-align:right;"> 25 </td> <td style="text-align:left;"> NO Ingresa </td> </tr> <tr> <td style="text-align:right;"> 97 </td> <td style="text-align:right;"> 23 </td> <td style="text-align:left;"> NO Ingresa </td> </tr> <tr> <td style="text-align:right;"> 98 </td> <td style="text-align:right;"> 20 </td> <td style="text-align:left;"> NO Ingresa </td> </tr> <tr> <td style="text-align:right;"> 99 </td> <td style="text-align:right;"> 24 </td> <td style="text-align:left;"> NO Ingresa </td> </tr> <tr> <td style="text-align:right;"> 100 </td> <td style="text-align:right;"> 20 </td> <td style="text-align:left;"> NO Ingresa </td> </tr> </tbody> </table></div> --- ## For loops y condicionales ¿Esto también funcionaría? .inter[ ```r cupos = 50 for (i in id){ inscripcion <- candidatos %>% mutate(status = ifelse(edad>=18 & cupos>0, "Ingresa", "No Ingresa")) cupos = cupos - 1 if (cupos==0) { print ("El punto de corte es el id " %+% i) cupos = (-1) } } ``` ] --- ## For loops y condicionales No, porque: - 1) lo que está pasando es que en cada iteración del loop va a estar generando nuevamente la columna status y evaluando la condición. El resultado de esa columna va a ser igual a la ultima iteración. -- Notar que si bien comparten la misma lógica, `ifelse()` no es la misma función que `elseif(){}` en R -- - 2) Y además en cada iteración cupos está restando 1, sin importar si la persona ingresa o no --- ## Funciones propias Piensen un momento en lo que hicimos y se pueden dar cuenta que tenemos todos los condimentos para armar una función: - Una *tarea* que quisiéramos realizar reiteradamente - Esa tarea implica una serie de pasos u *operaciones* estándares - Diferentes *inputs* que podemos recibir pero con una estructura similar - *Parámetros* que pueden tomar valores distintos -- Para construir una función debemos - asignarle un nombre - Inicializar la función con `function(arg1, arg2, ...){}` - `arg` serán los distintos argumentos que definiremos en nuestra función. - entre medio del corchete explicitamos todo lo que la función debe hacer --- ## Funciones propias En nuestro caso esos argumentos son un dataframe y un número que define la capacidad del local, y la tarea es el loop que definimos antes para determinar el ingreso .mid[ ```r mi_funcion <- function(df, lugares){ df$status <- NA for (i in 1:nrow(df)){ if(df$edad[i]>=18 & lugares>0){ lugares = lugares - 1 df$status[i] <- "Ingresa" } else{ df$status[i] <- "NO Ingresa" } if (lugares==0) { print ("El punto de corte es el id " %+% i) lugares = (-1) } } return(df) #necesario para que me "deje" #df en el environment } ``` ] --- ## Funciones propias Notar que en la función no escribimos *candidatos* porque hace alusión a un dataframe particular, en cambio escribimos *df* que es justamente el argumento que le pasamos a la función -- Dentro de la función no debemos llamar a nada que no esté definido en su entorno, es decir entre sus argumentos -- Es por esto que cambiamos también el nombre de *cupos* por *lugares* para hacer explicita esta distinción -- Este es un error típico cuando escribimos funciones --- ## Funciones propias Probemos nuestra función a ver si corre bien y hace el trabajo que necesitamos. ```r id <- seq(1:100) edad <- sample(17:25, 100, TRUE) candidatos <- data_frame(id, edad) ``` Nuestro trabajo es clasificar a los 100 hipotéticos candidatos en base a si son mayores de edad o no ```r candidatos <- mi_funcion(candidatos, 50) ``` ``` ## [1] "El punto de corte es el id 56" ``` --- ## Funciones propias La función nos avisa en qué momento se llena el local y genera este df como resultado <div style="border: 1px solid #ddd; padding: 0px; overflow-y: scroll; height:450px; overflow-x: scroll; width:100%; "><table class="table table-condensed table-responsive" style="font-size: 13px; margin-left: auto; margin-right: auto;"> <thead> <tr> <th style="text-align:right;position: sticky; top:0; background-color: #FFFFFF;"> id </th> <th style="text-align:right;position: sticky; top:0; background-color: #FFFFFF;"> edad </th> <th style="text-align:left;position: sticky; top:0; background-color: #FFFFFF;"> status </th> </tr> </thead> <tbody> <tr> <td style="text-align:right;"> 1 </td> <td style="text-align:right;"> 24 </td> <td style="text-align:left;"> Ingresa </td> </tr> <tr> <td style="text-align:right;"> 2 </td> <td style="text-align:right;"> 20 </td> <td style="text-align:left;"> Ingresa </td> </tr> <tr> <td style="text-align:right;"> 3 </td> <td style="text-align:right;"> 22 </td> <td style="text-align:left;"> Ingresa </td> </tr> <tr> <td style="text-align:right;"> 4 </td> <td style="text-align:right;"> 17 </td> <td style="text-align:left;"> NO Ingresa </td> </tr> <tr> <td style="text-align:right;"> 5 </td> <td style="text-align:right;"> 25 </td> <td style="text-align:left;"> Ingresa </td> </tr> <tr> <td style="text-align:right;"> 6 </td> <td style="text-align:right;"> 18 </td> <td style="text-align:left;"> Ingresa </td> </tr> <tr> <td style="text-align:right;"> 7 </td> <td style="text-align:right;"> 23 </td> <td style="text-align:left;"> Ingresa </td> </tr> <tr> <td style="text-align:right;"> 8 </td> <td style="text-align:right;"> 24 </td> <td style="text-align:left;"> Ingresa </td> </tr> <tr> <td style="text-align:right;"> 9 </td> <td style="text-align:right;"> 21 </td> <td style="text-align:left;"> Ingresa </td> </tr> <tr> <td style="text-align:right;"> 10 </td> <td style="text-align:right;"> 17 </td> <td style="text-align:left;"> NO Ingresa </td> </tr> <tr> <td style="text-align:right;"> 11 </td> <td style="text-align:right;"> 21 </td> <td style="text-align:left;"> Ingresa </td> </tr> <tr> <td style="text-align:right;"> 12 </td> <td style="text-align:right;"> 20 </td> <td style="text-align:left;"> Ingresa </td> </tr> <tr> <td style="text-align:right;"> 13 </td> <td style="text-align:right;"> 25 </td> <td style="text-align:left;"> Ingresa </td> </tr> <tr> <td style="text-align:right;"> 14 </td> <td style="text-align:right;"> 18 </td> <td style="text-align:left;"> Ingresa </td> </tr> <tr> <td style="text-align:right;"> 15 </td> <td style="text-align:right;"> 19 </td> <td style="text-align:left;"> Ingresa </td> </tr> <tr> <td style="text-align:right;"> 16 </td> <td style="text-align:right;"> 17 </td> <td style="text-align:left;"> NO Ingresa </td> </tr> <tr> <td style="text-align:right;"> 17 </td> <td style="text-align:right;"> 25 </td> <td style="text-align:left;"> Ingresa </td> </tr> <tr> <td style="text-align:right;"> 18 </td> <td style="text-align:right;"> 18 </td> <td style="text-align:left;"> Ingresa </td> </tr> <tr> <td style="text-align:right;"> 19 </td> <td style="text-align:right;"> 22 </td> <td style="text-align:left;"> Ingresa </td> </tr> <tr> <td style="text-align:right;"> 20 </td> <td style="text-align:right;"> 25 </td> <td style="text-align:left;"> Ingresa </td> </tr> <tr> <td style="text-align:right;"> 21 </td> <td style="text-align:right;"> 22 </td> <td style="text-align:left;"> Ingresa </td> </tr> <tr> <td style="text-align:right;"> 22 </td> <td style="text-align:right;"> 21 </td> <td style="text-align:left;"> Ingresa </td> </tr> <tr> <td style="text-align:right;"> 23 </td> <td style="text-align:right;"> 22 </td> <td style="text-align:left;"> Ingresa </td> </tr> <tr> <td style="text-align:right;"> 24 </td> <td style="text-align:right;"> 19 </td> <td style="text-align:left;"> Ingresa </td> </tr> <tr> <td style="text-align:right;"> 25 </td> <td style="text-align:right;"> 20 </td> <td style="text-align:left;"> Ingresa </td> </tr> <tr> <td style="text-align:right;"> 26 </td> <td style="text-align:right;"> 18 </td> <td style="text-align:left;"> Ingresa </td> </tr> <tr> <td style="text-align:right;"> 27 </td> <td style="text-align:right;"> 23 </td> <td style="text-align:left;"> Ingresa </td> </tr> <tr> <td style="text-align:right;"> 28 </td> <td style="text-align:right;"> 22 </td> <td style="text-align:left;"> Ingresa </td> </tr> <tr> <td style="text-align:right;"> 29 </td> <td style="text-align:right;"> 21 </td> <td style="text-align:left;"> Ingresa </td> </tr> <tr> <td style="text-align:right;"> 30 </td> <td style="text-align:right;"> 23 </td> <td style="text-align:left;"> Ingresa </td> </tr> <tr> <td style="text-align:right;"> 31 </td> <td style="text-align:right;"> 25 </td> <td style="text-align:left;"> Ingresa </td> </tr> <tr> <td style="text-align:right;"> 32 </td> <td style="text-align:right;"> 18 </td> <td style="text-align:left;"> Ingresa </td> </tr> <tr> <td style="text-align:right;"> 33 </td> <td style="text-align:right;"> 17 </td> <td style="text-align:left;"> NO Ingresa </td> </tr> <tr> <td style="text-align:right;"> 34 </td> <td style="text-align:right;"> 25 </td> <td style="text-align:left;"> Ingresa </td> </tr> <tr> <td style="text-align:right;"> 35 </td> <td style="text-align:right;"> 17 </td> <td style="text-align:left;"> NO Ingresa </td> </tr> <tr> <td style="text-align:right;"> 36 </td> <td style="text-align:right;"> 25 </td> <td style="text-align:left;"> Ingresa </td> </tr> <tr> <td style="text-align:right;"> 37 </td> <td style="text-align:right;"> 19 </td> <td style="text-align:left;"> Ingresa </td> </tr> <tr> <td style="text-align:right;"> 38 </td> <td style="text-align:right;"> 18 </td> <td style="text-align:left;"> Ingresa </td> </tr> <tr> <td style="text-align:right;"> 39 </td> <td style="text-align:right;"> 17 </td> <td style="text-align:left;"> NO Ingresa </td> </tr> <tr> <td style="text-align:right;"> 40 </td> <td style="text-align:right;"> 25 </td> <td style="text-align:left;"> Ingresa </td> </tr> <tr> <td style="text-align:right;"> 41 </td> <td style="text-align:right;"> 24 </td> <td style="text-align:left;"> Ingresa </td> </tr> <tr> <td style="text-align:right;"> 42 </td> <td style="text-align:right;"> 24 </td> <td style="text-align:left;"> Ingresa </td> </tr> <tr> <td style="text-align:right;"> 43 </td> <td style="text-align:right;"> 20 </td> <td style="text-align:left;"> Ingresa </td> </tr> <tr> <td style="text-align:right;"> 44 </td> <td style="text-align:right;"> 20 </td> <td style="text-align:left;"> Ingresa </td> </tr> <tr> <td style="text-align:right;"> 45 </td> <td style="text-align:right;"> 22 </td> <td style="text-align:left;"> Ingresa </td> </tr> <tr> <td style="text-align:right;"> 46 </td> <td style="text-align:right;"> 20 </td> <td style="text-align:left;"> Ingresa </td> </tr> <tr> <td style="text-align:right;"> 47 </td> <td style="text-align:right;"> 21 </td> <td style="text-align:left;"> Ingresa </td> </tr> <tr> <td style="text-align:right;"> 48 </td> <td style="text-align:right;"> 20 </td> <td style="text-align:left;"> Ingresa </td> </tr> <tr> <td style="text-align:right;"> 49 </td> <td style="text-align:right;"> 24 </td> <td style="text-align:left;"> Ingresa </td> </tr> <tr> <td style="text-align:right;"> 50 </td> <td style="text-align:right;"> 20 </td> <td style="text-align:left;"> Ingresa </td> </tr> <tr> <td style="text-align:right;"> 51 </td> <td style="text-align:right;"> 25 </td> <td style="text-align:left;"> Ingresa </td> </tr> <tr> <td style="text-align:right;"> 52 </td> <td style="text-align:right;"> 22 </td> <td style="text-align:left;"> Ingresa </td> </tr> <tr> <td style="text-align:right;"> 53 </td> <td style="text-align:right;"> 19 </td> <td style="text-align:left;"> Ingresa </td> </tr> <tr> <td style="text-align:right;"> 54 </td> <td style="text-align:right;"> 19 </td> <td style="text-align:left;"> Ingresa </td> </tr> <tr> <td style="text-align:right;"> 55 </td> <td style="text-align:right;"> 21 </td> <td style="text-align:left;"> Ingresa </td> </tr> <tr> <td style="text-align:right;"> 56 </td> <td style="text-align:right;"> 20 </td> <td style="text-align:left;"> Ingresa </td> </tr> <tr> <td style="text-align:right;"> 57 </td> <td style="text-align:right;"> 21 </td> <td style="text-align:left;"> NO Ingresa </td> </tr> <tr> <td style="text-align:right;"> 58 </td> <td style="text-align:right;"> 22 </td> <td style="text-align:left;"> NO Ingresa </td> </tr> <tr> <td style="text-align:right;"> 59 </td> <td style="text-align:right;"> 19 </td> <td style="text-align:left;"> NO Ingresa </td> </tr> <tr> <td style="text-align:right;"> 60 </td> <td style="text-align:right;"> 19 </td> <td style="text-align:left;"> NO Ingresa </td> </tr> <tr> <td style="text-align:right;"> 61 </td> <td style="text-align:right;"> 21 </td> <td style="text-align:left;"> NO Ingresa </td> </tr> <tr> <td style="text-align:right;"> 62 </td> <td style="text-align:right;"> 20 </td> <td style="text-align:left;"> NO Ingresa </td> </tr> <tr> <td style="text-align:right;"> 63 </td> <td style="text-align:right;"> 20 </td> <td style="text-align:left;"> NO Ingresa </td> </tr> <tr> <td style="text-align:right;"> 64 </td> <td style="text-align:right;"> 22 </td> <td style="text-align:left;"> NO Ingresa </td> </tr> <tr> <td style="text-align:right;"> 65 </td> <td style="text-align:right;"> 17 </td> <td style="text-align:left;"> NO Ingresa </td> </tr> <tr> <td style="text-align:right;"> 66 </td> <td style="text-align:right;"> 22 </td> <td style="text-align:left;"> NO Ingresa </td> </tr> <tr> <td style="text-align:right;"> 67 </td> <td style="text-align:right;"> 20 </td> <td style="text-align:left;"> NO Ingresa </td> </tr> <tr> <td style="text-align:right;"> 68 </td> <td style="text-align:right;"> 17 </td> <td style="text-align:left;"> NO Ingresa </td> </tr> <tr> <td style="text-align:right;"> 69 </td> <td style="text-align:right;"> 18 </td> <td style="text-align:left;"> NO Ingresa </td> </tr> <tr> <td style="text-align:right;"> 70 </td> <td style="text-align:right;"> 21 </td> <td style="text-align:left;"> NO Ingresa </td> </tr> <tr> <td style="text-align:right;"> 71 </td> <td style="text-align:right;"> 18 </td> <td style="text-align:left;"> NO Ingresa </td> </tr> <tr> <td style="text-align:right;"> 72 </td> <td style="text-align:right;"> 20 </td> <td style="text-align:left;"> NO Ingresa </td> </tr> <tr> <td style="text-align:right;"> 73 </td> <td style="text-align:right;"> 21 </td> <td style="text-align:left;"> NO Ingresa </td> </tr> <tr> <td style="text-align:right;"> 74 </td> <td style="text-align:right;"> 22 </td> <td style="text-align:left;"> NO Ingresa </td> </tr> <tr> <td style="text-align:right;"> 75 </td> <td style="text-align:right;"> 19 </td> <td style="text-align:left;"> NO Ingresa </td> </tr> <tr> <td style="text-align:right;"> 76 </td> <td style="text-align:right;"> 25 </td> <td style="text-align:left;"> NO Ingresa </td> </tr> <tr> <td style="text-align:right;"> 77 </td> <td style="text-align:right;"> 23 </td> <td style="text-align:left;"> NO Ingresa </td> </tr> <tr> <td style="text-align:right;"> 78 </td> <td style="text-align:right;"> 19 </td> <td style="text-align:left;"> NO Ingresa </td> </tr> <tr> <td style="text-align:right;"> 79 </td> <td style="text-align:right;"> 23 </td> <td style="text-align:left;"> NO Ingresa </td> </tr> <tr> <td style="text-align:right;"> 80 </td> <td style="text-align:right;"> 19 </td> <td style="text-align:left;"> NO Ingresa </td> </tr> <tr> <td style="text-align:right;"> 81 </td> <td style="text-align:right;"> 24 </td> <td style="text-align:left;"> NO Ingresa </td> </tr> <tr> <td style="text-align:right;"> 82 </td> <td style="text-align:right;"> 23 </td> <td style="text-align:left;"> NO Ingresa </td> </tr> <tr> <td style="text-align:right;"> 83 </td> <td style="text-align:right;"> 23 </td> <td style="text-align:left;"> NO Ingresa </td> </tr> <tr> <td style="text-align:right;"> 84 </td> <td style="text-align:right;"> 22 </td> <td style="text-align:left;"> NO Ingresa </td> </tr> <tr> <td style="text-align:right;"> 85 </td> <td style="text-align:right;"> 19 </td> <td style="text-align:left;"> NO Ingresa </td> </tr> <tr> <td style="text-align:right;"> 86 </td> <td style="text-align:right;"> 23 </td> <td style="text-align:left;"> NO Ingresa </td> </tr> <tr> <td style="text-align:right;"> 87 </td> <td style="text-align:right;"> 18 </td> <td style="text-align:left;"> NO Ingresa </td> </tr> <tr> <td style="text-align:right;"> 88 </td> <td style="text-align:right;"> 22 </td> <td style="text-align:left;"> NO Ingresa </td> </tr> <tr> <td style="text-align:right;"> 89 </td> <td style="text-align:right;"> 19 </td> <td style="text-align:left;"> NO Ingresa </td> </tr> <tr> <td style="text-align:right;"> 90 </td> <td style="text-align:right;"> 25 </td> <td style="text-align:left;"> NO Ingresa </td> </tr> <tr> <td style="text-align:right;"> 91 </td> <td style="text-align:right;"> 18 </td> <td style="text-align:left;"> NO Ingresa </td> </tr> <tr> <td style="text-align:right;"> 92 </td> <td style="text-align:right;"> 19 </td> <td style="text-align:left;"> NO Ingresa </td> </tr> <tr> <td style="text-align:right;"> 93 </td> <td style="text-align:right;"> 25 </td> <td style="text-align:left;"> NO Ingresa </td> </tr> <tr> <td style="text-align:right;"> 94 </td> <td style="text-align:right;"> 25 </td> <td style="text-align:left;"> NO Ingresa </td> </tr> <tr> <td style="text-align:right;"> 95 </td> <td style="text-align:right;"> 22 </td> <td style="text-align:left;"> NO Ingresa </td> </tr> <tr> <td style="text-align:right;"> 96 </td> <td style="text-align:right;"> 21 </td> <td style="text-align:left;"> NO Ingresa </td> </tr> <tr> <td style="text-align:right;"> 97 </td> <td style="text-align:right;"> 24 </td> <td style="text-align:left;"> NO Ingresa </td> </tr> <tr> <td style="text-align:right;"> 98 </td> <td style="text-align:right;"> 21 </td> <td style="text-align:left;"> NO Ingresa </td> </tr> <tr> <td style="text-align:right;"> 99 </td> <td style="text-align:right;"> 17 </td> <td style="text-align:left;"> NO Ingresa </td> </tr> <tr> <td style="text-align:right;"> 100 </td> <td style="text-align:right;"> 25 </td> <td style="text-align:left;"> NO Ingresa </td> </tr> </tbody> </table></div> --- ## Funciones propias Ahora que ya saben como pueden automatizar este trabajo de control de caso por caso, se dan cuenta de que pueden manejar mas de un local a la vez -- Estos son los beneficios de saber R ;) -- Entonces ahora reciben varias lista de aplicaciones para varios locales distintos. Creemos estas bases de aplicaciones ficticias .mid[ ```r id_1 <- seq(1:100) id_2 <- seq(1:250) id_3 <- seq(1:500) edad_1 <- sample(17:25, 100, TRUE) edad_2 <- sample(17:25, 250, TRUE) edad_3 <- sample(17:25, 500, TRUE) local_1 <- data_frame(id_1, edad_1) %>% rename(id = id_1, edad=edad_1) local_2 <- data_frame(id_2, edad_2) %>% rename(id = id_2, edad=edad_2) local_3 <- data_frame(id_3, edad_3) %>% rename(id = id_3, edad=edad_3) ``` ] --- ## Funciones propias Cuando terminemos esta clase, espero que esto sea lo primero que se les venga a la mente cuando aparezca un código como el anterior: <img src="inputs/Clase5/cartel_mod1.jpg" width="60%" height="40%" style="display: block; margin: auto;" /> --- ## Funciones propias Bien, retomemos...entonces tenemos varios df para pasarle a nuestra función con la lista de postulantes Quisiéramos aplicar algo que en intuición sea parecido a lo siguiente ```r locales <- c(local_1, local_2, local_3) capacidad <- c(50, 70, 85) ``` ```r i= 1 for(df in locales){ x <- capacidad[i] df <- mi_funcion(df, x) i = i+1 } ``` --- ## Listas Ahora, fijemosnos qué dimensión tiene nuestro vector de arriba ```r length(locales) ``` ``` ## [1] 6 ``` -- Tiene 6 elementos! Pero guardamos 3 dataframes... -- Lo que sucede es que los vectores no pueden almacenar un dataframe como elemento, solo almacenan una coleccion de valores, no de filas y columnas -- Es por eso que nuestro vector tiene 6 elementos, porque cada *df* tenía 2 columnas (3*2). Es decir que convierte un df en vectores, tratando a cada columna como un vector distinto -- Esto entonces no nos sirve para iterar sobre dataframes --- ## Listas Un concepto muy importante y útil en programación con R son las listas. -- ¿Qué son? -- Bueno, pueden pensarlo como **vectores más versátiles**, que en su interior pueden almacenar objetos de distinto tipo y distintas clases y por tanto son **estructuras heterogéneas**. -- Podemos tener listas que contengan datos atómicos, vectores, matrices, data frames, etc, e incluso u otras listas. <br> -- Exploremos un ejemplo --- ## Listas ```r edad <- sample(17:25, 50, TRUE) matriz <- matrix(1:4, nrow = 2) df <- candidatos mi_lista <- list(edad, matriz, df) mi_lista ``` ``` ## [[1]] ## [1] 23 24 21 25 22 20 18 22 22 20 24 17 22 24 22 18 19 19 20 18 20 23 24 17 21 ## [26] 24 21 25 24 21 25 20 19 23 24 24 25 21 25 23 17 18 24 18 17 24 17 21 19 18 ## ## [[2]] ## [,1] [,2] ## [1,] 1 3 ## [2,] 2 4 ## ## [[3]] ## # A tibble: 100 x 3 ## id edad status ## <int> <int> <chr> ## 1 1 24 Ingresa ## 2 2 20 Ingresa ## 3 3 22 Ingresa ## 4 4 17 NO Ingresa ## 5 5 25 Ingresa ## 6 6 18 Ingresa ## 7 7 23 Ingresa ## 8 8 24 Ingresa ## 9 9 21 Ingresa ## 10 10 17 NO Ingresa ## # ... with 90 more rows ``` --- ## Listas Como ya sospechan, las listas se construyen con la función `list()` -- Y así como a los vectores accedíamos con la indexación, aquí es lo mismo puesto que cada elemento tiene una posición -- La única diferencia es que para las listas usamos doble corchete :`[[i]]` - `vector[i]` - `listas[[i]]` ```r mi_lista[[2]] ``` ``` ## [,1] [,2] ## [1,] 1 3 ## [2,] 2 4 ``` --- ## Funciones propias y listas Bien, ya estamos equipados con lo que necesitamos para que podamos iterar sobre dataframes -- Volvamos a nuestra tarea: ```r locales_vec <- list(local_1, local_2, local_3) capacidad <- c(50, 70, 85) i= 1 for(df in locales_vec){ x <- capacidad[i] df <- mi_funcion(df, x) i = i+1 } ``` ``` ## [1] "El punto de corte es el id 57" ## [1] "El punto de corte es el id 79" ## [1] "El punto de corte es el id 95" ``` -- Esta función corre bien, pero... logramos lo que queremos? --- ## Funciones propias y listas No! En cada iteración, genera un nuevo dataframe que guarda siempre en el objeto `df` -- Es decir pisa siempre al objeto, y por tanto por mas que itere muchas veces nos quedará al final del loop un solo objeto generado en la última vuelta -- Lo que necesitamos es que el df que toma en cada vuelta quede almacenado con los cambios para luego recuperarlo. -- Indexar cada elemento de la lista nos va ayudar en esto --- ## Funciones propias y listas ```r locales <- list(local_1, local_2, local_3) capacidad <- c(50, 70, 85) for(i in 1:length(locales)){ x <- capacidad[i] locales[[i]] <- mi_funcion(locales[[i]], x) } ``` ``` ## [1] "El punto de corte es el id 57" ## [1] "El punto de corte es el id 79" ## [1] "El punto de corte es el id 95" ``` Ahora solo debemos recuperar cada dataframe guardado en cada elemento de nuestra lista ```r local_1 <- as.data.frame(locales[[1]]) local_2 <- as.data.frame(locales[[2]]) local_3 <- as.data.frame(locales[[3]]) ``` --- ## Funciones propias y listas Elijamos el segundo dataframe para verificar. Ninguna menor de 18 debería ingresar y a partir del postulante 76 en adelante tampoco, ya que los lugares estaban completos. <div style="border: 1px solid #ddd; padding: 0px; overflow-y: scroll; height:450px; overflow-x: scroll; width:100%; "><table class="table table-condensed table-responsive" style="font-size: 13px; margin-left: auto; margin-right: auto;"> <thead> <tr> <th style="text-align:right;position: sticky; top:0; background-color: #FFFFFF;"> id </th> <th style="text-align:right;position: sticky; top:0; background-color: #FFFFFF;"> edad </th> <th style="text-align:left;position: sticky; top:0; background-color: #FFFFFF;"> status </th> </tr> </thead> <tbody> <tr> <td style="text-align:right;"> 1 </td> <td style="text-align:right;"> 22 </td> <td style="text-align:left;"> Ingresa </td> </tr> <tr> <td style="text-align:right;"> 2 </td> <td style="text-align:right;"> 20 </td> <td style="text-align:left;"> Ingresa </td> </tr> <tr> <td style="text-align:right;"> 3 </td> <td style="text-align:right;"> 20 </td> <td style="text-align:left;"> Ingresa </td> </tr> <tr> <td style="text-align:right;"> 4 </td> <td style="text-align:right;"> 22 </td> <td style="text-align:left;"> Ingresa </td> </tr> <tr> <td style="text-align:right;"> 5 </td> <td style="text-align:right;"> 23 </td> <td style="text-align:left;"> Ingresa </td> </tr> <tr> <td style="text-align:right;"> 6 </td> <td style="text-align:right;"> 18 </td> <td style="text-align:left;"> Ingresa </td> </tr> <tr> <td style="text-align:right;"> 7 </td> <td style="text-align:right;"> 20 </td> <td style="text-align:left;"> Ingresa </td> </tr> <tr> <td style="text-align:right;"> 8 </td> <td style="text-align:right;"> 20 </td> <td style="text-align:left;"> Ingresa </td> </tr> <tr> <td style="text-align:right;"> 9 </td> <td style="text-align:right;"> 21 </td> <td style="text-align:left;"> Ingresa </td> </tr> <tr> <td style="text-align:right;"> 10 </td> <td style="text-align:right;"> 22 </td> <td style="text-align:left;"> Ingresa </td> </tr> <tr> <td style="text-align:right;"> 11 </td> <td style="text-align:right;"> 21 </td> <td style="text-align:left;"> Ingresa </td> </tr> <tr> <td style="text-align:right;"> 12 </td> <td style="text-align:right;"> 18 </td> <td style="text-align:left;"> Ingresa </td> </tr> <tr> <td style="text-align:right;"> 13 </td> <td style="text-align:right;"> 25 </td> <td style="text-align:left;"> Ingresa </td> </tr> <tr> <td style="text-align:right;"> 14 </td> <td style="text-align:right;"> 20 </td> <td style="text-align:left;"> Ingresa </td> </tr> <tr> <td style="text-align:right;"> 15 </td> <td style="text-align:right;"> 25 </td> <td style="text-align:left;"> Ingresa </td> </tr> <tr> <td style="text-align:right;"> 16 </td> <td style="text-align:right;"> 24 </td> <td style="text-align:left;"> Ingresa </td> </tr> <tr> <td style="text-align:right;"> 17 </td> <td style="text-align:right;"> 17 </td> <td style="text-align:left;"> NO Ingresa </td> </tr> <tr> <td style="text-align:right;"> 18 </td> <td style="text-align:right;"> 21 </td> <td style="text-align:left;"> Ingresa </td> </tr> <tr> <td style="text-align:right;"> 19 </td> <td style="text-align:right;"> 21 </td> <td style="text-align:left;"> Ingresa </td> </tr> <tr> <td style="text-align:right;"> 20 </td> <td style="text-align:right;"> 19 </td> <td style="text-align:left;"> Ingresa </td> </tr> <tr> <td style="text-align:right;"> 21 </td> <td style="text-align:right;"> 20 </td> <td style="text-align:left;"> Ingresa </td> </tr> <tr> <td style="text-align:right;"> 22 </td> <td style="text-align:right;"> 24 </td> <td style="text-align:left;"> Ingresa </td> </tr> <tr> <td style="text-align:right;"> 23 </td> <td style="text-align:right;"> 19 </td> <td style="text-align:left;"> Ingresa </td> </tr> <tr> <td style="text-align:right;"> 24 </td> <td style="text-align:right;"> 24 </td> <td style="text-align:left;"> Ingresa </td> </tr> <tr> <td style="text-align:right;"> 25 </td> <td style="text-align:right;"> 23 </td> <td style="text-align:left;"> Ingresa </td> </tr> <tr> <td style="text-align:right;"> 26 </td> <td style="text-align:right;"> 17 </td> <td style="text-align:left;"> NO Ingresa </td> </tr> <tr> <td style="text-align:right;"> 27 </td> <td style="text-align:right;"> 23 </td> <td style="text-align:left;"> Ingresa </td> </tr> <tr> <td style="text-align:right;"> 28 </td> <td style="text-align:right;"> 25 </td> <td style="text-align:left;"> Ingresa </td> </tr> <tr> <td style="text-align:right;"> 29 </td> <td style="text-align:right;"> 20 </td> <td style="text-align:left;"> Ingresa </td> </tr> <tr> <td style="text-align:right;"> 30 </td> <td style="text-align:right;"> 17 </td> <td style="text-align:left;"> NO Ingresa </td> </tr> <tr> <td style="text-align:right;"> 31 </td> <td style="text-align:right;"> 25 </td> <td style="text-align:left;"> Ingresa </td> </tr> <tr> <td style="text-align:right;"> 32 </td> <td style="text-align:right;"> 20 </td> <td style="text-align:left;"> Ingresa </td> </tr> <tr> <td style="text-align:right;"> 33 </td> <td style="text-align:right;"> 18 </td> <td style="text-align:left;"> Ingresa </td> </tr> <tr> <td style="text-align:right;"> 34 </td> <td style="text-align:right;"> 19 </td> <td style="text-align:left;"> Ingresa </td> </tr> <tr> <td style="text-align:right;"> 35 </td> <td style="text-align:right;"> 18 </td> <td style="text-align:left;"> Ingresa </td> </tr> <tr> <td style="text-align:right;"> 36 </td> <td style="text-align:right;"> 23 </td> <td style="text-align:left;"> Ingresa </td> </tr> <tr> <td style="text-align:right;"> 37 </td> <td style="text-align:right;"> 20 </td> <td style="text-align:left;"> Ingresa </td> </tr> <tr> <td style="text-align:right;"> 38 </td> <td style="text-align:right;"> 17 </td> <td style="text-align:left;"> NO Ingresa </td> </tr> <tr> <td style="text-align:right;"> 39 </td> <td style="text-align:right;"> 19 </td> <td style="text-align:left;"> Ingresa </td> </tr> <tr> <td style="text-align:right;"> 40 </td> <td style="text-align:right;"> 20 </td> <td style="text-align:left;"> Ingresa </td> </tr> <tr> <td style="text-align:right;"> 41 </td> <td style="text-align:right;"> 19 </td> <td style="text-align:left;"> Ingresa </td> </tr> <tr> <td style="text-align:right;"> 42 </td> <td style="text-align:right;"> 23 </td> <td style="text-align:left;"> Ingresa </td> </tr> <tr> <td style="text-align:right;"> 43 </td> <td style="text-align:right;"> 22 </td> <td style="text-align:left;"> Ingresa </td> </tr> <tr> <td style="text-align:right;"> 44 </td> <td style="text-align:right;"> 23 </td> <td style="text-align:left;"> Ingresa </td> </tr> <tr> <td style="text-align:right;"> 45 </td> <td style="text-align:right;"> 17 </td> <td style="text-align:left;"> NO Ingresa </td> </tr> <tr> <td style="text-align:right;"> 46 </td> <td style="text-align:right;"> 20 </td> <td style="text-align:left;"> Ingresa </td> </tr> <tr> <td style="text-align:right;"> 47 </td> <td style="text-align:right;"> 23 </td> <td style="text-align:left;"> Ingresa </td> </tr> <tr> <td style="text-align:right;"> 48 </td> <td style="text-align:right;"> 20 </td> <td style="text-align:left;"> Ingresa </td> </tr> <tr> <td style="text-align:right;"> 49 </td> <td style="text-align:right;"> 25 </td> <td style="text-align:left;"> Ingresa </td> </tr> <tr> <td style="text-align:right;"> 50 </td> <td style="text-align:right;"> 25 </td> <td style="text-align:left;"> Ingresa </td> </tr> <tr> <td style="text-align:right;"> 51 </td> <td style="text-align:right;"> 23 </td> <td style="text-align:left;"> Ingresa </td> </tr> <tr> <td style="text-align:right;"> 52 </td> <td style="text-align:right;"> 22 </td> <td style="text-align:left;"> Ingresa </td> </tr> <tr> <td style="text-align:right;"> 53 </td> <td style="text-align:right;"> 20 </td> <td style="text-align:left;"> Ingresa </td> </tr> <tr> <td style="text-align:right;"> 54 </td> <td style="text-align:right;"> 22 </td> <td style="text-align:left;"> Ingresa </td> </tr> <tr> <td style="text-align:right;"> 55 </td> <td style="text-align:right;"> 17 </td> <td style="text-align:left;"> NO Ingresa </td> </tr> <tr> <td style="text-align:right;"> 56 </td> <td style="text-align:right;"> 17 </td> <td style="text-align:left;"> NO Ingresa </td> </tr> <tr> <td style="text-align:right;"> 57 </td> <td style="text-align:right;"> 21 </td> <td style="text-align:left;"> Ingresa </td> </tr> <tr> <td style="text-align:right;"> 58 </td> <td style="text-align:right;"> 22 </td> <td style="text-align:left;"> Ingresa </td> </tr> <tr> <td style="text-align:right;"> 59 </td> <td style="text-align:right;"> 19 </td> <td style="text-align:left;"> Ingresa </td> </tr> <tr> <td style="text-align:right;"> 60 </td> <td style="text-align:right;"> 21 </td> <td style="text-align:left;"> Ingresa </td> </tr> <tr> <td style="text-align:right;"> 61 </td> <td style="text-align:right;"> 18 </td> <td style="text-align:left;"> Ingresa </td> </tr> <tr> <td style="text-align:right;"> 62 </td> <td style="text-align:right;"> 21 </td> <td style="text-align:left;"> Ingresa </td> </tr> <tr> <td style="text-align:right;"> 63 </td> <td style="text-align:right;"> 18 </td> <td style="text-align:left;"> Ingresa </td> </tr> <tr> <td style="text-align:right;"> 64 </td> <td style="text-align:right;"> 18 </td> <td style="text-align:left;"> Ingresa </td> </tr> <tr> <td style="text-align:right;"> 65 </td> <td style="text-align:right;"> 24 </td> <td style="text-align:left;"> Ingresa </td> </tr> <tr> <td style="text-align:right;"> 66 </td> <td style="text-align:right;"> 20 </td> <td style="text-align:left;"> Ingresa </td> </tr> <tr> <td style="text-align:right;"> 67 </td> <td style="text-align:right;"> 21 </td> <td style="text-align:left;"> Ingresa </td> </tr> <tr> <td style="text-align:right;"> 68 </td> <td style="text-align:right;"> 25 </td> <td style="text-align:left;"> Ingresa </td> </tr> <tr> <td style="text-align:right;"> 69 </td> <td style="text-align:right;"> 19 </td> <td style="text-align:left;"> Ingresa </td> </tr> <tr> <td style="text-align:right;"> 70 </td> <td style="text-align:right;"> 17 </td> <td style="text-align:left;"> NO Ingresa </td> </tr> <tr> <td style="text-align:right;"> 71 </td> <td style="text-align:right;"> 22 </td> <td style="text-align:left;"> Ingresa </td> </tr> <tr> <td style="text-align:right;"> 72 </td> <td style="text-align:right;"> 17 </td> <td style="text-align:left;"> NO Ingresa </td> </tr> <tr> <td style="text-align:right;"> 73 </td> <td style="text-align:right;"> 22 </td> <td style="text-align:left;"> Ingresa </td> </tr> <tr> <td style="text-align:right;"> 74 </td> <td style="text-align:right;"> 23 </td> <td style="text-align:left;"> Ingresa </td> </tr> <tr> <td style="text-align:right;"> 75 </td> <td style="text-align:right;"> 20 </td> <td style="text-align:left;"> Ingresa </td> </tr> <tr> <td style="text-align:right;"> 76 </td> <td style="text-align:right;"> 25 </td> <td style="text-align:left;"> Ingresa </td> </tr> <tr> <td style="text-align:right;"> 77 </td> <td style="text-align:right;"> 18 </td> <td style="text-align:left;"> Ingresa </td> </tr> <tr> <td style="text-align:right;"> 78 </td> <td style="text-align:right;"> 25 </td> <td style="text-align:left;"> Ingresa </td> </tr> <tr> <td style="text-align:right;"> 79 </td> <td style="text-align:right;"> 24 </td> <td style="text-align:left;"> Ingresa </td> </tr> <tr> <td style="text-align:right;"> 80 </td> <td style="text-align:right;"> 18 </td> <td style="text-align:left;"> NO Ingresa </td> </tr> <tr> <td style="text-align:right;"> 81 </td> <td style="text-align:right;"> 23 </td> <td style="text-align:left;"> NO Ingresa </td> </tr> <tr> <td style="text-align:right;"> 82 </td> <td style="text-align:right;"> 18 </td> <td style="text-align:left;"> NO Ingresa </td> </tr> <tr> <td style="text-align:right;"> 83 </td> <td style="text-align:right;"> 24 </td> <td style="text-align:left;"> NO Ingresa </td> </tr> <tr> <td style="text-align:right;"> 84 </td> <td style="text-align:right;"> 20 </td> <td style="text-align:left;"> NO Ingresa </td> </tr> <tr> <td style="text-align:right;"> 85 </td> <td style="text-align:right;"> 25 </td> <td style="text-align:left;"> NO Ingresa </td> </tr> <tr> <td style="text-align:right;"> 86 </td> <td style="text-align:right;"> 18 </td> <td style="text-align:left;"> NO Ingresa </td> </tr> <tr> <td style="text-align:right;"> 87 </td> <td style="text-align:right;"> 19 </td> <td style="text-align:left;"> NO Ingresa </td> </tr> <tr> <td style="text-align:right;"> 88 </td> <td style="text-align:right;"> 22 </td> <td style="text-align:left;"> NO Ingresa </td> </tr> <tr> <td style="text-align:right;"> 89 </td> <td style="text-align:right;"> 21 </td> <td style="text-align:left;"> NO Ingresa </td> </tr> <tr> <td style="text-align:right;"> 90 </td> <td style="text-align:right;"> 22 </td> <td style="text-align:left;"> NO Ingresa </td> </tr> <tr> <td style="text-align:right;"> 91 </td> <td style="text-align:right;"> 17 </td> <td style="text-align:left;"> NO Ingresa </td> </tr> <tr> <td style="text-align:right;"> 92 </td> <td style="text-align:right;"> 22 </td> <td style="text-align:left;"> NO Ingresa </td> </tr> <tr> <td style="text-align:right;"> 93 </td> <td style="text-align:right;"> 23 </td> <td style="text-align:left;"> NO Ingresa </td> </tr> <tr> <td style="text-align:right;"> 94 </td> <td style="text-align:right;"> 25 </td> <td style="text-align:left;"> NO Ingresa </td> </tr> <tr> <td style="text-align:right;"> 95 </td> <td style="text-align:right;"> 25 </td> <td style="text-align:left;"> NO Ingresa </td> </tr> <tr> <td style="text-align:right;"> 96 </td> <td style="text-align:right;"> 24 </td> <td style="text-align:left;"> NO Ingresa </td> </tr> <tr> <td style="text-align:right;"> 97 </td> <td style="text-align:right;"> 25 </td> <td style="text-align:left;"> NO Ingresa </td> </tr> <tr> <td style="text-align:right;"> 98 </td> <td style="text-align:right;"> 25 </td> <td style="text-align:left;"> NO Ingresa </td> </tr> <tr> <td style="text-align:right;"> 99 </td> <td style="text-align:right;"> 21 </td> <td style="text-align:left;"> NO Ingresa </td> </tr> <tr> <td style="text-align:right;"> 100 </td> <td style="text-align:right;"> 21 </td> <td style="text-align:left;"> NO Ingresa </td> </tr> <tr> <td style="text-align:right;"> 101 </td> <td style="text-align:right;"> 18 </td> <td style="text-align:left;"> NO Ingresa </td> </tr> <tr> <td style="text-align:right;"> 102 </td> <td style="text-align:right;"> 21 </td> <td style="text-align:left;"> NO Ingresa </td> </tr> <tr> <td style="text-align:right;"> 103 </td> <td style="text-align:right;"> 25 </td> <td style="text-align:left;"> NO Ingresa </td> </tr> <tr> <td style="text-align:right;"> 104 </td> <td style="text-align:right;"> 23 </td> <td style="text-align:left;"> NO Ingresa </td> </tr> <tr> <td style="text-align:right;"> 105 </td> <td style="text-align:right;"> 19 </td> <td style="text-align:left;"> NO Ingresa </td> </tr> <tr> <td style="text-align:right;"> 106 </td> <td style="text-align:right;"> 19 </td> <td style="text-align:left;"> NO Ingresa </td> </tr> <tr> <td style="text-align:right;"> 107 </td> <td style="text-align:right;"> 17 </td> <td style="text-align:left;"> NO Ingresa </td> </tr> <tr> <td style="text-align:right;"> 108 </td> <td style="text-align:right;"> 24 </td> <td style="text-align:left;"> NO Ingresa </td> </tr> <tr> <td style="text-align:right;"> 109 </td> <td style="text-align:right;"> 25 </td> <td style="text-align:left;"> NO Ingresa </td> </tr> <tr> <td style="text-align:right;"> 110 </td> <td style="text-align:right;"> 25 </td> <td style="text-align:left;"> NO Ingresa </td> </tr> <tr> <td style="text-align:right;"> 111 </td> <td style="text-align:right;"> 17 </td> <td style="text-align:left;"> NO Ingresa </td> </tr> <tr> <td style="text-align:right;"> 112 </td> <td style="text-align:right;"> 20 </td> <td style="text-align:left;"> NO Ingresa </td> </tr> <tr> <td style="text-align:right;"> 113 </td> <td style="text-align:right;"> 23 </td> <td style="text-align:left;"> NO Ingresa </td> </tr> <tr> <td style="text-align:right;"> 114 </td> <td style="text-align:right;"> 21 </td> <td style="text-align:left;"> NO Ingresa </td> </tr> <tr> <td style="text-align:right;"> 115 </td> <td style="text-align:right;"> 17 </td> <td style="text-align:left;"> NO Ingresa </td> </tr> <tr> <td style="text-align:right;"> 116 </td> <td style="text-align:right;"> 24 </td> <td style="text-align:left;"> NO Ingresa </td> </tr> <tr> <td style="text-align:right;"> 117 </td> <td style="text-align:right;"> 25 </td> <td style="text-align:left;"> NO Ingresa </td> </tr> <tr> <td style="text-align:right;"> 118 </td> <td style="text-align:right;"> 20 </td> <td style="text-align:left;"> NO Ingresa </td> </tr> <tr> <td style="text-align:right;"> 119 </td> <td style="text-align:right;"> 25 </td> <td style="text-align:left;"> NO Ingresa </td> </tr> <tr> <td style="text-align:right;"> 120 </td> <td style="text-align:right;"> 18 </td> <td style="text-align:left;"> NO Ingresa </td> </tr> <tr> <td style="text-align:right;"> 121 </td> <td style="text-align:right;"> 23 </td> <td style="text-align:left;"> NO Ingresa </td> </tr> <tr> <td style="text-align:right;"> 122 </td> <td style="text-align:right;"> 21 </td> <td style="text-align:left;"> NO Ingresa </td> </tr> <tr> <td style="text-align:right;"> 123 </td> <td style="text-align:right;"> 17 </td> <td style="text-align:left;"> NO Ingresa </td> </tr> <tr> <td style="text-align:right;"> 124 </td> <td style="text-align:right;"> 20 </td> <td style="text-align:left;"> NO Ingresa </td> </tr> <tr> <td style="text-align:right;"> 125 </td> <td style="text-align:right;"> 20 </td> <td style="text-align:left;"> NO Ingresa </td> </tr> <tr> <td style="text-align:right;"> 126 </td> <td style="text-align:right;"> 23 </td> <td style="text-align:left;"> NO Ingresa </td> </tr> <tr> <td style="text-align:right;"> 127 </td> <td style="text-align:right;"> 18 </td> <td style="text-align:left;"> NO Ingresa </td> </tr> <tr> <td style="text-align:right;"> 128 </td> <td style="text-align:right;"> 25 </td> <td style="text-align:left;"> NO Ingresa </td> </tr> <tr> <td style="text-align:right;"> 129 </td> <td style="text-align:right;"> 22 </td> <td style="text-align:left;"> NO Ingresa </td> </tr> <tr> <td style="text-align:right;"> 130 </td> <td style="text-align:right;"> 23 </td> <td style="text-align:left;"> NO Ingresa </td> </tr> <tr> <td style="text-align:right;"> 131 </td> <td style="text-align:right;"> 18 </td> <td style="text-align:left;"> NO Ingresa </td> </tr> <tr> <td style="text-align:right;"> 132 </td> <td style="text-align:right;"> 24 </td> <td style="text-align:left;"> NO Ingresa </td> </tr> <tr> <td style="text-align:right;"> 133 </td> <td style="text-align:right;"> 18 </td> <td style="text-align:left;"> NO Ingresa </td> </tr> <tr> <td style="text-align:right;"> 134 </td> <td style="text-align:right;"> 24 </td> <td style="text-align:left;"> NO Ingresa </td> </tr> <tr> <td style="text-align:right;"> 135 </td> <td style="text-align:right;"> 23 </td> <td style="text-align:left;"> NO Ingresa </td> </tr> <tr> <td style="text-align:right;"> 136 </td> <td style="text-align:right;"> 25 </td> <td style="text-align:left;"> NO Ingresa </td> </tr> <tr> <td style="text-align:right;"> 137 </td> <td style="text-align:right;"> 22 </td> <td style="text-align:left;"> NO Ingresa </td> </tr> <tr> <td style="text-align:right;"> 138 </td> <td style="text-align:right;"> 24 </td> <td style="text-align:left;"> NO Ingresa </td> </tr> <tr> <td style="text-align:right;"> 139 </td> <td style="text-align:right;"> 17 </td> <td style="text-align:left;"> NO Ingresa </td> </tr> <tr> <td style="text-align:right;"> 140 </td> <td style="text-align:right;"> 20 </td> <td style="text-align:left;"> NO Ingresa </td> </tr> <tr> <td style="text-align:right;"> 141 </td> <td style="text-align:right;"> 20 </td> <td style="text-align:left;"> NO Ingresa </td> </tr> <tr> <td style="text-align:right;"> 142 </td> <td style="text-align:right;"> 25 </td> <td style="text-align:left;"> NO Ingresa </td> </tr> <tr> <td style="text-align:right;"> 143 </td> <td style="text-align:right;"> 17 </td> <td style="text-align:left;"> NO Ingresa </td> </tr> <tr> <td style="text-align:right;"> 144 </td> <td style="text-align:right;"> 18 </td> <td style="text-align:left;"> NO Ingresa </td> </tr> <tr> <td style="text-align:right;"> 145 </td> <td style="text-align:right;"> 21 </td> <td style="text-align:left;"> NO Ingresa </td> </tr> <tr> <td style="text-align:right;"> 146 </td> <td style="text-align:right;"> 24 </td> <td style="text-align:left;"> NO Ingresa </td> </tr> <tr> <td style="text-align:right;"> 147 </td> <td style="text-align:right;"> 17 </td> <td style="text-align:left;"> NO Ingresa </td> </tr> <tr> <td style="text-align:right;"> 148 </td> <td style="text-align:right;"> 17 </td> <td style="text-align:left;"> NO Ingresa </td> </tr> <tr> <td style="text-align:right;"> 149 </td> <td style="text-align:right;"> 23 </td> <td style="text-align:left;"> NO Ingresa </td> </tr> <tr> <td style="text-align:right;"> 150 </td> <td style="text-align:right;"> 21 </td> <td style="text-align:left;"> NO Ingresa </td> </tr> <tr> <td style="text-align:right;"> 151 </td> <td style="text-align:right;"> 24 </td> <td style="text-align:left;"> NO Ingresa </td> </tr> <tr> <td style="text-align:right;"> 152 </td> <td style="text-align:right;"> 25 </td> <td style="text-align:left;"> NO Ingresa </td> </tr> <tr> <td style="text-align:right;"> 153 </td> <td style="text-align:right;"> 25 </td> <td style="text-align:left;"> NO Ingresa </td> </tr> <tr> <td style="text-align:right;"> 154 </td> <td style="text-align:right;"> 21 </td> <td style="text-align:left;"> NO Ingresa </td> </tr> <tr> <td style="text-align:right;"> 155 </td> <td style="text-align:right;"> 19 </td> <td style="text-align:left;"> NO Ingresa </td> </tr> <tr> <td style="text-align:right;"> 156 </td> <td style="text-align:right;"> 22 </td> <td style="text-align:left;"> NO Ingresa </td> </tr> <tr> <td style="text-align:right;"> 157 </td> <td style="text-align:right;"> 19 </td> <td style="text-align:left;"> NO Ingresa </td> </tr> <tr> <td style="text-align:right;"> 158 </td> <td style="text-align:right;"> 25 </td> <td style="text-align:left;"> NO Ingresa </td> </tr> <tr> <td style="text-align:right;"> 159 </td> <td style="text-align:right;"> 18 </td> <td style="text-align:left;"> NO Ingresa </td> </tr> <tr> <td style="text-align:right;"> 160 </td> <td style="text-align:right;"> 19 </td> <td style="text-align:left;"> NO Ingresa </td> </tr> <tr> <td style="text-align:right;"> 161 </td> <td style="text-align:right;"> 25 </td> <td style="text-align:left;"> NO Ingresa </td> </tr> <tr> <td style="text-align:right;"> 162 </td> <td style="text-align:right;"> 20 </td> <td style="text-align:left;"> NO Ingresa </td> </tr> <tr> <td style="text-align:right;"> 163 </td> <td style="text-align:right;"> 24 </td> <td style="text-align:left;"> NO Ingresa </td> </tr> <tr> <td style="text-align:right;"> 164 </td> <td style="text-align:right;"> 25 </td> <td style="text-align:left;"> NO Ingresa </td> </tr> <tr> <td style="text-align:right;"> 165 </td> <td style="text-align:right;"> 24 </td> <td style="text-align:left;"> NO Ingresa </td> </tr> <tr> <td style="text-align:right;"> 166 </td> <td style="text-align:right;"> 21 </td> <td style="text-align:left;"> NO Ingresa </td> </tr> <tr> <td style="text-align:right;"> 167 </td> <td style="text-align:right;"> 19 </td> <td style="text-align:left;"> NO Ingresa </td> </tr> <tr> <td style="text-align:right;"> 168 </td> <td style="text-align:right;"> 19 </td> <td style="text-align:left;"> NO Ingresa </td> </tr> <tr> <td style="text-align:right;"> 169 </td> <td style="text-align:right;"> 22 </td> <td style="text-align:left;"> NO Ingresa </td> </tr> <tr> <td style="text-align:right;"> 170 </td> <td style="text-align:right;"> 17 </td> <td style="text-align:left;"> NO Ingresa </td> </tr> <tr> <td style="text-align:right;"> 171 </td> <td style="text-align:right;"> 21 </td> <td style="text-align:left;"> NO Ingresa </td> </tr> <tr> <td style="text-align:right;"> 172 </td> <td style="text-align:right;"> 20 </td> <td style="text-align:left;"> NO Ingresa </td> </tr> <tr> <td style="text-align:right;"> 173 </td> <td style="text-align:right;"> 21 </td> <td style="text-align:left;"> NO Ingresa </td> </tr> <tr> <td style="text-align:right;"> 174 </td> <td style="text-align:right;"> 22 </td> <td style="text-align:left;"> NO Ingresa </td> </tr> <tr> <td style="text-align:right;"> 175 </td> <td style="text-align:right;"> 24 </td> <td style="text-align:left;"> NO Ingresa </td> </tr> <tr> <td style="text-align:right;"> 176 </td> <td style="text-align:right;"> 17 </td> <td style="text-align:left;"> NO Ingresa </td> </tr> <tr> <td style="text-align:right;"> 177 </td> <td style="text-align:right;"> 22 </td> <td style="text-align:left;"> NO Ingresa </td> </tr> <tr> <td style="text-align:right;"> 178 </td> <td style="text-align:right;"> 18 </td> <td style="text-align:left;"> NO Ingresa </td> </tr> <tr> <td style="text-align:right;"> 179 </td> <td style="text-align:right;"> 21 </td> <td style="text-align:left;"> NO Ingresa </td> </tr> <tr> <td style="text-align:right;"> 180 </td> <td style="text-align:right;"> 21 </td> <td style="text-align:left;"> NO Ingresa </td> </tr> <tr> <td style="text-align:right;"> 181 </td> <td style="text-align:right;"> 25 </td> <td style="text-align:left;"> NO Ingresa </td> </tr> <tr> <td style="text-align:right;"> 182 </td> <td style="text-align:right;"> 19 </td> <td style="text-align:left;"> NO Ingresa </td> </tr> <tr> <td style="text-align:right;"> 183 </td> <td style="text-align:right;"> 23 </td> <td style="text-align:left;"> NO Ingresa </td> </tr> <tr> <td style="text-align:right;"> 184 </td> <td style="text-align:right;"> 21 </td> <td style="text-align:left;"> NO Ingresa </td> </tr> <tr> <td style="text-align:right;"> 185 </td> <td style="text-align:right;"> 17 </td> <td style="text-align:left;"> NO Ingresa </td> </tr> <tr> <td style="text-align:right;"> 186 </td> <td style="text-align:right;"> 24 </td> <td style="text-align:left;"> NO Ingresa </td> </tr> <tr> <td style="text-align:right;"> 187 </td> <td style="text-align:right;"> 23 </td> <td style="text-align:left;"> NO Ingresa </td> </tr> <tr> <td style="text-align:right;"> 188 </td> <td style="text-align:right;"> 23 </td> <td style="text-align:left;"> NO Ingresa </td> </tr> <tr> <td style="text-align:right;"> 189 </td> <td style="text-align:right;"> 19 </td> <td style="text-align:left;"> NO Ingresa </td> </tr> <tr> <td style="text-align:right;"> 190 </td> <td style="text-align:right;"> 17 </td> <td style="text-align:left;"> NO Ingresa </td> </tr> <tr> <td style="text-align:right;"> 191 </td> <td style="text-align:right;"> 21 </td> <td style="text-align:left;"> NO Ingresa </td> </tr> <tr> <td style="text-align:right;"> 192 </td> <td style="text-align:right;"> 25 </td> <td style="text-align:left;"> NO Ingresa </td> </tr> <tr> <td style="text-align:right;"> 193 </td> <td style="text-align:right;"> 17 </td> <td style="text-align:left;"> NO Ingresa </td> </tr> <tr> <td style="text-align:right;"> 194 </td> <td style="text-align:right;"> 21 </td> <td style="text-align:left;"> NO Ingresa </td> </tr> <tr> <td style="text-align:right;"> 195 </td> <td style="text-align:right;"> 21 </td> <td style="text-align:left;"> NO Ingresa </td> </tr> <tr> <td style="text-align:right;"> 196 </td> <td style="text-align:right;"> 20 </td> <td style="text-align:left;"> NO Ingresa </td> </tr> <tr> <td style="text-align:right;"> 197 </td> <td style="text-align:right;"> 17 </td> <td style="text-align:left;"> NO Ingresa </td> </tr> <tr> <td style="text-align:right;"> 198 </td> <td style="text-align:right;"> 18 </td> <td style="text-align:left;"> NO Ingresa </td> </tr> <tr> <td style="text-align:right;"> 199 </td> <td style="text-align:right;"> 22 </td> <td style="text-align:left;"> NO Ingresa </td> </tr> <tr> <td style="text-align:right;"> 200 </td> <td style="text-align:right;"> 23 </td> <td style="text-align:left;"> NO Ingresa </td> </tr> <tr> <td style="text-align:right;"> 201 </td> <td style="text-align:right;"> 25 </td> <td style="text-align:left;"> NO Ingresa </td> </tr> <tr> <td style="text-align:right;"> 202 </td> <td style="text-align:right;"> 23 </td> <td style="text-align:left;"> NO Ingresa </td> </tr> <tr> <td style="text-align:right;"> 203 </td> <td style="text-align:right;"> 17 </td> <td style="text-align:left;"> NO Ingresa </td> </tr> <tr> <td style="text-align:right;"> 204 </td> <td style="text-align:right;"> 20 </td> <td style="text-align:left;"> NO Ingresa </td> </tr> <tr> <td style="text-align:right;"> 205 </td> <td style="text-align:right;"> 24 </td> <td style="text-align:left;"> NO Ingresa </td> </tr> <tr> <td style="text-align:right;"> 206 </td> <td style="text-align:right;"> 24 </td> <td style="text-align:left;"> NO Ingresa </td> </tr> <tr> <td style="text-align:right;"> 207 </td> <td style="text-align:right;"> 17 </td> <td style="text-align:left;"> NO Ingresa </td> </tr> <tr> <td style="text-align:right;"> 208 </td> <td style="text-align:right;"> 18 </td> <td style="text-align:left;"> NO Ingresa </td> </tr> <tr> <td style="text-align:right;"> 209 </td> <td style="text-align:right;"> 17 </td> <td style="text-align:left;"> NO Ingresa </td> </tr> <tr> <td style="text-align:right;"> 210 </td> <td style="text-align:right;"> 19 </td> <td style="text-align:left;"> NO Ingresa </td> </tr> <tr> <td style="text-align:right;"> 211 </td> <td style="text-align:right;"> 18 </td> <td style="text-align:left;"> NO Ingresa </td> </tr> <tr> <td style="text-align:right;"> 212 </td> <td style="text-align:right;"> 22 </td> <td style="text-align:left;"> NO Ingresa </td> </tr> <tr> <td style="text-align:right;"> 213 </td> <td style="text-align:right;"> 19 </td> <td style="text-align:left;"> NO Ingresa </td> </tr> <tr> <td style="text-align:right;"> 214 </td> <td style="text-align:right;"> 23 </td> <td style="text-align:left;"> NO Ingresa </td> </tr> <tr> <td style="text-align:right;"> 215 </td> <td style="text-align:right;"> 21 </td> <td style="text-align:left;"> NO Ingresa </td> </tr> <tr> <td style="text-align:right;"> 216 </td> <td style="text-align:right;"> 19 </td> <td style="text-align:left;"> NO Ingresa </td> </tr> <tr> <td style="text-align:right;"> 217 </td> <td style="text-align:right;"> 19 </td> <td style="text-align:left;"> NO Ingresa </td> </tr> <tr> <td style="text-align:right;"> 218 </td> <td style="text-align:right;"> 22 </td> <td style="text-align:left;"> NO Ingresa </td> </tr> <tr> <td style="text-align:right;"> 219 </td> <td style="text-align:right;"> 24 </td> <td style="text-align:left;"> NO Ingresa </td> </tr> <tr> <td style="text-align:right;"> 220 </td> <td style="text-align:right;"> 23 </td> <td style="text-align:left;"> NO Ingresa </td> </tr> <tr> <td style="text-align:right;"> 221 </td> <td style="text-align:right;"> 18 </td> <td style="text-align:left;"> NO Ingresa </td> </tr> <tr> <td style="text-align:right;"> 222 </td> <td style="text-align:right;"> 23 </td> <td style="text-align:left;"> NO Ingresa </td> </tr> <tr> <td style="text-align:right;"> 223 </td> <td style="text-align:right;"> 19 </td> <td style="text-align:left;"> NO Ingresa </td> </tr> <tr> <td style="text-align:right;"> 224 </td> <td style="text-align:right;"> 17 </td> <td style="text-align:left;"> NO Ingresa </td> </tr> <tr> <td style="text-align:right;"> 225 </td> <td style="text-align:right;"> 18 </td> <td style="text-align:left;"> NO Ingresa </td> </tr> <tr> <td style="text-align:right;"> 226 </td> <td style="text-align:right;"> 19 </td> <td style="text-align:left;"> NO Ingresa </td> </tr> <tr> <td style="text-align:right;"> 227 </td> <td style="text-align:right;"> 25 </td> <td style="text-align:left;"> NO Ingresa </td> </tr> <tr> <td style="text-align:right;"> 228 </td> <td style="text-align:right;"> 19 </td> <td style="text-align:left;"> NO Ingresa </td> </tr> <tr> <td style="text-align:right;"> 229 </td> <td style="text-align:right;"> 22 </td> <td style="text-align:left;"> NO Ingresa </td> </tr> <tr> <td style="text-align:right;"> 230 </td> <td style="text-align:right;"> 19 </td> <td style="text-align:left;"> NO Ingresa </td> </tr> <tr> <td style="text-align:right;"> 231 </td> <td style="text-align:right;"> 20 </td> <td style="text-align:left;"> NO Ingresa </td> </tr> <tr> <td style="text-align:right;"> 232 </td> <td style="text-align:right;"> 17 </td> <td style="text-align:left;"> NO Ingresa </td> </tr> <tr> <td style="text-align:right;"> 233 </td> <td style="text-align:right;"> 20 </td> <td style="text-align:left;"> NO Ingresa </td> </tr> <tr> <td style="text-align:right;"> 234 </td> <td style="text-align:right;"> 22 </td> <td style="text-align:left;"> NO Ingresa </td> </tr> <tr> <td style="text-align:right;"> 235 </td> <td style="text-align:right;"> 17 </td> <td style="text-align:left;"> NO Ingresa </td> </tr> <tr> <td style="text-align:right;"> 236 </td> <td style="text-align:right;"> 18 </td> <td style="text-align:left;"> NO Ingresa </td> </tr> <tr> <td style="text-align:right;"> 237 </td> <td style="text-align:right;"> 17 </td> <td style="text-align:left;"> NO Ingresa </td> </tr> <tr> <td style="text-align:right;"> 238 </td> <td style="text-align:right;"> 25 </td> <td style="text-align:left;"> NO Ingresa </td> </tr> <tr> <td style="text-align:right;"> 239 </td> <td style="text-align:right;"> 24 </td> <td style="text-align:left;"> NO Ingresa </td> </tr> <tr> <td style="text-align:right;"> 240 </td> <td style="text-align:right;"> 20 </td> <td style="text-align:left;"> NO Ingresa </td> </tr> <tr> <td style="text-align:right;"> 241 </td> <td style="text-align:right;"> 25 </td> <td style="text-align:left;"> NO Ingresa </td> </tr> <tr> <td style="text-align:right;"> 242 </td> <td style="text-align:right;"> 17 </td> <td style="text-align:left;"> NO Ingresa </td> </tr> <tr> <td style="text-align:right;"> 243 </td> <td style="text-align:right;"> 20 </td> <td style="text-align:left;"> NO Ingresa </td> </tr> <tr> <td style="text-align:right;"> 244 </td> <td style="text-align:right;"> 22 </td> <td style="text-align:left;"> NO Ingresa </td> </tr> <tr> <td style="text-align:right;"> 245 </td> <td style="text-align:right;"> 18 </td> <td style="text-align:left;"> NO Ingresa </td> </tr> <tr> <td style="text-align:right;"> 246 </td> <td style="text-align:right;"> 17 </td> <td style="text-align:left;"> NO Ingresa </td> </tr> <tr> <td style="text-align:right;"> 247 </td> <td style="text-align:right;"> 17 </td> <td style="text-align:left;"> NO Ingresa </td> </tr> <tr> <td style="text-align:right;"> 248 </td> <td style="text-align:right;"> 17 </td> <td style="text-align:left;"> NO Ingresa </td> </tr> <tr> <td style="text-align:right;"> 249 </td> <td style="text-align:right;"> 25 </td> <td style="text-align:left;"> NO Ingresa </td> </tr> <tr> <td style="text-align:right;"> 250 </td> <td style="text-align:right;"> 19 </td> <td style="text-align:left;"> NO Ingresa </td> </tr> </tbody> </table></div> --- ## Funciones lapply <img src="inputs/Clase5/cartel_mod2.jpg" width="60%" height="40%" style="display: block; margin: auto;" /> --- ## Funciones lapply R en cierta forma ya pensó como ayudarnos a hacer este trabajo. Por eso existe la función `lapply()` -- Su lógica es la siguiente `lapply(X, FUN)`: - `X`: Es el objeto sobre el cual quiero aplicar la operación - `FUN` es la función a aplicar -- Por cuestiones de espacio en el curso no cubriremos en profundidad la función `lapply()` y sus similares (`mapply()`, `sapply()`), aunque mas adelante incluimos un ejemplo básico para entender que la lógica detrás de estas familia de funciones está directamente emparentada con la noción de loops --- ## Aplicaicones Equipados con todas estas nociones, veamos ahora un contexto mas cercano a la economía y al uso de datos donde todas estas estructuras lógicas y estos contenidos nos resulten también útiles --- ## Iterando ando Equipados con todas estas nociones, veamos ahora un contexto mas cercano a la economía y al uso de datos donde todas estas estructuras lógicas y estos contenidos nos resulten también útiles -- Una de las aplicaciones mas típicas es manipular numerosas bases de datos. -- Ya sabemos cómo importar y exportar una base. Pero típicamente ocurre que no trabajabamos con una, dos o tres bases. -- Cuando estas son muchas escribir un código individual se vuelve tedioso y demasiado específico a esos archivos -- Supongamos que tenemos las EPH desde 2016 a 2021 en nuestro directorio, para cargarlas deberíamos escribir .inter[ ```r eph_2016 <- readRDS("Datos/Clase5/eph_2016.RDS") eph_2018 <- readRDS("Datos/Clase5/eph_2018.RDS") ... eph_2021 <- readRDS("Datos/Clase5/eph_2018.RDS") ``` ] --- ## Iterando ando Esto se vuelve un trabajo pesado si son más, y si agregaramos o quitaramos una base del directorio, nos obliga a voler al código y cambiarlo -- La forma eficiente de hacerlo es construir un bucle y, ayudados con una lista, en cada iteración cargar una base distinta como elemento de esa lista -- Para eso necesitariamos iterar sobre un objeto que contenga un listado de todas las bases disponibles en nuestro directorio. Así en cada iteración, el elemeneto será una base eph de un año distinto -- La función `list.files()` hace ese trabajo, nos devuelve todos los archivos alojados en una carpeta ```r bases <- list.files("Datos/Clase5/eph/") bases ``` ``` ## [1] "eph_2016.rds" "eph_2017.rds" "eph_2018.rds" "eph_2019.rds" "eph_2020.rds" ## [6] "eph_2021.rds" ``` --- ## Iterando ando Bien, ya tenemos los archivos a usar, ahora construyamos el bucle como sabemos e iteremos sobre cada elemeneto de la lista con un contador .inter[ ```r load_list <- list() i=1 for(j in bases){ print(j) load_list[[i]] <- readRDS("Datos/Clase5/eph/" %+% j) i = i +1 } ``` ``` ## [1] "eph_2016.rds" ## [1] "eph_2017.rds" ## [1] "eph_2018.rds" ## [1] "eph_2019.rds" ## [1] "eph_2020.rds" ## [1] "eph_2021.rds" ``` ] --- ## Iterando ando Ya tenemos las bases cargadas en la nuestra lista, pero las necesitamos como un dataframe. -- Para ello podemos recuperarla escribiendo una linea para cada dataframe aunque no nos convence mucho ```r eph_2016 <- as.data.frame(load_list[[1]]) eph_2017 <- as.data.frame(load_list[[2]]) ... eph_2021 <- as.data.frame(load_list[[3]]) ``` Esto era justamente el tipo de trabajo que queríamos evitar -- Debemos emplear la función `assign()`, que nos permite asignarle a un valor (en este caso un elemento de la lista) un nombre y almacenarlo en el environment. -- Exactamente lo que hacíamos en el código de arriba ```r name <- "df_prueba" assign(name, as.data.frame(load_list[[1]])) ``` --- ## Iterando ando Bien ahora incorporemos esta función dentro de nuestro bucle, para terminar la tarea .inter[ ```r load_list <- list() i=1 for(j in bases){ print(j) load_list[[i]] <- readRDS("Datos/Clase5/eph/" %+% j) name = substr(j, 0, 8) #para nombrar el df, no quiero el ".rds" assign(name, as.data.frame(load_list[[i]])) i = i +1 } ``` ``` ## [1] "eph_2016.rds" ## [1] "eph_2017.rds" ## [1] "eph_2018.rds" ## [1] "eph_2019.rds" ## [1] "eph_2020.rds" ## [1] "eph_2021.rds" ``` ] --- ## Iterando ando Ahora pensemos el caso a la inversa, a veces necesitamos cargar múltiples bases y dividirlas en subconjuntos mas pequeños -- Por ejemplo cada base de la eph que cargamos tiene 4 trimestres, si necesitara dividir cada una de ellas, un bucle también sería una herramienta adecuada .mid[ ```r i=1 for(j in bases){ load_list[[i]] <- readRDS("Datos/Clase5/eph/" %+% j) for(t in 1:4){ df_itera <- as.data.frame(load_list[[i]]) df_itera <- df_itera %>% filter(trimestre==t) name = paste( substr(j, 0, 8), "_trim", t ) saveRDS(df_itera, "Datos/Clase5/trim/" %+% name %+% ".rds") } i = i + 1 } ``` ] --- ## Iterando ando Como resultado deberían ver todos los archivos en su carpeta donde exportaron -- Dos tip adicionales. En este caso guardamos todos los archivos en un misma carpeta, lo más recomedable sería guardarlos en carpetas distintas, una por cada año. Para eso pueden explorar la función `dir.create()` y sumarla al loop, para que en cada iteración creen una carpeta donde ir guardando -- En este caso, cargamos todos los df, pero a veces lo que necesitamos es iterar sobre bases que ya están en nuestro entorno. Para esto les recomiendo explorar la función `get()` Al pasarle un nombre como *string* la función les devuelve el objeto que encuentra en el entorno con ese nombre --- ## Iterando ando En otros casos no tenemos en la carpeta la base y lo que queremos programar es la descarga justamente. -- Por ejemplo, en este [link](https://www.indec.gob.ar/indec/web/Institucional-Indec-BasesDeDatos-3) y revisan las bases de datos verán que hay una base por año disponible. -- Lo importante de notar es que todos los links tienen un patrón similar entre 2017 y 2021 y otro patrón entre 2016 y 2017. En estos solo cambia el año (para esto hagan click derecho sobre el url e inspeccionar) -- Con la ayuda de la función `download.file()` podemos descargar todos los archivos de una vez --- ## Iterando ando .mid[ ```r for(j in seq(2016,2021,1)){ i=j-1 if(j<=2017){ url <- "https://www.indec.gob.ar/ftp/cuadros/menusuperior/entic/EPH_usu_Tic_4to_Trim_" %+%j %+%".zip" download.file(url, destfile ="Datos/Clase5/TICs/base_tic_" %+% j %+% ").zip") } else{ j = j-2000 #porque está expresa como 17 y no como 2017 url <- "https://www.indec.gob.ar/ftp/cuadros/menusuperior/entic/EPH_Base_Usu_Tic_T4" %+% j %+%".zip" download.file(url, destfile ="Datos/Clase5/TICs/base_tic_" %+% j %+% ".zip") } } ``` ] --- ## Iterando ando Listo, ya tienen todos los archivos disponibles en su ruta, para usarlos Dos recomendaciones adicionales. Noten que los archivos se descargaron como zip, es decir comprimidos -- En el mismo bucle (o en otro posterior) pueden extraer los archivos con R con al función `unzip()` -- En segundo lugar, noten que descargamos "fisicamente" los archivos, por razones de espacio o eficiencia, puede ser que no querramos guardarlos en nuestro disco, solamente descargar la base, usarla y listo. -- Para esto, pueden explorar el uso de `tempfiles()` -- Un buen ejemplo con ambas funciones pueden encontrar en [esta](https://stackoverflow.com/questions/3053833/using-r-to-download-zipped-data-file-extract-and-import-data) respuesta --- ## Funciones Ya vimos varios ejemplos de cómo podemos iterar para ganar eficiencia y hacer mejor algunas tareas -- Veamos un ejemplo de cómo las funciones propias también nos ayudan muchisimo con esto -- Tenemos varias EPH de distinto año. Para cada año lo que queremos es calcular las estadísticas laborales, por lo que una misma operación la repeterimes sobre varios dataframes --- ## Funciones Ya sé lo que están pensando, en una función. -- De hecho nuestra función va replicar la tarea del INDEC, calculando el cuadro de cifras ocupacionales .mid[ ```r cuadro_indec<- function(df){ df_new <- df %>% summarise(anio = min(ano4), poblacion = sum(pondera), ocupados = sum(pondera[estado==1]), desocupados = sum(pondera[estado==2]), pea = ocupados + desocupados, ocuapdos_dem = sum(pondera[estado==1 & pp03j==1]), subocup_dem = sum(pondera[estado==1 & intensi==1 & pp03j==1]), subocup_nodem = sum(pondera[estado==1 & intensi==1 & pp03j %in% c(2,9)]), subocupados = subocup_dem + subocup_nodem, tasa_activ = pea/poblacion, tasa_inac = 1- tasa_activ, tasa_empleo = ocupados/poblacion, tasa_desocup = desocupados/pea ) return(df_new) } ``` ] --- ## Funciones Probemos si funciona ```r stats_prueba <- cuadro_indec(eph_2016) ``` <div style="border: 1px solid #ddd; padding: 0px; overflow-y: scroll; height:150px; overflow-x: scroll; width:100%; "><table class="table table-condensed table-responsive" style="font-size: 13px; margin-left: auto; margin-right: auto;"> <thead> <tr> <th style="text-align:right;position: sticky; top:0; background-color: #FFFFFF;"> anio </th> <th style="text-align:right;position: sticky; top:0; background-color: #FFFFFF;"> poblacion </th> <th style="text-align:right;position: sticky; top:0; background-color: #FFFFFF;"> ocupados </th> <th style="text-align:right;position: sticky; top:0; background-color: #FFFFFF;"> desocupados </th> <th style="text-align:right;position: sticky; top:0; background-color: #FFFFFF;"> pea </th> <th style="text-align:right;position: sticky; top:0; background-color: #FFFFFF;"> ocuapdos_dem </th> <th style="text-align:right;position: sticky; top:0; background-color: #FFFFFF;"> subocup_dem </th> <th style="text-align:right;position: sticky; top:0; background-color: #FFFFFF;"> subocup_nodem </th> <th style="text-align:right;position: sticky; top:0; background-color: #FFFFFF;"> subocupados </th> <th style="text-align:right;position: sticky; top:0; background-color: #FFFFFF;"> tasa_activ </th> <th style="text-align:right;position: sticky; top:0; background-color: #FFFFFF;"> tasa_inac </th> <th style="text-align:right;position: sticky; top:0; background-color: #FFFFFF;"> tasa_empleo </th> <th style="text-align:right;position: sticky; top:0; background-color: #FFFFFF;"> tasa_desocup </th> </tr> </thead> <tbody> <tr> <td style="text-align:right;"> 2016 </td> <td style="text-align:right;"> 16459103 </td> <td style="text-align:right;"> 6811350 </td> <td style="text-align:right;"> 636381 </td> <td style="text-align:right;"> 7447731 </td> <td style="text-align:right;"> 1088216 </td> <td style="text-align:right;"> 540484 </td> <td style="text-align:right;"> 239036 </td> <td style="text-align:right;"> 779520 </td> <td style="text-align:right;"> 0.4524992 </td> <td style="text-align:right;"> 0.5475008 </td> <td style="text-align:right;"> 0.4138348 </td> <td style="text-align:right;"> 0.0854463 </td> </tr> </tbody> </table></div> -- Ahora simplemente resta aplicarlo sobre cada dataframe --- ## Funciones Para ello veremos cómo hacerlo en un loop y luego el análogo usando la función `lapply` -- Al aplicar la función no queremos pisar los dataframes originales con el output, mas bien queremos guardarlos en un objeto distinto. Por eso generamos otra lista nueva donde ir guardando ese output que surge del return de la función .mid[ ```r dflist <- load_list stats <- list() #creo lista nueva como vacía for(i in 1:length(dflist)){ stats[[i]] <- cuadro_indec(dflist[[i]]) } ``` ] Entonces ahora en cada elemento de la lista *stats* tenemos el tabulado resumen para cada año --- ## Funciones El análogo a correr este loop es utilizar la función `lapply` -- Habíamos dicho que su lógica es la siguiente `lapply(X, FUN)`: -- - `X`: será entonces mi lista con los dataframes - `FUN` es la función que creamos antes -- ```r dflist <- load_list stats <- lapply(dflist, cuadro_indec) ``` Y listo! -- ```r stats[[1]] ``` ``` ## anio poblacion ocupados desocupados pea ocuapdos_dem subocup_dem ## 1 2016 16459103 6811350 636381 7447731 1088216 540484 ## subocup_nodem subocupados tasa_activ tasa_inac tasa_empleo tasa_desocup ## 1 239036 779520 0.4524992 0.5475008 0.4138348 0.08544629 ``` --- ## Funciones Para cerrar, a cada tabulado lo guardaremos ahora como un dataframe distinto en el entorno de trabajo -- También consolidaremos todos estos en un df llamado *full_stats*, que es una append de los anteriores .mid[ ```r dflist <- load_list stats <- lapply(dflist, cuadro_indec) ``` ```r full_stats <- data.frame() for (i in 1:length(stats)) { j = 2015 + i df_itera <- as.data.frame(stats[[i]]) assign(paste0("stats_", j), df_itera) full_stats <- bind_rows(full_stats, df_itera) } ``` ] --- ## Funciones Listo! En pocos pasos tenemos los calculos para múltiples años <div style="border: 1px solid #ddd; padding: 0px; overflow-y: scroll; height:250px; overflow-x: scroll; width:100%; "><table class="table table-condensed table-responsive" style="font-size: 13px; margin-left: auto; margin-right: auto;"> <thead> <tr> <th style="text-align:right;position: sticky; top:0; background-color: #FFFFFF;"> anio </th> <th style="text-align:right;position: sticky; top:0; background-color: #FFFFFF;"> poblacion </th> <th style="text-align:right;position: sticky; top:0; background-color: #FFFFFF;"> ocupados </th> <th style="text-align:right;position: sticky; top:0; background-color: #FFFFFF;"> desocupados </th> <th style="text-align:right;position: sticky; top:0; background-color: #FFFFFF;"> pea </th> <th style="text-align:right;position: sticky; top:0; background-color: #FFFFFF;"> ocuapdos_dem </th> <th style="text-align:right;position: sticky; top:0; background-color: #FFFFFF;"> subocup_dem </th> <th style="text-align:right;position: sticky; top:0; background-color: #FFFFFF;"> subocup_nodem </th> <th style="text-align:right;position: sticky; top:0; background-color: #FFFFFF;"> subocupados </th> <th style="text-align:right;position: sticky; top:0; background-color: #FFFFFF;"> tasa_activ </th> <th style="text-align:right;position: sticky; top:0; background-color: #FFFFFF;"> tasa_inac </th> <th style="text-align:right;position: sticky; top:0; background-color: #FFFFFF;"> tasa_empleo </th> <th style="text-align:right;position: sticky; top:0; background-color: #FFFFFF;"> tasa_desocup </th> </tr> </thead> <tbody> <tr> <td style="text-align:right;"> 2016 </td> <td style="text-align:right;"> 16459103 </td> <td style="text-align:right;"> 6811350 </td> <td style="text-align:right;"> 636381 </td> <td style="text-align:right;"> 7447731 </td> <td style="text-align:right;"> 1088216 </td> <td style="text-align:right;"> 540484 </td> <td style="text-align:right;"> 239036 </td> <td style="text-align:right;"> 779520 </td> <td style="text-align:right;"> 0.4524992 </td> <td style="text-align:right;"> 0.5475008 </td> <td style="text-align:right;"> 0.4138348 </td> <td style="text-align:right;"> 0.0854463 </td> </tr> <tr> <td style="text-align:right;"> 2017 </td> <td style="text-align:right;"> 22091132 </td> <td style="text-align:right;"> 9145398 </td> <td style="text-align:right;"> 859737 </td> <td style="text-align:right;"> 10005135 </td> <td style="text-align:right;"> 1455980 </td> <td style="text-align:right;"> 715492 </td> <td style="text-align:right;"> 313892 </td> <td style="text-align:right;"> 1029384 </td> <td style="text-align:right;"> 0.4529028 </td> <td style="text-align:right;"> 0.5470972 </td> <td style="text-align:right;"> 0.4139850 </td> <td style="text-align:right;"> 0.0859296 </td> </tr> <tr> <td style="text-align:right;"> 2018 </td> <td style="text-align:right;"> 22339862 </td> <td style="text-align:right;"> 9514579 </td> <td style="text-align:right;"> 953023 </td> <td style="text-align:right;"> 10467602 </td> <td style="text-align:right;"> 1700070 </td> <td style="text-align:right;"> 824166 </td> <td style="text-align:right;"> 378998 </td> <td style="text-align:right;"> 1203164 </td> <td style="text-align:right;"> 0.4685616 </td> <td style="text-align:right;"> 0.5314384 </td> <td style="text-align:right;"> 0.4259014 </td> <td style="text-align:right;"> 0.0910450 </td> </tr> <tr> <td style="text-align:right;"> 2019 </td> <td style="text-align:right;"> 22547783 </td> <td style="text-align:right;"> 9478971 </td> <td style="text-align:right;"> 1122079 </td> <td style="text-align:right;"> 10601050 </td> <td style="text-align:right;"> 1913902 </td> <td style="text-align:right;"> 959756 </td> <td style="text-align:right;"> 387033 </td> <td style="text-align:right;"> 1346789 </td> <td style="text-align:right;"> 0.4701593 </td> <td style="text-align:right;"> 0.5298407 </td> <td style="text-align:right;"> 0.4203948 </td> <td style="text-align:right;"> 0.1058460 </td> </tr> <tr> <td style="text-align:right;"> 2020 </td> <td style="text-align:right;"> 22795885 </td> <td style="text-align:right;"> 8862616 </td> <td style="text-align:right;"> 1073562 </td> <td style="text-align:right;"> 9936178 </td> <td style="text-align:right;"> 1569155 </td> <td style="text-align:right;"> 780171 </td> <td style="text-align:right;"> 443605 </td> <td style="text-align:right;"> 1223776 </td> <td style="text-align:right;"> 0.4358759 </td> <td style="text-align:right;"> 0.5641241 </td> <td style="text-align:right;"> 0.3887814 </td> <td style="text-align:right;"> 0.1080458 </td> </tr> <tr> <td style="text-align:right;"> 2021 </td> <td style="text-align:right;"> 23147026 </td> <td style="text-align:right;"> 9835021 </td> <td style="text-align:right;"> 838535 </td> <td style="text-align:right;"> 10673556 </td> <td style="text-align:right;"> 1821828 </td> <td style="text-align:right;"> 946980 </td> <td style="text-align:right;"> 414819 </td> <td style="text-align:right;"> 1361799 </td> <td style="text-align:right;"> 0.4611200 </td> <td style="text-align:right;"> 0.5388800 </td> <td style="text-align:right;"> 0.4248935 </td> <td style="text-align:right;"> 0.0785619 </td> </tr> </tbody> </table></div> --- ## Extra: Googleando ando Para finalizar, dejamos algunos tips que son muy útiles a la hora de aprender a programar en R, o para cualquier otro uso u aplicación -- Me gusta decir que -- **"para aprender a programar hay que saber googlear bien"** -- y estoy convencido de eso por experiencia propia En cualquier lenguaje de programación los errores y las dudas son parte esencial del aprendizaje y son continuos. Uno convive con el error y nunca deja de googlear errores y mensajes que le arroja R, ni el mas experto programador o data scientist. -- Es parte de la **lógica de prueba y error** --- ## Extra: Googleando ando Pero por más básico que parezca, hay tips que nos ayudan a poder resolver mejor y más rapido nuestras dudas. -- Les dejo algunos: -- - Buscar errores o preguntas en inglés aumenta considerablemente la posibilidad y calidad de respuestas - Ante errores eliminar el nombre de las variables específicas y buscar el error genérico - Anteponer la letra R, para filtrar consultas similares pero de otros lenguajes - Evitar describir el problema de forma muy larga, mas bien pensar en palabras o expresiones claves que resuman lo que quieren - Si no aparecen respuestas satisfactorias, probar refraseando la búsqueda - Aprovechar las respuestas verificadas, por ejemplo en stackoverflow, pero no descartar el resto. A veces esas otras soluciones se ajustan mejor al caso de uno - Gurdar respuesta que les hayan servido, no sobrestimen su memoria, uno se encuentra googleando el mismo problema más veces de las que cree --- ## Cierre ¡** Muchas gracias** por haber llegado hasta aquí! -- Espero que este material haya sido de ayuda para adentrarse en el mundo de R -- <br> Ahora a seguir por su cuenta, googleando y aprovechando la enorme comunidad mundial que utiliza este gran lenguaje -- Hay que **construir a hombros de gigantes** y lo mas importante: -- **disfrutar el viaje**! -- <br> Por cualquier cosa ya saben donde encontrarme: crisbonavida@gmail.com