Per spiegare la necessità di pulire i dati, può essere utile fare un esempio.

Global Footprint Network è una organizzazione no profit che si occupa di sostenibilità ambientale. Nel sito dell’organizzazione vi è una sezione open data, dove sono riportate delle statistiche relative all’impronta ecologica dei paesi del mondo. La pagina Sustainable Development confronta tre indici relativi a 178 paesi:

  1. lo Human Development Index (HDI), sviluppato dalle nazioni unite
  2. l’impronta ecologica, definita in termini di area biologicamente produttiva di mare e di terra necessaria a rigenerare le risorse consumate da una popolazione umana (o - nel caso dei dati, pro-capite) e ad assorbire i rifiuti prodotti
  3. la popolazione di quel paese.

Possiamo usare read.csv() per scaricare la tabella di dati

sustain <- read.csv("https://s3.eu-central-1.amazonaws.com/bussolon/dati/Sustainable_Development.csv", header = TRUE, stringsAsFactors = FALSE)
str (sustain)
## 'data.frame':    184 obs. of  5 variables:
##  $ Country.Name: chr  "Armenia" "Afghanistan" "Albania" "Algeria" ...
##  $ countryName : chr  "Armenia" "Afghanistan" "Albania" "Algeria" ...
##  $ EFConsPerCap: chr  "2.02" "0.77" "2.14" "2.45" ...
##  $ HDI         : chr  "0.74" "0.48" "0.76" "0.74" ...
##  $ Population  : num  3006154 31627506 2889676 38934336 24227524 ...

Attraverso la funzione str() possiamo analizzare la struttura del data frame. Due cose saltano all’occhio. La prima: Country.Name sembra uguale a countryName o, quantomeno, le due colonne appaiono ridondanti. La seconda, forse meno evidente, è che anche le colonne apparentemente numeriche (EFConsPerCap e HDI) vengono viste da r come testo (chr).

Utilizzando la funzione View(sustain) è possibile visualizzare il data frame. Si scopre così che:

  1. le prime due colonne sono davvero uguali
  2. il nome di alcuni paesi si è spalmato sulle colonne adiacenti, sporcando i dati.

Diventa dunque necessario quantomeno ripulire le righe in cui i nomi si sono spalmati nelle colonne adiacenti; in secondo luogo, è opportuno eliminare una delle prime due colonne.

Per ripulire le righe, l’approccio più ovvio può essere quello di aprire il file con excel o libre office. Ma forse la soluzione più semplice è quella di aprire il file con un editor di testo. Se andiamo alla riga 70 vediamo che l’Iran è definito come Iran, Islamic Republic of.

Iran, Islamic Republic of,Iran, Islamic Republic of,3.4,0.77,78143640 

Ma la virgola viene interpreatata come separatore di campo (comma separated). La cosa più semplice è cancellare le virgole di troppo.

Una volta fatta questa prima correzione, è possibile ricaricare il file per verificare che il problema sia risolto.

sustainable <- read.csv("/home/bussolon/documenti/didattica/r_dottorato/dati/Sustainable_Development_pulito.csv")
str(sustainable)
## 'data.frame':    178 obs. of  5 variables:
##  $ Country.Name: Factor w/ 178 levels "Afghanistan",..: 7 1 2 3 4 5 6 8 9 11 ...
##  $ countryName : Factor w/ 178 levels "Afghanistan",..: 7 1 2 3 4 5 6 8 9 11 ...
##  $ EFConsPerCap: Factor w/ 160 levels "0.5","0.57","0.6",..: 62 6 67 74 40 113 107 151 142 126 ...
##  $ HDI         : num  0.74 0.48 0.76 0.74 0.53 0.78 0.83 0.94 0.89 0.79 ...
##  $ Population  : num  3006154 31627506 2889676 38934336 24227524 ...
levels(sustainable$EFConsPerCap)
##   [1] "0.5"       "0.57"      "0.6"       "0.67"      "0.76"     
##   [6] "0.77"      "0.78"      "0.79"      "0.82"      "0.85"     
##  [11] "0.87"      "0.95"      "0.96"      "0.97"      "0.98"     
##  [16] "1.01"      "1.03"      "1.04"      "1.09"      "1.1"      
##  [21] "1.11"      "1.12"      "1.19"      "1.2"       "1.21"     
##  [26] "1.22"      "1.23"      "1.27"      "1.28"      "1.3"      
##  [31] "1.31"      "1.32"      "1.36"      "1.46"      "1.47"     
##  [36] "1.48"      "1.53"      "1.54"      "1.55"      "1.56"     
##  [41] "1.59"      "1.61"      "1.63"      "1.64"      "1.66"     
##  [46] "1.73"      "1.75"      "1.76"      "1.77"      "1.78"     
##  [51] "1.79"      "1.84"      "1.85"      "1.9"       "1.91"     
##  [56] "1.93"      "1.96"      "1.98"      "12.28"     "15.65"    
##  [61] "2"         "2.02"      "2.04"      "2.05"      "2.07"     
##  [66] "2.09"      "2.14"      "2.17"      "2.29"      "2.3"      
##  [71] "2.32"      "2.39"      "2.4"       "2.45"      "2.49"     
##  [76] "2.51"      "2.53"      "2.54"      "2.55"      "2.72"     
##  [81] "2.8"       "2.84"      "2.87"      "2.92"      "2.94"     
##  [86] "2.96"      "2.98"      "3.02"      "3.07"      "3.08"     
##  [91] "3.1"       "3.17"      "3.21"      "3.27"      "3.29"     
##  [96] "3.3"       "3.32"      "3.35"      "3.4"       "3.42"     
## [101] "3.5"       "3.55"      "3.6"       "3.63"      "3.64"     
## [106] "3.68"      "3.69"      "3.71"      "3.8"       "3.81"     
## [111] "3.9"       "4.03"      "4.18"      "4.2"       "4.29"     
## [116] "4.33"      "4.42"      "4.44"      "4.64"      "4.68"     
## [121] "4.69"      "4.7"       "4.71"      "4.74"      "4.8"      
## [126] "4.82"      "4.85"      "4.89"      "5.05"      "5.19"     
## [131] "5.55"      "5.56"      "5.57"      "5.6"       "5.63"     
## [136] "5.68"      "5.8"       "5.81"      "5.82"      "5.84"     
## [141] "5.86"      "5.88"      "5.92"      "6"         "6.03"     
## [146] "6.09"      "6.32"      "6.59"      "6.69"      "6.71"     
## [151] "6.89"      "6.97"      "7.13"      "7.65"      "8.05"     
## [156] "8.37"      "8.71"      "9.5"       "9.75"      "undefined"

Il prossimo passaggio consiste nell’eliminare una delle due colonne. Il passaggio successivo consiste nel capire perché la colonna relativa all’impronta ecologica (EFConsPerCap) sia vista come fattore. Analizzando i livelli si scopre che i missing sono etichettati come undefined.

sustainable$EFConsPerCap[sustainable$EFConsPerCap=="undefined"] <- NA
sustainable$EFConsPerCap <- as.numeric(sustainable$EFConsPerCap)

È dunque necessario trasformare gli undefined in NA, e poi convertire il vettore da fattore a numerico, con la funzione as.numeric().

A questo punto il dataframe è tecnicamente corretto.