6  Un approccio moderno all’analisi dei dati

In questo capitolo imparerai a:
  • installare R e RStudio;
  • creare e gestire progetti in RStudio;
  • manipolare oggetti e vettori in R;
  • utilizzare funzioni e lavorare con dati mancanti;
  • estrarre e gestire sottoinsiemi di dati;
  • apprezzare l’importanza di rendere riproducibile l’analisi dei dati, condividendone ogni passaggio.
Preparazione del Notebook
here::here("code", "_common.R") |> 
  source()

# Load packages
if (!requireNamespace("pacman")) install.packages("pacman")
pacman::p_load(tidyr)

Introduzione

Nell’analisi dei dati psicologici, R non è solo uno strumento statistico avanzato, ma un vero e proprio linguaggio per organizzare il pensiero scientifico. La sua sintassi trasforma procedure complesse in passaggi chiari, verificabili e ripetibili, rispondendo alla crisi della replicabilità che ha coinvolto la psicologia negli ultimi anni (Obels et al., 2020). Imparare R significa quindi acquisire un metodo di lavoro rigoroso e trasparente.

6.1 La Sintassi di R come Garanzia di Trasparenza

A differenza dei software a menu grafici (come Excel o SPSS), dove le operazioni restano “nascoste” dietro click del mouse, R richiede di descrivere esplicitamente ogni passaggio. Prendiamo questo esempio base:

dati <- read.csv("esperimento1.csv")
modello <- lm(risposta ~ trattamento, data = dati)

Questo semplice script realizza tre cose fondamentali:

  1. Documentazione automatica: Ogni operazione resta tracciata nel codice.
  2. Verifica immediata: È possibile ispezionare ogni passaggio (Cosa contiene dati? Come è definito modello?).
  3. Modifiche controllate: Cambiare un parametro (es. il file di input) non richiede di rifare tutta l’analisi manualmente.

6.1.1 Perché R Favorisce la Replicabilità

Tre caratteristiche di R facilitano direttamente la replicabilità:

  1. Struttura basata su script: Scrivere codice in file .R o .qmd crea una traccia completa e ordinata dell’analisi, integrando:

    • istruzioni eseguibili,
    • annotazioni metodologiche,
    • visualizzazione dei risultati.
  2. Gestione esplicita dei pacchetti:
    Comandi come library(lme4) o install.packages("brms") rendono esplicite tutte le risorse usate, evitando il classico “Sul mio computer funzionava!”.

  3. Literate programming tramite R Markdown:
    La combinazione di codice, testo narrativo e risultati dinamici (Knuth, 1984) in documenti Quarto (o R Markdown) consente di generare report che combinano:

    • testo esplicativo,
    • analisi eseguibile,
    • risultati dinamici (grafici, tabelle).

6.1.2 Buone Abitudini da Adottare Subito

  1. Nomi descrittivi
    Utilizzare sempre nomi chiari per oggetti e dati:

    # Da evitare
    x <- read.csv("file1.csv")  
    
    # Preferibile
    demographics_data <- read.csv("demographic_questionnaire.csv")  
  2. Salvataggio progressivo delle modifiche (versionamento)
    R permette di salvare e tenere traccia delle modifiche ai file con sistemi come Git. Non è necessario impararlo subito, ma è utile sapere che strumenti come GitHub consentono facilmente di archiviare versioni successive del proprio lavoro, facilitando il recupero di versioni precedenti in caso di necessità.

  3. Checklist pre-invio
    Prima di condividere un’analisi, è buona norma verificare:

    • eseguire lo script integralmente (Ctrl+Shift+Enter su RStudio);
    • controllare che i percorsi dei file siano corretti (es.: “Il file dati.csv si trova nella cartella giusta?”);
    • aggiornare tutti i pacchetti installati con update.packages(ask = FALSE).

Queste pratiche rendono il codice più robusto, l’analisi più affidabile e i risultati più facilmente verificabili.

6.1.3 Perché Queste Regole Contano nella Ricerca Psicologica

L’apprendimento di R va oltre l’acquisizione di competenze tecniche. Ogni scelta sintattica riflette un principio scientifico:

Elemento del codice Principio metodologico
set.seed(123) Controllo delle fonti di casualità
dplyr::filter() Tracciabilità delle esclusioni
APA_style() Standardizzazione della reportistica

In un contesto dove il 50% degli studi psicologici mostra difficoltà di replicazione (Collaboration, 2015), R offre un framework per costruire ricerche solide fin dalla fase di progettazione.

