Visualizzazione post con etichetta matrici. Mostra tutti i post
Visualizzazione post con etichetta matrici. Mostra tutti i post

domenica 5 marzo 2023

Gestione dei dati mancanti

Per illustrare il tema, che è strettamente collegato all'ordinamento dei dati [1], vediamo tre cose:
→ come individuare i dati mancanti;
→ come i dati mancanti - identificati in R con la sigla NA (Not Available) - possono bloccare l'esecuzione di calcoli sulle variabili numeriche che li contengono e come in questo caso sia possibile omettere selettivamente dai calcoli i dati NA
→ come al bisogno sia possibile eliminare per intero da un vettore o matrice o tabella [2] i casi con dati NA.

Per proseguire dovete, seguendo le istruzioni fornite alla pagina Dati:
effettuare il download del file importa_csv.csv
salvare il file nella cartella C:\Rdati\

In alternativa copiate le otto righe riportate qui sotto, incollatele in un editor di file di testo aggiungendo un ↵ Invio al termine dell'ultima riga, e salvate il tutto in C:\Rdati\ in un file di testo denominato importa_csv.csv (attenzione: assicuratevi che il file sia effettivamente salvato con l'estensione .csv):

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

Vediamo come individuare i dati mancanti. Copiate e incollate nella Console di R questo script e premete ↵ Invio:

# IDENTIFICA E CONTEGGIA I DATI MANCANTI 
#
# importa i dati, notare / invece di \ su windows
mydata <- read.table("C:/Rdati/importa_csv.csv", header=TRUE, sep=";", dec=",", row.names="id")
#
mydata # mostra i dati importati
#
is.na(mydata) # identifica i dati mancanti
#
colSums(is.na(mydata)) # conteggia i dati mancanti per colonna/variabile
#
which(is.na(mydata$altezza_m)) # identifica la posizione dei dati mancanti
#

Dopo avere importato i dati, richiamando il nome dell'oggetto mydata che li contiene questi sono mostrati con la sigla NA riportata automaticamente da R in corrispondenza di ciascuno dei dati mancanti.

> mydata # mostra i dati importati
   sesso anni peso_kg altezza_m
MT     M   69      76      1.78
GF     F   56      63        NA
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

Nel caso di piccole tabelle come questa non serve altro: ma nel caso di estesi database ci servono funzioni che forniscano qualche soluzione più pratica e immediata. 

Impieghiamo quindi la funzione is.na() che identifica nella tabella mydata i dati mancanti riportando TRUE in corrispondenza di ciascuno di essi 

> is.na(mydata) # identifica i dati mancanti
   sesso  anni peso_kg altezza_m
MT FALSE FALSE   FALSE     FALSE
GF FALSE FALSE   FALSE      TRUE
MC FALSE FALSE   FALSE     FALSE
SB FALSE FALSE   FALSE     FALSE
FE FALSE FALSE   FALSE     FALSE
AB FALSE FALSE   FALSE     FALSE
RF FALSE FALSE   FALSE     FALSE

I dati della tabella mydata trasformati nei corrispettivi valori logici con la funzione is.na() possono allora essere impiegati come argomento della funzione colSums() che effettua il conteggio dei dati mancanti per ciascuna colonna/variabile

colSums(is.na(mydata)) # conteggia i dati mancanti per colonna/variabile
    sesso      anni   peso_kg altezza_m 
        0         0         0         1 

A questo punto abbiamo individuato in altezza_m la variabile con i dati mancanti e abbiamo conteggiato il loro numero

Non ci resta quindi che impiegare i dati della variabile mydata$altezza_m trasformati nei corrispettivi valori logici con is.na() come argomento della funzione which() per identificare la posizione dei  dati mancanti

> which(is.na(mydata$altezza_m)) # identifica la posizione dei dati mancanti
[1] 2

che nel nostro caso risultano essere il dato della riga numero 2 della variabile mydata$altezza_m.

Per l'effetto che i dati mancanti possono determinare sui calcoli copiate e incollate nella Console di R questo script e premete ↵ Invio:

# ESEMPIO DI MEDIA ARITMETICA NON COMPUTABILE A CAUSA DI DATI MANCANTI 
#
# importa i dati, notare / invece di \ su windows
mydata <- read.table("C:/Rdati/importa_csv.csv", header=TRUE, sep=";", dec=",", row.names="id")
#
mydata # mostra i dati importati
#
mean(mydata$peso_kg) # calcola la media aritmetica dei valori di peso
mean(mydata$altezza_m) # calcola la media aritmetica dei valori di altezza
#

