La console interattiva è in genere comoda, ma spesso è meglio scrivere il codice in un unico file di testo: questo darà vita ad uno
script R. Farlo è davvero semplice, basta scrivere nel testo tutti i comandi che digiteremmo da console interattiva,
ed una volta salvato potrà essere avviato con Rscript, l'esecutore da riga di comando.
All'interno dello script si possono usare commenti per aumentare la leggibilità del codice. Esistono anche funzioni che producono un output testuale su console, come print
e message
.
Esempio
Vediamo un esempio completo che offrirà anche l'opportunità di vedere qualche altra interessante funzionalità di R. Supponiamo che:
- su un nostro server vengano caricati dei file in CSV, all'interno di una cartella denominata in
"AG002";149.12 "AG001";301.8 "AG001";146.53 "AG004";110.69 "AG003";292.62
- ogni file CSV contiene importi misti, relativi ad agenzie diverse.
Creiamo uno script R che recupera tutti i file presenti nella cartella con estensione .csv out
# fissiamo le cartelle di origine e destinazione dei dati
dir.root <- "D:\\dati"
dir.origine <- paste(dir.root, "in", sep="\\")
dir.destinazione <- paste(dir.root, "out", sep="\\")
# selezioniamo tutti i file della cartella origine il cui nome termina con il suffisso csv
files <- list.files(path=dir.origine, pattern="csv$")
# cicliamo su ogni file
for (f in files)
{
# leggiamo il file
nomefile <- paste(dir.origine, f, sep="\\")
df <- read.table(nomefile, sep=";")
colnames(df) <- c("Agenzia", "Importo")
# prendiamo l'elenco, senza duplicati, dei codici di agenzia
agenzie <- unique(df$Agenzia)
# per ogni codice selezioniamo dal file origine i record dell'agenzia e li salviamo su file CSV
for (k in agenzie)
{
# costruiamo il nome del file destinazione usando il codice agenzia
nomefile.dest=paste(k,"csv", sep=".");
nomefile.completo=paste(dir.destinazione, nomefile.dest, sep="\\")
# estraiamo solo i dati relativi all'agenzia trattata in questa iterazione
sub <- subset(df, Agenzia==k)
# salviamo su file
write.table(sub, nomefile.completo, append=TRUE, row.names=FALSE, col.names=FALSE, sep=";")
}
}
Oltre a quello che riguarda strettamente i file CSV, nello script
appaiono - per la prima volta in questa guida - i cicli for
for ( ... in .... )
{
# operazioni da svolgere
}
L'operatore in
con la variabile definita alla sua sinistra. Il primo ciclo
posto nella cartella di origine. Si noti che la funzione list.files
cartella indicata dal parametro path
pattern
Andiamo a recuperare il contenuto del file CSV e lo poniamo nel data.frame. A quest'ultimo, rinomineremo le colonne con col.names
Con il ciclo interno
quelli etichettati con la sigla che stiamo attualmente analizzando ed infine lo salviamo in un file.
Si faccia attenzione che si richiede una scrittura con append
svolto dalle precedenti iterazioni.
Si potrà verificare nella cartella out
Usare file di input
Prima di concludere, vediamo in che modo abbiamo generato i dati usati per il nostro esercizio, quelli presenti nella cartella di origine:
num.righe <- 20
num.file <- 5
dir.destinazione <- "D:\\dati\\in"
agenzie <- c("AG001","AG002","AG003","AG004")
for (i in 1:num.file)
{
# generiamo colonna di agenzie
ag <- sample(agenzie, size=num.righe, replace=TRUE)
# generiamo colonna importi
imp <- round(runif(num.righe)*300+50, digits=2)
# rendiamo i due vettori colonne di data.frame
df <- data.frame(ag, imp)
# file destinazione con percorso
nome <- paste(dir.destinazione,paste(i,"csv",sep="."), sep="\\")
# salviamo data.frame su file
write.table(df, nome, row.names=FALSE, col.names=FALSE, sep=";")
}
Abbiamo fatto uso di molte funzioni di R che generano valori casuali.
La funzione sample produce una serie casuale di elementi prelevati da un campione.
In questo caso, dal vettore agenzie vengono recuperati i codici che vogliamo usare ed estratti casualmente
per venti volte: ciò ci darà un primo vettore. Il secondo vettore viene prodotto con runif: estraiamo venti numeri
casuali compresi tra 0 e 1 e tali valori vengono espansi con dei coefficienti in modo di avere un importo
che vada da 50 a 350 euro, poi arrotondati a due cifre con la funzione round.
È interessante notare che la funzione round
viene applicata ad ogni singolo
elemento dello stesso, come avviene in Python, Matlab e altri linguaggi di programmazione in grado di gestire operazioni vettoriali.