6.1.4 Prossimi Passi

  1. Scarica e installa R.
    Vai al sito ufficiale di CRAN (https://cran.r-project.org/), scegli la versione per il tuo sistema operativo (Windows, Mac o Linux) e segui le istruzioni di installazione.

  2. Scarica e installa RStudio.
    Dopo aver installato R, scarica RStudio dal sito ufficiale (https://posit.co/download/rstudio-desktop/). Scegli la versione gratuita “RStudio Desktop” e segui le istruzioni per il tuo sistema operativo.

Una spiegazione dettagliata del processo di installazione di R e RStudio è disponibile in Okoye & Hosseini (2024).

6.2 Panoramica sull’interfaccia di RStudio

RStudio rende l’uso di R più intuitivo grazie alla sua interfaccia divisa in quattro pannelli principali:

  • Pannello degli script: Qui puoi scrivere e modificare i tuoi script, cioè sequenze di comandi salvabili per analisi ripetibili e organizzate.
  • Console: Esegue i comandi scritti direttamente o lanciati dagli script, mostrando risultati, messaggi e errori.
  • Pannello dell’ambiente: Mostra i dataset, le variabili e gli oggetti caricati nella sessione di lavoro, permettendoti di gestire facilmente i dati.
  • Pannello grafici/aiuto/file: Visualizza grafici, fornisce accesso alla documentazione di R e consente di navigare tra file e cartelle sul tuo sistema.

6.3 Creare un Nuovo Progetto in RStudio

Avviare un nuovo progetto
Dal menu di RStudio, seleziona File > New Project… per creare un nuovo progetto. I progetti in RStudio sono uno strumento efficace per organizzare il lavoro relativo a una specifica analisi o domanda di ricerca. All’interno di un progetto puoi raccogliere script, file di dati e output, mantenendo tutto ben strutturato.

Scegliere la posizione del progetto
Puoi creare una nuova directory dedicata al progetto oppure associare il progetto a una directory esistente. Organizzare i progetti in cartelle dedicate aiuta a mantenere i file in ordine e a utilizzare percorsi relativi, rendendo il tuo lavoro più facile da condividere con collaboratori e più portabile tra diversi sistemi.

Questa organizzazione è particolarmente utile per evitare confusione e assicurarsi che tutti i file necessari siano facilmente accessibili e collegati al progetto corretto.

6.4 Concetti di Base nella Programmazione in R

Iniziare a usare R, soprattutto per chi si avvicina per la prima volta a questo linguaggio nel contesto della psicologia, significa comprendere i concetti fondamentali che ne costituiscono la base. Questo capitolo introduce i principi essenziali della programmazione in R, tra cui:

  • La comprensione della sintassi di R.
  • La familiarizzazione con i principali tipi di dati e strutture.
  • L’acquisizione delle operazioni di base.

Questi concetti sono fondamentali per manipolare efficacemente i dati e condurre analisi statistiche, rappresentando il punto di partenza per sfruttare al meglio le potenzialità di R.

6.5 Oggetti in R

In R, tutto è un oggetto: dai numeri e stringhe di testo più semplici fino a strutture più complesse come vettori, data frame, funzioni, modelli statistici o persino grafici. Un oggetto in R è semplicemente un contenitore che memorizza un valore o una serie di valori, permettendoti di manipolarli e riutilizzarli nel codice.

6.5.1 Creare oggetti

Per creare un oggetto, è necessario assegnargli un nome e un valore utilizzando l’operatore di assegnazione <- (consigliato) o = (meno utilizzato):

my_obj <- 48

In questo esempio, abbiamo creato un oggetto chiamato my_obj e gli abbiamo assegnato il valore 48. Ora questo numero è memorizzato con quel nome e può essere richiamato facilmente.

Per visualizzare il valore di un oggetto, basta scriverne il nome e premere Invio:

my_obj
#> [1] 48

6.5.1.1 Dove vengono salvati gli oggetti?

Gli oggetti creati vengono memorizzati nell’ambiente di lavoro (workspace) e restano disponibili finché non vengono rimossi o finché la sessione di R non viene chiusa. Se stai usando RStudio, puoi vedere tutti gli oggetti attualmente presenti nella scheda Environment, dove vengono mostrati con dettagli come tipo, lunghezza e valore.

6.5.1.2 Perché gli oggetti sono importanti?

Lavorare con oggetti in R permette di:

  • Riutilizzare dati e risultati senza doverli digitare nuovamente.
  • Organizzare il codice in modo chiaro e leggibile, rendendo le analisi più strutturate.
  • Manipolare facilmente i dati, combinando, trasformando e analizzando gli oggetti in base alle esigenze.

6.5.1.3 Stringhe

È possibile assegnare a un oggetto anche una stringa di testo, racchiudendola tra virgolette:

my_obj2 <- "R è fantastico"
my_obj2
#> [1] "R è fantastico"

Se dimentichi le virgolette, R mostrerà un errore.

6.5.1.4 Modificare Oggetti

Per modificare il valore di un oggetto esistente, basta riassegnarlo:

my_obj2 <- 1024

Ora il tipo di my_obj2 è cambiato da carattere a numerico. È anche possibile usare oggetti per crearne di nuovi:

my_obj3 <- my_obj + my_obj2
my_obj3
#> [1] 1072

6.5.1.5 Manipolare Oggetti

Se provi a sommare oggetti di tipo diverso, R restituirà un errore:

char_obj <- "ciao"
char_obj2 <- "mondo"
char_obj3 <- char_obj + char_obj2
#> Error in char_obj + char_obj2 : non-numeric argument to binary operator

Quando incontri errori come questo, chiedi a AI la spiegazione del messaggio, per esempio: “non-numeric argument to binary operator error + r”. Un errore comune è anche:

my_obj <- 48
my_obj4 <- my_obj + no_obj
#> Error: object 'no_obj' not found

R segnala che no_obj non è stato definito e, di conseguenza, l’oggetto my_obj4 non è stato creato.

6.6 Nomi degli Oggetti

Attribuire nomi agli oggetti potrebbe sembrare un dettaglio secondario, ma è fondamentale scegliere nomi brevi e informativi. Un buon nome migliora la leggibilità del codice e ne facilita la manutenzione. È importante adottare uno stile coerente, come uno dei seguenti:

  • Snake case: output_summary
  • Dot case: output.summary
  • Camel case: outputSummary

In questo corso useremo lo stile più diffuso, Snake Case, che separa le parole con il carattere di sottolineatura _.

Ci sono alcune regole fondamentali da rispettare nella scelta dei nomi:

  1. Non possono iniziare con un numero (ad esempio, 2my_variable non è valido).
  2. Non possono contenere caratteri speciali come &, ^, /, ecc.
  3. Evita di usare parole riservate (ad esempio, TRUE, NA) o nomi di funzioni esistenti (ad esempio, data).

Esempio di cosa non fare:

data <- read.table("mydatafile", header = TRUE) # `data` è già una funzione!

6.7 Commenti

I commenti sono uno strumento essenziale per rendere il codice più chiaro e comprensibile, sia per te stesso sia per altri. Nel linguaggio R, i commenti iniziano con il simbolo #, e tutto ciò che lo segue sulla stessa riga viene ignorato dall’interprete durante l’esecuzione.

6.7.1 Perché commentare?

I commenti servono a spiegare perché il codice è scritto in un certo modo, non solo come funziona (questo è evidente leggendo il codice). Una buona pratica consiste nel commentare le decisioni o i passaggi che non risultano immediatamente evidenti.

Ad esempio, invece di scrivere un commento ridondante come:

# Assegno 42 alla variabile x
x <- 42

è più utile fornire un contesto:

# Valore iniziale scelto per semplificare i calcoli successivi
x <- 42

6.7.2 Vantaggi

Commentare in modo appropriato aiuta a:

  • Ridurre il tempo necessario per comprendere o modificare il codice, anche mesi o anni dopo averlo scritto.
  • Facilitare la collaborazione con altri, rendendo il codice leggibile e accessibile.
  • Migliorare la manutenibilità e il riutilizzo del codice.

Un codice ben commentato non è solo più facile da leggere, ma anche più professionale e robusto nel lungo termine.

6.8 Usare R come Calcolatore

R può essere utilizzato come un semplice calcolatore digitando direttamente nella console numeri e operatori aritmetici per eseguire operazioni come somma, sottrazione, moltiplicazione e divisione (+, -, *, /). Questo lo rende uno strumento immediato e versatile per calcoli di base e avanzati.

Esempio 6.1 La Satisfaction With Life Scale (SWLS) contiene 5 item, ciascuno valutato con una scala Likert a 7 punti, dove:

1 = “completamente in disaccordo” e 7 = “completamente d’accordo”.

Gli item sono:

  1. Per la maggior parte, la mia vita si avvicina al mio ideale.
  2. Le mie condizioni di vita sono eccellenti.
  3. Sono soddisfatto della mia vita.
  4. Fino ad ora, ho ottenuto le cose importanti che voglio nella vita.
  5. Se potessi vivere la mia vita di nuovo, non cambierei quasi nulla.

Supponiamo che un individuo risponda nel seguente modo:

  • Item 1: 5
  • Item 2: 3
  • Item 3: 4
  • Item 4: 2
  • Item 5: 2

Il punteggio totale sulla SWLS si calcola sommando i punteggi di ciascun item:

sogg1 <- 5 + 3 + 4 + 2 + 2 
sogg1
#> [1] 16

Esempio 6.2 Il Body Mass Index (BMI) si calcola dividendo il peso, in chilogrammi, per il quadrato dell’altezza, in metri.
La formula è:

\[ \text{BMI} = \frac{\text{Peso (kg)}}{\text{Altezza (m)}^2} . \]

Supponiamo che un individuo pesi 79000 grammi (79 kg) e sia alto 176 cm. Il calcolo in R sarà:

bmi <- (79000 / 1000) / (176 / 100)^2
bmi
#> [1] 25.5

Nota. L’uso di parentesi è fondamentale per garantire che le operazioni vengano eseguite nell’ordine corretto. In R, come in matematica, le operazioni racchiuse tra parentesi hanno la precedenza rispetto ad altre operazioni. Ad esempio, nel calcolo del BMI, abbiamo usato le parentesi per calcolare prima la conversione dei valori nell’unità di misura appropriata.

6.9 Ordine di precedenza degli operatori

Le operazioni algebriche vengono eseguite in una particolare sequenza in R, nota come ordine di precedenza degli operatori. Questo ordine determina quali operazioni vengono eseguite per prime quando un’espressione include più operatori. In assenza di parentesi, l’ordine di precedenza è il seguente (dal più alto al più basso):

  1. Parentesi: Le operazioni racchiuse tra parentesi () vengono eseguite per prime. Questo permette di sovrascrivere l’ordine naturale delle operazioni.

    result <- (2 + 3) * 4  # Risultato: 20
  2. Esponenziazione: L’operatore ^ viene eseguito dopo le parentesi.

    result <- 2^3  # Risultato: 8
  3. Segni unari: Il segno meno - o più + applicato a un singolo valore.

    result <- -3 + 5  # Risultato: 2
  4. Moltiplicazione, divisione e modulo: Gli operatori *, /, %/% (divisione intera) e %% (resto) hanno la stessa precedenza e vengono eseguiti da sinistra a destra.

    result <- 10 / 2 * 3  # Risultato: 15
    result <- 10 %% 3     # Risultato: 1
  5. Addizione e sottrazione: Gli operatori + e - vengono eseguiti dopo quelli di moltiplicazione/divisione.

    result <- 5 + 3 - 2  # Risultato: 6
  6. Operatori di assegnazione: Gli operatori <-, ->, =, che assegnano valori a variabili, vengono valutati per ultimi.

    x <- 2 + 3 * 4  # Risultato: 14

Note importanti:

  • Associazione a sinistra: La maggior parte degli operatori in R viene valutata da sinistra a destra (ad esempio, +, *, /).
  • Uso delle parentesi: Quando l’ordine di precedenza non è immediatamente chiaro o si vuole assicurare un ordine specifico, è sempre buona pratica usare le parentesi.

Capire l’ordine di precedenza è fondamentale per evitare errori logici e garantire che il codice funzioni come previsto.

6.10 Funzioni

Fino ad ora abbiamo creato oggetti semplici assegnando loro direttamente un valore. Con l’aumento dell’esperienza in R, potresti voler creare oggetti più complessi. Per aiutarti, R offre numerose funzioni già disponibili nella sua installazione di base, e altre possono essere aggiunte installando pacchetti. Una funzione è un insieme di istruzioni che eseguono un compito specifico. Inoltre, è possibile creare funzioni personalizzate.

6.10.1 La funzione c() per creare vettori

La prima funzione utile da imparare è c(), che serve a concatenare valori in un vettore. Ad esempio:

my_vec <- c(2, 3, 1, 6, 4, 3, 3, 7)

Questo codice crea un oggetto chiamato my_vec che contiene una sequenza di numeri. Alcuni concetti fondamentali sulle funzioni in R:

  1. Nome e parentesi: Le funzioni in R sono sempre seguite da parentesi tonde ().
  2. Argomenti: Gli elementi passati alla funzione (tra le parentesi) ne personalizzano il comportamento e sono separati da virgole.

Per vedere il contenuto del vettore:

my_vec
#> [1] 2 3 1 6 4 3 3 7

6.10.2 Funzioni per analizzare vettori

Puoi utilizzare altre funzioni per calcolare statistiche sul vettore:

mean(my_vec)    # Media
#> [1] 3.625
var(my_vec)     # Varianza
#> [1] 3.982
sd(my_vec)      # Deviazione standard
#> [1] 1.996
length(my_vec)  # Numero di elementi
#> [1] 8

Puoi anche salvare i risultati in nuovi oggetti per riutilizzarli:

vec_mean <- mean(my_vec)
vec_mean
#> [1] 3.625

La varianza e la deviazione standard sono misure statistiche descrittive che sintetizzano in un unico valore numerico la variabilità di un insieme di dati. Questi indici, che verranno approfonditi nel Capitolo 19, forniscono informazioni su quanto i valori di un dataset siano simili o diversi tra loro.

In particolare:

  • la varianza e la deviazione standard sono pari a 0 quando tutti i valori nel dataset sono identici, indicando assenza di variabilità;
  • assumono valori più elevati all’aumentare delle differenze tra i dati, segnalando una maggiore dispersione.

Per i nostri scopi attuali, è sufficiente comprendere che queste misure descrivono il grado di diversità o omogeneità dei dati.

6.10.3 Creare sequenze regolari

Per creare sequenze di numeri in passi regolari, puoi usare i seguenti comandi.

Simbolo : per sequenze semplici:

my_seq <- 1:10
my_seq
#>  [1]  1  2  3  4  5  6  7  8  9 10

Funzione seq() per maggiore controllo:

my_seq2 <- seq(from = 1, to = 5, by = 0.5)
my_seq2
#> [1] 1.0 1.5 2.0 2.5 3.0 3.5 4.0 4.5 5.0

6.10.4 Ripetere valori

Puoi ripetere valori o sequenze con la funzione rep().

Ripetere un valore:

my_seq3 <- rep(2, times = 10)
my_seq3
#>  [1] 2 2 2 2 2 2 2 2 2 2

Ripetere una sequenza:

my_seq5 <- rep(1:5, times = 3)

Ripetere ogni elemento di una sequenza:

my_seq6 <- rep(1:5, each = 3)
my_seq6
#>  [1] 1 1 1 2 2 2 3 3 3 4 4 4 5 5 5

6.10.5 Annidare funzioni

È possibile combinare funzioni per creare comandi più complessi, come nell’esempio:

my_seq7 <- rep(c(3, 1, 10, 7), each = 3)
my_seq7
#>  [1]  3  3  3  1  1  1 10 10 10  7  7  7

Per maggiore leggibilità, puoi separare i passaggi:

in_vec <- c(3, 1, 10, 7)
my_seq7 <- rep(in_vec, each = 3)
my_seq7
#>  [1]  3  3  3  1  1  1 10 10 10  7  7  7

Questa pratica facilita la comprensione del codice e lo rende più chiaro.

6.11 Lavorare con i Vettori in R

In R, i vettori sono uno degli elementi fondamentali per manipolare, riassumere e ordinare i dati. Qui trovi una panoramica su come estrarre, sostituire, ordinare, lavorare con dati mancanti e sfruttare la vettorizzazione dei vettori.

6.11.1 Estrarre elementi da un vettore

Puoi estrarre uno o più elementi da un vettore usando le parentesi quadre [ ].

Per posizione: Specifica la posizione degli elementi.

my_vec <- c(2, 3, 1, 6, 4, 3, 3, 7)
my_vec[3]  # Terzo elemento
#> [1] 1
my_vec[c(1, 5, 6)]  # Elementi 1°, 5° e 6°
#> [1] 2 4 3
my_vec[3:8]  # Da 3° a 8°
#> [1] 1 6 4 3 3 7

Con condizioni logiche: Usa espressioni logiche per selezionare elementi.

my_vec[my_vec > 4]  # Elementi > 4
#> [1] 6 7
my_vec[my_vec <= 4]  # Elementi ≤ 4
#> [1] 2 3 1 4 3 3
my_vec[my_vec != 4]  # Elementi diversi da 4
#> [1] 2 3 1 6 3 3 7

Operatori logici: Combina condizioni con & (AND) e | (OR).

my_vec[my_vec > 2 & my_vec < 6]  # Tra 2 e 6
#> [1] 3 4 3 3

6.11.2 Sostituire Elementi in un Vettore

Puoi modificare i valori di un vettore usando [ ] e l’operatore <-.

Un singolo elemento:

my_vec[4] <- 500  # Cambia il 4° elemento
my_vec
#> [1]   2   3   1 500   4   3   3   7

Più elementi:

my_vec[c(6, 7)] <- 100  # Cambia il 6° e 7° elemento
my_vec
#> [1]   2   3   1 500   4 100 100   7

Con condizioni logiche:

my_vec[my_vec <= 4] <- 1000  # Cambia valori ≤ 4
my_vec
#> [1] 1000 1000 1000  500 1000  100  100    7

6.11.3 Ordinare un Vettore

Dal più piccolo al più grande:

vec_sort <- sort(my_vec)
vec_sort
#> [1]    7  100  100  500 1000 1000 1000 1000

Dal più grande al più piccolo:

vec_sort2 <- sort(my_vec, decreasing = TRUE)
vec_sort2
#> [1] 1000 1000 1000 1000  500  100  100    7

Ordinare un vettore in base a un altro:

height <- c(180, 155, 160, 167, 181)
p.names <- c("Joanna", "Charlotte", "Helen", "Karen", "Amy")
height_ord <- order(height)
names_ord <- p.names[height_ord]
names_ord
#> [1] "Charlotte" "Helen"     "Karen"     "Joanna"    "Amy"

6.12 Operazioni Vettoriali e Vettorizzazione in R

La vettorializzazione è una delle caratteristiche più potenti di R, che consente di applicare operazioni o funzioni direttamente a tutti gli elementi di un vettore in modo simultaneo, senza dover ricorrere a cicli espliciti. Questo approccio rende il codice più conciso, leggibile ed efficiente, sfruttando al meglio le capacità intrinseche del linguaggio.

6.12.1 Operazioni Aritmetiche su Vettori

Le operazioni algebriche in R, come addizione, sottrazione, moltiplicazione e divisione, sono vettorizzate. Questo significa che ogni operazione viene applicata “elemento per elemento” al vettore.

Consideriamo ad esempio il seguente vettore:

my_vec <- c(3, 5, 7, 1, 9, 20)

Se vogliamo moltiplicare ciascun elemento di my_vec per 5, possiamo scrivere:

my_vec * 5
#> [1]  15  25  35   5  45 100

Analogamente, possiamo effettuare altre operazioni algebriche, come divisione o elevamento a potenza:

my_vec / 2
#> [1]  1.5  2.5  3.5  0.5  4.5 10.0
my_vec^2
#> [1]   9  25  49   1  81 400

Queste operazioni vengono applicate automaticamente a ciascun elemento del vettore, senza dover iterare su di essi.

6.12.2 Operazioni Elemento per Elemento tra Due Vettori

La vettorializzazione consente anche di eseguire operazioni tra due vettori, applicandole elemento per elemento. Supponiamo di avere un secondo vettore:

my_vec2 <- c(17, 15, 13, 19, 11, 0)

Se vogliamo sommare i due vettori, possiamo scrivere:

my_vec + my_vec2
#> [1] 20 20 20 20 20 20

In questo caso, il primo elemento di my_vec viene sommato al primo elemento di my_vec2, il secondo elemento al secondo, e così via.

Esempio 6.3 Di seguito mostriamo come calcolare i punteggi totali per 10 individui che hanno risposto ai 5 item della Satisfaction With Life Scale (SWLS), utilizzando le formule e l’aritmetica vettorializzata di R.

Step 1: Definiamo i punteggi per ciascun item. Ogni vettore contiene i punteggi dati dai 10 individui a uno specifico item della scala:

# Punteggi dei 10 individui per ciascun item
item1 <- c(5, 4, 6, 7, 3, 2, 5, 6, 4, 7)
item2 <- c(3, 2, 4, 6, 2, 1, 4, 5, 3, 6)
item3 <- c(4, 5, 6, 5, 3, 2, 5, 7, 4, 5)
item4 <- c(2, 3, 4, 3, 2, 1, 3, 4, 2, 5)
item5 <- c(2, 2, 3, 4, 1, 1, 3, 3, 2, 4)

I valori 5, 3, 4, 2, 2 sono i punteggi del primo individuo sui 5 item; i punteggio 4, 2, 5, 3, 2 sono i punteggi del secondo individuo sui 5 item, e così via.

Step 2: Sommiamo i punteggi per calcolare il totale. Il punteggio totale di ciascun individuo è la somma dei punteggi relativi ai 5 item. Formalmente, per l’individuo \(i\) (\(i = 1, 2, \ldots, 10\)), il punteggio totale è calcolato come:

\[ \text{PunteggioTotale}_i = \text{item1}_i + \text{item2}_i + \text{item3}_i + \text{item4}_i + \text{item5}_i . \]

In R, possiamo sommare i vettori direttamente grazie all’aritmetica vettorializzata:

# Calcolo dei punteggi totali per ciascun individuo
total_scores <- item1 + item2 + item3 + item4 + item5
total_scores
#>  [1] 16 16 23 25 11  7 20 25 15 27

Il risultato è un vettore con i punteggi totali per ciascun individuo.

Step 3: Mostriamo i risultati. Per organizzare meglio i dati, creiamo una tabella che associa i punteggi totali agli individui:

# Creiamo una tabella con i punteggi totali
individui <- paste("Individuo", 1:10)
risultati_swls <- data.frame(Individuo = individui, PunteggioTotale = total_scores)
print(risultati_swls)
#>       Individuo PunteggioTotale
#> 1   Individuo 1              16
#> 2   Individuo 2              16
#> 3   Individuo 3              23
#> 4   Individuo 4              25
#> 5   Individuo 5              11
#> 6   Individuo 6               7
#> 7   Individuo 7              20
#> 8   Individuo 8              25
#> 9   Individuo 9              15
#> 10 Individuo 10              27

Spiegazione delle operazioni:

  1. Ogni vettore contiene i punteggi di 10 individui per un dato item. Ad esempio, il vettore item1 contiene i punteggi relativi al primo item, e così via.

  2. Grazie all’aritmetica vettorializzata, quando sommiamo i vettori \(\text{item1}\), \(\text{item2}\), \(\text{item3}\), \(\text{item4}\), \(\text{item5}\), R somma elemento per elemento:

    \[ \text{total\_scores}_i = \text{item1}_i + \text{item2}_i + \text{item3}_i + \text{item4}_i + \text{item5}_i \]

  3. Questa tecnica consente di calcolare rapidamente i punteggi totali per tutti gli individui senza dover scrivere un ciclo esplicito, rendendo il codice più semplice e leggibile.

Questo esempio illustra come R semplifichi operazioni complesse grazie al calcolo vettorializzato, migliorando l’efficienza e la chiarezza del codice.

6.12.3 Attenzione al Riciclo dei Vettori

Se i due vettori hanno lunghezze diverse, R applicherà il meccanismo di riciclo: gli elementi del vettore più corto verranno ripetuti ciclicamente per abbinarsi alla lunghezza del vettore più lungo. Questo comportamento, sebbene utile, richiede attenzione per evitare risultati inattesi.

Ad esempio:

short_vec <- c(1, 2)
my_vec + short_vec
#> [1]  4  7  8  3 10 22

In questo caso, gli elementi di short_vec vengono riciclati per abbinarsi alla lunghezza di my_vec. Il risultato è:

(3+1, 5+2, 7+1, 1+2, 9+1, 20+2)

6.12.4 Applicazione di Funzioni su Vettori

La vettorializzazione non si limita alle operazioni algebriche, ma si estende anche all’uso di funzioni. Supponiamo di voler calcolare il logaritmo naturale di ciascun elemento di un vettore:

log(my_vec)
#> [1] 1.099 1.609 1.946 0.000 2.197 2.996

La funzione log() viene applicata automaticamente a ogni elemento del vettore. Analogamente, possiamo utilizzare altre funzioni predefinite di R, come:

sqrt(my_vec)  # Calcola la radice quadrata di ciascun elemento
#> [1] 1.732 2.236 2.646 1.000 3.000 4.472
exp(my_vec)   # Eleva e alla potenza specificata da ciascun elemento
#> [1] 2.009e+01 1.484e+02 1.097e+03 2.718e+00 8.103e+03 4.852e+08

In conclusione, la vettorializzazione in R rappresenta un approccio elegante ed efficiente per gestire calcoli su vettori. Che si tratti di operazioni algebriche, operazioni tra vettori o applicazione di funzioni, la possibilità di evitare cicli espliciti migliora la leggibilità e la velocità del codice. Tuttavia, è importante prestare attenzione al riciclo dei vettori per evitare errori non intenzionali.

6.13 Gestire Dati Mancanti (NA)

R rappresenta i dati mancanti con NA. La gestione dei dati mancanti dipende dalla funzione utilizzata.

Calcolo con dati mancanti:

temp <- c(7.2, NA, 7.1, 6.9, 6.5, 5.8, 5.8, 5.5, NA, 5.5)
mean(temp)  # Restituisce NA
#> [1] NA
mean(temp, na.rm = TRUE)  # Ignora i valori mancanti
#> [1] 6.287

Nota: na.rm = TRUE è un argomento comune per ignorare i NA, ma non tutte le funzioni lo supportano. Consulta la documentazione della funzione per verificare come gestisce i dati mancanti.

In conclusione, manipolare vettori è un’abilità essenziale in R. Dalla selezione e modifica degli elementi all’ordinamento e gestione di dati mancanti, queste tecniche sono alla base dell’analisi dei dati in R.

6.14 I Dati in R

In R, i dati possono essere rappresentati in diversi tipi e strutture. Comprendere come gestirli è fondamentale per manipolare, analizzare e riassumere i dataset più complessi.

6.14.1 Tipi di Dati in R

R supporta diversi tipi di dati:

  1. Numeric: Numeri decimali (es. 2.5).
  2. Integer: Numeri interi (es. 3).
  3. Logical: Valori booleani (TRUE o FALSE) e NA per dati mancanti.
  4. Character: Stringhe di testo (es. "hello").
  5. Factor: Variabili categoriche (es. livelli come "low", "medium", "high").

Puoi verificare il tipo di un oggetto con class() e controllare se appartiene a un tipo specifico con funzioni come is.numeric(). È anche possibile convertire un tipo in un altro con funzioni come as.character().

6.14.2 Strutture di Dati in R

Vettori: Contengono dati dello stesso tipo (es. numeri, stringhe o logici).

my_vec <- c(1, 2, 3)
my_vec
#> [1] 1 2 3

Matrici e array: Strutture bidimensionali (matrici) o multidimensionali (array) con dati dello stesso tipo.

Creare una matrice:

my_mat <- matrix(1:12, nrow = 3, byrow = TRUE)
my_mat
#>      [,1] [,2] [,3] [,4]
#> [1,]    1    2    3    4
#> [2,]    5    6    7    8
#> [3,]    9   10   11   12

Operazioni utili:

  • Trasposizione: t(my_mat)
  • Diagonale: diag(my_mat)
  • Moltiplicazione matriciale: mat1 %*% mat2

Liste: Possono contenere elementi di tipi diversi, inclusi vettori, matrici o altre liste.

my_list <- list(
  numbers = c(1, 2), 
  text = "hello", 
  mat = matrix(1:4, nrow = 2)
)
my_list$numbers  # Accedi agli elementi con il nome
#> [1] 1 2

Data frame: Strutture bidimensionali che possono contenere colonne di tipi diversi. Ideale per dataset strutturati.

Creare un data frame:

height <- c(180, 155, 160)
weight <- c(65, 50, 52)
names <- c("Joanna", "Charlotte", "Helen")

dataf <- data.frame(height = height, weight = weight, names = names)
str(dataf)  # Mostra la struttura del data frame
#> 'data.frame':    3 obs. of  3 variables:
#>  $ height: num  180 155 160
#>  $ weight: num  65 50 52
#>  $ names : chr  "Joanna" "Charlotte" "Helen"

Per convertire le stringhe in fattori durante la creazione:

dataf <- data.frame(
  height = height, 
  weight = weight, 
  names = names, 
  stringsAsFactors = TRUE
)

dataf
#>   height weight     names
#> 1    180     65    Joanna
#> 2    155     50 Charlotte
#> 3    160     52     Helen

6.14.3 Operazioni Utili sui Data Frame

  • Verificare dimensioni: dim(dataf)
  • Visualizzare struttura: str(dataf)
  • Accedere a colonne: dataf$height

6.15 Operazioni di Base in R

6.15.1 Operazioni Aritmetiche

Come abbiamo visto in precedenza, R supporta le classiche operazioni aritmetiche come somma (+), sottrazione (-), moltiplicazione (*), divisione (/) ed esponenziazione (^).

6.15.2 Operazioni Logiche

Le operazioni logiche in R includono:

  • &: “and” logico
  • |: “or” logico
  • !: “not” logico
  • >: maggiore di
  • <: minore di
  • ==: uguale a
  • !=: diverso da

Per esempio:

# Maggiore di
3 > 2
#> [1] TRUE
# Uguale a
3 == 2
#> [1] FALSE

Esempio 6.4 Consideriamo l’esempio precedente, in cui abbiamo calcolato i punteggi totali dei 10 individui sulla Satisfaction With Life Scale (SWLS). Ora vogliamo determinare la proporzione di individui nel campione che ha ottenuto un punteggio totale maggiore di 15.

I punteggi totali dei 10 individui sono memorizzati nella colonna PunteggioTotale del data frame risultati_swls:

risultati_swls$PunteggioTotale
#>  [1] 16 16 23 25 11  7 20 25 15 27

Possiamo creare un vettore logico che indica, per ciascun individuo, se il suo punteggio totale supera 15. In R, l’operatore di confronto > restituisce un valore TRUE se la condizione è soddisfatta e FALSE altrimenti:

risultati_swls$PunteggioTotale > 15
#>  [1]  TRUE  TRUE  TRUE  TRUE FALSE FALSE  TRUE  TRUE FALSE  TRUE

In R, i valori TRUE e FALSE possono essere trattati come numeri: TRUE equivale a 1 e FALSE equivale a 0. Questo ci permette di sommare i valori logici per contare quante volte la condizione è soddisfatta. Per calcolare la proporzione, dividiamo questa somma per il numero totale di individui:

sum(risultati_swls$PunteggioTotale > 15) / length(risultati_swls$PunteggioTotale)
#> [1] 0.7

La proporzione è calcolata come:

\[ \text{Proporzione} = \frac{\sum_{i=1}^{n} I(\text{PunteggioTotale}_i > 15)}{n} , \]

dove:

  • \(n\) è il numero totale di individui (in questo caso, 10),
  • \(I(\text{PunteggioTotale}_i > 15)\) è una funzione indicatrice che vale 1 se il punteggio dell’individuo \(i\) è maggiore di 15, e 0 altrimenti.

Nel nostro esempio, la proporzione degli individui con punteggio totale maggiore di 15 è 0.7, cioè il 70% del campione soddisfa questa condizione.

6.16 Estrazione di Sottoinsiemi di Oggetti in R

In R esistono tre operatori principali per estrarre sottoinsiemi di oggetti:

  1. Operatore [ ]
    Questo operatore restituisce sempre un oggetto della stessa classe dell’originale. È utile per selezionare più elementi da un oggetto. È importante chiudere l’estrazione con ].

  2. Operatore [[ ]]
    Questo operatore viene utilizzato per estrarre elementi da liste o data frame. A differenza di [ ], permette di estrarre un solo elemento alla volta e la classe dell’oggetto restituito non sarà necessariamente una lista o un data frame. L’estrazione va chiusa con ]].

  3. Operatore $
    Come visto in precedenza, questo operatore serve per estrarre elementi da una lista o un data frame utilizzando il loro nome letterale. Il comportamento semantico è simile a quello di [[ ]].

