Data management con R base

Vedremo ora alcune operazioni molto semplici di data management che possono essere fatte con R base – cioè senza usare alcuna funzione da librerie aggiuntive che sono state sviluppate per fare data management in modo più efficiente. Imparare come interagire con i dati usando R base è importante perché le funzioni di R base non vi deluderanno mai. Sono il modo più basilare (anche se non sempre user-friendly o efficiente) per fare quello che avete bisogno di fare.

Innanzi tutto, carichiamo i dati:

library(rio)
setwd("/folder/where/you/keep/the/data")
cses <- import("cses2018small.xlsx")

Come promemoria, questo dataset è un sottoinsieme di variabili dalla versione “grezza” dei dati di un sondaggio svolto dopo le elezioni del 2018 in Italia per il progetto CSES. Include le seguenti variabili:

Selezionare variabili

Come abbiamo detto, il data frame non è altro che una matrice, con alcune differenza: (1) i valori contenuti possono essere di tipo diverso in colonne diverse, e (2) le colonne hanno un nome. Questo implica che ci sono 2 modi per selezionare le variabili in un data frame:

  1. Usando il nome delle variabili
  2. Usando il numero di indice

Per selezionare le variabili utilizzando il loro nome, il metodo più semplice e comune è utilizzare il simbolo del dollaro $:

cses$area

