Archivio tag: as.Date

La variabile età

Svincolarsi da vecchi retaggi del passato, tanto consolidati da diventare prassi, non è semplice. Le abitudini ottimizzano il nostro modo di agire, rendendolo per molti aspetti più efficiente. Capita però che i tempi cambino e certe abitudini ci portino a sprecare risorse invece di risparmiale.

Qualche decennio fa, nelle nostre vite è entrato il computer. Non solo: negli ultimi anni le prestazioni di calcolo di queste macchine sono diventate tali da consentire elaborazioni quasi impensabili fino a soli dieci anni fa. Eppure, nonostante questo, per certi aspetti continuiamo a costruire i dataset in modo simile a come venivano costruiti carta e matita.

È per esempio il caso della variabile “età”.

Codificare la variabile età in un dataset è una questione di scelte. Comunemente, se parliamo di adulti o di bambini in età scolare, l’età viene registrata in anni compiuti. Se invece si parla di bambini molto piccoli, l’età viene più spesso registrata in mesi compiuti, se non addirittura in giorni se i soggetti sono neonati. Ci sono poi i ricercatori a cui piace aggregare, per cui registrano le età come fasce: “da 30 a 35”, “da 36 a 40”, eccetera eccetera. In questo caso, le fasce sono spesso definite a seconda del legame che l’età potrebbe avere con altre variabili incluse nel dataset, per cui il modo in cui questa viene codificata è contestuale alla raccolta dati e non indipendente da essa.

La codifica in fasce d’età è secondo me retaggio di un passato in cui i computer non c’erano o avevano delle prestazioni molto limitate rispetto a quello a cui siamo abituati oggi. Anni addietro era necessario economizzare e semplificare il più possibile i calcoli: aggregare faceva comodo.

Oggi, aggregare è anacronistico. Chiaro, un minimo di livello di aggregazione ci può essere e fa comunque comodo, ma spesso si esagera, perdendo della preziosissima informazione. Ricordiamoci infatti che da un’informazione micro se ne può ricavare una macro, mentre non è sempre vero il contrario. Se io vi dicessi che ho 33 anni, potrete facilmente dedurre che posso essere collocato nella fascia “30-35”. Se però vi dicessi che mi trovo nella fascia “30-35” e vi chiedessi quanti anni ho, sapreste rispondermi?

Aggregare le età in fase di codifica dati è secondo me controproducente per tre ragioni.

Primo, ad aggregare si fa sempre in tempo in un momento successivo e più consono (sempre che usiate un software abbastanza flessibile che vi consenta di farlo).

Secondo, in fase di analisi dei dati potreste rendervi conto che quel tipo di aggregazione non è adeguato al fenomeno che state studiando e potreste desiderare delle fasce d’età costruite in un altro modo.

Terzo, l’età è una variabile continua. Per comodità noi possiamo concepire il tempo come discreto, ma ovviamente non è tale. Classificando l’età, anche semplicemente esplicitandola in anni compiuti, la stiamo in un certo senso “discretizzando”. Certo, bisogna dire che “età” non è sinonimo di “tempo”, ma è un suo derivato; inoltre, l’età è un concetto che può assumere forme diverse a seconda del contesto (fasce, anni, mesi, giorni, ecc.), mentre il tempo no. A mio parere, però, codificando l’età dovremmo per quanto possibile evitare di spezzare il tempo: dovremmo invece provare a fermarlo.

Quando possibile, io chiedo sempre che nei dataset che mi vengono forniti non venga registrata l’età, o meglio, non venga registrata solo l’età. Soprattutto se le unità statistiche sono soggetti in età evolutiva, trovo molto utile che l’età sia accompagnata da altre due variabili: la data di nascita del soggetto e la data in cui sono state rilevate le misure. L’età può infatti essere tranquillamente dedotta a partire dallo scarto fra queste due variabili, con la differenza però che in questo caso sarà chi effettua le analisi a decidere su quale unità di misura esprimerla.

