here::here("code", "_common.R") |>
source()
# Load packages
if (!requireNamespace("pacman")) install.packages("pacman")
pacman::p_load(tidyr)
7 Utility functions
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 sec-eda-proj-structure, 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
sessionInfo()
#> R version 4.5.0 (2025-04-11)
#> Platform: aarch64-apple-darwin20
#> Running under: macOS Sequoia 15.5
#>
#> Matrix products: default
#> BLAS: /Library/Frameworks/R.framework/Versions/4.5-arm64/Resources/lib/libRblas.0.dylib
#> LAPACK: /Library/Frameworks/R.framework/Versions/4.5-arm64/Resources/lib/libRlapack.dylib; LAPACK version 3.12.1
#>
#> 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.11.0
#> [5] gridExtra_2.3 patchwork_1.3.0 bayesplot_1.12.0 psych_2.5.3
#> [9] scales_1.4.0 markdown_2.0 knitr_1.50 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.2
#> [21] tidyverse_2.0.0 rio_1.2.3 here_1.0.1
#>
#> loaded via a namespace (and not attached):
#> [1] generics_0.1.4 stringi_1.8.7 lattice_0.22-7
#> [4] hms_1.1.3 digest_0.6.37 magrittr_2.0.3
#> [7] evaluate_1.0.3 grid_4.5.0 timechange_0.3.0
#> [10] RColorBrewer_1.1-3 fastmap_1.2.0 R.oo_1.27.1
#> [13] rprojroot_2.0.4 jsonlite_2.0.0 R.utils_2.13.0
#> [16] mnormt_2.1.1 cli_3.6.5 rlang_1.1.6
#> [19] R.methodsS3_1.8.2 withr_3.0.2 tools_4.5.0
#> [22] parallel_4.5.0 tzdb_0.5.0 pacman_0.5.1
#> [25] vctrs_0.6.5 R6_2.6.1 lifecycle_1.0.4
#> [28] htmlwidgets_1.6.4 pkgconfig_2.0.3 pillar_1.10.2
#> [31] gtable_0.3.6 data.table_1.17.2 glue_1.8.0
#> [34] xfun_0.52 tidyselect_1.2.1 rstudioapi_0.17.1
#> [37] farver_2.1.2 htmltools_0.5.8.1 nlme_3.1-168
#> [40] rmarkdown_2.29 compiler_4.5.0