Il risultato che compare nella Console di R è il seguente:

> mydata # mostra i dati importati 
   sesso anni peso_kg altezza_m
MT     M   69      76      1.78
GF     F   56      63        NA
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
> #
> mean(mydata$peso_kg) # calcola la media aritmetica dei valori di peso 
[1] 72.85714
> mean(mydata$altezza_m) # calcola la media aritmetica dei valori di altezza 
[1] NA

Come potete vedere il calcolo della media effettuato con la funzione mean() ha avuto successo solamente per il peso. Per l'altezza in luogo del valore della media è stata riportata la sigla NA, evidente conseguenza del valore mancante dell'altezza nel caso GF.

Copiate e incollate nella Console di R queste due ulteriori righe di codice e premete ↵ Invio:

# la corretta gestione dei dati mancanti consente di calcolare la media dei valori di altezza 
#
mean(mydata$peso_kg) # ricalcola la media aritmetica dei valori di peso
mean(mydata$altezza_m, na.rm=TRUE) # ricalcola la media aritmetica dei valori di altezza
#

Il risultato dei calcoli della media che compare nella Console di R ora è questo:

> mean(mydata$peso_kg) # ricalcola la media aritmetica dei valori di peso
[1] 72.85714
> mean(mydata$altezza_m, na.rm=TRUE) # ricalcola la media aritmetica dei valori di altezza
[1] 1.683333

Quindi con l'aggiunta nella funzione mean() dell'argomento na.rm=TRUE, che rimuove dal calcolo i dati mancanti (in questo caso uno solo, ma potrebbero essere anche molti), è stato reso possibile il calcolo della media anche per l'altezza.

Con la funzione na.omit() è infine possibile eliminare definitivamente i casi con dati mancanti: anche un solo dato mancante/campo vuoto comporta la cancellazione dell'intera riga/caso. Copiate e incollate nella Console di R questo script e premete ↵ Invio:

# ELIMINA I CASI CON DATI MANCANTI 
#
# importa i dati, notare / invece di \ su windows
mydata <- read.table("C:/Rdati/importa_csv.csv", header=TRUE, sep=";", dec=",", row.names="id")
#
mydata # mostra i dati importati
#
newdata <- na.omit(mydata) # elimina da mydata i casi con dati mancanti
newdata # mostra i dati dopo eliminazione dei casi con dati mancanti
#
mean(newdata$peso_kg) # calcola la media aritmetica dei valori di peso
mean(newdata$altezza_m) # calcola la media aritmetica dei valori di altezza
#

Dai dati importati nella tabella mydata mediante la funzione na.omit() viene generata una nuova tabella denominata newdata dalla quale sono esclusi i casi con dati mancanti. Con l'eliminazione dalla tabella del caso GF i calcoli vanno subito a buon fine sia per il peso sia per l'altezza.

> mydata # mostra i dati importati 
   sesso anni peso_kg altezza_m
MT     M   69      76      1.78
GF     F   56      63        NA
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
> #
> newdata <- na.omit(mydata) # elimina da mydata i casi con dati mancanti
> newdata # mostra i dati dopo eliminazione dei casi con dati mancanti
   sesso anni peso_kg altezza_m
MT     M   69      76      1.78
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
> #  
> mean(newdata$peso_kg) # calcola la media aritmetica dei valori di peso 
[1] 74.5
> mean(newdata$altezza_m) # calcola la media aritmetica dei valori di altezza 
[1] 1.683333

Da notare che impiegando la funzione na.omit() la media dei valori di peso, che con lo script precedente era 72.85714 kg, ora è cambiata ed è diventata 74.5 kg in quanto in seguito all'eliminazione dell'intero caso GF è stato eliminato anche il suo valore di peso 63 kg che contribuiva a determinare la media di quest'ultimo.


----------

[1] Vedere il post Ordinamento dei dati.

[2] 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


lunedì 26 novembre 2018

Inserimento manuale dei dati [2]

Sapere inserire a mano i dati in R può essere utilePer questo ho predisposto due esempi che illustrano la sintassi da utilizzare per inserire direttamente da tastiera array (vettori) e combinarli in matrici o tabelle [1] assegnando i nomi alle variabili e ai casi.

Questo script genera una matrice di due righe per due colonne. Si tratta della struttura dati tipica necessaria per effettuare il test chi-quadrato, per effettuare il test di Fisher, il test di McNemar o impiegare il teorema di Bayes [2].