6.16.1 Gli Indici di un Data Frame in R

In R, gli indici di un data frame sono utilizzati per selezionare righe e colonne. La sintassi generale è:

df[i, j]

dove:

  • i rappresenta l’indice o gli indici delle righe,
  • j rappresenta l’indice o gli indici delle colonne.

Se uno degli indici viene omesso, si considerano tutte le righe o tutte le colonne, a seconda della dimensione omessa.

6.16.1.1 Esempi Pratici

  1. Selezione di righe specifiche su tutte le colonne
    Se vogliamo estrarre solo alcune righe, possiamo specificare gli indici delle righe nel primo argomento e lasciare vuoto il secondo. Ad esempio:

    df[c(2, 3, 5), ]

    Questo seleziona la seconda, terza e quinta riga del data frame df, includendo tutte le colonne.

  2. Selezione di colonne specifiche su tutte le righe
    Per selezionare solo alcune colonne, specifichiamo i loro indici nel secondo argomento e lasciamo vuoto il primo. Ad esempio:

    df[, c(2, 3, 5)]

    Questo seleziona la seconda, terza e quinta colonna del data frame df, includendo tutte le righe.

  3. Selezione di righe e colonne specifiche
    Possiamo combinare gli indici per selezionare una sotto-matrice specifica. Ad esempio:

    df[c(2, 4), c(1, 3)]

    Questo seleziona le righe 2 e 4 e le colonne 1 e 3.

