1.22 Scrivere proprie funzioni

Abbiamo visto in precedenza come sia possibile simulare i risultati prodotti da dieci lanci di un dado o, in maniera equivalente, dal singolo lancio di dieci dadi. Possiamo replicare questo processo digitando ripetutamente le stesse istruzioni nella console. Otterremo ogni volta risultati diversi perché, ad ogni ripetizione, il generatore di numeri pseudo-casuali di R dipende dal valore ottenuto dal clock interno della macchina. La funzione set.seed() ci permette di replicare esattamente i risultati della generazione di numeri casuali. Per ottenere questo risultato, basta assegnare al seed un numero arbitrario, es. set.seed(12345). Tuttavia, questa procedura è praticamente difficile da perseguire se il numero di ripetizioni è alto. In tal caso è vantaggioso scrivere una funzione contenente il codice che specifica il numero di ripetizioni. In questo modo, per trovare il risultato cercato basterà chiamare la funzione una sola volta.

Le funzioni utilizzate da \(\mathsf{R}\) sono costituite da tre elementi: il nome, il blocco del codice e una serie di argomenti. Per creare una funzione è necessario immagazzinare in R questi tre elementi e function() consente di ottenere tale risultato usando la sintassi seguente:

nome_funzione <- function(arg1, arg2, ...) {
  espressione1
  espressione2
  return(risultato)
}

Una chiamata di funzione è poi eseguita nel seguente modo:

nome_funzione(arg1, arg2, ...)

Per potere essere utilizzata, una funzione deve essere presente nella memoria di lavoro di \(\mathsf{R}\). Le funzioni salvate in un file possono essere richiamate utilizzando la funzione source(), ad esempio, source("file_funzioni.R").

Consideriamo ora la funzione two_rolls() che ritorna la somma dei punti prodotti dal lancio di due dadi non truccati:

two_rolls <- function() {
  die <- 1:6
  res <- sample(die, size = 2, replace = TRUE)
  sum_res <- sum(res)
  return(sum_res)
}

La funzione two_rolls() inizia con il creare il vettore die che contiene sei elementi: i numeri da \(1\) a \(6\). Viene poi utilizzata la funzione sample() con gli gli argomenti, die, size = 2 e replace = TRUE. Tale funzione restituisce il risultato del lancio di due dadi. Il risultato fornito da sample(die, size = 2, replace = TRUE) viene assegnato all’oggetto res. L’oggetto res corrisponde dunque ad un vettore di due elementi. L’istruzione sum(res) somma gli elementi del vettore res e attribuisce il risultato di questa operazione a sum_res. Infine, la funzione return() ritorna il contenuto dell’oggetto sum_res. Invocando la funzione two_rolls() si ottiene dunque la somma del lancio di due dadi. In generale, la funzione two_rolls() produrrà un risultato diverso ogni volta che viene usata:

two_rolls()
#> [1] 9
two_rolls()
#> [1] 4
two_rolls()
#> [1] 7

La formattazione del codice mediante l’uso di spazi e rientri non è necessaria ma è altamente raccomandata per minimizzare la probabilità di compiere errori.