Hasta ahora hemos visto un bucle de manera muy simple, donde repetíamos o iterábamos un bloque de operaciones para un solo conjunto de elementos. Hay veces que sin embargo tendremos que realizar esas operaciones para combinaciones de varios conjuntos de elementos. Para ello, es posible incluir un bucle dentro de otro bucle (anidarlos) para de esa manera poder ejecutar todas las combinaciones de los elementos de dichos conjuntos. Vamos a verlo con un ejemplo. Podemos hacer tantas combinaciones de conjuntos como necesitemos.
Vamos a tener un supuesto ahora en el que tuviéramos que trabajar con escenarios de cambio climático. Para ello tendríamos dos modelos de circulación general de la atmósfera (GCMs), que vamos a llamar por las instituciones que los han producido: el CSIRO de Australia y el Hadley Center de la Universidad de Manchester. Cada uno de estos dos modelos produce su modelo en tres momentos temporales. Por lo tanto, tendríamos 6 combinaciones posibles de estos escenarios en los que tuviéramos que ejecutar operaciones.Es decir, los escenarios temporales quedan dentro de los modelos: habrá 3 escenarios para el CSIRO y 3 para el Hadley, Por tanto, necesitaríamos dos bucles en los que ejecutar las operaciones que necesitáramos.
Primero vamos a preparar esos datos:
instituciones<-c("CSIRO","HADLEY") #vector con los nombres de modelo
años<-c(2030,2050,2080) #años de las predicciones
Tendremos que introducir un bucle dentro de otro bucle. Empezaremos con el temporal, de manera que las operaciones sobre nuestros datos se ejecutarán sobre los tres escenarios temporales del primer modelo climático. No pasaremos al segundo hasta que no se ejecuten las operaciones de los tres escenarios temporales. A nivel de estructura de nuestro lenguaje, el primer bucle queda “envuelto” por el segundo.
En un caso real disponemos de datos verdaderos, pero en este caso vamos a limitarnos a imprimir por pantalla un texto que nos diga en qué combinación de escenarios nos encontramos. Usaremos el objeto centro
como índice que indique en qué modelo climático nos encontramos, y año
como objeto cambiante para recorrer los tres escenarios temporales.
for(centro in instituciones){
for (año in años){
print(paste(centro,año))
}
}
## [1] "CSIRO 2030"
## [1] "CSIRO 2050"
## [1] "CSIRO 2080"
## [1] "HADLEY 2030"
## [1] "HADLEY 2050"
## [1] "HADLEY 2080"
Así obtenemos por pantalla los resultados de combinar esto. A nivel real, en el ejercicio guiado para construir el dataset de ríos, es justo lo que haríamos:
Estas operaciones nos van a permitir ejecutar funciones e instrucciones para cambiar de directorio cada vez, y leer uno a uno los nombres que contenga un vector que aloje los nombres de cada uno de los archivos a leer. No os preocupéis, el ejercicio guiado clarificará a qué me refiero. No tengo que construir este vector manualmente, escribiendo uno a uno los archivos que a mí me interesa leer.
La función list.files()
me permite hacer eso. Pero quiero filtrar la lista, por lo que voy a recurrir al argumento ’pattern=` porque me va a permitir decirle qué tipo de archivos quiero que lea.
En el supuesto de que quiera leer los tres archivos que tengo en mi carpeta de trabajo, que sean del tipo bio_XX.tif
(son mapas con datos climáticos) y obviar los demás, el argumento pattern=
es mi solución, dado que me permite buscar una cadena de texto determinada:
bio<-list.files(pattern="bio")
Aunque se incluye biocrust.csv
porque también lo incluye, no vamos a complicar este tutorial y lo vamos a quitar de nuestro vector a mano. Ahora podría hacer un bucle para que me los leyera uno tras otro y realizara las operaciones. Para leer este tipo de mapas, si no habéis hecho la parte de visualización de mapas del tema 5, tenéis que instalar y cargar el paquete raster
.
install.packages("raster")
library(raster)
## Loading required package: sp
Selecciono solo los tres primeros elementos de mi vector bio y así me quito el nombre biocrust.csv
.
La función en la primera línea del bucle va a ser capaz de leer directamente con la función raster el nombre que contiene el objeto mapa que llamo en el bucle.
bio<-bio[1:3]
for (mapa in bio){
mapa_temporal<-raster(mapa)
plot(mapa_temporal,main=mapa)
}