Copiate lo script, incollatelo nella Console di R e premete ↵ Invio.

# DA QUATTRO VALORI GENERA UNA MATRICE 2x2
#
cells <- c(1, 26, 24, 68) # genera l'array cells con i valori numerici contenuti nelle celle
cells # mostra l'array cells
#
rnames <- c("Riga 1", "Riga 2") # genera l'array rnames con i nomi delle righe
rnames # mostra l'array rnames
#
cnames <- c("Colonna 1", "Colonna 2") # genera l'array cnames con i nomi delle colonne
cnames # mostra l'array cnames
#
mymatrix <- matrix(cells, nrow=2, ncol=2, byrow=TRUE, dimnames=list(rnames, cnames)) # costruisce la matrice a partire dagli array cells, rnames, cnames
mymatrix # mostra la matrice 
#

Dopo avere eseguito lo script utilizzate i tasti Pag-su e Pag-giù per scorrere nella finestra della Console di R quanto è accaduto.

Mediante la funzione c() [3] sono generati gli array che mediante l'operatore di assegnamento <- vengono denominati cells, rnames, cnames e contengono rispettivamente i dati (cells), i nomi delle righe (rnames) e i nomi delle colonne (cnames).

Mediante la funzione matrix() [4] gli array sono combinati nella matrice mymatrix di 2 righe (nrow=2) per due colonne (ncol=2) inserendo i valori per riga (byrow=TRUE) e quindi da sinistra a destra e dall'alto in basso ottenendo quindi la matrice desiderata alla quale con l'ultimo argomento (dimnames=list(rnames, cnames)) sono assegnati i nomi alle righe e alle colonne.

Questo è il contenuto dell'oggetto mymatrix definitivo riportato da R al termine dell'elaborazione dopo l'ultimo comando mymatrix:

> mymatrix
       Colonna 1 Colonna 2
Riga 1         1        26
Riga 2        24        68

Quest'altro script genera una tabella (dataframe) che contiene valori numerici, alfanumerici e logici, e assegna i nomi alle variabili (colonne).

Copiatelo per intero quindi incollatelo nella Console di R e premete ↵ Invio:

# GENERA UNA TABELLA (DATAFRAME) DI 3 COLONNE PER 4 RIGHE
#
d <- c(9901, 9902, 9903, 9904) # genera un array con quattro valori numerici
d # mostra l'array d
#
e <- c("rosso", "bianco", "blu", NA) # genera un array con quattro valori alfanumerici, NA=Not Available
e # mostra l'array e
f <- c(TRUE,TRUE,TRUE,FALSE) # genera un array con quattro valori logici
f # mostra l'array f
#
mytable <- data.frame(d, e, f) # genera una tabella (dataframe) a partire dagli array d, e, f
mytable # mostra il contenuto della tabella
#
names(mytable) <- c("Codice", "Colore", "Dato valido") # assegna i nomi alle variabili/colonne
row.names(mytable) <- c("A", "B", "C", "D") # sostituisce gli identificativi numerici di riga di R con nuovi descrittori univoci dei casi/righe
mytable # mostra il contenuto della tabella 
#

Dopo avere eseguito lo script utilizzate casi i tasti Pag-su e Pag-giù per scorrere nella finestra della Console di R quanto è accaduto.

Qui di nuovo con la funzione c() sono generati gli array che mediante l'operatore di assegnamento <- vengono denominati d, e, f e che subito dopo sono combinati mediante la funzione data.frame() nella tabella mytable.

Successivamente con la funzione names() sono generati i nomi che vengono assegnati alle colonne/variabili della tabella e con la funzione row.names() sono sostituiti gli identificativi numerici assegnati di default ai casi/righe.

Questo è il contenuto dell'oggetto definitivo riportato al termine dell'elaborazione dopo l'ultimo comando mytable:

> mytable # mostra il contenuto della tabella 
  Codice Colore Dato valido
A   9901  rosso        TRUE
B   9902 bianco        TRUE
C   9903    blu        TRUE
D   9904   <NA>       FALSE

