Dai link qui riportati è possibile scaricare la raccolta dei post, attualmente sono oltre 500 pagine in formato .pdf
Un blog di R per imparaRfacendo, seguendo il motto “se ascolto dimentico, se vedo ricordo, se faccio capisco”.
Visualizzazione post con etichetta R. Mostra tutti i post
Visualizzazione post con etichetta R. Mostra tutti i post
giovedì 15 agosto 2024
lunedì 10 gennaio 2022
Gestione delle date del calendario
Se avete la necessità di gestire le date del calendario, dovete partire dal fatto che R assume essere date del calendario quelle contenute in oggetti della classe "Date" ed espresse in uno specifico formato.
Vediamo di capire questa cosa con lo script che segue, copiatelo e incollatelo nella Console di R e premete ↵ Invio:
# GESTIONE DELLE DATE DEL CALENDARIO CON R - parte prima
#
# (1/5)
lemiedate <- c("13/05/1998", "16/12/1945", "23/09/2012") # i dati inseriti
lemiedate # il contenuto dell'oggetto
class(lemiedate) # la classe dell'oggetto
str(lemiedate) # la struttura dell'oggetto
#
# (2/5)
con_asDate <- as.Date(lemiedate, format="%d/%m/%Y") # i dati trasformati
con_asDate # il contenuto dell'oggetto
class(con_asDate) # la classe dell'oggetto
str(con_asDate) # la struttura dell'oggetto
#
# (3/5)
con_format <- format(con_asDate, "%d/%m/%Y") # i dati trasformati
con_format # il contenuto dell'oggetto
class(con_format) # la classe dell'oggetto
str(con_format) # la struttura dell'oggetto
#
# (4/5)
as.Date("23/09/2012", format="%d/%m/%Y") # dati in formato gg/mm/aaaa
#
as.Date("09/23/2012", format="%m/%d/%Y") # dati in formato mm/gg/aaaa
#
as.Date("2012/09/23", format="%Y/%m/%d") # dati in formato aaaa/mm/gg
#
as.Date("23 settembre 2012", format="%d %B %Y") # dati in formato gg mese aaaa con spazio come separatore
#
as.Date("09-3-2012", format="%m-%d-%Y") # dati in formato mm-gg-aaaa con - come separatore
#
# (5/5)
library(lubridate)
dmy(c("13/05/1998", "16/12/1945", "23/09/2012"))
#
Questo è il risultato della prima parte dello script:
> # (1/5)
> lemiedate <- c("13/05/1998", "16/12/1945", "23/09/2012") # i dati inseriti
> lemiedate # il contenuto dell'oggetto
[1] "13/05/1998" "16/12/1945" "23/09/2012"
> class(lemiedate) # la classe dell'oggetto
[1] "character"
> str(lemiedate) # la struttura dell'oggetto
chr [1:3] "13/05/1998" "16/12/1945" "23/09/2012"
> #
In pratica siamo partiti dal presupposto che
→ 13/05/1998
→ 16/12/1945
→ 23/09/2012
sono tre date del calendario che vogliamo gestire con R. Le abbiamo inserite nell'oggetto lemiedate con la funzione c()
> lemiedate <- c("13/05/1998", "16/12/1945", "23/09/2012") # i dati inseriti
le abbiamo ritrovate digitando il nome dell'oggetto
> lemiedate # il contenuto dell'oggetto
[1] "13/05/1998" "16/12/1945" "23/09/2012"
con la funzione class() che mostra la classe di un oggetto vediamo che R ha identificato le tre date come "character"
> class(lemiedate) # la classe dell'oggetto
[1] "character"
e con la funzione str() che mostra la struttura interna di un oggetto ne abbiamo riportato un ulteriore riepilogo sintetico
> str(lemiedate) # la struttura dell'oggetto
chr [1:3] "13/05/1998" "16/12/1945" "23/09/2012"
nel quale "chr" sta di nuovo per "character", la classe dell'oggetto.
Quindi inserendo i dati con la funzione c() quelle che per noi erano tre date sono state identificate in R come "character", cioè come semplici stringhe o in altre parole come tre sequenze di caratteri alfanumerici: in pratica invece delle date avremmo potuto inserire "ciao Giovanni", "domani farà bel tempo", "viva la pappa col pomodoro”" o quant'altro.
Vediamo ora cosa accade con il successivo e secondo blocco di codice:
> # (2/5)
> con_asDate <- as.Date(lemiedate, format="%d/%m/%Y") # i dati trasformati
> con_asDate # il contenuto dell'oggetto
[1] "1998-05-13" "1945-12-16" "2012-09-23"
> class(con_asDate) # la classe dell'oggetto
[1] "Date"
> str(con_asDate) # la struttura dell'oggetto
Date[1:3], format: "1998-05-13" "1945-12-16" "2012-09-23"
> #
Questa volta impieghiamo la funzione as.Date() per inserire lemiedate (l'oggetto della classe "character" contenente tre stringhe alfanumeriche) in un nuovo oggetto denominato con_asDate (giusto per ricordarci come lo abbiamo generato)
> con_asDate <- as.Date(lemiedate, format="%d/%m/%Y") # i dati trasformati
Dopo avere ritrovato quello che abbiamo inserito digitando il nome dell'oggetto
> con_asDate # il contenuto dell'oggetto
[1] "1998-05-13" "1945-12-16" "2012-09-23"
con la funzione class()
> class(con_asDate) # la classe dell'oggetto
[1] "Date"
e con la funzione str()
> str(con_asDate) # la struttura dell'oggetto
Date[1:3], format: "1998-05-13" "1945-12-16" "2012-09-23"
> #
vediamo che con_asDate è un oggetto della classe "Date" nel quale in R per definizione sono contenute date del calendario
L'argomento format="...." impiegato nella funzione as.Date() specifica sia l'ordine sia il formato dei dati in ingresso con i seguenti codici:
Codice Valore
%d Giorno del mese (numero decimale)
%m Mese (numero decimale)
%b Mese (abbreviato)
%B Mese (nome esteso)
%y Anno (2 cifre)
%Y Anno (4 cifre)
Se ora nella Console di R digitate help(as.Date) si apre una pagina web con la definizione della funzione in questione, che è definita come "la funzione che converte le rappresentazioni [di date] sotto forma di caratteri [stringhe di testo] in oggetti della classe "Date" che rappresentano date di calendario".
Come certamente avrete notato una volta importate in R con la funzione asDate() le date sono state convertite nel formato aaaa-mm-gg. A questo punto la domanda è d'obbligo: e se volessi tornare a convertirle nel formato gg/mm/aaaa? La cosa è possibile, e vediamo come con la terza parte di codice:
> # (3/5)
> con_format <- format(con_asDate, "%d/%m/%Y") # i dati trasformati
> con_format # il contenuto dell'oggetto
[1] "13/05/1998" "16/12/1945" "23/09/2012"
> class(con_format) # la classe dell'oggetto
[1] "character"
> str(con_format) # la struttura dell'oggetto
chr [1:3] "13/05/1998" "16/12/1945" "23/09/2012"
> #
Con la funzione format() - da non confondere con l'argomento format= della funzione asDate() - possiamo convertire le date dal formato aaaa-mm-gg nel quale erano nell'oggetto con_asDate al formato gg/mm/aaaa specificato con l'argomento "%d/%m/%Y"
> con_format <- format(con_asDate, "%d/%m/%Y") # i dati trasformati
Questo può essere utile ad esempio se vogliamo visualizzare o stampare le date in questo formato. Ma in questo modo le date per R non sono più tali. Se esaminiamo il nuovo oggetto con_format
> con_format # il contenuto dell'oggetto
[1] "13/05/1998" "16/12/1945" "23/09/2012"
con la funzione class()
> class(con_format) # la classe dell'oggetto
[1] "character"
e con la funzione str()
> str(con_format) # la struttura dell'oggetto
chr [1:3] "13/05/1998" "16/12/1945" "23/09/2012"
> #
vediamo che si tratta di un oggetto di classe "character": imponendo il formato gg/mm/aaaa le date tornano ad essere nuovamente delle stringhe ovvero generiche sequenze di caratteri alfanumerici esattamente come quelle da cui eravamo partiti.
Quindi concludendo: le date del calendario in R sono per definizione quelle contenute in un oggetto della classe “Date” ed espresse nel formato aaaa-mm-gg.
Vediamo ora alcuni altri esempi di date importate in R mediante la funzione as.Date():
> # (4/5)
> as.Date("23/09/2012", format="%d/%m/%Y") # dati in formato gg/mm/aaaa
[1] "2012-09-23"
> #
> as.Date("09/23/2012", format="%m/%d/%Y") # dati in formato mm/gg/aaaa
[1] "2012-09-23"
> #
> as.Date("2012/09/23", format="%Y/%m/%d") # dati in formato aaaa/mm/gg
[1] "2012-09-23"
> #
> as.Date("23 settembre 2012", format="%d %B %Y") # dati in formato gg mese aaaa con spazio come separatore
[1] "2012-09-23"
> #
> as.Date("09-3-2012", format="%m-%d-%Y") # dati in formato mm-gg-aaaa con - come separatore
[1] "2012-09-03"
> #
I risultati confermano che se specificate opportunamente l'argomento format= dei dati in ingresso potete rappresentare sotto forma di stringhe alfanumeriche le vostre date predisposte:
→ nel formato gg/mm/aaaa
→ nel formato mm/gg/aaaa
→ nel formato aaaa/gg/mm
→ nel formato gg mese aaaa impiegando lo spazio come separatore
→ nel formato mm-gg-aaaa impiegando come separatore il tratto a metà altezza -
ovvero in altri modi purché sia correttamente e completamente specificato il formato dei dati in ingresso.
Se installate il pacchetto lubridate potete infine fruire di una sintassi più concisa come nell'esempio che segue, che porta ovviamente allo stesso risultato
> # (5/5)
> library(lubridate)
> dmy(c("13/05/1998", "16/12/1945", "23/09/2012"))
[1] "1998-05-13" "1945-12-16" "2012-09-23"
Vediamo ora cosa accade nel caso di date importate da un file in formato Excel (.xls o .xlsx) o, meglio ancora, in formato .csv (il formato dei dati da importare consigliato da R).
Andate alla pagina Dati nella quale trovate diverse opzioni per scaricare i file di dati, quindi scaricate e copiate nella cartella C:\Rdati\ il file PA.xls e il file PA.csv
Nei file sono riportati i valori della pressione arteriosa sistolica e diastolica e della frequenza cardiaca registrati alle date del calendario riportate nella variabile "Data" (prima colonna).
Se ancora non l'avete fatto, scaricate dal CRAN e installate il pacchetto xlsx, quindi copiate e incollate nella Console di R questo script e premete ↵ Invio:
# GESTIONE DELLE DATE DEL CALENDARIO CON R - parte seconda
#
# importare le date da un file .xls
#
require(xlsx) # carica il pacchetto xlsx
PA_xls <- read.xlsx("C:/Rdati/PA.xls", sheetName="M") # importa i dati del file e del foglio specificati
PA_xls # mostra la tabella che contiene i dati
str(PA_xls) # la variabile Data viene riconosciuta come una data del calendario (classe "Date")
#
# importare le date da un file .csv
#
PA_csv <- read.table("C:/Rdati/PA.csv", header=TRUE, sep=",") # carica i dati del file specificato
PA_csv # mostra la tabella che contiene i dati
str(PA_csv) # la variabile Data viene riconosciuta come una semplice stringa di testo (classe "character")
#
PA_csv$Data <- as.Date(PA_csv$Data, format="%d/%m/%Y") # la stringa Data viene convertita con as.Date
str(PA_csv) # la variabile Data viene ora riconosciuta come una data del calendario
#
# elaborare le date (esempi)
#
Sys.Date()
PA_xls$Data[13] - PA_xls$Data[1]
PA_xls$Data[13] + 32
weekdays(PA_csv$Data[1])
#
Dopo avere caricato il pacchetto xlsx
> require(xlsx) # carica il pacchetto xlsx
Caricamento del pacchetto richiesto: xlsx
i dati sono importati dal foglio M del file PA.xls
> PA_xls <- read.xlsx("C:/Rdati/PA.xls", sheetName="M") # importa i dati del file e del foglio specificati
e richiamando il nome dell'oggetto (PA_xls) nel quale sono stati importati vediamo che i dati sono stati importati correttamente
> PA_xls # mostra la tabella che contiene i dati
Data Sistolica Diastolica Frequenza
1 2021-05-07 112 64 50
2 2021-05-08 118 69 49
3 2021-05-08 101 57 62
4 2021-05-09 111 65 56
5 2021-05-09 117 67 60
6 2021-05-10 110 69 59
7 2021-05-10 109 63 53
8 2021-05-16 115 66 49
9 2021-09-17 121 65 48
10 2021-09-17 92 58 63
11 2021-09-17 131 79 68
12 2021-09-17 116 68 57
13 2021-09-29 114 69 56
La funzione str() ci conferma che anche la variabile Data è stata correttamente identificata come “Date” quindi il pacchetto xlsx ha trasferito i dati della prima colonna in modo tale che R li ha riconosciuti e li riporta come date del calendario.
> str(PA_xls) # la variabile Data viene riconosciuta come una data del calendario (classe "Date")
'data.frame': 13 obs. of 4 variables:
$ Data : Date, format: "2021-05-07" "2021-05-08" ...
$ Sistolica : num 112 118 101 111 117 110 109 115 121 92 ...
$ Diastolica: num 64 69 57 65 67 69 63 66 65 58 ...
$ Frequenza : num 50 49 62 56 60 59 53 49 48 63 ...
> #
Vediamo ora cosa accade quando si importano i dati da un file .csv
Dopo avere importato i dati nell'oggetto PA_csv
> # importare le date da un file .csv
> #
> PA_csv <- read.table("C:/Rdati/PA.csv", header=TRUE, sep=",") # carica i dati del file specificato
e averli visualizzati richiamando il nome dell'oggetto nel quale sono stati importati
> PA_csv # mostra la tabella che contiene i dati
Data Sistolica Diastolica Frequenza
1 07/05/2021 112 64 50
2 08/05/2021 118 69 49
3 08/05/2021 101 57 62
4 09/05/2021 111 65 56
5 09/05/2021 117 67 60
6 10/05/2021 110 69 59
7 10/05/2021 109 63 53
8 16/05/2021 115 66 49
9 17/09/2021 121 65 48
10 17/09/2021 92 58 63
11 17/09/2021 131 79 68
12 17/09/2021 116 68 57
13 29/09/2021 114 69 56
con la funzione str() vediamo che questa volta la variabile Data è stata identificata come una stringa / generica sequenza di caratteri alfanumerici (chr)
> str(PA_csv) # la variabile Data viene riconosciuta come una semplice stringa di testo (classe "character")
'data.frame': 13 obs. of 4 variables:
$ Data : chr "07/05/2021" "08/05/2021" "08/05/2021" "09/05/2021" ...
$ Sistolica : int 112 118 101 111 117 110 109 115 121 92 ...
$ Diastolica: int 64 69 57 65 67 69 63 66 65 58 ...
$ Frequenza : int 50 49 62 56 60 59 53 49 48 63 ...
> #
Questo accade perché nel file PA.csv che aperto con un editor di testo così ci appare
Data,Sistolica,Diastolica,Frequenza
07/05/2021,112,64,50
08/05/2021,118,69,49
08/05/2021,101,57,62
09/05/2021,111,65,56
09/05/2021,117,67,60
10/05/2021,110,69,59
10/05/2021,109,63,53
16/05/2021,115,66,49
17/09/2021,121,65,48
17/09/2021,92,58,63
17/09/2021,131,79,68
17/09/2021,116,68,57
29/09/2021,114,69,56
non è riportata alcuna informazione che consenta ad R di identificare la variabile Data come una data del calendario (nel file .xls questa informazione c'è, anche se non potete visualizzarla trattandosi di un file binario).
Nel caso di dati importati da un file .csv - che di fatto è un semplice file di testo - è pertanto necessario impiegare la funzione as.Date() per convertire le date/stringhe in ingresso in date del calendario:
> PA_csv$Data <- as.Date(PA_csv$Data, format="%d/%m/%Y") # la stringa Data viene convertita con as.Date
> str(PA_csv) # la variabile Data viene ora riconosciuta come una data del calendario
'data.frame': 13 obs. of 4 variables:
$ Data : Date, format: "2021-05-07" "2021-05-08" ...
$ Sistolica : int 112 118 101 111 117 110 109 115 121 92 ...
$ Diastolica: int 64 69 57 65 67 69 63 66 65 58 ...
$ Frequenza : int 50 49 62 56 60 59 53 49 48 63 ...
> #
Questa conversione è necessaria se vogliamo che R riconosca le operazioni che è possibile eseguire su questi oggetti, che saranno, appunto, solamente le operazioni applicabili alle date del calendario.
A questo punto la domanda: ma perché fare tanta fatica per arrivare fin qui? La risposta la trovate a conclusione dello script, laddove sono riportate alcune delle possibilità offerte da R nella gestione delle date che prima o poi possono tornare utili, come ad esempio:
→ la data attuale presente sul sistema
> Sys.Date()
[1] "2021-11-29"
→ la differenza in giorni tra due date
> PA_xls$Data[13] - PA_xls$Data[1]
Time difference of 145 days
→ la data corrispondente a una specifica differenza in giorni rispetto a una data di riferimento
> PA_xls$Data[13] + 32
[1] "2021-10-31"
→ il giorno della settimana corrispondente ad una specifica data
> weekdays(PA_csv$Data[1])
[1] "venerdì"
> #
In un prossimo post vedremo come gestire contemporaneamente data e ora.
----------
martedì 9 giugno 2020
Inserimento manuale dei dati [3]
Abbiamo
già visto alcuni esempi di dati riportati
direttamente (cablati) nel codice R, dove comunque possono
essere modificati a piacere [1, 2]. Una modalità molto elementare ma utile
nella pratica quando si debbano inserire pochi dati, come in un test
chi-quadrato, in un grafico a torta o quant'altro.
Vediamo
ora due nuovi esempi un po' particolari, in quanto prevedono l'inserimento dei dati in modo interattivo, cioè da parte di
un operatore che deve inserire manualmente i dati nella
Console di R su richiesta, nel punto
previsto dallo script, perché l'esecuzione dello script possa
proseguire. Si tratta di una modalità di inserimento dei dati che,
mentre consente di familiarizzare con qualche aspetto un po' più tecnico di R, può risultare utile in casi particolari.
Copiate
lo script
che segue quindi incollatelo nella
Console
di R
e premete
↵ Invio:
#
INSERIMENTO MANUALE DEI DATI [3a]
#
inserimento di un singolo dato
#
#
predispone la funzione inserisci_un_dato() compresa tra { e }
inserisci_un_dato
<- function() {
#
legge il dato inserito nella Console di R
datoinserito
<- readline("Dato da elaborare = ")
#
converte il dato inserito in un numero
datoinserito
<- as.numeric(datoinserito)
#
calcola la radice quadrata del numero inserito e mostra il risultato
print(paste("La
radice quadrata di", datoinserito, "è",
sqrt(datoinserito)), quote=FALSE)
}
#
esegue la funzione inserisci_un_dato() in modalità interattiva attendendo un input da tastiera
if(interactive())
inserisci_un_dato()
Con
le prime quattro righe di codice viene predisposta la funzione inserisci_un_dato,
il cui codice è incluso tra la parentesi graffa {
e la parentesi graffa }. La funzione prevede di acquisire il dato (un solo dato) dalla Console di R con readline(), trasformare quanto immesso in un numero con as.numeric() quindi calcolarne la radice quadrata e mostrare il risultato con la quarta riga di codice.
L'ultima riga di codice con if(interactive()) manda in esecuzione la funzione
inserisci_un_dato()
in modo interattivo, restando in attesa dell'immissione da tastiera
nella
Console di R del
dato.
I commenti inseriti nel codice R sono sufficientemente esplicativi di quanto avviene, mentre la documentazione delle funzioni impiegate può essere visualizzata come al solito digitando help(nomedellafunzione) nella Console di R.
I commenti inseriti nel codice R sono sufficientemente esplicativi di quanto avviene, mentre la documentazione delle funzioni impiegate può essere visualizzata come al solito digitando help(nomedellafunzione) nella Console di R.
Ora
copiate lo script che segue
quindi incollatelo nella Console
di R e premete
↵ Invio:
#
INSERIMENTO MANUALE DEI DATI [3b]
#
inserimento di più dati
#
#
imposta 1 come dato iniziale
datoinserito
<- 1
#
ripete le istruzioni inserite nel loop fino a quando il dato inserito
è diverso da 0 (zero)
while(datoinserito!=0)
{
#
richiede di inserire la temperatura in gradi Celsius
datoinserito
<- readline("Temperatura in gradi Celsius = ")
#
converte il dato inserito in un numero
datoinserito
<- as.numeric(datoinserito)
#
effettua il calcolo e presenta il risultato
print(paste(datoinserito,
"gradi Celsius corrispondono a", ((datoinserito * 1.8) +
32), "gradi Fahrenheit"), quote=FALSE)
}
Mediante
la funzione while() viene
realizzato un loop, il cui codice è incluso tra la parentesi graffa
{ e la parentesi graffa },
che viene reiterato fino a quando il dato inserito risulta diverso da
0 (datoinserito!=0). Quando il dato inserito è 0 il loop viene terminato.
Il codice
prevede che nella Console di R
sia inserito manualmente da tastiera un dato di temperatura
(datoinserito) in gradi Celsius
(°C), per il quale viene calcolata e mostrata la corrispondente
temperatura in gradi Fahrenheit (°F) essendo
°F = (°C ∙ 1.8) + 32
Possono essere inseriti anche valori negativi di temperatura in gradi
Celsius.
Anche in questo caso i commenti inseriti nel codice R sono sufficientemente
esplicativi di quanto avviene mentre di nuovo al bisogno la documentazione delle funzioni impiegate può
essere visualizzata digitando help(nomedellafunzione)
nella Console di R.
Per
entrambi gli script ci si può inoltre divertire a immaginare i
controlli che potrebbero essere eseguiti sul dato inserito, e per
il secondo script anche a trovare qualcosa di meglio dell'uscita
dal loop piuttosto grezza realizzata inserendo 0 come dato, ma questo
va al di la degli scopi del post.
In
definitiva i due script, pur nella loro semplicità, forniscono come
sottoprodotto utile due esempi didattici:
→ di
come con R sia possibile realizzare una funzione,
cioè un blocco di codice che può essere eseguito semplicemente
richiamando nomedellafunzione(eventualiargomenti);
→ di
come con R sia possibile realizzare un loop
(ciclo, iterazione), cioè la ripetizione ciclica di una sequenza di
operazioni finché risulta vera la condizione di controllo
prefissata, una struttura di controllo ampiamente utilizzata in qualsiasi linguaggio di programmazione, oltre che all'interno delle funzioni di R.
----------
[1] Vedere il post Inserimento manuale dei dati [1] per l'assemblamento dei vettori in matrici.
[2] Vedere il post Inserimento manuale dei dati [2] per l'assemblamento di vettori in tabelle.
Nota: parliamo di array o vettore nel caso di dati numerici monodimensionali, disposti su una sola riga,
8 | 6 | 11 | 7 |
di matrice nel caso di dati numerici disposti su più righe e più colonne
8 | 9 | 15 | 14 |
6 | 7 | 18 | 12 |
11 | 8 | 17 | 13 |
7 | 4 | 19 | 17 |
e di tabella nei casi in cui il contenuto, disposto su più righe e più colonne, è rappresentato oltre che da dati numerici, anche da testo e/o operatori logici
M | 7 | 9 | VERO |
F | 3 | 12 | VERO |
F | 5 | 10 | FALSO |
Di fatto i vettori sono matrici aventi una sola riga o una sola colonna. Una matrice con una sola riga e più colonne è detta matrice riga o vettore riga, mentre una matrice con una sola colonna e più righe è detta matrice colonna o vettore colonna.
giovedì 12 marzo 2020
Importazione dei dati da un file di solo testo
Abbiamo visto in precedenza come sono
organizzati i dati in un file
.csv, il formato raccomandato per R, e abbiamo visto
che un file .csv è un
semplice file di testo [1].
Se aprite con un editor di testo il file
importa_csv.csv (se non l'avete già scaricato, trovate come farlo nella pagina Dati) questo è quello che vi appare:
id;sesso;anni;peso_kg;altezza_m
MT;M;69;76;1,78
GF;F;56;63;
MC;F;53;71;1,60
SB;M;28;73;1,78
FE;F;61;54;1,54
AB;M;46;92;1,84
RF;F;31;81;1,56
Se
ci pensate bene, però, oltre a lettere, numeri, caratteri di
interpunzione e qualche altro carattere accessorio, o, più
tecnicamente, oltre a una serie di caratteri ASCII stampabili [2] nel testo è incluso un "a capo" (o se preferite un
↵ Invio) che segna il passaggio da una riga alla successiva,
o, in altre parole, che separa un record dal successivo: ed è
chiaro che in qualche modo questo carattere, uno dei caratteri
non stampabili (detti anche caratteri di controllo) del codice
ASCII, deve essere stato codificato nel file.
Che
proprio questo sia il caso è dimostrabile aprendo il file con un
editor di testo che sia in grado di mostrare, oltre ai caratteri
ASCII, anche i caratteri di controllo contenuti nel file, uno dei
quali è appunto il carattere di "a capo".
Per esempio se
aprite il file importa_csv.csv
con PSPad [3] ed attivate nel menù
Visualizza la funzione
Modalità esadecimale vedete questo:
Sulla destra compaiono i caratteri ASCII contenuti nel file, sulla sinistra compare il valore esadecimale corrispondente. Sulla destra vedete ricorrere al termine di ogni record una sequenza di due punti consecutivi (..), sulla sinistra vedete che ad essi corrisponde la sequenza 0D0A che è la rappresentazione esadecimale di CR (Carriage Return) e di LF (Line Feed) cioè rispettivamente del ritorno di carrello a inizio riga (0D esadecimale) e del passaggio ad una nuova riga (0A esadecimale) che l'informatica ha ereditato dalla macchina da scrivere
Questi due caratteri ASCII l'editor di testo li
interpreta come caratteri di controllo, cioè come caratteri che non devono essere
rappresentati, ma che indicano una azione da compiere: passare a una
nuova riga di testo inserendo un "a capo"
(un ↵ Invio) [4].
R
è ovviamente in grado di interpretare correttamente i caratteri di
controllo, infatti se nella
Console di R incollate questa riga di codice
mydatacsv
<- read.table("C:/Rdati/importa_csv.csv", header=TRUE,
sep=";", dec=",")
e premete ↵ Invio per
importare i dati dal file .csv,
quindi digitate
mydatacsv
e premete ↵ Invio per
mostrare i dati importati, ottenete questo risultato:
>
mydatacsv <- read.table("C:/Rdati/importa_csv.csv",
header=TRUE, sep=";", dec=",")
>
mydatacsv
id sesso anni peso_kg altezza_m
1 MT M 69 76 1.78
2 GF F 56 63 NA
3 MC F 53 71 1.60
4 SB M 28 73 1.78
5 FE F 61 54 1.54
6 AB M 46 92 1.84
7 RF F 31 81 1.56
(NA indica un dato mancante).
Ma
con R è possibile un'altra cosa: si possono codificare i
caratteri di controllo in chiaro, come viene fatto nel file
importa_txt.txt che contiene gli stessi dati e che, aperto con
un editor di testo, così vi appare:
MT;M;69;76;1,78\nGF;F;56;63;\nMC;F;53;71;1,60\nSB;M;28;73;1,78\nFE;F;61;54;1,54\nAB;M;46;92;1,84\nRF;F;31;81;1,56
Da
notare che nel file
importa_txt.txt rispetto al
corrispondente file
.csv:
→ i
caratteri di controllo
CR e
LF (nascosti nel file .csv) sono stati
sostituiti con i caratteri (in chiaro)
\n ove la barra rovesciata
\ (o backslash)
indica a R la
presenza di un carattere di controllo e
n sta per
New Line (“passa a una nuova
riga”);
→ il
file non contiene i nomi delle variabili, che devono essere
specificati nella funzione read.table()
mediante l'argomento col.names;
→ l'ultimo
carattere nel file deve
essere un
↵ Invio (cioè un "a
capo") che in questo caso deve immediatamente seguire il
6 del dato finale
1,56.
Il
file importa_txt.txt potete
scaricarlo e installarlo nella cartella C:\Rdati seguendo le istruzioni fornite nella pagina Dati. Ora copiate nella
Console di R questa riga di codice
mydatatxt
<- read.table("c:/Rdati/importa_txt.txt", header=TRUE,
col.names=c("id", "sesso", "anni",
"peso_kg", "altezza_m"), sep=";",
dec=",", allowEscapes=TRUE)
e premete ↵ Invio per
importare i dati, quindi digitate
mydatatxt
e premete ↵ Invio per
visualizzare i dati importati.
Da notare che l'argomento allowEscapes=TRUE fa si che R interpreti la sequenza \n come un carattere di controllo (un ↵ Invio) e non come due semplici caratteri di testo. Come vedete il risultato ottenuto
Da notare che l'argomento allowEscapes=TRUE fa si che R interpreti la sequenza \n come un carattere di controllo (un ↵ Invio) e non come due semplici caratteri di testo. Come vedete il risultato ottenuto
>
mydatatxt <- read.table("c:/Rdati/importa_txt.txt",
header=TRUE, col.names=c("id","sesso","anni","peso_kg","altezza_m"),
sep=";", dec=",", allowEscapes=TRUE)
>
mydatatxt
id sesso anni peso_kg altezza_m
1 MT M 69 76 1.78
2 GF F 56 63 NA
3 MC F 53 71 1.60
4 SB M 28 73 1.78
5 FE F 61 54 1.54
6 AB M 46 92 1.84
7 RF F 31 81 1.56
è
identico a quello ottenuto importando i dati del file
.csv.
Il
senso di tutto ciò? Semplice. Guardate il set di dati Galton, si
tratta di 928 righe di dati, ciascuna corrispondente a un record, più una
riga per i nomi delle variabili. Se invece di un file
.csv impiegate un file
.txt separando i record con
\n potete compattare i dati in un
numero enormemente inferiore di righe, cosa che ad esempio rende
possibile inserire un numero così elevato di record in un testo.
----------
Addendum
Se
siete arrivati fino a qui, avete certamente notato che nel post manca una cosa fondamentale: un metodo semplice per generare un file di testo nel quale
i caratteri di controllo nascosti
CR e LF sono
sostituiti con un \n riportato
in chiaro.
In effetti ci
sono programmi che consentono di effettuare la sostituzione online: alcuni forniscono come
risultato un file nel quale la sequenza di caratteri di controllo
CRLF è automaticamente sostituita con \n [5], altri forniscono come risultato un file nel quale
detta sequenza è sostituita con uno spazio vuoto [6], che successivamente
può essere sostituito manualmente con \n.
Qui
vediamo come effettuare la sostituzione con la seconda modalità, che è la più
semplice, impiegando R e un comune editor di testo.
Scaricate
dal CRAN e installate il pacchetto stringr [7]. Quindi
copiate e incollate nella Console
di R questo script e premete
↵ Invio
#
SALVA I DATI IN UN FILE DI TESTO ELIMINANDO I CARATTERI DI CONTROLLO
CR e LF
#
library(stringr)
# carica il pacchetto
mydata
<- readLines("C:/Rdati/importa_csv.csv") #
legge il file
newdata
<- mydata[-c(1)] # elimina la prima riga che contiene i
nomi delle variabili
mystring
<- str_c(newdata, collapse=" ") # concatena i
record in un'unica stringa separandoli con uno spazio
write(mystring,
file="C:/Rdati/temp.txt") # salva la stringa in
un file di testo
Va
subito precisato che il messaggio che vi comparirà
Warning
message:
In
readLines("C:/Rdati/importa_csv.csv") :
incomplete
final line found on 'C:/Rdati/importa_csv.csv'
non
indica un errore, ma è un semplice avvertimento che segnala la mancanza
della sequenza CRLF (cioè
di un
↵ Invio) alla
fine del file: i dati sono importati correttamente, come potete
constatare digitando mydata.
Nelle
cinque righe di codice, nell'ordine:
→ con
la funzione library() viene
caricato il pacchetto stringr;
→ con
readLine(s) un normale file .csv (vedere il post Importazione dei dati da un file .csv) viene
importato riga per riga;
→ con
[-c(1)]
viene eliminata la prima riga, quella che contiene i nomi delle
variabili;
→ con
la funzione str_c() del pacchetto
stringr le righe (record) del file importate sono concatenate
in un'unica stringa separando l'una dall'altra con uno spazio
(collapse=" ") ;
→ la
stringa che risulta dal concatenamento viene salvata nel file
C:/Rdati/temp.txt.
Digitate
mydata, poi newdata
e infine mystring per
visualizzare la progressiva trasformazione dei dati.
Infine,
impiegando un editor di testo come il
Blocco note di Windows:
→ aprite
il file C:/Rdati/temp.txt
→ utilizzate
la funzione
Modifica > Sostituisci per
sostituire lo spazio vuoto con i caratteri
\n
A
questo punto ricordatevi che l'ultimo carattere del file deve essere un ↵ Invio (cioè un "a capo") che dovete inserire manualmente immediatamente dopo il 6 del dato finale 1,56. Poi salvate il risultato nel file definitivo,
denominato a piacere ma possibilmente per coerenza con estensione
.txt, e avrete finalmente un file di dati di R in formato testo come questo
che impiega come separatore di record la sequenza di caratteri
\n codificata in chiaro, e che può essere importato in R mediante la
funzione read.table() impiegando
l'argomento allowEscapes=TRUE.
Supponendo che abbiate denominato questo file C:\Rdati\ilmiofile_txt.txt se copiate nella Console di R questa riga di codice
MT;M;69;76;1,78\nGF;F;56;63;\nMC;F;53;71;1,60\nSB;M;28;73;1,78\nFE;F;61;54;1,54\nAB;M;46;92;1,84\nRF;F;31;81;1,56
Supponendo che abbiate denominato questo file C:\Rdati\ilmiofile_txt.txt se copiate nella Console di R questa riga di codice
mydatatxt <- read.table("c:/Rdati/ilmiofile_txt.txt", header=TRUE, col.names=c("id", "sesso", "anni", "peso_kg", "altezza_m"), sep=";", dec=",", allowEscapes=TRUE)
e premete ↵ Invio per importare i dati, quindi digitate
mydatatxt
e premete ↵ Invio per visualizzare i dati importati, potete verificare che il tutto ha funzionato correttamente e che pertanto siete in grado, al bisogno, da un lato di generare un file di testo con i caratteri di controllo in chiaro, e dall'altro lato di importarne i dati in R.
----------
[1] Vedere il post Importazione dei dati da un file .csv
[3] PSPad freeware editor.
https://www.pspad.com/it/
[4] In realtà esistono tre modi per codificare un "a capo" (un ↵ Invio), e dipendono dal sistema operativo impiegato:
→ CRLF (\r\n): usato da MS-DOS e Microsoft Windows, al quale si fa qui riferimento;
→ LF (\n): usato da sistemi Unix, Linux e Apple (GNU/Linux, Mac OS X e macOS);
→ CR (\r): usato da Commodore e Apple (Mac OS fino alla versione 9 inclusa).
[5]
Remove/Replace all line breaks of a text.
https://gillmeister-software.com/online-tools/text/remove-line-breaks.aspx
[6]
Convert Newlines to Spaces.
https://www.browserling.com/tools/newlines-to-spaces
[7]
Vedere il manuale di riferimento del pacchetto Package 'stringr'.
https://cran.r-project.org/web/packages/stringr/stringr.pdf
Iscriviti a:
Post (Atom)