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
datos <- tibble::tribble(
   ~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 ", 
              datos$Nombre[1], # Extrae el dato 1 de la columna Nombre 
              " ", 
              datos$Apellido[1], # Extrae el dato 1 de la columna Apellido
              " y soy ", 
              datos$Trabajo[1], # Extrae el dato 1 de la columna Trabajo
            ". ¡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 valor 1 de la columna Trabajo de la data.frame datos.

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. 
i <- 1

# INTRODUCIMOS EL OBJETO DE ARRIBA EN EL CASO N = 1

# Presentación del individuo #i. 
print(str_c("Hola, mi nombre es ", 
              datos$Nombre[i], # Extrae el dato i de la columna Nombre 
              " ", 
              datos$Apellido[i], # Extrae el dato i de la columna Apellido
              " y soy ", 
              datos$Trabajo[i], # Extrae el dato i de la columna Trabajo
            ". ¡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){
  ...haz paso 1...
  ...haz paso 2...
  ...haz paso 3...
}

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 ", 
              datos$Nombre[i], 
              " ", 
              datos$Apellido[i], 
              " y soy ", 
              datos$Trabajo[i], ". ¡Mucho gusto!"))
}
## [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.