R dispone di un tipo di dato particolare che consente di esplicitare che una variabile è di tipo “data”. Questo tipo di dato non è in realtà semplicissimo da gestire, principalmente a causa dell’elevatissima varietà di modi che si possono usare per codificare le date. Per esempio, la data di oggi, 29 luglio 2016, può essere scritta come “29.07.16”, “29/7/2016”, “29 lug 2016”, eccetera, eccetera, eccetera… R utilizza come formato standard per la codifica delle date quello anglosassone, per cui richiede che la data sia scritta come “anno-mese-giorno”, tutto in formato numerico e facendo in modo che i giorni e i mesi siano sempre scritti con due cifre, mentre l’anno con quattro. Per intenderci, la data di oggi in questo formato sarebbe “2016-07-29”.

Se la data è già scritta in questo formato, possiamo utilizzare il comando as.Date() per esplicitare che la stringa è una data:

> x <- as.Date("2016-07-29") 
> x 
[1] "2016-07-29"
> str(x) 
 Date[1:1], format: "2016-07-29"

Se la data non è in questo formato… beh, lo deve diventare. Attraverso l’argomento format, il comando as.Date() offre la possibilità di esplicitare la struttura del formato di origine in modo che R sia in grado di comprendere come sono disposte le informazioni all’interno della stringa.

Vediamo subito un esempio:

> x <- as.Date("29/07/2016", format="%d/%m/%Y") 
> x 
[1] "2016-07-29" 
> str(x) 
 Date[1:1], format: "2016-07-29"

All’argomento format ho passato una stringa nella quale viene dichiarato che il primo numero rappresenta il giorno in formato numerico (%d), il secondo numero rappresenta il mese sempre in formato numerico (%m) e il terzo numero rappresenta l’anno in formato numerico a quattro cifre (%Y); inoltre, ogni valore è separato da uno slash e non da un trattino.

Come facevo a sapere come costruire la stringa da passare a format? Semplice: richiamando l’help ?strptime sarà possibile studiarsi tutti i dettagli.

Torniamo ora alla questione delle età. Immaginiamo di avere un vettore born che indica la data di nascita di ogni soggetto e un vettore test che indica la data in cui è stata rilevata una misura.

> born <- c("02/12/2012","12/11/2012","17/05/2013","04/07/2013","29/02/2013") 
> test <- c("21/10/2015","21/10/2015","21/10/2015","26/10/2015","26/10/2015")
&#91;/code&#93;

I dati contenuti in queste due variabili possono essere convertiti in date:

&#91;code language="R"&#93;
> born <- as.Date(born, format="%d/%m/%Y") 
> test <- as.Date(test, format="%d/%m/%Y") 
&#91;/code&#93;

Ecco il risultato:

&#91;code language="R"&#93;
> born 
[1] "2012-12-02" "2012-11-12" "2013-05-17" "2013-07-04" "2013-02-29" 
> test 
[1] "2015-10-21" "2015-10-21" "2015-10-21" "2015-10-26" "2015-10-26"

A questo punto, per ogni soggetto è possibile calcolare l’età facendo la sottrazione fra le due variabili:

> test - born 
Time differences in days 
[1] 1053 1073  887  844  970

R esprime la differenza fra due date in giorni. Per ogni soggetto, quindi, possiamo conoscere l’età espressa in giorni.

Chiaramente, non sempre l’età espressa in giorni ci può andare bene. Se desideriamo un’unità di misura più consona, come i mesi o gli anni compiuti, possiamo ricorrere alla funzione age_calc() del pacchetto kyotil.

> library(kyotil)
# Mesi:
> age_calc(born, test, units="months") 
[1] 34.61290 35.29032 29.12903 27.70968 31.90538 
# Anni:
> age_calc(born, test, units="years") 
[1] 2.884707 2.939352 2.430137 2.312329 2.657534

La stessa funzione age_calc() del pacchetto kyotil è contenuta anche nel pacchetto eeptools, ma probabilmente quella di eeptools è una versione più vecchia, perché sembra avere delle limitazioni che quella di kyotil non ha.

Infine, non dimentichiamoci che possiamo utilizzare il comando cut(), distributo con la versione base di R, per creare delle fasce d’età. Questa, però, è un’altra storia.