Loop for con multiples elementos variables
En este mini ejemplo vamos a ver como hacer un loop for
en el cual los elementos van a ir variando, en cada ciclo, por cada uno de los renglones de una base de datos.
Ejemplo:
En este caso, el ejemplo trata de que tenemos los nombres y la ocupación de 5 personas, y queremos generar una cadena de texto en la cual cada una de estas personas se presente.
Los datos son los siguientes:
library(tidyverse)
# Los datos, copiados y pegados desde un excel con la librería datapasta
<- tibble::tribble(
datos ~Nombre, ~Apellido, ~Trabajo,
"Luís", "Pérez", "Bombero",
"Isaac", "Carmona", "Soldado",
"César", "Suárez", "Maestro",
"Benito", "Juárez", "Político",
"Juana", "Guerra", "Abogada")
Nombre | Apellido | Trabajo |
---|---|---|
Luís | Pérez | Bombero |
Isaac | Carmona | Soldado |
César | Suárez | Maestro |
Benito | Juárez | Político |
Juana | Guerra | Abogada |
El resultado que queremos es el siguiente:
## [1] "Hola, mi nombre es Luís Pérez y soy Bombero. ¡Mucho gusto!"
## [1] "Hola, mi nombre es Isaac Carmona y soy Soldado. ¡Mucho gusto!"
## [1] "Hola, mi nombre es César Suárez y soy Maestro. ¡Mucho gusto!"
## [1] "Hola, mi nombre es Benito Juárez y soy Político. ¡Mucho gusto!"
## [1] "Hola, mi nombre es Juana Guerra y soy Abogada. ¡Mucho gusto!"
Para esto, necesitamos definir lo siguiente:
Un
contador
que vaya tomando el valor del numero del renglón que tiene los datos que se van a emplear en cada presentación.Generar una secuencia de todos los valores que va a tomar este contador. Dado que los datos tienen 5 renglones, vamos a generar una secuencia que vaya del 1 al 5.
El cuerpo del loop o el proceso que se va a replicar en cada una de las etapas del bucle.
Paso 1. Hacemos el caso n = 1.
Antes de armar un loop, es necesario primero armar un caso particular para despues extrapolar ese proceso a todos los demás elementos de nuestros datos.
En este caso, el caso n = 1
va a ser el caso en donde se presenta el individuo cuyos datos estan en el renglón 1. Los pedazos de la presentación los vamos a unir o concatenar como texto utilizando la función stringr::str_c()
.
# Presentación del individuo #1.
print(str_c("Hola, mi nombre es ",
$Nombre[1], # Extrae el dato 1 de la columna Nombre
datos" ",
$Apellido[1], # Extrae el dato 1 de la columna Apellido
datos" y soy ",
$Trabajo[1], # Extrae el dato 1 de la columna Trabajo
datos". ¡Mucho gusto!"))
## [1] "Hola, mi nombre es Luís Pérez y soy Bombero. ¡Mucho gusto!"
Para generar este loop partimos del hecho de que sabemos hacer
subsetting
utilizando la sintaxis de R base: esto es, que al acceder a un elemento de R utilizando el signo de pesos,$
, vamos a acceder a la columna de una tabla y que, al utilizar los corchetes, vamos a acceder al valor o a los valores que ocupen la posición o las posiciones que estamos metiendo dentro de estos corchetes. En el caso de arriba,datos$Trabajo[1]
accedía al valor1
de la columnaTrabajo
de la data.framedatos
.
Paso 2. Cambiamos el 1 por el i.
Y de esta forma realizamos la presentación del individuo 1. Ahora, vamos a sustituir el 1
por un objeto que va a tomar cualquier valor, y el primer valor que le vamos a asignar va a ser el valor de 1
, para corroborar que nos sale lo mismo que en el paso anterior.
Este objeto se va a llamar i
.
# Objeto que va a ir cambiando de valor, con el valor 1.
<- 1
i
# INTRODUCIMOS EL OBJETO DE ARRIBA EN EL CASO N = 1
# Presentación del individuo #i.
print(str_c("Hola, mi nombre es ",
$Nombre[i], # Extrae el dato i de la columna Nombre
datos" ",
$Apellido[i], # Extrae el dato i de la columna Apellido
datos" y soy ",
$Trabajo[i], # Extrae el dato i de la columna Trabajo
datos". ¡Mucho gusto!"))
## [1] "Hola, mi nombre es Luís Pérez y soy Bombero. ¡Mucho gusto!"
Y vemos que da lo mismo en este caso i = 1
que en el caso N = 1
.
Paso 3. Implementamos el loop.
Ahora que ya tenemos un elemento que puede tomar cualquier valor, ya podemos construir el loop: solo nos falta programarlo.
Para programarlo, utilizamos la sintaxis vista en clase:
for(elemento_contador in secuencia_valores){
1...
...haz paso 2...
...haz paso 3...
...haz paso }
En este caso, el elemento_contador
va a ser el objeto i
del paso anterior. Este elemento va a tomar todos los valores que le metamos a la secuencia de valores que va a tomar el contador. Para este caso, la secuencia de valores va a tomar los numeros del 1 al 5, ya que tenemos 5 renglones y cada presentación toma los valores de cada uno de los renglones para llevarse a cabo.
Para generar esta secuencia, utilizamos el siguiente código:
1:nrow(datos) # Secuencia que empieza en 1 y termina en el numero de renglones que tiene la tabla datos (5)
## [1] 1 2 3 4 5
Finalmente, se incluyen en el loop los pasos que se van a ejecutar; para este caso, va a ser el pegado de todos los elementos de cada renglón, a través de la función stringr::str_c()
que vimos en los dos pasos anteriores.
El loop, entonces, quedaría así:
for (i in 1:nrow(datos)){
print(str_c("Hola, mi nombre es ",
$Nombre[i],
datos" ",
$Apellido[i],
datos" y soy ",
$Trabajo[i], ". ¡Mucho gusto!"))
datos }
## [1] "Hola, mi nombre es Luís Pérez y soy Bombero. ¡Mucho gusto!"
## [1] "Hola, mi nombre es Isaac Carmona y soy Soldado. ¡Mucho gusto!"
## [1] "Hola, mi nombre es César Suárez y soy Maestro. ¡Mucho gusto!"
## [1] "Hola, mi nombre es Benito Juárez y soy Político. ¡Mucho gusto!"
## [1] "Hola, mi nombre es Juana Guerra y soy Abogada. ¡Mucho gusto!"
Y así vamos armando nuestras presentaciones.
De esta manera, es como, a través de un contador que va sacando los datos por renglones, podemos ir haciendo un loop donde los datos vayan variando a nivel renglón, a diferencia del visto en clase, donde directamente se metía el elemento que iba a ir variando en el cuerpo del loop.
Implicaciones en la tarea.
En la tarea se hace un proceso similar a este, dado que lo que va a ir variando son los datos de la fecha (para darle nombre al archivo) y la dirección de descarga por renglón (para la descarga del archivo), los cuales van a ser parte de los argumentos que requiere la función de descarga curl::curl_downolad()
.
Igualmente, hay que hacer que el elemento variable de nuestro loop sea una secuencia que vaya del 1 al numero total de renglones y que el proceso de descarga y de renombrado de archivo tome los valores correspondientes a cada uno de los renglones.