6.16.1.2 Ulteriori Dettagli

  • Selezione singola di riga o colonna
    Se vogliamo estrarre una singola riga o colonna, possiamo specificare un solo valore per i o j. Ad esempio:

    df[1, ]  # Prima riga, tutte le colonne
    df[, 2]  # Seconda colonna, tutte le righe
  • Uso di nomi invece di indici
    Se il data frame ha nomi per righe o colonne, possiamo utilizzarli per la selezione. Ad esempio:

    df["nome_riga", ]        # Seleziona la riga con nome "nome_riga"
    df[, "nome_colonna"]     # Seleziona la colonna con nome "nome_colonna"
  • Selezione logica
    Possiamo utilizzare un vettore logico per selezionare righe o colonne. Ad esempio, per selezionare le righe dove il valore nella prima colonna è maggiore di 10:

    df[df[, 1] > 10, ]

6.16.1.3 Sintesi Visiva

Sintassi Descrizione
df[i, ] Seleziona la riga i con tutte le colonne.
df[, j] Seleziona la colonna j con tutte le righe.
df[c(i1, i2), c(j1, j2)] Seleziona righe e colonne specifiche.
df[i, j] Seleziona l’intersezione di righe e colonne.
df[ , ] Restituisce l’intero data frame.

Questa flessibilità rende l’indicizzazione dei data frame in R potente ed efficace per manipolare e analizzare i dati.