Anche se il significato dei vari passaggi è stato illustrato con i commenti inclusi negli script, si ricordano alcune regole generali:
→ i nomi assegnati agli oggetti che vengono generati (cells, rnames, d, fmytable e quant'altro) possono essere stabiliti liberamente;
→ potete stabilire liberamente anche i nomi da assegnare alle colonne/variabili e ai casi/righe;
per vedere il contenuto di un oggetto è sufficiente digitare nella Console di R il nome dell'oggetto;
→ una tabella per definizione può contenere sia valori numerici, sia valori alfanumerici (stringhe di testo), sia valori logici;
→ se un dato non è disponibile, al posto del dato va inserita la sigla NA (Not Available).

Se siete interessati al tema potrebbero esservi utili anche gli esempi riportati in:

----------

[1] 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

[2] Vedere le rispettive voci alla pagina Indice.

[3] Digitate help(c) nella Console di R per la documentazione della funzione c().

[4] Digitate help(matrix) nella Console di R per la documentazione della funzione matrix.

domenica 25 novembre 2018

Inserimento manuale dei dati [1]

Inserire a mano i dati in R non accade di frequente, ma è utile quando i dati da inserire sono pochi, come ad esempio quando si vuole effettuare un test chi-quadrato [1], impiegare il teorema di Bayes [2] o realizzare dei grafici a torta [3].

Per questo ho predisposto due esempi che illustrano la sintassi da utilizzare per inserire direttamente da tastiera array (vettori) e combinarli in matrici assegnando i nomi alle variabili e ai casi [4].

Il primo esempio genera un vettore (array), lo trasforma in una matrice, assegna un nuovo nome alla variabile/colonna e infine assegna un nuovo descrittore a ciascuno dei casi/righe.

Per eseguire lo script copiatelo quindi incollatelo nella Console di R e premete ↵ Invio.

# GENERA UN ARRAY E LO TRASFORMA IN UNA MATRICE
#
x <- c(4.2, 6.8, 2.5, 8.3, 5.4, 7.9, 5.3, 6.7, 2.2, 3.1) # genera l'array x
x # mostra l'array x
mean(x) # calcola la media
#
mymatrix <- data.frame(x) # trasforma l'array x in una matrice
mymatrix # mostra la matrice con i casi/righe identificati automaticamente da R
mean (mymatrix$x) # calcola la media
#
names(mymatrix) <- c("Variabile_1") # assegna un nuovo nome alla variabile/colonna
mymatrix # mostra la matrice con il nuovo nome della variabile/colonna
mean(mymatrix$Variabile_1) # calcola la media richiamando il nome della variabile/colonna
#
row.names(mymatrix) <- c("Riga_uno", "Riga_due", "Riga_tre", "Riga_quattro", "Riga_cinque", "Riga_sei", "Riga_sette", "Riga_otto", "Riga_nove", "Riga_dieci") # sostituisce gli identificativi numerici di riga di R con nuovi descrittori univoci dei casi/righe
mymatrix # mostra la matrice con i nuovi descrittori dei casi/righe
mean(mymatrix[,1]) # calcola la media richiamando il numero della variabile/colonna
#

Utilizzate i tasti Pag-su e Pag-giù per scorrere nella finestra della Console di R quanto è accaduto, che viene illustrato dai commenti inseriti in ciascuna riga.

Da notare come, quando l'array x viene trasformato nella matrice mymatrix mediante la funzione data.frame() [5], ai casi/righe viene assegnato di default un identificativo numerico univoco.

A questo punto viene impiegata la funzione names() per assegnare un nuovo nome alla variabile. In questo modo gli identificativi numerici dei casi/righe assegnati di default sono sostituiti con dei nuovi descrittori univoci (“Riga_uno”, “Riga_due”, eccetera) impiegando la funzione row.names().

Questo è quindi il contenuto dell'oggetto mymatrix definitivo riportato alla penultima riga di codice:

> mymatrix # mostra mymatrix con il nome della variabile/colonna e i descrittori dei casi
             Variabile_1
Riga_uno             4.2
Riga_due             6.8
Riga_tre             2.5
Riga_quattro         8.3
Riga_cinque          5.4
Riga_sei             7.9
Riga_sette           5.3
Riga_otto            6.7
Riga_nove            2.2
Riga_dieci           3.1

Il calcolo della media è stato introdotto ogni volta per illustrare la sintassi da impiegare. Interessante l'ultimo caso, all'ultima riga di codice: qui la media è stata calcolata richiamando il numero della colonna sulla quale va calcolata, un modo interessante e utile per richiamare una variabile di una matrice o di una tabella.

> mean(mymatrix[,1]) # calcola la media richiamando il numero della colonna
[1] 5.24

In questo secondo esempio di inserimento manuale dei dati sono generati due vettori (array), che sono combinati in una matrice di 2 colonne per 10 righe, quindi alla matrice viene aggiunta una terza colonna/variabile. Sono poi assegnati nuovi nomi alle variabili/colonne e infine viene assegnato un nuovo descrittore univoco a ciascuno dei casi/righe.

Copiate lo script quindi incollatelo nella Console di R e premete ↵ Invio.

# GENERA DUE ARRAY, LI COMBINA IN UNA MATRICE E AGGIUNGE UNA COLONNA
#
x <- c(4.2, 6.8, 2.5, 8.3, 5.4, 7.9, 5.3, 6.7, 2.2, 3.1) # genera l'array x
y <- c(3.1, 2.2, 6.7, 5.3, 7.9, 5.4, 8.3, 2.5, 6.8, 4.2) # genera l'array y
#
mymatrix <- data.frame(x, y) # combina gli array x e y in una matrice
mymatrix # mostra la matrice con i casi/righe identificati automaticamente da R
sapply(mymatrix, mean) # calcola la media
#
mymatrix$z <- mymatrix$x + mymatrix$y # aggiunge una nuova colonna
mymatrix # mostra la matrice con i casi/righe identificati automaticamente da R
sapply(mymatrix, mean) # calcola la media
#
names(mymatrix) <- c("Var_1", "Var_2", "Var_3") # assegna un nuovo nome alle variabili/colonne
mymatrix # mostra la matrice con i nuovi nomi delle variabili/colonne
mean(mymatrix$Var_3) # calcola la media richiamando il nome della variabile/colonna
#
row.names(mymatrix) <- c("Caso_uno", "Caso_due", "Caso_tre", "Caso_quattro", "Caso_cinque", "Caso_sei", "Caso_sette", "Caso_otto", "Caso_nove", "Caso_dieci") # sostituisce gli identificativi numerici di riga di R con nuovi descrittori univoci dei casi/righe
mymatrix # mostra la matrice con i nuovi descrittori dei casi/righe
mean(mymatrix[,3]) # calcola la media richiamando il numero della variabile/colonna
#

Dopo avere eseguito lo script utilizzate i tasti Pag-su e Pag-giù per scorrere nella finestra della Console di R quanto è accaduto, che viene di nuovo illustrato dai commenti inseriti in ciascuna riga.

Da notare nuovamente come una volta combinati i due array x e y nella matrice mymatrix mediante la funzione data.frame() ai casi/righe viene assegnato di default un identificativo numerico univoco. Quindi con la funzione sapply() viene calcolata la media su tutte le colonne/variabili della matrice. Questo accade anche quando viene aggiunta alla matrice una nuova colonna/variabile z contenente la somma della variabile x e della variabile y.

A questo punto viene impiegata la funzione names() per assegnare i nuovi nomi alle variabili delle due colonne mentre con la funzione mean() è possibile calcolare separatamente la media della colonna/variabile Var_3.

Infine gli identificativi numerici delle righe/casi assegnati da R sono sostituiti con dei nuovi descrittori univoci (“Riga uno”, “Riga due”, eccetera) impiegando la funzione row.names().

Questo è quindi il contenuto dell'oggetto mymatrix definitivo riportato alla penultima riga di codice:

> mymatrix # mostra la matrice con i nuovi descrittori dei casi/righe
             Var_1 Var_2 Var_3
Caso_uno       4.2   3.1   7.3
Caso_due       6.8   2.2   9.0
Caso_tre       2.5   6.7   9.2
Caso_quattro   8.3   5.3  13.6
Caso_cinque    5.4   7.9  13.3
Caso_sei       7.9   5.4  13.3
Caso_sette     5.3   8.3  13.6
Caso_otto      6.7   2.5   9.2
Caso_nove      2.2   6.8   9.0
Caso_dieci     3.1   4.2   7.3

Infine l'ultima riga di codice ci ricorda la possibilità di impiegare il numero della colonna per specificare i dati sui quali effettuare il calcolo della media:

> mean(mymatrix[,3]) # calcola la media richiamando il numero della colonna
[1] 10.48

Se siete interessati al tema potrebbero esservi utili anche gli esempi riportati in:


----------

[1] Vedere la sezione Analisi di dati qualitativi alla pagina Indice.


[3] Vedere il post Grafici a torta.

[4] 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.

[5] Digitate help(nomedellafunzione) nella Console di R per la documentazione di questa e delle altre funzioni qui impiegate.