here::here("code", "_common.R") |>
source()
# Load packages
if (!requireNamespace("pacman")) install.packages("pacman")
pacman::p_load(tidyr)
7 Utility functions
- conoscere e sapere utilizzare le principali funzioni di utilità di R;
- sapere come importare un data set in R e esportare un data set in un file esterno;
- usare i percorsi relativi rispetto alla radice del progetto con
here::here()
.
7.1 Introduzione
In questo capitolo, esploreremo le principali funzioni di utilità in R per l’importazione di dati da file esterni e la raccolta di statistiche descrittive, fornendo una panoramica generale sui data frame.
7.2 Importare dati in R con rio::import()
Prima di analizzare i dati, è necessario importarli in R.
7.2.1 Il problema: Tanti Formati, un’Unica Soluzione
Nella ricerca psicologica i dati possono essere forniti in molti formati:
- File Excel (
.xlsx
) da questionari compilati in laboratorio, - CSV (
.csv
) da piattaforme online come Qualtrics, - File SPSS (
.sav
) per confrontare studi precedenti, - Solo testo (
.txt
) da esperimenti comportamentali.
Invece di imparare funzioni diverse, una specifica per ciascun formato, il pacchetto rio offre un solo comando universale per le importazioni.
7.2.2 Come Funziona import()
# Carica il pacchetto (installalo prima con install.packages("rio"))
library(rio)
# Importa un file CSV da una cartella "dati" nel tuo progetto
risposte <- rio::import("dati/questionario.csv")
# Importa un foglio Excel con i tempi di reazione
tempi_reazione <- rio::import("dati/esperimento1.xlsx")
# Importa un file SPSS con dati demografici
dati_demografici <- rio::import("dati/partecipanti.sav")
Perché è utile:
- riconosce automaticamente il formato dal nome del file;
- traduce i dati in un formato R pronto per l’analisi (
data.frame
); - conserva le etichette delle variabili (cruciale per questionari!).
7.2.3 Esportare Dati con rio::export()
Dopo aver pulito i dati, è possibile salvarli in qualsiasi formato usando rio::export()
:
7.3 Utilizzare Percorsi Relativi con here::here()
Quando importiamo i dati da file esterni in R, succede spesso di commettere uno dei tre errori seguenti. Vediamo come eviarli.
-
Percatori sbagliati
File aperti in altri programmi
“Errore: non posso aprire il file” → Chiudi Excel/SPSS e riprova-
Codifica caratteri strani
Se vedi � nei testi, specifica l’encoding:import("dati/testo.txt", encoding = "UTF-8")
7.3.1 Evitare Percorsi Assoluti
Come vedremo meglio nel Capitolo 14, il primo passo di un progetto di analisi dei dati è l’organizzazione dei file in cartelle con una struttura chiara:
tuo_progetto/
├── dati/
│ ├── raw/ # Dati originali
│ └── cleaned/ # Dati elaborati
├── script/
└── rapporti/
Tutti i file e le cartelle devono essere contenuti nella directory del progetto.
Il pacchetto here rende l’importazione dei dati più semplice, evitando problemi dovuti a percorsi assoluti che possono cambiare se si modifica la directory di lavoro o si sposta il progetto.
La funzione here()
crea percorsi relativi a partire dalla radice del progetto (cioè dalla cartella che contiene il file .Rproj
o da dove viene inizializzato il progetto RStudio).
Esempio di utilizzo combinato con rio::import()
:
library(rio)
library(here)
# Percorso robusto al file csv
dati <- import(here("data", "dati.csv"))
# Percorso robusto al file Excel
dati_excel <- import(here("data", "dati.xlsx"))
In questo modo, l’importazione diventa indipendente dalla cartella di lavoro attuale e il codice sarà più facilmente condivisibile e riproducibile.
Vantaggi:
-
Semplicità:
rio::import()
riconosce automaticamente il tipo di file. -
Robustezza:
here::here()
garantisce che il percorso sia sempre corretto, indipendentemente da dove viene eseguito lo script.
Questa combinazione rende le analisi riproducibili e consente di collaborare facilmente con altri ricercatori o studenti.
7.4 Funzioni Principali e Loro Utilizzo
R offre una serie di funzioni per esplorare rapidamente i dati e comprenderne la struttura prima di passare a manipolazioni più avanzate.
Funzione | Descrizione |
---|---|
summary() |
Restituisce statistiche descrittive di base per ogni colonna di un data frame. Per le colonne numeriche, calcola valori come il minimo, massimo, media, mediana, primo e terzo quartile, e il numero di valori mancanti (se presenti). Per le colonne non numeriche, restituisce il tipo di dati (carattere, logico) e il conteggio delle categorie. Esempio: summary(iris) restituisce una sintesi delle colonne del dataset iris . |
str() e glimpse()
|
Forniscono una rappresentazione sintetica delle informazioni di un data frame, come dimensione, nomi delle colonne, tipi di dati e valori iniziali. La funzione str() fa parte della configurazione base di R (pacchetto utils ), mentre glimpse() è inclusa in dplyr (pacchetto tidyverse ). Esempio: str(mtcars) o glimpse(mtcars) . |
head() e tail()
|
Permettono di visualizzare rispettivamente le prime o ultime righe di un data frame. Utile per una rapida ispezione del contenuto. Si può specificare il numero di righe da mostrare (es. head(df, 10) ), altrimenti il valore predefinito è sei righe. Esempio: head(iris) per vedere le prime righe del dataset iris . |
View() e view()
|
Visualizzano un data frame in una finestra grafica tipo foglio di calcolo all’interno di RStudio. La funzione View() è parte della configurazione base di R, mentre view() è un alias fornito da tibble (pacchetto tidyverse ). Utile per piccoli data frame, ma poco pratico per dataset di grandi dimensioni. Esempio: View(iris) apre il dataset iris nel visualizzatore di RStudio. |
unique() |
Restituisce i valori unici presenti in una colonna o in un vettore. Esempio: unique(iris$Species) restituisce le specie uniche nel dataset iris . |
names() |
Restituisce i nomi delle colonne di un data frame. Esempio: names(mtcars) restituisce i nomi delle colonne del dataset mtcars . |
class() |
Indica il tipo di dato di un oggetto in R, come numeric , character , logical , o data.frame . Esempio: class(iris) restituisce data.frame . |
length() |
Restituisce il numero di elementi di un oggetto. Per i data frame, restituisce il numero di colonne. Esempio: length(iris) restituisce 5 (colonne). |
nrow() e ncol()
|
Restituiscono rispettivamente il numero di righe e colonne di un data frame. Esempio: nrow(iris) restituisce 150 (righe), mentre ncol(iris) restituisce 5 (colonne). |
7.5 Illustrazione
Immagina di dover analizzare i dati del tuo esperimento sul sonno e la memoria, salvati nel file msleep.csv
. La struttura del tuo progetto RStudio è organizzata così:
mio_esperimento/
├── mio_esperimento.Rproj
├── data/
│ └── msleep.csv
├── script/
│ └── analisi.R
└── output/
La prima cosa da fare è caricare i pacchetti necessari:
A questo punto possiamo importare i dati:
Controlli post-importazione (fondamentali!)
head(msleep)
#> name genus vore order conservation
#> 1 Cheetah Acinonyx carni Carnivora lc
#> 2 Owl monkey Aotus omni Primates
#> 3 Mountain beaver Aplodontia herbi Rodentia nt
#> 4 Greater short-tailed shrew Blarina omni Soricomorpha lc
#> 5 Cow Bos herbi Artiodactyla domesticated
#> 6 Three-toed sloth Bradypus herbi Pilosa
#> sleep_total sleep_rem sleep_cycle awake brainwt bodywt
#> 1 12.1 NA NA 11.9 NA 50.000
#> 2 17.0 1.8 NA 7.0 0.01550 0.480
#> 3 14.4 2.4 NA 9.6 NA 1.350
#> 4 14.9 2.3 0.1333 9.1 0.00029 0.019
#> 5 4.0 0.7 0.6667 20.0 0.42300 600.000
#> 6 14.4 2.2 0.7667 9.6 NA 3.850
str(msleep)
#> 'data.frame': 83 obs. of 11 variables:
#> $ name : chr "Cheetah" "Owl monkey" "Mountain beaver" "Greater short-tailed shrew" ...
#> $ genus : chr "Acinonyx" "Aotus" "Aplodontia" "Blarina" ...
#> $ vore : chr "carni" "omni" "herbi" "omni" ...
#> $ order : chr "Carnivora" "Primates" "Rodentia" "Soricomorpha" ...
#> $ conservation: chr "lc" "" "nt" "lc" ...
#> $ sleep_total : num 12.1 17 14.4 14.9 4 14.4 8.7 7 10.1 3 ...
#> $ sleep_rem : num NA 1.8 2.4 2.3 0.7 2.2 1.4 NA 2.9 NA ...
#> $ sleep_cycle : num NA NA NA 0.133 0.667 ...
#> $ awake : num 11.9 7 9.6 9.1 20 9.6 15.3 17 13.9 21 ...
#> $ brainwt : num NA 0.0155 NA 0.00029 0.423 NA NA NA 0.07 0.0982 ...
#> $ bodywt : num 50 0.48 1.35 0.019 600 ...
glimpse(msleep)
#> Rows: 83
#> Columns: 11
#> $ name <chr> "Cheetah", "Owl monkey", "Mountain beaver", "Greater …
#> $ genus <chr> "Acinonyx", "Aotus", "Aplodontia", "Blarina", "Bos", …
#> $ vore <chr> "carni", "omni", "herbi", "omni", "herbi", "herbi", "…
#> $ order <chr> "Carnivora", "Primates", "Rodentia", "Soricomorpha", …
#> $ conservation <chr> "lc", "", "nt", "lc", "domesticated", "", "vu", "", "…
#> $ sleep_total <dbl> 12.1, 17.0, 14.4, 14.9, 4.0, 14.4, 8.7, 7.0, 10.1, 3.…
#> $ sleep_rem <dbl> NA, 1.8, 2.4, 2.3, 0.7, 2.2, 1.4, NA, 2.9, NA, 0.6, 0…
#> $ sleep_cycle <dbl> NA, NA, NA, 0.1333, 0.6667, 0.7667, 0.3833, NA, 0.333…
#> $ awake <dbl> 11.9, 7.0, 9.6, 9.1, 20.0, 9.6, 15.3, 17.0, 13.9, 21.…
#> $ brainwt <dbl> NA, 0.01550, NA, 0.00029, 0.42300, NA, NA, NA, 0.0700…
#> $ bodywt <dbl> 50.000, 0.480, 1.350, 0.019, 600.000, 3.850, 20.490, …
names(msleep)
#> [1] "name" "genus" "vore" "order"
#> [5] "conservation" "sleep_total" "sleep_rem" "sleep_cycle"
#> [9] "awake" "brainwt" "bodywt"
dim(msleep)
#> [1] 83 11
Errori comuni e soluzioni.
-
“File not found”:
- Verifica che:
- il file sia realmente in
data/
; - il nome del file sia esatto (attenzione a .csv vs .CSV);
- non ci siano spazi nel nome del file.
- il file sia realmente in
- Verifica che:
-
Pacchetti non installati:
# Esegui una volta install.packages("rio") install.packages("here")
-
Progetto non aperto:
- Assicurati di aver aperto il file
.Rproj
prima di iniziare.
- Assicurati di aver aperto il file
Esaminiamo le modalità della variabile qualitativa vore
:
unique(msleep$vore)
#> [1] "carni" "omni" "herbi" "" "insecti"
Se vogliamo la numerosità di ciascuna categoria, possiamo usare table()
:
table(msleep$vore)
#>
#> carni herbi insecti omni
#> 7 19 32 5 20
Si noti che table()
esclude i dati mancanti.
Stampiamo i nomi delle colonne del data frame:
names(msleep)
#> [1] "name" "genus" "vore" "order"
#> [5] "conservation" "sleep_total" "sleep_rem" "sleep_cycle"
#> [9] "awake" "brainwt" "bodywt"
Esaminiamo il tipo di variabile della colonna vore
:
class(msleep$vore)
#> [1] "character"
Le dimensioni del data frame sono date da:
dim(msleep)
#> [1] 83 11
laddove il primo valore è il numero di righe e il secondo valore è il numero di colonne.
Il numero di elementi di un vettore è dato da:
length(msleep$vore)
#> [1] 83
In alternativa, possiamo usare nrow()
nrow(msleep)
#> [1] 83
per il numero di righe e ncol()
ncol(msleep)
#> [1] 11
per il numero di colonne. In maniera equivalente:
dim(msleep)[2]
#> [1] 11
7.6 Esercizi
In questo esercizio, utilizzerai R per esplorare i dati raccolti con il questionario Satisfaction With Life Scale (SWLS) dagli studenti del tuo gruppo TPV. L’obiettivo è familiarizzare con le funzioni di base di R per caricare, visualizzare e manipolare i dati.
Parte 1: Operazioni Manuali
-
Creazione e gestione degli oggetti in R
- Scrivi su carta i comandi R che creerebbero un oggetto chiamato
swls_scores
contenente i punteggi di 10 studenti. - Quali sono le regole per assegnare un nome a un oggetto in R?
- Scrivi su carta i comandi R che creerebbero un oggetto chiamato
-
Visualizzazione dei dati
- Scrivi il comando R per visualizzare il contenuto dell’oggetto
swls_scores
. - Come puoi visualizzare solo i primi 5 valori del vettore?
- Scrivi il comando R per visualizzare il contenuto dell’oggetto
-
Esplorazione della struttura dei dati
- Scrivi i comandi R per verificare il tipo di dati contenuti in
swls_scores
. - Come puoi verificare quanti elementi contiene?
- Scrivi i comandi R per verificare il tipo di dati contenuti in
Parte 2: Esecuzione in R
-
Creazione del dataset in R
- Inserisci i dati in un oggetto chiamato
swls_scores
in R.
- Inserisci i dati in un oggetto chiamato
- Verifica della struttura dei dati
- Visualizzazione dei dati
-
Identificazione dei valori unici
- Usa
unique(swls_scores)
per individuare i punteggi distinti.
- Usa
-
Creazione di una tabella con i dati
- Trasforma
swls_scores
in un data frame con una colonna"Punteggio"
e una colonna"Studente"
(numerata da 1 a 10).
- Trasforma
-
Esportazione dei dati
- Salva il data frame in un file CSV chiamato
"swls_data.csv"
usandowrite.csv()
.
- Salva il data frame in un file CSV chiamato
Consegna
- Scrivi le risposte della Parte 1 su carta.
- Scrivi il codice e i risultati della Parte 2 in un file
.R
e invialo come consegna.
Parte 1: Operazioni Manuali
-
Creazione e gestione degli oggetti in R
-
Consideriamo dei valori di risposta arbitrari. Il comando per creare l’oggetto
swls_scores
è:swls_scores <- c(20, 16, 23, 25, 11, 7, 20, 25, 15, 27)
-
Regole per assegnare un nome a un oggetto in R:
- Non può iniziare con un numero.
- Non può contenere spazi o caratteri speciali (tranne
_
e.
). - Non deve avere lo stesso nome di funzioni già esistenti.
-
-
Visualizzazione dei dati
-
Per visualizzare il contenuto:
swls_scores
-
Per visualizzare solo i primi 5 valori:
head(swls_scores, 5)
-
- Esplorazione della struttura dei dati
Parte 2: Esecuzione in R
-
Creazione del dataset in R
swls_scores <- c(20, 16, 23, 25, 11, 7, 20, 25, 15, 27)
-
Verifica della struttura dei dati
-
Visualizzazione dei dati
-
Identificazione dei valori unici
unique(swls_scores)
- Restituisce:
7, 11, 15, 16, 20, 23, 25, 27
.
- Restituisce:
-
Creazione di una tabella con i dati
df_swls <- data.frame(Studente = 1:10, Punteggio = swls_scores) df_swls
-
Esportazione dei dati
write.csv(df_swls, "swls_data.csv", row.names=FALSE)
Conclusione
Questi esercizi hanno introdotto i comandi di base per creare, visualizzare e manipolare dati in R.
sessionInfo()
#> R version 4.4.2 (2024-10-31)
#> Platform: aarch64-apple-darwin20
#> Running under: macOS Sequoia 15.3.1
#>
#> Matrix products: default
#> BLAS: /Library/Frameworks/R.framework/Versions/4.4-arm64/Resources/lib/libRblas.0.dylib
#> LAPACK: /Library/Frameworks/R.framework/Versions/4.4-arm64/Resources/lib/libRlapack.dylib; LAPACK version 3.12.0
#>
#> locale:
#> [1] C/UTF-8/C/C/C/C
#>
#> time zone: Europe/Rome
#> tzcode source: internal
#>
#> attached base packages:
#> [1] stats graphics grDevices utils datasets methods base
#>
#> other attached packages:
#> [1] thematic_0.1.6 MetBrewer_0.2.0 ggokabeito_0.1.0 see_0.10.0
#> [5] gridExtra_2.3 patchwork_1.3.0 bayesplot_1.11.1 psych_2.4.12
#> [9] scales_1.3.0 markdown_1.13 knitr_1.49 lubridate_1.9.4
#> [13] forcats_1.0.0 stringr_1.5.1 dplyr_1.1.4 purrr_1.0.4
#> [17] readr_2.1.5 tidyr_1.3.1 tibble_3.2.1 ggplot2_3.5.1
#> [21] tidyverse_2.0.0 rio_1.2.3 here_1.0.1
#>
#> loaded via a namespace (and not attached):
#> [1] generics_0.1.3 stringi_1.8.4 lattice_0.22-6 hms_1.1.3
#> [5] digest_0.6.37 magrittr_2.0.3 evaluate_1.0.3 grid_4.4.2
#> [9] timechange_0.3.0 fastmap_1.2.0 R.oo_1.27.0 rprojroot_2.0.4
#> [13] jsonlite_1.9.1 R.utils_2.13.0 mnormt_2.1.1 cli_3.6.4
#> [17] rlang_1.1.5 R.methodsS3_1.8.2 munsell_0.5.1 withr_3.0.2
#> [21] tools_4.4.2 parallel_4.4.2 tzdb_0.4.0 colorspace_2.1-1
#> [25] pacman_0.5.1 vctrs_0.6.5 R6_2.6.1 lifecycle_1.0.4
#> [29] htmlwidgets_1.6.4 pkgconfig_2.0.3 pillar_1.10.1 gtable_0.3.6
#> [33] data.table_1.17.0 glue_1.8.0 xfun_0.51 tidyselect_1.2.1
#> [37] rstudioapi_0.17.1 farver_2.1.2 htmltools_0.5.8.1 nlme_3.1-167
#> [41] rmarkdown_2.29 compiler_4.4.2