Esempio 6.5 Consideriamo il data frame iris incluso di default in base R.

iris |> head()
#>   Sepal.Length Sepal.Width Petal.Length Petal.Width Species
#> 1          5.1         3.5          1.4         0.2  setosa
#> 2          4.9         3.0          1.4         0.2  setosa
#> 3          4.7         3.2          1.3         0.2  setosa
#> 4          4.6         3.1          1.5         0.2  setosa
#> 5          5.0         3.6          1.4         0.2  setosa
#> 6          5.4         3.9          1.7         0.4  setosa

Usiamo la funzione head() per stampare le prime 6 righe del data frame.

L’istruzione seguente restituisce le prime tre colonne del dataset iris.

iris[, 1:3] |> head()
#>   Sepal.Length Sepal.Width Petal.Length
#> 1          5.1         3.5          1.4
#> 2          4.9         3.0          1.4
#> 3          4.7         3.2          1.3
#> 4          4.6         3.1          1.5
#> 5          5.0         3.6          1.4
#> 6          5.4         3.9          1.7

Selezione di colonne specifiche per nome:

iris[, c('Sepal.Length', 'Petal.Length')] |> 
  head()  
#>   Sepal.Length Petal.Length
#> 1          5.1          1.4
#> 2          4.9          1.4
#> 3          4.7          1.3
#> 4          4.6          1.5
#> 5          5.0          1.4
#> 6          5.4          1.7