Tuttavia, si possono utilizzare anche le parentesi quadre [:

cses[, "area"]

Notare 2 cose: (1) il data frame è un oggetto a 2 dimensioni, come la matrice, e quindi per selezionare le colonne occorre scrivere dopo la virgola per indicare l’elemento o gli elementi desiderati. (2) Se si vuole selezionare una variabile chiamandola per nome con le parentesi quadre occorre usare le virgolette ". Inoltre, in questo modo è anche possibile selezionare più di una sola variabile:

cses[, c("area", "mip1")]

Un terzo modo per selezionare variabili è utilizzando il numero di indice. Per esempio, se vogliamo selezionare la variabile id possiamo anche farlo selezionando la prima colonna del data frame:

cses[, 1]

E anche in questo caso, si possono selezionare più di un’unica colonna:

# Selezionare le prime 3 variabili
cses[, 1:3]

Tuttavia, quando le colonne sono variabili, è molto più comune (e ha molto più senso) utilizzare il nome, piuttosto che il numero di indice (per diversi motivi: per esempio, la posizione di una variabile in un dataset può cambiare a seconda delle trasformazioni che ne vengono fatte. In generale è sempre meglio evitare di mettere nel codice numeri la cui provenienza non è chiara, ci si risparmia molta confusione nel momento in cui si va a riprendere il codice in futuro).

In generale, è sempre possibile individualre il numero di indice di un elemento conoscendone il nome (l’elemento può essere una variabile in un data frame, ma anche un elemento in una lista, e addirittura in un vettore e in una matrice). Per fare questo si usa la funzione which() in combinazione con names():

# Restituisce un vettore di TRUE/FALSE
names(cses) == "eta"
## [1] FALSE FALSE  TRUE FALSE FALSE FALSE FALSE FALSE
# Restituisce il numero di indice dell'elemento (o degli elementi) associato a TRUE
which(names(cses) == "eta")
## [1] 3

Si può essere ancora più sofisticati e cercare variabili sulla base di pattern nei nomi. Per esempio, sappiamo che ci sono due variabili che hanno lo stesso prefisso nel dataset cses, ovvero mip1 e mip2, e vogliamo selezionarle entrambe scrivendo poco (pensate se si arrivasse a mip10).

Un modo per farlo con le funzioni di R base è utilizzando due funzioni che trovano corrispondenze tra sequenze di caratteri, grepl() e grep().

# Restituisce un vettore di TRUE/FALSE
grepl("mip", names(cses))
## [1] FALSE FALSE FALSE FALSE  TRUE  TRUE FALSE FALSE
# Restituisce il numero di indice dell'elemento (o degli elementi) associato a TRUE
grep("mip", names(cses))
## [1] 5 6
# Restituisce i nomi delle variabili desiderate
grep("mip", names(cses), value = T)
## [1] "mip1" "mip2"

Selezionare osservazioni

Anche nel caso delle osservazioni, ci sono 2 modi per selezionare quello che ci serve:

  1. Usando i numeri di indice delle righe del data frame
  2. Selezionando le osservazioni sulla base del valore che hanno in determinate variabili

Il numero di indice funziona sempre nello stesso modo

# Seleziona una riga
cses[10, ]
##    id     sex eta eta_gr              mip1       mip2 eco_eval area
## 10 10 Femmina  37  35 54 la disoccupazione la poverta       -1  Sud
# Seleziona tante righe
cses[c(1, 4, 10, 350), ]
##      id     sex eta eta_gr              mip1           mip2 eco_eval   area
## 1     1 Femmina  60    55+         la scuola      il lavoro       -1    Sud
## 4     4 Maschio  62    55+         il lavoro   immigrazione       -1    Sud
## 10   10 Femmina  37  35 54 la disoccupazione     la poverta       -1    Sud
## 350 350 Maschio  61    55+      immigrazione disoccupazione       -1 Centro

Si può utilizzare la funzione sample() per estrarre un campione casuale di osservazioni

# Seleziona un campione casuale di 20 osservazioni
cses[sample(1:nrow(cses), 20), ]
##        id     sex eta eta_gr
## 753   753 Femmina  67    55+
## 977   977 Maschio  58    55+
## 594   594 Femmina  58    55+
## 735   735 Maschio  58    55+
## 588   588 Femmina  76    55+
## 1550 1550 Femmina  47  35 54
## 134   134 Maschio  36  35 54
## 714   714 Femmina  45  35 54
## 7       7 Maschio  24  18 34
## 1942 1942 Maschio  53  35 54
## 402   402 Femmina  22  18 34
## 467   467 Maschio  67    55+
## 1841 1841 Femmina  75    55+
## 554   554 Femmina  52  35 54
## 1284 1284 Maschio  41  35 54
## 1478 1478 Maschio  53  35 54
## 429   429 Maschio  78    55+
## 1036 1036 Maschio  55    55+
## 1212 1212 Femmina  78    55+
## 40     40 Femmina  39  35 54
##                                                                                                                                                  mip1
## 753                                                                                                                                              <NA>
## 977                                                                                                                                    disoccupazione
## 594                                                                                                                                            sanita
## 735                                                                                                                                         stabilita
## 588  lavoro, infrastrutture, protezione del territorio, evitare nuove cementificazioni, recupero arenile che in Liguria si sta completamente erodendo
## 1550                                                                                                                                   disoccupazione
## 134                                                                                                                                        corruzione
## 714                                                                                                                                LUNIONE CHE NON CE
## 7                                                                                                                              valorizzare  i giovani
## 1942                                                                                                                                           sanità
## 402                                                                                                                                    Disoccupazione
## 467                                                                                                                                       occupazione
## 1841                                                                                                                                   sanita+ lavoro
## 554                                                                                                                                         il lavoro
## 1284                                                                                                                                     fare governo
## 1478                                                                                                                                           lavoro
## 429                                                                                                                                      la sicurezza
## 1036                                                                                                                          investire per il lavoro
## 1212                                                                                                                                           lavoro
## 40                                                                                                                                       Immigrazione
##                                    mip2 eco_eval       area
## 753                                <NA>        0        Sud
## 977                            pensione       -1        Sud
## 594                                <NA>        0        Sud
## 735                             poverta        1   Nord-Est
## 588  disegualianze, lotta alla povertà.        0 Nord-Ovest
## 1550                          sicurezza        1 Nord-Ovest
## 134               conflitto d'interesse        0     Centro
## 714                         IL RISPETTO        0   Nord-Est
## 7        gestire meglio i fondi europei        1        Sud
## 1942             serietà nella politica       -1 Nord-Ovest
## 402                    Evasione fiscale       -1        Sud
## 467                             riforme        1        Sud
## 1841                          immigrati        0 Nord-Ovest
## 554                           la sanita       -1     Centro
## 1284                               <NA>        0        Sud
## 1478                       immigrazione        1        Sud
## 429                           il lavoro        1 Nord-Ovest
## 1036                          Sicurezza       -1        Sud
## 1212                           pensione       -1     Centro
## 40                         Criminalita'        1 Nord-Ovest

In alternativa, è possibile selezionare alcune osservaizoni specifiche in base al valore che hanno in alcune variabili. Per esempio, se vogliamo selezionare tutti gli intervistati che vivono nelle regioni del Sud e del Centro Italia:

# Abitanti del Sud
cses_sud <- cses[cses$area == "Sud", ]
head(cses_sud)
##    id     sex eta eta_gr                   mip1                           mip2 eco_eval area
## 1   1 Femmina  60    55+              la scuola                      il lavoro       -1  Sud
## 4   4 Maschio  62    55+              il lavoro                   immigrazione       -1  Sud
## 7   7 Maschio  24  18 34 valorizzare  i giovani gestire meglio i fondi europei        1  Sud
## 8   8 Femmina  69    55+                 lavoro                   immigrazione       -1  Sud
## 9   9 Femmina  53  35 54           immigrazione           costi della politica        1  Sud
## 10 10 Femmina  37  35 54      la disoccupazione                     la poverta       -1  Sud
# Abitanti del Centro
cses_centro <- cses[cses$area == "Centro", ]
head(cses_centro)
##    id     sex eta eta_gr            mip1              mip2 eco_eval   area
## 2   2 Maschio  62    55+            <NA>              <NA>       -1 Centro
## 15 15 Femmina  65    55+          lavoro             tasse       -1 Centro
## 18 18 Maschio  64    55+          lavoro         sicurezza        1 Centro
## 22 22 Maschio  18  18 34 debito pubblico crise finanziaria        1 Centro
## 24 24 Femmina  69    55+       il lavoro          le tasse        0 Centro
## 26 26 Femmina  47  35 54          scuola            lavoro        0 Centro

Questo può anche essere fatto sulla base di condizioni più complesse

# Selezionare tutte le femmine del sud che hanno più di 40 anni
head(cses[cses$area == "Sud" & cses$eta > 40 & cses$sex == "Femmina", ])
##    id     sex eta eta_gr         mip1                 mip2 eco_eval area
## 1   1 Femmina  60    55+    la scuola            il lavoro       -1  Sud
## 8   8 Femmina  69    55+       lavoro         immigrazione       -1  Sud
## 9   9 Femmina  53  35 54 immigrazione costi della politica        1  Sud
## 19 19 Femmina  57    55+       lavoro            sicurezza        0  Sud
## 21 21 Femmina  77    55+       lavoro                 <NA>       -1  Sud
## 29 29 Femmina  63    55+     pensioni               lavoro       -1  Sud

Rimuovere le osservazioni mancanti (missing)

Un caso particolare della selezione di osservazioni in base al loro valore in una o più variabili è quando abbiamo bisogno di identificare o rimuovere le osservazioni mancanti, i cosiddetti “missing data”. Le osservazioni missing sono problematiche in alcuni casi. Mentre esistono metodi diversi per incorporare i missing e gestirli all’interno dei modelli di regressione, il primo passo è essere in grado di identificare queste osservazioni e possibilmente rimuoverle.

La funzione is.na() è un modo per chiedere a R se un elemento in un vettore è NA (il codice che R usa per identificare le osservazioni mancanti) o no. Restituisce un vettore logico TRUE/FALSE. Possiamo utilizzare la sua negazione, ovvero !is.na() per identificare le osservazioni presenti:

# Identifica le osservazioni mancanti
is.na(cses$mip2)
# Identifica le osservaizoni presenti
!is.na(cses$mip2)

Possiamo quindi selezionare tutte le osservazioni che non sono missing in una o più variabili

# Eliminare le osservazioni che sono missing nella variabile "mip2"
head(cses[!is.na(cses$mip2), ])
##   id     sex eta eta_gr                   mip1                           mip2 eco_eval       area
## 1  1 Femmina  60    55+              la scuola                      il lavoro       -1        Sud
## 3  3 Femmina  68    55+         poverta,lavoro                   immigrazione       -1   Nord-Est
## 4  4 Maschio  62    55+              il lavoro                   immigrazione       -1        Sud
## 5  5 Femmina  54  35 54                 lavoro                   immigrazione       -1 Nord-Ovest
## 6  6 Femmina  71    55+              il lavoro                 l'immigrazione        0 Nord-Ovest
## 7  7 Maschio  24  18 34 valorizzare  i giovani gestire meglio i fondi europei        1        Sud
# Eliminare le osservazioni che sono missing nelle variabili "mip1" e "mip2"
head(cses[!is.na(cses$mip1) & !is.na(cses$mip2), ])
##   id     sex eta eta_gr                   mip1                           mip2 eco_eval       area
## 1  1 Femmina  60    55+              la scuola                      il lavoro       -1        Sud
## 3  3 Femmina  68    55+         poverta,lavoro                   immigrazione       -1   Nord-Est
## 4  4 Maschio  62    55+              il lavoro                   immigrazione       -1        Sud
## 5  5 Femmina  54  35 54                 lavoro                   immigrazione       -1 Nord-Ovest
## 6  6 Femmina  71    55+              il lavoro                 l'immigrazione        0 Nord-Ovest
## 7  7 Maschio  24  18 34 valorizzare  i giovani gestire meglio i fondi europei        1        Sud

Se vogliamo capire quante osservazioni mancanti abbiamo in ogni variabile possiamo usare la funzione apply():

apply(cses, 2, function(x) sum(is.na(x)))
##       id      sex      eta   eta_gr     mip1     mip2 eco_eval     area 
##        0        0        0        0       62      195       23        0

La funzione na.omit() elimina ogni osservazione per la quale esiste almeno un valore mancante. Una soluzione un po’ radicale:

cses_fullobs <- na.omit(cses)
dim(cses_fullobs) # Il numero di osservazioni è diminuito di molto
## [1] 1790    8
# Ci sono osservazioni mancanti rimaste?
apply(cses_fullobs, 2, function(x) sum(is.na(x)))
##       id      sex      eta   eta_gr     mip1     mip2 eco_eval     area 
##        0        0        0        0        0        0        0        0

Ricodificare variabili

Una delle attività principali di data management è trasformare le variabili. Questa attività è spesso chiamata “ricodifica”. In generale, ricodificare significa cambiare i valori di una variabile in un modo che sia utile per l’analisi. Ci sono molti modi per trasformare una variabile, dipende da quello che occorre fare. Tuttavia, ci sono alcuni tipi di ricodifica più comuni di altri.

Ci sono due modi di ricodificare una variabile:

  1. Cambiare i valori di una variabile esistente
  2. Creare una nuova variabile dove mettere la variabile esistente ricodificata

In generale, raccomando l’opzione 2 – creare una nuova variabile. Le ragioni sono diverse: si può confrontare la nuova variabile ricodificata con la variabile originale per vedere se la ricodifica è andata bene; non si perde la vecchia variabile, e si può così ricodificarla di nuovo con valori diversi; in generale non si perdono informazioni potenzialmente utili.

Per creare una nuova variabile è sufficiente aggiungerla al data frame utilizzando il segno del dollaro $, e assegnandole i valori usando la freccia <-

cses$newvar <- 1
head(cses$newvar)
## [1] 1 1 1 1 1 1

In questo caso abbiamo creato una costante, non una variabile. Tuttavia, aggiungere una variabile ricodificata si basa sulla stessa procedura.

Variabili numeriche/metriche

Le variabili metriche sono variabili numeriche in cui i numeri mantengono il loro effettivo significato quantitativo. Per esempio, nella variabile eta, il numero 30 è una quantità che si riferisce al numero di anni interi trascorsi dalla nascita dell’intervistato. La differenza tra 30 e 31 riflette la stessa quantità di tempo della differenza tra 45 e 46 o tra 101 e 102. Ciò implica che questi valori possono essere trasformati usando operazioni matematiche.

Alcuni esempi con la variabile eta (l’unica variabile veramente metrica che abbiamo qui):

  • Logaritmo: utile per lavorare con variabili che hanno una distribuzione poco simmetriche (skewed) come percentuali o proporzioni.
cses$eta_log <- log(cses$eta)

Per capire come un logaritmo trasforma una variabile, confrontiamo le due variabili con un grafico:

plot(cses$eta, cses$eta_log)

  • Centratura: operazione che si fa talvolta con le variabili metriche da includere come variabili indipendenti nei modelli di regressione. In questo caso, centriamo la variabile sulla mediana:
cses$eta_cen <- cses$eta - median(cses$eta, na.rm = T)
plot(cses$eta, cses$eta_cen)

  • Standardizzazione: operazione simile alla centratura, secondo me ancora più utile. Per standardizzare una variabile la centriamo sulla media, e cambiamo la scala dividendola per la sua deviazione standard:
cses$eta_std <- (cses$eta - mean(cses$eta, na.rm = T)) / sd(cses$eta, na.rm = T)
plot(cses$eta, cses$eta_std)

  • La funzione scale() esegue queste trasformazioni in automatico:
# Centratura (sulla media)
head(
  cbind(
    cses$eta - mean(cses$eta, na.rm = T),
    scale(cses$eta, center = T, scale = F)
  )
)
##           [,1]      [,2]
## [1,]  8.598201  8.598201
## [2,] 10.598201 10.598201
## [3,] 16.598201 16.598201
## [4,] 10.598201 10.598201
## [5,]  2.598201  2.598201
## [6,] 19.598201 19.598201
# Standardizzazione
head(
  cbind(
    (cses$eta - mean(cses$eta, na.rm = T)) / sd(cses$eta, na.rm = T),
    scale(cses$eta, center = T, scale = T)
  )
)
##           [,1]      [,2]
## [1,] 0.5124959 0.5124959
## [2,] 0.6317059 0.6317059
## [3,] 0.9893360 0.9893360
## [4,] 0.6317059 0.6317059
## [5,] 0.1548658 0.1548658
## [6,] 1.1681511 1.1681511
  • Un’altro tipo di operazione che si svolge talvolta con le variabili metriche è cambiare la scala in modo che vada da \(0\) a \(1\):
cses$eta_01 <- (cses$eta - min(cses$eta, na.rm = T)) / (max(cses$eta, na.rm = T) - min(cses$eta, na.rm = T))
plot(cses$eta, cses$eta_01)

Variabili categoriche

Nelle variabili categoriche i valori numerici sono semplici etichette di categorie, non hanno alcun valore quantitativo (al massimo possono dirci qualcosa sull’ordine delle categorie, come nelle variabili ordinali).

Un esempio è la variabile eco_eval: questa variabile ha valori numerici [-1, 0, 1], ma non si riferiscono a una reale quantità. I valori potrebbero anche essere 10, 11 e 12, e l’ordine rimarrebbe immutato. In altre parole, i valori si riferiscono a categorie, ovvero etichette che identificano gruppi di osservazioni (come la categoria “Italiano” identifica un gruppo di persone sulla base della loro nazionalità). Quello che si può fare con i gruppi è:

  1. Cambiare le etichette per modificare l’ordine delle categorie
  2. Mettere alcune categorie assieme per avere gruppi più grandi

Per esempio, la variabile area ha 4 categorie

table(cses$area)
## 
##     Centro   Nord-Est Nord-Ovest        Sud 
##        446        349        553        653

Vogliamo mettere assieme gli intervistati che vivono nel Nord-Est con quelli che vivono nel Nord-Ovest nella categoria “Nord”. Il modo per farlo è con la funzione ifelse():

cses$area_2 <- ifelse(cses$area == "Nord-Est" | cses$area == "Nord-Ovest", "Nord", cses$area)
table(cses$area, cses$area_2)
##             
##              Centro Nord Sud
##   Centro        446    0   0
##   Nord-Est        0  349   0
##   Nord-Ovest      0  553   0
##   Sud             0    0 653

Per evitare di ripetere tutte le categorie con l’operatore “OR” | (in questo caso sono 2 ma potrebbero essere molte di più) è utilizzare l’operatore %in%, che è un operatore che R usa per le operazioni di algebra delle matrici:

cses$area_3 <- ifelse(cses$area %in% c("Nord-Est", "Nord-Ovest"), "Nord", cses$area)
table(cses$area, cses$area_3)
##             
##              Centro Nord Sud
##   Centro        446    0   0
##   Nord-Est        0  349   0
##   Nord-Ovest      0  553   0
##   Sud             0    0 653

La funzione ifelse() si usa praticamente in tutti questi casi. Può venire anche utilizzata per operazioni multiple. Per esempio, vogliamo creare una variabile in cui raggruppiamo gli intervistati per fasce di età (come con eta_gr, ma con gruppi differenti):

cses$eta_gr_2 <- ifelse(cses$eta <= 30, "<=30",
                        ifelse(cses$eta <= 50, "31-50",
                               "51+"))
with(cses, table(eta, eta_gr_2))
##     eta_gr_2
## eta  <=30 31-50 51+
##   18   15     0   0
##   19   14     0   0
##   20   15     0   0
##   21   21     0   0
##   22   19     0   0
##   23   30     0   0
##   24   27     0   0
##   25   23     0   0
##   26   27     0   0
##   27   32     0   0
##   28   27     0   0
##   29   33     0   0
##   30   21     0   0
##   31    0    20   0
##   32    0    23   0
##   33    0    33   0
##   34    0    18   0
##   35    0    27   0
##   36    0    18   0
##   37    0    34   0
##   38    0    30   0
##   39    0    29   0
##   40    0    20   0
##   41    0    23   0
##   42    0    34   0
##   43    0    41   0
##   44    0    24   0
##   45    0    35   0
##   46    0    34   0
##   47    0    32   0
##   48    0    46   0
##   49    0    42   0
##   50    0    39   0
##   51    0     0  52
##   52    0     0  39
##   53    0     0  40
##   54    0     0  41
##   55    0     0  40
##   56    0     0  46
##   57    0     0  52
##   58    0     0  38
##   59    0     0  39
##   60    0     0  45
##   61    0     0  36
##   62    0     0  35
##   63    0     0  41
##   64    0     0  35
##   65    0     0  51
##   66    0     0  30
##   67    0     0  62
##   68    0     0  31
##   69    0     0  42
##   70    0     0  39
##   71    0     0  31
##   72    0     0  20
##   73    0     0  22
##   74    0     0  25
##   75    0     0  23
##   76    0     0  17
##   77    0     0  30
##   78    0     0  17
##   79    0     0  16
##   80    0     0  12
##   81    0     0  11
##   82    0     0  16
##   83    0     0   4
##   84    0     0   5
##   85    0     0   2
##   86    0     0   3
##   87    0     0   3
##   88    0     0   2
##   90    0     0   1
##   93    0     0   1

La funzione cut() aiuta a sistematicizzare un po’ questo processo, per evitare di avere troppi ifelse() contenuti uno dentro l’altro:

cses$eta_gr_3 <- cut(cses$eta, 
    breaks = c(-Inf, 25, 35, 45, 55, 65, +Inf), 
    labels = c("<=24", "25-34", "35-44", "45-54", "55-64", "65<"),
    right = F)
with(cses, table(eta, eta_gr_3))
##     eta_gr_3
## eta  <=24 25-34 35-44 45-54 55-64 65<
##   18   15     0     0     0     0   0
##   19   14     0     0     0     0   0
##   20   15     0     0     0     0   0
##   21   21     0     0     0     0   0
##   22   19     0     0     0     0   0
##   23   30     0     0     0     0   0
##   24   27     0     0     0     0   0
##   25    0    23     0     0     0   0
##   26    0    27     0     0     0   0
##   27    0    32     0     0     0   0
##   28    0    27     0     0     0   0
##   29    0    33     0     0     0   0
##   30    0    21     0     0     0   0
##   31    0    20     0     0     0   0
##   32    0    23     0     0     0   0
##   33    0    33     0     0     0   0
##   34    0    18     0     0     0   0
##   35    0     0    27     0     0   0
##   36    0     0    18     0     0   0
##   37    0     0    34     0     0   0
##   38    0     0    30     0     0   0
##   39    0     0    29     0     0   0
##   40    0     0    20     0     0   0
##   41    0     0    23     0     0   0
##   42    0     0    34     0     0   0
##   43    0     0    41     0     0   0
##   44    0     0    24     0     0   0
##   45    0     0     0    35     0   0
##   46    0     0     0    34     0   0
##   47    0     0     0    32     0   0
##   48    0     0     0    46     0   0
##   49    0     0     0    42     0   0
##   50    0     0     0    39     0   0
##   51    0     0     0    52     0   0
##   52    0     0     0    39     0   0
##   53    0     0     0    40     0   0
##   54    0     0     0    41     0   0
##   55    0     0     0     0    40   0
##   56    0     0     0     0    46   0
##   57    0     0     0     0    52   0
##   58    0     0     0     0    38   0
##   59    0     0     0     0    39   0
##   60    0     0     0     0    45   0
##   61    0     0     0     0    36   0
##   62    0     0     0     0    35   0
##   63    0     0     0     0    41   0
##   64    0     0     0     0    35   0
##   65    0     0     0     0     0  51
##   66    0     0     0     0     0  30
##   67    0     0     0     0     0  62
##   68    0     0     0     0     0  31
##   69    0     0     0     0     0  42
##   70    0     0     0     0     0  39
##   71    0     0     0     0     0  31
##   72    0     0     0     0     0  20
##   73    0     0     0     0     0  22
##   74    0     0     0     0     0  25
##   75    0     0     0     0     0  23
##   76    0     0     0     0     0  17
##   77    0     0     0     0     0  30
##   78    0     0     0     0     0  17
##   79    0     0     0     0     0  16
##   80    0     0     0     0     0  12
##   81    0     0     0     0     0  11
##   82    0     0     0     0     0  16
##   83    0     0     0     0     0   4
##   84    0     0     0     0     0   5
##   85    0     0     0     0     0   2
##   86    0     0     0     0     0   3
##   87    0     0     0     0     0   3
##   88    0     0     0     0     0   2
##   90    0     0     0     0     0   1
##   93    0     0     0     0     0   1

Tuttavia, questa funzione ha dei problemi di chiarezza che fanno sí che spesso si preferisca usare in ogni caso tanti ifelse().

Eliminare le variabili

Ovviamente quando si creano troppe variabili è anche possibile eliminarne alcune. Questo si può fare con le parentesi quadre e con l’operatore %in%:

to.drop <- c("newvar", "area_2", "area_3", "eta_log", "eta_cen", "eta_std", "eta_01", "eta_gr_2", "eta_gr_3")
cses <- cses[, !names(cses) %in% to.drop]

Aggiungere osservazioni o variabili da altri dataset

A volte nelle nostre operazioni di data management capita di dover mettere assieme dati da diverse fonti. Una matrice è un oggetto quadrato con righe e colonne e quindi, intuitivamente, si possono aggiungere righe (osservazioni) o colonne (variabili).

Aggiungere osservazioni

Ricordate i due dataset cses_sud e cses_centro che abbiamo creato poco fa? Immaginiamo che non siano due parti di un unico dataset ma che siano effettivamente due dataset separati, magari raccolti in diverse parti di Italia (questo capita più facilmente con dati raccolti in paesi diversi). Come facciamo ad aggiungere le osservazioni degli intervistati in Centro Italia a quelle degli intervistati del Sud? Utilizziamo la funzione rbind() che conosciamo già:

cses_cs <- rbind(cses_sud, cses_centro)
table(cses_cs$area)
## 
## Centro    Sud 
##    446    653

Notare tuttavia che aggiungere osservazioni non è un’operazione che si fa troppo spesso. Innanzi tutto perchè può essere fatto solo se i due dataset da cui provengono le osservazioni hanno esattamente le stesse variabili chiamate con gli stessi nomi. Molto più comune è aggiungere variabili.

Aggiungere variabili

Aggiungere variabili a un dataset è complicato, perchè i valori devono essere assegnati alle giuste osservazioni. Perchè questo sia fattibile occorre quindi che entrambi i dataset abbiano almeno una variabile in comune che identifica in modo univoco le singole osservazioni e che possa fare da ponte tra loro. Se non abbiamo questa variabile, non possiamo fare niente. Se invece la abbiamo, possiamo mettere assieme i due dataset utilizzando la funzione merge().

PEr fare un esempio, carichiamo il file “cses2018edu.dta”, che include una variabile chiamata titstu che registra il titolo di studio dell’intervistato.

cses_edu <- import("cses2018edu.dta")
head(cses_edu)
##   id titstu
## 1  1      9
## 2  2      5
## 3  3      5
## 4  4      6
## 5  5      5
## 6  6      4

Notare che il data frame cses_edu ha 2 variabili: id (il codice identificativo dell’intervistato che abbiamo anche in cses) e titstu. Mentre la seconda è l’informazione che effettivamente vogliamo aggiungere ai nostri dati, la prima è necessaria per assegnare i valori di titolo di studio alle osservazioni giuste.

cses_full <- merge(cses, cses_edu, by = "id")
head(cses_full)
##   id     sex eta eta_gr           mip1           mip2 eco_eval       area titstu
## 1  1 Femmina  60    55+      la scuola      il lavoro       -1        Sud      9
## 2  2 Maschio  62    55+           <NA>           <NA>       -1     Centro      5
## 3  3 Femmina  68    55+ poverta,lavoro   immigrazione       -1   Nord-Est      5
## 4  4 Maschio  62    55+      il lavoro   immigrazione       -1        Sud      6
## 5  5 Femmina  54  35 54         lavoro   immigrazione       -1 Nord-Ovest      5
## 6  6 Femmina  71    55+      il lavoro l'immigrazione        0 Nord-Ovest      4

Esercizio

In cses abbiamo la variabile eco_eval, definita sopra come la valutazione di come lo stato dell’economia del paese è cambiato nel corso dell’anno precedente, codificato in 3 classi (1 = è migliorato; 0 = è rimasto uguale; -1 = è peggiorato).

Calcolate la media di questa variabile per gli intervistati nelle diverse aree geografiche (Nord-Est, Nord-Ovest, Centro, Sud). Come interpretate le differenze osservate?