Approfondimenti sulla programmazione funzionale (ancora sul package purrr)
Author
Domenico Vistocco
Riepilogo delle iterazioni con il ciclo for
Il ciclo for permette di effettuare delle iterazioni in modo abbastanza intuitivo. Consideriamo la famosa tabella degli iris di Fisher, disponibile in R:
Sfruttando il ciclo for ed una variabile di accumulo vet_medie possiamo calcolare la media di ciascuna colonna; possiamo sfruttare la funzione names per assegnare a ciascuna media un’etichetta che contiene il nome della corrispondente variabile:
Le funzioni map hanno un argomento .progress che può essere utile nel caso di lunghe iterazioni per controllarne l’avanzamento. Per mostrarne la funzionalità sfruttiamo la funzione Sys.sleep che mette in pausa R per il numero di secondi specificato in input:
La funzione map_df organizza l’output di map in un forma tabellare laddove possibile. Ecco un esempio in cui calcoliamo alcune statistiche di sintesi sulle colonne della tabella iris_num:
Le funzioni map possono essere utili anche per effettuare simulazioni con numeri casuali. Creo una tabella che contiene 5 vettori di numeri casuali estratti da una distribuzione uniforme impostando opportunamente i nomi di colonna:
set.seed(20)campione_casuale <-map_dfc(1:5, function(i){ x =data.frame(runif(n =50))colnames(x) <-paste0("X", i)return(x) } )campione_casuale
Sfruttando opportunamente map è possibile costruire una tabella per “visualizzare” lo spazio campionario, ovvero l’insieme (o meglio un sottoinsieme in questo caso) dei possibili campioni che è possibile osservare in un dato problema inferenziale.
Consideriamo ad esempio un DGP (data generating process) uniforme tra 10 e 20
set.seed(123)a <-10b <-20
E generiamo 500 campioni di ampiezza 20 a partire da un’uniforme continua tra 10 e 20, aggiungendo una colonna media che calcola la media di ciascuno dei 500 campioni (nota: per calcolare le medie per riga possiamo sfruttare la funzione rowwise):
Ciascuna colonna rappresenta una variabile casuale osservazione campionaria, i.i.d. come il DGP. Ecco un istogramma della v.c. \(X_1\) prima osservazione campionaria:
hist(spazio_campionario$X1)
Dal teorema del limite centrale sappiamo che la media campionaria converge ad una normale:
hist(spazio_campionario$media)
Anche se il campione è solo di ampiezza 20, il DGP è simmetrico per cui l’effetto del limite centrale è già presente. Possiamo sfruttare un grafico quantile-quantile (qqnorm) per apprezzare la convergenza alla normale:
qqnorm(spazio_campionario$media)
Da quanto noto sulla v.c. uniforme, possiamo calcolare la media del DGP:
(a + b) /2
[1] 15
e la varianza del DGP:
(((b - a)^2) /12)
[1] 8.333333
Il valore atteso della media campionaria è uguale alla media del DGP, mentre la varianza è pari alla varianza del DGP diviso per n:
(((b - a)^2) /12) /20
[1] 0.4166667
Possiamo verificare empiricamente il valore della media e della varianza dei 500 campioni generati:
Possiamo sfruttare la funzione map2 che effettua un’iterazione su una coppia di vettori in input (primi due argomenti .x e y) applicando la funzione .f (terzo argomento) a ciascuna coppia di elementi dei due vettori:
Possiamo verificare empiricamente media e standard deviation dei numeri generati:
map_vec(numeri_normali, mean)
[1] 200.6205 300.6847 399.5618
map_vec(numeri_normali, sd)
[1] 1.380892 2.030393 3.364595
La funzione pmap permette di generalizzare l’iterazione su input multipli organizzati in una lista passata alla funzione come primo argomento. Possiamo generalizzare facilmente l’esempio precedente generando tre vettori di numeri casuali di differente numerosità (vet_n), con differenti medie (vet_medie) e differenti standard deviation (vet_sigma):
così come ispezionare la cardinalità, le medie e le deviazioni standard dei numeri casuali genera
map_vec(numeri_normali, length)
[1] 20 30 40
map_vec(numeri_normali, mean)
[1] 199.4815 300.4340 400.2793
map_vec(numeri_normali, sd)
[1] 1.721591 2.606318 4.128880
Le varianti walk, walk2 e pwalk
Nel package purrr sono disponibili tre funzioni (walk, walk2 e pwalk) che permettono di effettuare iterazioni allo stesso modo delle controparti map, map2 e pmap ma che non restituiscono oggetti in output. Le funzioni della famiglia walk sono utili quando si è interessati perciò agli effetti collaterali prodotti dalla funzioni piuttosto che ai valori restituiti in output. Esempi tipici di questi casi sono iterazioni che permettono di creare un insieme di grafici o di scrivere un insieme di file.
Proviamo ad esempio ad effettuare un’iterazione sulla lista numeri_normali costruita nella sezione precedente per ottenere una rappresentazione grafica di ciascun vettore di numeri casuali sfruttando la funzione walk:
walk(.x = numeri_normali,.f =~hist(.x, breaks =7, col ="darkblue"))
Possiamo migliorare i grafici inserendo un titolo che descriva le caratteristiche dei dati rappresentati, ovvero numerosità dei dati e media e standard deviation usata per generarli. In questo caso è utile sfruttare la funzione pwalk iterando sui vettori
pwalk(.l =list(vet_n, vet_medie, vet_sigma, numeri_normali),.f =function(el_1, el_2, el_3, el_4) { title_plot <-bquote(paste("N(", mu == .(el_2), ", ", sigma == .(el_3), ") | n = ", .(el_1)))hist(el_4, breaks =7, col ="darkblue", main = title_plot) })
map - esempio pratico 1: lettura e combinazione di fogli multipli da una cartella MS-Excel
La funzione map può essere utilizzata per leggere fogli multipli da una cartella di lavoro MS-Excel. Per testare il codice in questa sezione puoi scaricare da questo link la cartella MS-Excel di esempio e copiarlo all’interno della cartella del progetto di lavoro o della cartella di lavoro.
Per leggere un file MS-Excel utilizziamo il package readxl. Il seguente codice leggere il foglio MSDUE15 dalla cartella di lavoro, impostando la prima colonna come formato date e la seconda come formato numeric; una volta letto il file impostiamo i nomi delle due colonne rispettivamente come data e price sfruttando la funzione set_names:
Otteniamo una lista di tabelle, i dati di ciascun foglio di lavoro corrispondono ad un elemento della lista:
class(dati_ms)
[1] "list"
length(dati_ms)
[1] 11
Le elaborazioni possono essere effettuate agevolemnte sulle singole tabelle accedendo ai singoli elementi. Il seguente codice calcola il rendimento dei titoli a partire dalle colonne dei prezzi dei singoli indici sfruttando la funzione lag per effettuare la differenza tra il valore al tempo t e quello al tempo t-1. La funzione slice permette di eliminare la prima riga della tabella, per la quale ovviamente non può essere calcolato il rendimento:
La lista delle tabelle ottenuta è una lista senza nomi, come è possibile verificare sfruttando la funzione names:
names(dati_ms)
NULL
Possiamo sfruttare la funzione set_names per assegnare a ciascun elemento della lista il nome corrispondente al foglio di lavoro da cui sono stati letti i dati:
Questo ci consente di identificare i dati inserendo la colonna dei nomi nel caso siamo interessati ad impilare le singole tabelle in un’unica tabella sfruttando la funzione list_rbind:
walk - esempio pratico 2: scrittura di file .csv multipli
Sfruttando lo stesso file utilizzato nella precedente sezione (disponibile su questo link), possiamo mostrare la funzione walk per salvare un singolo file in formato .csv dove archiviare le tabelle dei dati presenti in ciascun foglio di lavoro. In questo caso siamo interessati solo all’effetto collaterale, che consiste nel salvataggio dei file, piuttosto che ai valori di output di ciascun funzione, per cui la funzione walk è più opportuna della funzione map. In particolare la funzione walk2 ci permette di iterare sulla lista della tabella e sul vettore dei nomi per scrivere le singole tabelle:
walk - esempio pratico 3: creazione di report parametrici multipli
Per questo esempio dell’utilizzo delle funzioni walk, walk2 e pwalk è necessario caricare il package quarto in modo da compilare il report via riga di comando sfruttando la funzione quarto_render (l’equivalente della compilazione del report sfruttando il tasto Render dell’interfaccia):
library(quarto)
Consideriamo ai fini di questo esempio la tabella gapminder disponibile nel package gapminder:
# A tibble: 6 × 6
country continent year lifeExp pop gdpPercap
<fct> <fct> <int> <dbl> <int> <dbl>
1 Afghanistan Asia 1952 28.8 8425333 779.
2 Afghanistan Asia 1957 30.3 9240934 821.
3 Afghanistan Asia 1962 32.0 10267083 853.
4 Afghanistan Asia 1967 34.0 11537966 836.
5 Afghanistan Asia 1972 36.1 13079460 740.
6 Afghanistan Asia 1977 38.4 14880372 786.
e il semplice modello di report parametrico che è possibile scaricare da questo link.
La funzione quarto_render permette la compilazione (rendering) di un report Quarto sfruttando il codice: è l’equivalente del tasto render dell’interfaccia. Se non utilizziamo i parametri previsti nel modello di report parametrico, viene compilato il report con i valori di default presenti nella sezione YAML del file .qmd:
# NOTA: se vuoi provare questo comando scarica in locale il template del # del report parametricoquarto_render(input ="lab_18-report-parametrico.qmd",output_format ="html",output_file ="report-parametrico-default.html")
Sfruttando la funzione quarto_render è possibile personalizzare il report passando in input i parametri di interesse del particolare report sfruttando l’argomento execute_params. Ecco un esempio di codice che permette di ottenere un report per l’anno 1952 per il continente Asia:
# NOTA: se vuoi provare questo comando scarica in locale il template del # del report parametricoquarto_render(input ="lab_18-report-parametrico.qmd",execute_params =list(anno =1952,continente ="Asia"),output_format ="html",output_file ="report-asia-1952.html")
Quanti sono i possibili report? Il numero di report che posso ottenere a partire da questo semplice modello dipendono dal numero di anni distinti presenti nella tabella. Utilizziamo la funzione pull() per ottenere un output di tipo atomico:
anni <- gapminder::gapminder |>distinct(year) |>pull()anni
[1] Asia Europe Africa Americas Oceania
Levels: Africa Americas Asia Europe Oceania
Poichè i continenti sono codificati come una variabile di tipo factor e il parametro del report parametrico è di tipo stringa converto il vettore atomico in un vettore di caratteri:
Il numero di possibili report è pari al prodotto tra il numero di continenti:
length(continenti)
[1] 5
e il numero di anni presenti nella tabella dati:
length(anni)
[1] 12
Posso ottenere una tabella che riporta tutti i possibili incroci sfruttando la funzione expand_grid passando in input i due vettori atomici:
incroci <-expand_grid(continenti, anni)incroci
# A tibble: 60 × 2
continenti anni
<chr> <int>
1 Asia 1952
2 Asia 1957
3 Asia 1962
4 Asia 1967
5 Asia 1972
6 Asia 1977
7 Asia 1982
8 Asia 1987
9 Asia 1992
10 Asia 1997
# ℹ 50 more rows
nrow(incroci)
[1] 60
Sarebbe possibile ottenere l’insieme di tutti i possibili incroci sfruttando il join incrociato (cross_join):
# A tibble: 60 × 2
continent year
<fct> <int>
1 Asia 1952
2 Asia 1957
3 Asia 1962
4 Asia 1967
5 Asia 1972
6 Asia 1977
7 Asia 1982
8 Asia 1987
9 Asia 1992
10 Asia 1997
# ℹ 50 more rows
Possiamo costruire i report per un dato continente per tutti i possibili anni. Posso in particolare costruire un vettore con i nomi dei file di output desiderati
nomi_file <-paste0("report-Europa-", anni, ".html")nomi_file
# NOTA: se vuoi provare questo comando scarica in locale il template del # del report parametricowalk2(.x = anni, .y = nomi_file,.f =~quarto_render(input ="lab_18-report-parametrico.qmd",execute_params =list(anno = .x,continente ="Europe"),output_format ="html",output_file = .y))
Per ottenere i report per tutti i possibili incroci sfrutto la funzione expand_grid aggiungendo prima di una colonna con i nomi dei file di output:
incroci <-expand_grid(continenti, anni) |>mutate(nomi =paste0("report-", continenti, "-", anni, ".html"))incroci
# A tibble: 60 × 3
continenti anni nomi
<chr> <int> <chr>
1 Asia 1952 report-Asia-1952.html
2 Asia 1957 report-Asia-1957.html
3 Asia 1962 report-Asia-1962.html
4 Asia 1967 report-Asia-1967.html
5 Asia 1972 report-Asia-1972.html
6 Asia 1977 report-Asia-1977.html
7 Asia 1982 report-Asia-1982.html
8 Asia 1987 report-Asia-1987.html
9 Asia 1992 report-Asia-1992.html
10 Asia 1997 report-Asia-1997.html
# ℹ 50 more rows
Possiamo sfruttare la funzione pwalk (o pmap) per ottenere tutti i report. Ecco un esempio di pmap: creazione un vettore con i tre elementi presenti su ogni riga della tabella incroci:
pmap(incroci, ~c(a = ..1, b = ..2, c = ..3))
[[1]]
a b c
"Asia" "1952" "report-Asia-1952.html"
[[2]]
a b c
"Asia" "1957" "report-Asia-1957.html"
[[3]]
a b c
"Asia" "1962" "report-Asia-1962.html"
[[4]]
a b c
"Asia" "1967" "report-Asia-1967.html"
[[5]]
a b c
"Asia" "1972" "report-Asia-1972.html"
[[6]]
a b c
"Asia" "1977" "report-Asia-1977.html"
[[7]]
a b c
"Asia" "1982" "report-Asia-1982.html"
[[8]]
a b c
"Asia" "1987" "report-Asia-1987.html"
[[9]]
a b c
"Asia" "1992" "report-Asia-1992.html"
[[10]]
a b c
"Asia" "1997" "report-Asia-1997.html"
[[11]]
a b c
"Asia" "2002" "report-Asia-2002.html"
[[12]]
a b c
"Asia" "2007" "report-Asia-2007.html"
[[13]]
a b c
"Europe" "1952" "report-Europe-1952.html"
[[14]]
a b c
"Europe" "1957" "report-Europe-1957.html"
[[15]]
a b c
"Europe" "1962" "report-Europe-1962.html"
[[16]]
a b c
"Europe" "1967" "report-Europe-1967.html"
[[17]]
a b c
"Europe" "1972" "report-Europe-1972.html"
[[18]]
a b c
"Europe" "1977" "report-Europe-1977.html"
[[19]]
a b c
"Europe" "1982" "report-Europe-1982.html"
[[20]]
a b c
"Europe" "1987" "report-Europe-1987.html"
[[21]]
a b c
"Europe" "1992" "report-Europe-1992.html"
[[22]]
a b c
"Europe" "1997" "report-Europe-1997.html"
[[23]]
a b c
"Europe" "2002" "report-Europe-2002.html"
[[24]]
a b c
"Europe" "2007" "report-Europe-2007.html"
[[25]]
a b c
"Africa" "1952" "report-Africa-1952.html"
[[26]]
a b c
"Africa" "1957" "report-Africa-1957.html"
[[27]]
a b c
"Africa" "1962" "report-Africa-1962.html"
[[28]]
a b c
"Africa" "1967" "report-Africa-1967.html"
[[29]]
a b c
"Africa" "1972" "report-Africa-1972.html"
[[30]]
a b c
"Africa" "1977" "report-Africa-1977.html"
[[31]]
a b c
"Africa" "1982" "report-Africa-1982.html"
[[32]]
a b c
"Africa" "1987" "report-Africa-1987.html"
[[33]]
a b c
"Africa" "1992" "report-Africa-1992.html"
[[34]]
a b c
"Africa" "1997" "report-Africa-1997.html"
[[35]]
a b c
"Africa" "2002" "report-Africa-2002.html"
[[36]]
a b c
"Africa" "2007" "report-Africa-2007.html"
[[37]]
a b
"Americas" "1952"
c
"report-Americas-1952.html"
[[38]]
a b
"Americas" "1957"
c
"report-Americas-1957.html"
[[39]]
a b
"Americas" "1962"
c
"report-Americas-1962.html"
[[40]]
a b
"Americas" "1967"
c
"report-Americas-1967.html"
[[41]]
a b
"Americas" "1972"
c
"report-Americas-1972.html"
[[42]]
a b
"Americas" "1977"
c
"report-Americas-1977.html"
[[43]]
a b
"Americas" "1982"
c
"report-Americas-1982.html"
[[44]]
a b
"Americas" "1987"
c
"report-Americas-1987.html"
[[45]]
a b
"Americas" "1992"
c
"report-Americas-1992.html"
[[46]]
a b
"Americas" "1997"
c
"report-Americas-1997.html"
[[47]]
a b
"Americas" "2002"
c
"report-Americas-2002.html"
[[48]]
a b
"Americas" "2007"
c
"report-Americas-2007.html"
[[49]]
a b
"Oceania" "1952"
c
"report-Oceania-1952.html"
[[50]]
a b
"Oceania" "1957"
c
"report-Oceania-1957.html"
[[51]]
a b
"Oceania" "1962"
c
"report-Oceania-1962.html"
[[52]]
a b
"Oceania" "1967"
c
"report-Oceania-1967.html"
[[53]]
a b
"Oceania" "1972"
c
"report-Oceania-1972.html"
[[54]]
a b
"Oceania" "1977"
c
"report-Oceania-1977.html"
[[55]]
a b
"Oceania" "1982"
c
"report-Oceania-1982.html"
[[56]]
a b
"Oceania" "1987"
c
"report-Oceania-1987.html"
[[57]]
a b
"Oceania" "1992"
c
"report-Oceania-1992.html"
[[58]]
a b
"Oceania" "1997"
c
"report-Oceania-1997.html"
[[59]]
a b
"Oceania" "2002"
c
"report-Oceania-2002.html"
[[60]]
a b
"Oceania" "2007"
c
"report-Oceania-2007.html"
Ecco invece un esempio di pwalk: stampo i tre elementi presenti su ogni riga della tabella incroci:
pwalk(incroci, ~print(paste0("El. 1 -> ", ..1, " | El. 2 -> ", ..2, "| El. 3 -> ", ..3)))
[1] "El. 1 -> Asia | El. 2 -> 1952| El. 3 -> report-Asia-1952.html"
[1] "El. 1 -> Asia | El. 2 -> 1957| El. 3 -> report-Asia-1957.html"
[1] "El. 1 -> Asia | El. 2 -> 1962| El. 3 -> report-Asia-1962.html"
[1] "El. 1 -> Asia | El. 2 -> 1967| El. 3 -> report-Asia-1967.html"
[1] "El. 1 -> Asia | El. 2 -> 1972| El. 3 -> report-Asia-1972.html"
[1] "El. 1 -> Asia | El. 2 -> 1977| El. 3 -> report-Asia-1977.html"
[1] "El. 1 -> Asia | El. 2 -> 1982| El. 3 -> report-Asia-1982.html"
[1] "El. 1 -> Asia | El. 2 -> 1987| El. 3 -> report-Asia-1987.html"
[1] "El. 1 -> Asia | El. 2 -> 1992| El. 3 -> report-Asia-1992.html"
[1] "El. 1 -> Asia | El. 2 -> 1997| El. 3 -> report-Asia-1997.html"
[1] "El. 1 -> Asia | El. 2 -> 2002| El. 3 -> report-Asia-2002.html"
[1] "El. 1 -> Asia | El. 2 -> 2007| El. 3 -> report-Asia-2007.html"
[1] "El. 1 -> Europe | El. 2 -> 1952| El. 3 -> report-Europe-1952.html"
[1] "El. 1 -> Europe | El. 2 -> 1957| El. 3 -> report-Europe-1957.html"
[1] "El. 1 -> Europe | El. 2 -> 1962| El. 3 -> report-Europe-1962.html"
[1] "El. 1 -> Europe | El. 2 -> 1967| El. 3 -> report-Europe-1967.html"
[1] "El. 1 -> Europe | El. 2 -> 1972| El. 3 -> report-Europe-1972.html"
[1] "El. 1 -> Europe | El. 2 -> 1977| El. 3 -> report-Europe-1977.html"
[1] "El. 1 -> Europe | El. 2 -> 1982| El. 3 -> report-Europe-1982.html"
[1] "El. 1 -> Europe | El. 2 -> 1987| El. 3 -> report-Europe-1987.html"
[1] "El. 1 -> Europe | El. 2 -> 1992| El. 3 -> report-Europe-1992.html"
[1] "El. 1 -> Europe | El. 2 -> 1997| El. 3 -> report-Europe-1997.html"
[1] "El. 1 -> Europe | El. 2 -> 2002| El. 3 -> report-Europe-2002.html"
[1] "El. 1 -> Europe | El. 2 -> 2007| El. 3 -> report-Europe-2007.html"
[1] "El. 1 -> Africa | El. 2 -> 1952| El. 3 -> report-Africa-1952.html"
[1] "El. 1 -> Africa | El. 2 -> 1957| El. 3 -> report-Africa-1957.html"
[1] "El. 1 -> Africa | El. 2 -> 1962| El. 3 -> report-Africa-1962.html"
[1] "El. 1 -> Africa | El. 2 -> 1967| El. 3 -> report-Africa-1967.html"
[1] "El. 1 -> Africa | El. 2 -> 1972| El. 3 -> report-Africa-1972.html"
[1] "El. 1 -> Africa | El. 2 -> 1977| El. 3 -> report-Africa-1977.html"
[1] "El. 1 -> Africa | El. 2 -> 1982| El. 3 -> report-Africa-1982.html"
[1] "El. 1 -> Africa | El. 2 -> 1987| El. 3 -> report-Africa-1987.html"
[1] "El. 1 -> Africa | El. 2 -> 1992| El. 3 -> report-Africa-1992.html"
[1] "El. 1 -> Africa | El. 2 -> 1997| El. 3 -> report-Africa-1997.html"
[1] "El. 1 -> Africa | El. 2 -> 2002| El. 3 -> report-Africa-2002.html"
[1] "El. 1 -> Africa | El. 2 -> 2007| El. 3 -> report-Africa-2007.html"
[1] "El. 1 -> Americas | El. 2 -> 1952| El. 3 -> report-Americas-1952.html"
[1] "El. 1 -> Americas | El. 2 -> 1957| El. 3 -> report-Americas-1957.html"
[1] "El. 1 -> Americas | El. 2 -> 1962| El. 3 -> report-Americas-1962.html"
[1] "El. 1 -> Americas | El. 2 -> 1967| El. 3 -> report-Americas-1967.html"
[1] "El. 1 -> Americas | El. 2 -> 1972| El. 3 -> report-Americas-1972.html"
[1] "El. 1 -> Americas | El. 2 -> 1977| El. 3 -> report-Americas-1977.html"
[1] "El. 1 -> Americas | El. 2 -> 1982| El. 3 -> report-Americas-1982.html"
[1] "El. 1 -> Americas | El. 2 -> 1987| El. 3 -> report-Americas-1987.html"
[1] "El. 1 -> Americas | El. 2 -> 1992| El. 3 -> report-Americas-1992.html"
[1] "El. 1 -> Americas | El. 2 -> 1997| El. 3 -> report-Americas-1997.html"
[1] "El. 1 -> Americas | El. 2 -> 2002| El. 3 -> report-Americas-2002.html"
[1] "El. 1 -> Americas | El. 2 -> 2007| El. 3 -> report-Americas-2007.html"
[1] "El. 1 -> Oceania | El. 2 -> 1952| El. 3 -> report-Oceania-1952.html"
[1] "El. 1 -> Oceania | El. 2 -> 1957| El. 3 -> report-Oceania-1957.html"
[1] "El. 1 -> Oceania | El. 2 -> 1962| El. 3 -> report-Oceania-1962.html"
[1] "El. 1 -> Oceania | El. 2 -> 1967| El. 3 -> report-Oceania-1967.html"
[1] "El. 1 -> Oceania | El. 2 -> 1972| El. 3 -> report-Oceania-1972.html"
[1] "El. 1 -> Oceania | El. 2 -> 1977| El. 3 -> report-Oceania-1977.html"
[1] "El. 1 -> Oceania | El. 2 -> 1982| El. 3 -> report-Oceania-1982.html"
[1] "El. 1 -> Oceania | El. 2 -> 1987| El. 3 -> report-Oceania-1987.html"
[1] "El. 1 -> Oceania | El. 2 -> 1992| El. 3 -> report-Oceania-1992.html"
[1] "El. 1 -> Oceania | El. 2 -> 1997| El. 3 -> report-Oceania-1997.html"
[1] "El. 1 -> Oceania | El. 2 -> 2002| El. 3 -> report-Oceania-2002.html"
[1] "El. 1 -> Oceania | El. 2 -> 2007| El. 3 -> report-Oceania-2007.html"
Sfruttando la funzione pwalk possiamo ottenere tutti i 60 report in modo automatico incrociando tutti i possibili valori di anno e continente (prime due colonne della tabella incroci) e passando i nomi dei file di output desiderati (terza colonna):
# NOTA: se vuoi provare questo comando scarica in locale il template del # del report parametricopwalk(incroci, ~quarto_render(input ="lab_18-report-parametrico.qmd",execute_params =list(anno = ..2,continente = ..1),output_format ="html",output_file = ..3))# file creati automaticamente sfruttando la funzione pwalklist.files(pattern ="report-*.html")# sposto i file creati nella cartella report# NOTA: creo la directory se non già presente sul disco dir.create("report", showWarnings =FALSE)file.rename(from =list.files(pattern ="report-.*\\.html"),to =paste0("report/", list.files(pattern ="report-.*\\.html")))