Selezione di una singola colonna:

iris[, 'Petal.Length'] 
#>   [1] 1.4 1.4 1.3 1.5 1.4 1.7 1.4 1.5 1.4 1.5 1.5 1.6 1.4 1.1 1.2 1.5 1.3
#>  [18] 1.4 1.7 1.5 1.7 1.5 1.0 1.7 1.9 1.6 1.6 1.5 1.4 1.6 1.6 1.5 1.5 1.4
#>  [35] 1.5 1.2 1.3 1.4 1.3 1.5 1.3 1.3 1.3 1.6 1.9 1.4 1.6 1.4 1.5 1.4 4.7
#>  [52] 4.5 4.9 4.0 4.6 4.5 4.7 3.3 4.6 3.9 3.5 4.2 4.0 4.7 3.6 4.4 4.5 4.1
#>  [69] 4.5 3.9 4.8 4.0 4.9 4.7 4.3 4.4 4.8 5.0 4.5 3.5 3.8 3.7 3.9 5.1 4.5
#>  [86] 4.5 4.7 4.4 4.1 4.0 4.4 4.6 4.0 3.3 4.2 4.2 4.2 4.3 3.0 4.1 6.0 5.1
#> [103] 5.9 5.6 5.8 6.6 4.5 6.3 5.8 6.1 5.1 5.3 5.5 5.0 5.1 5.3 5.5 6.7 6.9
#> [120] 5.0 5.7 4.9 6.7 4.9 5.7 6.0 4.8 4.9 5.6 5.8 6.1 6.4 5.6 5.1 5.6 6.1
#> [137] 5.6 5.5 4.8 5.4 5.6 5.1 5.1 5.9 5.7 5.2 5.0 5.2 5.4 5.1

oppure

iris$Petal.Length
#>   [1] 1.4 1.4 1.3 1.5 1.4 1.7 1.4 1.5 1.4 1.5 1.5 1.6 1.4 1.1 1.2 1.5 1.3
#>  [18] 1.4 1.7 1.5 1.7 1.5 1.0 1.7 1.9 1.6 1.6 1.5 1.4 1.6 1.6 1.5 1.5 1.4
#>  [35] 1.5 1.2 1.3 1.4 1.3 1.5 1.3 1.3 1.3 1.6 1.9 1.4 1.6 1.4 1.5 1.4 4.7
#>  [52] 4.5 4.9 4.0 4.6 4.5 4.7 3.3 4.6 3.9 3.5 4.2 4.0 4.7 3.6 4.4 4.5 4.1
#>  [69] 4.5 3.9 4.8 4.0 4.9 4.7 4.3 4.4 4.8 5.0 4.5 3.5 3.8 3.7 3.9 5.1 4.5
#>  [86] 4.5 4.7 4.4 4.1 4.0 4.4 4.6 4.0 3.3 4.2 4.2 4.2 4.3 3.0 4.1 6.0 5.1
#> [103] 5.9 5.6 5.8 6.6 4.5 6.3 5.8 6.1 5.1 5.3 5.5 5.0 5.1 5.3 5.5 6.7 6.9
#> [120] 5.0 5.7 4.9 6.7 4.9 5.7 6.0 4.8 4.9 5.6 5.8 6.1 6.4 5.6 5.1 5.6 6.1
#> [137] 5.6 5.5 4.8 5.4 5.6 5.1 5.1 5.9 5.7 5.2 5.0 5.2 5.4 5.1

Per selezionare righe specifiche, definiamo gli indici corrispondenti. Per esempio, l’istruzione seguente restituisce le righe 1 e 3.

iris[c(1, 3), ]
#>   Sepal.Length Sepal.Width Petal.Length Petal.Width Species
#> 1          5.1         3.5          1.4         0.2  setosa
#> 3          4.7         3.2          1.3         0.2  setosa

Filtraggio logico di righe:

iris[iris$Species == 'versicolor', ] |> head()
#>    Sepal.Length Sepal.Width Petal.Length Petal.Width    Species
#> 51          7.0         3.2          4.7         1.4 versicolor
#> 52          6.4         3.2          4.5         1.5 versicolor
#> 53          6.9         3.1          4.9         1.5 versicolor
#> 54          5.5         2.3          4.0         1.3 versicolor
#> 55          6.5         2.8          4.6         1.5 versicolor
#> 56          5.7         2.8          4.5         1.3 versicolor

Restituisce le righe con Species uguale a “versicolor”. Numero di righe e colonne del sottoinsieme:

dim(iris[iris$Species == 'versicolor', ])
#> [1] 50  5

6.16.2 Filtraggio Avanzato con Operatori Logici

Gli operatori logici & (AND), | (OR) e ! (NOT) permettono un filtraggio più sofisticato.

Esempio: Filtrare le osservazioni di specie “versicolor” con lunghezza del sepalo non superiore a 5.0:

iris[(iris$Species == 'versicolor') & (iris$Sepal.Length <= 5.0), ]
#>    Sepal.Length Sepal.Width Petal.Length Petal.Width    Species
#> 58          4.9         2.4          3.3           1 versicolor
#> 61          5.0         2.0          3.5           1 versicolor
#> 94          5.0         2.3          3.3           1 versicolor

Numero di osservazioni trovate:

dim(iris[(iris$Species == 'versicolor') & (iris$Sepal.Length <= 5.0), ])
#> [1] 3 5

6.17 Riflessioni Conclusive

R non è soltanto un linguaggio di programmazione per la statistica, ma rappresenta una filosofia che si fonda su tre principi chiave: apertura, collaborazione e avanzamento della conoscenza scientifica.

Per chi si avvicina a R, sia nel campo della comunicazione sia in altri ambiti, cogliere questa filosofia è essenziale per apprezzarne appieno il valore. R promuove non solo competenze tecniche, ma anche un impegno verso pratiche di ricerca trasparente e riproducibile, che costituiscono un pilastro fondamentale per una scienza rigorosa e affidabile.

Open Source
R è un software open source, liberamente accessibile a tutti. Questo significa che chiunque può visualizzarne, modificarne e distribuirne il codice sorgente, promuovendo un ambiente trasparente e collaborativo. Essendo gratuito, R garantisce accessibilità a ricercatori di tutto il mondo, indipendentemente dal budget o dal supporto istituzionale. Inoltre, grazie alla sua natura aperta, R beneficia del contributo collettivo di una comunità globale eterogenea.

Contributi della Comunità
La comunità di R è uno dei suoi punti di forza principali. Statistici, ricercatori e data scientist di diverse discipline arricchiscono continuamente R sviluppando pacchetti: raccolte di funzioni, dati e codice che ampliano le sue funzionalità. Questa collaborazione ha portato alla creazione di migliaia di pacchetti che coprono tecniche statistiche, metodi grafici e strumenti per la manipolazione dei dati, rendendo R uno strumento sempre più versatile e adatto a un’ampia gamma di esigenze di ricerca.

Ricerca Riproducibile
La ricerca riproducibile consiste nel condurre studi in modo tale che altri possano replicarne i risultati utilizzando gli stessi dati e seguendo la stessa metodologia. Questo approccio è cruciale per la validazione delle scoperte scientifiche, permettendo la verifica dei risultati e la costruzione di nuove conoscenze su basi solide.

R facilita la ricerca riproducibile grazie a:

  • Un ecosistema completo di pacchetti per l’analisi dei dati e la generazione di report dinamici.
  • Strumenti come R Markdown e Quarto, che permettono di integrare testo descrittivo e codice R in un unico documento. Questa integrazione consente di documentare ogni fase del processo di ricerca—dalla pulizia dei dati all’analisi e alla presentazione dei risultati—garantendo trasparenza e replicabilità.

In conclusione, comprendere la filosofia open source di R e il suo ruolo nella promozione della ricerca riproducibile fornisce un quadro chiaro del motivo per cui R è diventato uno strumento essenziale per ricercatori e statistici di diverse discipline. Per chi opera in psicologia, sfruttare le potenzialità di R significa produrre risultati di ricerca più trasparenti, replicabili e credibili, contribuendo alla robustezza e affidabilità della conoscenza scientifica nel settore.

Esercizi

Svolgere gli esercizi da 1 a 38, sia in modo manuale che utilizzando R. Gli esercizi sono disponibili al seguente link:
Esercizi su Summation Notation.

In questo esercizio, lavorerai con i dati della Satisfaction With Life Scale (SWLS) raccolti da ciascuno degli studenti del gruppo TPV di appartenenza.

Istruzioni SWLS: Di seguito sono riportate alcune affermazioni con cui puoi descrivere la tua soddisfazione rispetto alla tua vita. Indica quanto sei d’accordo con ciascuna affermazione utilizzando la scala di risposta fornita.

  • Il più delle volte la mia vita è vicina al mio ideale di vita.
  • Le condizioni della mia vita sono eccellenti.
  • Sono soddisfatto/a della mia vita.
  • Finora ho ottenuto le cose importanti che voglio dalla vita.
  • Se io potessi rivivere la mia vita, non cambierei quasi nulla.

La SWLS utilizza una scala Likert a 7 punti, con i seguenti ancoraggi:

  1. Fortemente in disaccordo
  2. Disaccordo
  3. Leggermente in disaccordo
  4. Né d’accordo né in disaccordo
  5. Leggermente d’accordo
  6. D’accordo
  7. Fortemente d’accordo

Il tuo compito sarà analizzare i dati raccolti sia manualmente su carta che utilizzando R.

Parte 1: Calcolo Manuale

  1. Calcolo del punteggio totale

    • La SWLS è composta da 5 item, ciascuno valutato su una scala Likert da 1 a 7.
    • Somma i punteggi dei 5 item per ciascun partecipante per ottenere il punteggio totale.
    • Registra i punteggi totali su carta.
  2. Determinazione della media del campione

    • Calcola la media aritmetica dei punteggi totali dei 10 studenti.
    • Scrivi il calcolo e il risultato.
  3. Calcolo della deviazione standard

    • Calcola la deviazione standard dei punteggi totali manualmente utilizzando la formula:

      \[ s^2 = \sqrt{\frac{\sum_{i=1}^n (x_i - \bar{x})^2}{n-1}}. \]

    • Registra il risultato.

Parte 2: Analisi con R

  1. Creazione del dataset in R

    • Inserisci i dati in R come un vettore chiamato swls_scores.
  2. Calcolo della media e della deviazione standard in R

    • Usa le funzioni mean() e sd() per ottenere la media e la deviazione standard dei punteggi totali.
  3. Visualizzazione dei dati

    • Crea un istogramma per visualizzare la distribuzione dei punteggi totali utilizzando hist(). Se non conosci l’istogramma, fai una ricerca su web; commenta il risultato ottenuto.
  4. Identificazione dei punteggi superiori a 20

    • Utilizza un’operazione logica per contare quanti partecipanti hanno un punteggio totale maggiore di 20.
  5. Filtraggio dei dati

    • Estrai e visualizza solo i punteggi superiori alla media del campione.
  6. Esportazione dei risultati

    • Salva i punteggi totali in un file CSV utilizzando la funzione write.csv().

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: Calcolo Manuale

  1. Calcolo del punteggio totale
    • Supponiamo che i punteggi per 10 studenti siano:

      Studente Item 1 Item 2 Item 3 Item 4 Item 5 Totale
      1 5 4 6 3 2 20
      2 4 2 5 3 2 16
      3 6 4 6 4 3 23
      4 7 6 5 3 4 25
      5 3 2 3 2 1 11
      6 2 1 2 1 1 7
      7 5 4 5 3 3 20
      8 6 5 7 4 3 25
      9 4 3 4 2 2 15
      10 7 6 5 5 4 27
  2. Determinazione della media
    • Media:

      \[ \bar{x} = \frac{20+16+23+25+11+7+20+25+15+27}{10} = 18.9 \]

  3. Calcolo della deviazione standard
    • La deviazione standard è:

      \[ s = \sqrt{\frac{1}{9} \sum (x_i - 18.9)^2} \approx 6.56 \]

Parte 2: Analisi con R

  1. Creazione del dataset in R

    swls_scores <- c(20, 16, 23, 25, 11, 7, 20, 25, 15, 27)
  2. Calcolo della media e della deviazione standard

    mean(swls_scores)  # Media
    sd(swls_scores)    # Deviazione standard
  3. Visualizzazione dei dati

    hist(swls_scores, main="Distribuzione SWLS", xlab="Punteggi", col="lightblue", border="black")
  4. Identificazione dei punteggi superiori a 20

    sum(swls_scores > 20)  # Numero di studenti con punteggio > 20
  5. Filtraggio dei dati

    swls_scores[swls_scores > mean(swls_scores)]
  6. Esportazione dei risultati

    write.csv(data.frame(Student=1:10, Score=swls_scores), "swls_results.csv", row.names=FALSE)

Conclusione Questi esercizi hanno permesso di confrontare il calcolo manuale con l’automatizzazione tramite R, facilitando l’analisi statistica della SWLS.

Informazioni sull’Ambiente di Sviluppo

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     rprojroot_2.0.4   jsonlite_1.9.1   
#> [13] mnormt_2.1.1      cli_3.6.4         rlang_1.1.5       munsell_0.5.1    
#> [17] withr_3.0.2       tools_4.4.2       parallel_4.4.2    tzdb_0.4.0       
#> [21] colorspace_2.1-1  pacman_0.5.1      vctrs_0.6.5       R6_2.6.1         
#> [25] lifecycle_1.0.4   htmlwidgets_1.6.4 pkgconfig_2.0.3   pillar_1.10.1    
#> [29] gtable_0.3.6      glue_1.8.0        xfun_0.51         tidyselect_1.2.1 
#> [33] rstudioapi_0.17.1 farver_2.1.2      htmltools_0.5.8.1 nlme_3.1-167     
#> [37] rmarkdown_2.29    compiler_4.4.2

Bibliografia

Collaboration, O. S. (2015). Estimating the reproducibility of psychological science. Science, 349(6251), aac4716.
Irizarry, R. A. (2024). Introduction to Data Science: Data Wrangling and Visualization with R. CRC Press.
Knuth, D. E. (1984). Literate programming. The Computer Journal, 27(2), 97–111.
Obels, P., Lakens, D., Coles, N. A., Gottfried, J., & Green, S. A. (2020). Analysis of open data and computational reproducibility in registered reports in psychology. Advances in Methods and Practices in Psychological Science, 3(2), 229–237.
Okoye, K., & Hosseini, S. (2024). Introduction to R Programming and RStudio Integrated Development Environment (IDE). In R Programming: Statistical Data Analysis in Research (pp. 3–24). Springer.
Wickham, H., Çetinkaya-Rundel, M., & Grolemund, G. (2023). R for data science. " O’Reilly Media, Inc.".