14  Il ciclo di vita di un progetto di analisi dei dati

“Se la tua analisi non è riproducibile, non è scienza.”

Gary King, Professore di Scienze Sociali e Statistica, Università di Harvard

Introduzione

Nella ricerca psicologica i dati sono il legame concreto tra le teorie e la loro verifica empirica. Gestirli con rigore non significa soltanto tenerli in ordine: è la condizione che rende le analisi affidabili, le conclusioni sensate e i risultati riproducibili.

Un dataset solido deve avere tre caratteristiche: integrità (i dati non devono essere alterati senza traccia), chiarezza semantica (ogni variabile deve avere un significato esplicito), e tracciabilità (ogni trasformazione deve poter essere ricostruita). Ad esempio: se rinomini un item da Q5 a Ansia_Sociale, questa modifica deve comparire in uno script, non solo nella memoria di chi analizza. Senza questa trasparenza, anche l’analisi più sofisticata perde credibilità e diventa irriproducibile.

La riproducibilità, cardine della scienza aperta (Open Science), non è facoltativa. Documentare accuratamente dati e processi permette alla comunità scientifica — e al proprio gruppo di ricerca nel tempo — di riesaminare, validare, criticare o estendere il lavoro. La gestione dei dati non è quindi un compito tecnico secondario, ma un atto scientifico con implicazioni etiche e metodologiche profonde.

I dati psicologici sono oggi sempre più complessi: possono essere longitudinali (misure ripetute nel tempo), multimodali (questionari, dati EMA da app, registrazioni digitali), e provenire da fonti eterogenee. Ogni dataset riflette scelte teoriche e tecniche: rendere queste scelte esplicite, tracciabili e accessibili significa trasformare una semplice elaborazione in un processo analitico trasparente e criticabile.

In questo capitolo vedremo principi e pratiche per costruire un progetto di analisi dati che abbia fin dalle fondamenta chiarezza, rigore e tracciabilità. L’obiettivo non è solo operativo, ma epistemologico: creare un ponte solido tra l’osservazione empirica e l’inferenza scientifica, attraverso strumenti concreti e replicabili.

Panoramica del capitolo

  • Pianificazione iniziale.
  • Come configurare l’ambiente R.
  • Come gestire il ciclo di vita di un progetto di Data Science.
  • Come garantire la riproducibilità usando Make.

  • Leggere Veridical Data Science (Yu & Barter, 2024) focalizzandoti sul primo capitolo, che introduce le problematiche della data science, e sul quarto capitolo, che fornisce le linee guida dettagliate sull’organizzazione di un progetto di analisi dei dati.
# Carica il file _common.R per impostazioni di pacchetti e opzioni
here::here("code", "_common.R") |> 
  source()

Prima di immergerti nella lettura di questo capitolo, prenditi un momento per riflettere sulle seguenti domande. Quali risposte daresti prima di leggere il materiale?

  • Perché è importante organizzare e documentare accuratamente i dati in un progetto di ricerca?
  • Quali problemi possono emergere se si inizia a scrivere codice senza una pianificazione adeguata?
  • Quali vantaggi offre R per la gestione dei dati rispetto ad altri strumenti?
  • Quali strategie potrebbero migliorare la riproducibilità del tuo lavoro?
  • Come struttureresti un progetto di analisi dati per mantenerlo chiaro e facilmente replicabile?

Ora, mentre leggi il capitolo, confronta le tue risposte con i concetti discussi.

14.1 L’importanza della pianificazione iniziale

Affrontare un progetto di analisi senza una pianificazione accurata è come condurre un esperimento psicologico senza ipotesi: si procede in modo confuso, con errori, ripensamenti e soluzioni improvvisate che rendono il lavoro inefficiente e difficile da mantenere nel tempo. Scrivere codice, contrariamente a quanto si crede, è solo una piccola parte del processo. La maggior parte dello sforzo riguarda la definizione degli obiettivi, la scelta degli strumenti appropriati, la costruzione di un percorso coerente e la prevenzione dei cosiddetti debiti tecnici — scorciatoie temporanee che in seguito diventano ostacoli complessi da risolvere.

Un approccio non strutturato può portare, ad esempio, a importare i dati in modo disordinato, a confondere i file originali con versioni intermedie o a trascurare la documentazione delle trasformazioni. In queste condizioni, anche l’analisi più brillante diventa fragile e poco trasparente, fino a compromettere la possibilità di replicare i risultati.

14.1.1 Costruire un flusso di lavoro efficace

Un progetto ben strutturato nasce da una fase di progettazione concettuale: chiarire le domande di ricerca, identificare le variabili chiave e ipotizzare i passaggi fondamentali dell’analisi. Anche uno schema molto semplice, disegnato su carta, può aiutare a visualizzare l’intero percorso: dalla pulizia dei dati all’inferenza statistica, fino alla comunicazione dei risultati. Questa rappresentazione preliminare diventa una bussola per mantenere coerenza ed evitare deviazioni inutili.

È altrettanto importante suddividere il lavoro in unità gestibili, stimando in modo realistico il tempo necessario per ciascuna e formulando obiettivi specifici. Dire “fare un’analisi preliminare” è troppo vago; meglio stabilire: “esplorare la distribuzione dei punteggi tra il gruppo sperimentale e quello di controllo e produrre un grafico documentato e interpretabile”. Questo livello di precisione facilita il monitoraggio dei progressi e la divisione dei compiti nei progetti collaborativi.

La scelta degli strumenti merita attenzione sin dall’inizio: dedicare tempo a selezionare pacchetti R affidabili evita soluzioni improvvisate poco sostenibili. Ad esempio, janitor semplifica la pulizia dei dati e report produce automaticamente output in stile APA. Tuttavia, lo strumento più importante resta la documentazione quotidiana: annotare le motivazioni delle scelte nel codice, descrivere chiaramente le trasformazioni e integrare testo, codice ed evidenze in un documento Quarto crea un archivio trasparente e facilmente condivisibile.

Infine, la riproducibilità è la chiave per garantire solidità nel tempo. Una struttura di progetto ordinata, con cartelle distinte per dati, script, output e report, facilita l’orientamento e la collaborazione. Anche i dettagli apparentemente minori — nomi chiari per le variabili, coerenza nell’indentazione, commenti sintetici ma informativi — contribuiscono a rendere l’analisi più leggibile, robusta e sostenibile.

14.1.2 Prevenire e gestire il debito tecnico

Con l’avanzare del progetto, è naturale accumulare complessità e dover affrontare problemi di manutenzione del codice. Per evitarne l’escalation, conviene ritagliarsi momenti periodici di revisione: semplificare strutture ridondanti, dividere gli script troppo lunghi in moduli più chiari e trasformare blocchi ripetitivi in funzioni riutilizzabili. Un codice pulito riduce il rischio di errori, rende più semplice collaborare e garantisce la possibilità di estendere il progetto senza doverlo riscrivere da capo.

Un’altra buona pratica è mantenere allineati codice e commenti. Ogni modifica sostanziale deve essere accompagnata da un aggiornamento delle annotazioni: pochi commenti chiari valgono più di intere sezioni obsolete che confondono chi legge.

Prima di condividere il progetto è utile effettuare una “checklist di qualità”:

  • verificare che i dati originali siano conservati separatamente e non alterati;
  • documentare l’ambiente di lavoro (ad esempio, salvando l’output di sessionInfo());
  • controllare che ogni script sia leggibile, ben commentato e riproducibile dall’inizio alla fine.

In definitiva, pianificare un flusso di lavoro in R non significa complicarsi la vita: significa creare le condizioni per analisi più chiare, durature e scientificamente robuste. L’organizzazione del progetto, la cura del codice e l’adozione di buone pratiche non sono accessori, ma il fondamento di un approccio che mira a comprendere e non solo a calcolare.

14.2 Capacità di gestione dei dati in R

Una volta compresa l’importanza di pianificare il lavoro, il passo successivo è dotarsi di strumenti affidabili per gestire, analizzare e documentare i dati. In questo contesto, R si rivela un alleato prezioso. È un ambiente di programmazione pensato per accompagnare l’intero ciclo di vita dei dati: dall’importazione e trasformazione, all’analisi statistica, fino alla produzione di report riproducibili. La sua versatilità lo rende centrale in qualsiasi flusso di lavoro orientato alla qualità e alla trasparenza — qualità indispensabili soprattutto in psicologia, dove i dataset sono spesso complessi e richiedono al tempo stesso flessibilità e rigore.

R permette innanzitutto di importare ed esportare dati in molti formati. Pacchetti come readr e rio semplificano l’interazione con file CSV, database o persino fonti web. Una volta acquisiti, i dati possono essere puliti e trasformati in modo rapido ed elegante grazie a strumenti come dplyr, tidyr e stringr, che offrono un linguaggio espressivo per filtrare osservazioni, ristrutturare tabelle e modificare stringhe. La fase di esplorazione può poi contare su ggplot2, che consente di visualizzare pattern e riassumere indicatori descrittivi con grafici chiari e informativi.

La vera forza di R, tuttavia, emerge quando si tratta di documentare l’intero processo analitico. Con R Markdown e Quarto è possibile integrare codice, testo esplicativo, tabelle e grafici in un unico documento dinamico: un report che mostra non solo i risultati finali, ma anche come sono stati ottenuti, garantendo così riproducibilità e trasparenza. A questo si aggiunge la possibilità di usare Git, integrato in RStudio, per tracciare le modifiche, collaborare in modo strutturato e mantenere un archivio verificabile del lavoro.

L’integrazione tra strategia progettuale e strumenti tecnici rende R una piattaforma ideale per chi vuole lavorare in modo affidabile, efficiente e scientificamente solido. Nei progetti con dati complessi, questa combinazione rappresenta una garanzia di qualità e sostenibilità analitica.

14.3 Configurare l’ambiente R

Per sfruttare al meglio R è importante partire da un ambiente di lavoro ben configurato. RStudio offre un’interfaccia potente e flessibile, che consente di controllare in dettaglio il comportamento delle sessioni.

Un primo passo utile è disattivare il salvataggio automatico dell’ambiente di lavoro. Dal menu Tools > Global Options > General si consiglia di:

  • deselezionare l’opzione di caricamento automatico del file .RData all’avvio,
  • impostare il salvataggio del workspace su Never.

In questo modo si evitano “residui invisibili” delle sessioni precedenti e si favorisce l’uso sistematico degli script come unico riferimento per l’analisi. L’obiettivo è rendere ogni passaggio esplicito e documentato, piuttosto che affidarsi a oggetti temporanei difficili da tracciare.

Un ambiente ben preparato deve includere anche i pacchetti fondamentali. Tra questi, il tidyverse costituisce un vero ecosistema integrato per la manipolazione (dplyr), la visualizzazione (ggplot2), l’importazione (readr) e molte altre operazioni, sempre con una sintassi coerente e leggibile. Il pacchetto here, invece, semplifica la gestione dei percorsi relativi: gli script diventano portabili e funzionano senza modifiche anche su sistemi o directory differenti.

L’installazione si effettua una sola volta con install.packages(), mentre il caricamento va ripetuto all’inizio di ogni script. Un setup iniziale tipico potrebbe essere:

# install.packages(c("here", "tidyverse"))  # solo la prima volta
library(here)
library(tidyverse)

Adottare da subito queste pratiche di configurazione significa ridurre errori, aumentare la leggibilità del codice e costruire un ambiente solido, adatto ad analisi ripetibili e condivisibili. È qui che la programmazione incontra il metodo scientifico: nella combinazione di rigore tecnico e trasparenza metodologica.

14.4 Gestione dei progetti

In RStudio, i progetti permettono di organizzare tutto il lavoro analitico all’interno di una cartella dedicata, che contiene dati, script, output e documentazione. Ogni progetto è così un’unità autonoma, con percorsi relativi stabili e indipendenti dagli altri lavori. Questo riduce il rischio di confusione e rende più semplice riprodurre le analisi anche a distanza di tempo.

Creare un nuovo progetto è immediato: basta selezionare File > New Project e indicare la directory in cui raccogliere i file. Da quel momento, aprendo il file .Rproj, si ritrova automaticamente l’ambiente configurato e pronto all’uso.

Più che una questione di ordine, lavorare per progetti significa adottare una struttura replicabile: ogni analisi può essere riaperta, eseguita e condivisa senza dipendere da impostazioni esterne o da file sparsi. È anche un vantaggio per la collaborazione, perché rende chiaro a tutti dove trovare dati, script e risultati.

14.5 Il ciclo di vita di un progetto di Data Science

Una volta predisposto un ambiente stabile e ben organizzato, il progetto di Data Science può essere affrontato in modo sistematico. Seguendo la proposta di Yu & Barter (2024), il ciclo di vita tipico comprende cinque fasi fondamentali: formulazione della domanda di ricerca, preparazione e analisi esplorativa dei dati, eventuale modellazione inferenziale o predittiva, valutazione dei risultati e comunicazione degli esiti.

Non tutti i progetti arrivano alla modellazione, ma tutti traggono vantaggio da un percorso ordinato che attraversi in modo coerente queste fasi. Un approccio strutturato migliora la qualità delle analisi e riduce il rischio di errori o ambiguità interpretative.

14.5.1 Formulazione del problema e raccolta dei dati

Il primo passo è definire con chiarezza gli obiettivi. In ambito applicativo ciò può significare, ad esempio, valutare l’efficacia di un intervento con un report descrittivo; in ambito accademico, ancorare la domanda alla letteratura e a un quadro teorico esplicito. In entrambi i casi, la domanda deve essere precisa e affrontabile con i dati disponibili.

La raccolta dei dati può basarsi su fonti esistenti (dataset pubblici, archivi di laboratorio) o su nuove rilevazioni. Pianificare in anticipo l’analisi aiuta a evitare dati inutili o non pertinenti. È inoltre fondamentale documentare le modalità di raccolta ed esplicitare eventuali limiti.

14.5.2 Pulizia, preprocessing e analisi esplorativa

Una volta acquisiti, i dati vanno importati in R in formato analizzabile, di norma come data frame. Pacchetti come rio rendono semplice l’importazione, mentre here facilita la gestione dei percorsi. I dati grezzi vanno sempre conservati separati dai dati trasformati.

La pulizia comprende la correzione di errori, la gestione dei valori mancanti, l’eliminazione di duplicati e l’uniformazione delle codifiche. Le trasformazioni non vanno mai fatte “a mano” ma registrate in script, per garantire tracciabilità.

Il preprocessing adatta i dati all’analisi: ad esempio standardizzare variabili, creare indici compositi o ricodificare categorie. Ogni passo deve essere documentato, perché ha effetti diretti sull’interpretazione.

L’analisi esplorativa (EDA) serve a conoscere i dati prima di modellarli: statistiche descrittive, distribuzioni, visualizzazioni con ggplot2. Questa fase permette di individuare pattern, anomalie e relazioni preliminari che guideranno le scelte successive.

14.5.3 Analisi predittiva e inferenziale

Quando previsto, il cuore del progetto è la modellazione. In psicologia si usano comunemente regressioni, test parametrici e non parametrici, modelli ad effetti misti o algoritmi di classificazione. L’obiettivo può essere inferenziale (trarre conclusioni su una popolazione) o predittivo (anticipare valori futuri). In ogni caso le scelte modellistiche devono essere motivate, e le ipotesi verificate.

14.5.4 Valutazione dei risultati

Interpretare i risultati richiede attenzione su due livelli:

  • statistico, attraverso indici di bontà del modello, intervalli di confidenza o posteriori credibili,
  • concettuale, verificando la coerenza con la teoria di riferimento o con il contesto applicativo.

Ricollegarsi sempre agli obiettivi iniziali aiuta a distinguere ciò che il modello davvero mostra da ciò che resta incerto.

14.5.5 Comunicazione dei risultati

La fase finale è la comunicazione, che può assumere forme diverse: articolo scientifico, report tecnico, presentazione a un pubblico non specialistico. In ogni caso serve un linguaggio chiaro e motivato, supportato da visualizzazioni curate. Un buon risultato analitico non è completo finché non viene presentato in modo comprensibile e utile a chi lo riceve.

14.6 Organizzazione del progetto

Per garantire riproducibilità e gestione a lungo termine, è utile adottare una struttura chiara e strumenti che automatizzino i passaggi chiave. Un esempio concreto è documentato nel repository ccaudek/make-tutorial, che mostra come integrare R, Quarto e GNU Make in un flusso unico e completamente ricostruibile.

14.6.1 Perché Make

Make è uno strumento nato per compilare software, ma perfetto anche per la ricerca: invece di un “master script” che lancia tutto in sequenza, Make lavora con dipendenze dichiarative. Ogni output (un file pulito, un grafico, un report) viene associato agli input necessari e al comando che lo genera. Così, se modifichi un solo script, Make ricostruisce solo ciò che dipende da quel file, senza ricalcolare inutilmente il resto.

Tre principi fondamentali:

  • Modularità: ogni passaggio (pulizia, scoring, analisi, report) è uno script autonomo.
  • Dichiaratività: il Makefile descrive cosa dipende da cosa, non come eseguirlo manualmente.
  • Efficienza: make all ricostruisce l’intero progetto, make clean lo riporta allo stato iniziale.

14.6.2 Struttura del progetto

make-tutorial/
├─ data/
│  ├─ raw/         # input "sorgente" o simulati
│  └─ processed/   # output intermedi (clean, scored)
├─ scripts/        # step atomici della pipeline (Rscript)
├─ stan/           # modelli Stan (se usati)
├─ fits/           # oggetti dei fit (rds/csv)
├─ figs/           # figure prodotte dagli script
├─ report/         # report .qmd e .html
├─ Makefile        # regole e dipendenze
└─ README.md       # istruzioni d'uso

14.6.3 Il cuore del progetto: il Makefile essenziale

Quando un progetto di analisi dati cresce, tenere traccia di tutti i file, script e delle loro dipendenze può diventare complicato. GNU Make è uno strumento che automatizza il processo di costruzione (o “build”) di un progetto. La sua logica è semplice ma potente: definisci cosa vuoi produrre (i file-obiettivo), da cosa dipende (i prerequisiti) e come produrlo (i comandi). Make si occuperà di eseguire i comandi nell’ordine corretto, solo quando necessario. Un file che contiene queste istruzioni si chiama Makefile.

14.6.3.1 Anatomia di una regola

La struttura fondamentale di un Makefile è la regola. Ogni regola è composta da tre elementi:

target: prerequisito1 prerequisito2 ...
    comando
  1. Target: il file che vuoi costruire (ad esempio, un dataset pulito, un grafico, un report HTML).
  2. Prerequisiti: i file di cui il target ha bisogno per essere costruito (ad esempio, gli script R e i dati grezzi). Sono le dipendenze del target.
  3. Comando: la ricetta, ossia la riga di comando che, eseguita, trasforma i prerequisiti nel target. È fondamentale che questa riga inizi con un carattere di tabulazione (TAB), non con spazi.

Come funziona Make? Quando gli chiedi di costruire un target (ad esempio, make report.html), Make fa questo:

  1. Controlla le dipendenze: guarda tutti i prerequisiti del target.
  2. Verifica la necessità: controlla se il target esiste già e se è più recente di tutti i suoi prerequisiti.
    • Se il target non esiste o è più vecchio di anche solo uno dei suoi prerequisiti, Make esegue il comando per aggiornarlo.
    • Se il target esiste ed è più recente di tutti i prerequisiti, Make sa che non c’è nulla da fare e salta la ricetta, risparmiando tempo.
  3. Si propaga: applica questa stessa logica ricorsivamente a tutti i prerequisiti che sono a loro volta target di altre regole.

Questo meccanismo intelligente assicura che tutto il tuo progetto venga ricostruito in modo efficiente e sempre aggiornato.

14.6.3.2 Spiegazione del nostro Makefile

Analizziamo ora il Makefile utilizzato in ccaudek/make-tutorial pezzo per pezzo.

1. Impostare l’obiettivo predefinito

# Esegui la pipeline completa se non passi argomenti a 'make'
.DEFAULT_GOAL := all

Questa riga dice a Make: “Se l’utente digita semplicemente make senza specificare un target, esegui di default il target chiamato all”. È un’utile convenzione per avviare l’intera pipeline con un comando minimo.

2. Generazione dei dati (DAG: da raw a processed)

data/raw/rosenberg_raw.csv: scripts/00_simulate.R
    Rscript $<
  • Target: data/raw/rosenberg_raw.csv (i dati simulati grezzi).
  • Prerequisito: scripts/00_simulate.R (lo script che genera i dati).
  • Comando: Rscript $<
    • $< è una variabile automatica di Make. Viene sostituita con il nome del primo prerequisito della regola. In questo caso, $< diventa scripts/00_simulate.R.
    • Quindi, il comando eseguito è Rscript scripts/00_simulate.R.
data/processed/clean.csv: scripts/01_clean.R data/raw/rosenberg_raw.csv
    Rscript $<
  • Target: data/processed/clean.csv (i dati puliti).
  • Prerequisiti: Lo script di pulizia (01_clean.R) e i dati grezzi. Se i dati grezzi cambiano, anche i dati puliti devono essere rigenerati.
  • Comando: Rscript $< (dove $< è scripts/01_clean.R).

3. Creazione delle figure (EDA)

figs/dist_by_gender.png figs/scatter_rosenberg_vs_outcome.png: scripts/03_eda.R data/processed/scored.csv
    Rscript scripts/03_eda.R

Questa regola è interessante perché ha due target. Significa che eseguendo un unico comando (Rscript scripts/03_eda.R) vengono generati entrambi i file figura. Se uno dei due file PNG o lo script EDA viene modificato, Make rigenererà entrambe le figure.

4. Esecuzione delle analisi

fits/freq_done.flag: scripts/10_freq_tests.R data/processed/scored.csv
    Rscript scripts/10_freq_tests.R && touch $@
  • Target: fits/freq_done.flag. Questo è un file flag (o sentinella). A volte un’analisi non produce un file di output vero e proprio, o lo produce con un nome imprevedibile. Il file flag è un file vuoto il cui unico scopo è registrare quando l’analisi è stata eseguita con successo per l’ultima volta.
  • Comando: Rscript scripts/10_freq_tests.R && touch $@
    • && significa “esegui il comando successivo solo se il primo è terminato con successo”.
    • $@ è un’altra variabile automatica. Viene sostituita con il nome del target della regola. In questo caso, $@ diventa fits/freq_done.flag.
    • Quindi, il comando esegue prima lo script R e, se ha successo, crea/tocca il file flag.
fits/brms_fit.rds: scripts/11_bayes_brms.R data/processed/scored.csv
    Rscript $<
  • Target: fits/brms_fit.rds (un file binario R che contiene il modello fitted).
  • Il comando usa $< per riferirsi al primo prerequisito, lo script.

5. Generazione del report finale

report/report.html: report/report.qmd figs/dist_by_gender.png figs/scatter_rosenberg_vs_outcome.png fits/freq_done.flag fits/brms_fit.rds fits/cmdstan_fit.rds
    quarto render $<
  • Target: Il report HTML finale.
  • Prerequisiti: Tutto ciò di cui il report ha bisogno: il file Quarto source (.qmd), tutte le figure e i risultati di tutte le analisi (compreso il file flag).
  • Comando: quarto render $< (dove $< è report/report.qmd). Questo comando compila il documento Quarto in HTML, incorporando figure e risultati.

6. Target “fittizi” (phony) e pulizia

.PHONY: all clean
all: report/report.html

clean:
    rm -f data/raw/rosenberg_raw.csv \
          data/processed/*.csv \
          figs/*.png \
          fits/*.rds fits/*.flag \
          report/report.html
  • .PHONY: Questa è una direttiva speciale che dice a Make che i target all e clean non sono nomi di file. Sono comandi, azioni. Senza .PHONY, se per caso esistesse un file chiamato all o clean nella cartella, Make penserebbe che quel target è già aggiornato e non eseguirebbe il comando, il che non è ciò che vogliamo.
  • all: report/report.html: Definisce il target all come un semplice collegamento (alias) al nostro report finale. È il target che costruisce l’intero progetto.
  • clean: Questo target ha un comando molto importante: elimina tutti i file generati. È utile per ricominciare da zero con una pulizia profonda. Nota la continuazione di riga con il carattere \.

14.6.3.3 Riepilogo delle Variabili Automatiche

  • $<: Il nome del primo prerequisito.
  • $@: Il nome del target.

14.6.3.4 Come usare questo Makefile

Apri un terminale nella cartella del progetto contenente il Makefile e digita:

  • make o make all: costruisce l’intero progetto (dati, figure, analisi, report).
  • make data/processed/clean.csv: costruisce solo il dataset pulito e tutto ciò da cui dipende (dati grezzi).
  • make figs/dist_by_gender.png: genera solo quella figura specifica e le sue dipendenze.
  • make clean: cancella tutti i file prodotti, lasciando solo il codice sorgente e il Makefile.
  • make -n target: esegue una simulazione (“dry run”). Make mostrerà i comandi che eseguirebbe senza eseguirli realmente. Ottimo per debug.

Il Makefile contenuto nel repository ccaudek/make-tutorial trasforma il progetto di analisi dei dati da una collezione di script in una pipeline di dati riproducibile e automatizzata.

14.6.4 DAG della pipeline

flowchart LR
    A["raw.csv"] --> B["clean.csv"]
    B --> C["scored.csv"]
    C --> D1["EDA figs"]
    C --> D2["freq tests"]
    C --> D3["bayes (brms)"]
    C --> D4["bayes (cmdstanr)"]
    D1 --> RPT["report.html"]
    D2 --> RPT
    D3 --> RPT
    D4 --> RPT

flowchart LR
    A["raw.csv"] --> B["clean.csv"]
    B --> C["scored.csv"]
    C --> D1["EDA figs"]
    C --> D2["freq tests"]
    C --> D3["bayes (brms)"]
    C --> D4["bayes (cmdstanr)"]
    D1 --> RPT["report.html"]
    D2 --> RPT
    D3 --> RPT
    D4 --> RPT

14.6.5 Buone pratiche operative

  • Shebang facoltativo negli script (#!/usr/bin/env Rscript) + chmod +x per lanciarli anche come eseguibili. Nei Makefile va benissimo Rscript script.R.
  • Percorsi stabili: nel report .qmd, usa percorsi relativi o abilita embed-resources: true per incorporare le immagini nell’HTML.
  • CmdStanR e file CSV: gli oggetti CmdStanMCMC salvati con saveRDS() puntano ai CSV generati dal sampler. Salvali in una cartella persistente (es. fits/cmdstan_csv/ con output_dir=) oppure salva direttamente un summary (fit$summary()) in RDS per evitare dipendenza dai CSV temporanei.
  • Idempotenza: ogni regola dovrebbe essere deterministica dato il suo input (se simuli dati, fissa il seed negli script).
  • Pulizia selettiva: clean rimuove solo artefatti ricostruibili. Se vuoi mantenere determinati risultati (es. fit costosi), non includerli nel clean.

14.6.6 Vantaggi pratici

  • Automatizzazione del flusso di lavoro: elimina la necessità di orchestrazione manuale degli script, sostituendo il classico “master script” con un grafo di dipendenze esplicito ed eseguibile.
  • Esecuzione incrementale: modifiche a singoli componenti innescano automaticamente solo il riprocessamento degli output dipendenti, ottimizzando significativamente i tempi di esecuzione.
  • Documentazione attiva: il Makefile stesso costituisce una documentazione sempre aggiornata e verificabile della pipeline analitica, garantendo trasparenza e riproducibilità.
  • Portabilità cross-piattaforma: il comando make all produce risultati consistenti attraverso macOS, Linux e Windows (quest’ultimo tramite ambienti come WSL o strumenti GNU), astraendo dalle specificità del sistema operativo.

Se vuoi estendere l’esempio (più analisi, cross-validation, modelli addizionali), basta aggiungere nuovi target con prerequisiti appropriati e collegarli al report. Make farà il resto.

Riflessioni conclusive

La riproducibilità computazionale rappresenta un fondamento metodologico essenziale, che trascende la mera esecuzione tecnica per diventare garanzia di integrità scientifica. In psicologia, dove la complessità dei dati e la natura iterativa dell’analisi richiedono tracciabilità completa, un flusso di lavoro codificato e ben documentato non è opzionale ma necessario.

I vantaggi si manifestano su tre livelli:

  1. Personale: la capacità di riattivare, correggere o estendere un’analisi a distanza di tempo senza perdita di informazione
  2. Collettivo: la possibilità per altri ricercatori di verificare, adattare e costruire sulle procedure condivise
  3. Epistemologico: la costruzione di una conoscenza cumulativa e criticabile, basata su processi analitici trasparenti

Strumenti come il versioning (git), la strutturazione coerente dei progetti e l’automazione dei flussi (make) non sono mere questioni organizzative, ma abilitatori concreti di rigore metodologico. Un’analisi riproducibile non è solo “ordinata” — è intrinsecamente più robusta, in quanto costringe a esplicitare assunzioni, scelte e trasformazioni.

Investire in pratiche riproducibili significa quindi investire nella qualità del proprio lavoro: non un vincolo “burocratico”, ma una disciplina che affina il pensiero critico e trasforma l’analisi dati da attività esecutiva a processo scientifico pienamente consapevole.

Un problema cruciale della psicologia contemporanea è la crisi di replicabilità, che evidenzia come molti risultati di ricerca non siano replicabili (Collaboration, 2015). La riproducibilità computazionale, pur avendo un obiettivo più ristretto, si concentra sulla possibilità di ottenere gli stessi risultati applicando lo stesso codice agli stessi dati. Questo approccio, sebbene non risolva completamente la crisi, rappresenta un passo fondamentale verso una scienza più trasparente e rigorosa.

Ora che hai completato il capitolo, confrontiamo le risposte alle domande iniziali con quanto appreso:

  1. Perché è importante organizzare e documentare accuratamente i dati in un progetto di ricerca?
    • Una gestione strutturata dei dati riduce il rischio di errori, facilita l’analisi e migliora la riproducibilità, rendendo il lavoro scientifico più affidabile e trasparente.
  2. Quali problemi possono emergere se si inizia a scrivere codice senza una pianificazione adeguata?
    • Senza una pianificazione strategica si rischia di incorrere nel “debito tecnico”, accumulando codice disordinato che richiede correzioni costose in termini di tempo e risorse. Inoltre, si potrebbero fare scelte subottimali che compromettono la scalabilità e manutenibilità del progetto.
  3. Quali vantaggi offre R per la gestione dei dati rispetto ad altri strumenti?
    • R fornisce strumenti avanzati per importazione, pulizia, analisi e visualizzazione dei dati, oltre a supportare la documentazione dinamica e il controllo delle versioni con Git. La sua ampia comunità e la disponibilità di pacchetti specializzati lo rendono particolarmente adatto per l’analisi statistica e la ricerca.
  4. Quali strategie potrebbero migliorare la riproducibilità del tuo lavoro?
    • Utilizzare strumenti come Quarto per documentare il codice e le analisi, adottare percorsi relativi con il pacchetto here, strutturare i dati in cartelle ben organizzate e integrare il controllo delle versioni con Git.
  5. Come struttureresti un progetto di analisi dati per mantenerlo chiaro e facilmente replicabile?
    • Adottando una struttura chiara, ad esempio:

      nome_progetto/
      ├── nome_progetto.Rproj
      ├── data/
      │   ├── raw/
      │   │   └── my_data.csv
      │   ├── processed/
      ├── dslc_documentation/
      │   ├── 01_data_cleaning.qmd
      │   ├── 02_analysis.qmd
      │   └── functions/
      └── README.md
      • Questa organizzazione separa i dati grezzi da quelli elaborati, include documentazione chiara e facilita la riproducibilità.

Conclusione: Riflettere in anticipo sui problemi e sulle strategie di gestione dei dati aiuta a costruire workflow più efficienti e affidabili. Se le tue risposte iniziali differivano da queste, quali nuovi spunti hai appreso da questo capitolo?

Esercizi

L’obiettivo di questo esercizio è comprendere il ciclo di vita di un progetto di analisi dei dati, l’organizzazione del progetto e la gestione della riproducibilità.

  1. Gestione del progetto di analisi

    • Quali sono le fasi principali di un progetto di analisi dei dati secondo Yu (2024)?
    • Spiega il ruolo della fase di formulazione del problema e raccolta dei dati.
  2. Organizzazione del workspace in R

    • Quali impostazioni devono essere modificate in RStudio per favorire la riproducibilità?
    • Perché è importante usare percorsi relativi nei progetti in RStudio?
    • Descrivi il ruolo del pacchetto here nella gestione dei percorsi dei file.
  3. Struttura dei progetti in R

    • Quali sono i vantaggi dell’utilizzo dei progetti in RStudio?
    • Quali sono le cartelle principali in una struttura organizzata di un progetto?
    • Perché è utile separare i dati grezzi dai dati processati?
  4. Importazione ed esportazione dei dati

    • Quali pacchetti di R possono essere utilizzati per importare ed esportare dati?
    • Scrivi un esempio di codice per importare un file CSV usando rio e il pacchetto here.
    • Come puoi esportare un dataset modificato in una cartella dedicata ai dati processati?
  5. Pulizia e preprocessing dei dati

    • Qual è la differenza tra pulizia e preprocessing dei dati?
    • Quali strumenti di dplyr sono comunemente usati per pulire e trasformare i dati?
  6. Analisi esplorativa dei dati (EDA)

    • Quali sono alcuni strumenti utilizzati in R per effettuare un’analisi esplorativa dei dati?
    • Scrivi un breve esempio di codice in R per calcolare statistiche descrittive di base su un dataset.
  7. Riproducibilità e comunicazione dei risultati

    • Perché la riproducibilità è un elemento chiave nella scienza dei dati?
    • Quali strumenti offre Quarto per la documentazione e la condivisione dei risultati di un’analisi?

1. Gestione del progetto di analisi

  • Fasi principali del progetto di analisi dei dati (Yu, 2024):
    1. Formulazione del problema e raccolta dei dati
    2. Pulizia, preprocessing e analisi esplorativa
    3. Analisi predittiva e/o inferenziale (se applicabile)
    4. Valutazione dei risultati
    5. Comunicazione dei risultati
  • Ruolo della fase di formulazione del problema:
    Aiuta a definire gli obiettivi dell’analisi e a selezionare le fonti di dati adeguate. Una domanda di ricerca ben definita garantisce che i dati siano pertinenti e che le analisi siano mirate.

2. Organizzazione del workspace in R

  • Impostazioni da modificare in RStudio:

    • Disabilitare Restore .RData into workspace at startup
    • Impostare Save workspace to .RData on exit su “Never”
  • Importanza dei percorsi relativi:
    Permettono di rendere il progetto portabile e riproducibile, evitando problemi di percorsi assoluti specifici per un computer.

  • Ruolo del pacchetto here
    Aiuta a gestire i percorsi relativi all’interno del progetto senza dover specificare percorsi assoluti.

3. Struttura dei progetti in R

  • Vantaggi dell’uso dei progetti in RStudio:
    Mantengono ambienti separati, organizzano i file e facilitano la riproducibilità.

  • Cartelle principali in una struttura organizzata:

    • data/raw/ → Dati grezzi
    • data/processed/ → Dati elaborati
    • dslc_documentation/ → Documentazione e script
    • functions/ → Funzioni personalizzate
  • Separare dati grezzi da dati processati:
    Evita di modificare accidentalmente i dati originali, garantendo riproducibilità.

4. Importazione ed esportazione dei dati

  • Pacchetti per importazione/esportazione:

    • rio: unifica funzioni di import/export
    • readr: specifico per CSV e altri formati di testo
    • here: gestisce percorsi relativi
  • Esempio di codice per importare dati CSV:

    library(here)
    library(rio)
    df <- rio::import(here("data", "raw", "my_data.csv"))
  • Esportare dati modificati:

    rio::export(df, here("data", "processed", "my_data_processed.csv"))

5. Pulizia e preprocessing dei dati

  • Differenza tra pulizia e preprocessing:
    • Pulizia: rimozione di errori, gestione dei dati mancanti, formattazione
    • Preprocessing: trasformazione dei dati per adattarli a modelli specifici
  • Strumenti di dplyr per pulizia e trasformazione:

6. Analisi esplorativa dei dati (EDA)

7. Riproducibilità e comunicazione dei risultati

  • Importanza della riproducibilità:
    • Facilita la verifica e il miglioramento degli studi
    • Previene errori accidentali
    • Consente a terzi di replicare e costruire su ricerche precedenti
  • Strumenti di Quarto:
    • Permette di combinare testo, codice e output in documenti riproducibili
    • Supporta citazioni automatiche e gestione delle bibliografie
sessionInfo()
#> R version 4.5.1 (2025-06-13)
#> Platform: aarch64-apple-darwin20
#> Running under: macOS Sequoia 15.6.1
#> 
#> 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/Zagreb
#> tzcode source: internal
#> 
#> attached base packages:
#> [1] stats     graphics  grDevices utils     datasets  methods   base     
#> 
#> other attached packages:
#>  [1] pillar_1.11.0         tinytable_0.11.0      patchwork_1.3.1      
#>  [4] ggdist_3.3.3          tidybayes_3.0.7       bayesplot_1.13.0     
#>  [7] ggplot2_3.5.2         reliabilitydiag_0.2.1 priorsense_1.1.0     
#> [10] posterior_1.6.1       loo_2.8.0             rstan_2.32.7         
#> [13] StanHeaders_2.32.10   brms_2.22.0           Rcpp_1.1.0           
#> [16] sessioninfo_1.2.3     conflicted_1.2.0      janitor_2.2.1        
#> [19] matrixStats_1.5.0     modelr_0.1.11         tibble_3.3.0         
#> [22] dplyr_1.1.4           tidyr_1.3.1           rio_1.2.3            
#> [25] here_1.0.1           
#> 
#> loaded via a namespace (and not attached):
#>  [1] svUnit_1.0.6         tidyselect_1.2.1     farver_2.1.2        
#>  [4] fastmap_1.2.0        TH.data_1.1-3        tensorA_0.36.2.1    
#>  [7] digest_0.6.37        timechange_0.3.0     estimability_1.5.1  
#> [10] lifecycle_1.0.4      survival_3.8-3       magrittr_2.0.3      
#> [13] compiler_4.5.1       rlang_1.1.6          tools_4.5.1         
#> [16] knitr_1.50           bridgesampling_1.1-2 htmlwidgets_1.6.4   
#> [19] curl_6.4.0           pkgbuild_1.4.8       RColorBrewer_1.1-3  
#> [22] abind_1.4-8          multcomp_1.4-28      withr_3.0.2         
#> [25] purrr_1.1.0          grid_4.5.1           stats4_4.5.1        
#> [28] colorspace_2.1-1     xtable_1.8-4         inline_0.3.21       
#> [31] emmeans_1.11.2       scales_1.4.0         MASS_7.3-65         
#> [34] cli_3.6.5            mvtnorm_1.3-3        rmarkdown_2.29      
#> [37] ragg_1.4.0           generics_0.1.4       RcppParallel_5.1.10 
#> [40] cachem_1.1.0         stringr_1.5.1        splines_4.5.1       
#> [43] parallel_4.5.1       vctrs_0.6.5          V8_6.0.5            
#> [46] Matrix_1.7-3         sandwich_3.1-1       jsonlite_2.0.0      
#> [49] arrayhelpers_1.1-0   systemfonts_1.2.3    glue_1.8.0          
#> [52] codetools_0.2-20     distributional_0.5.0 lubridate_1.9.4     
#> [55] stringi_1.8.7        gtable_0.3.6         QuickJSR_1.8.0      
#> [58] htmltools_0.5.8.1    Brobdingnag_1.2-9    R6_2.6.1            
#> [61] textshaping_1.0.1    rprojroot_2.1.0      evaluate_1.0.4      
#> [64] lattice_0.22-7       backports_1.5.0      memoise_2.0.1       
#> [67] broom_1.0.9          snakecase_0.11.1     rstantools_2.4.0    
#> [70] coda_0.19-4.1        gridExtra_2.3        nlme_3.1-168        
#> [73] checkmate_2.3.2      xfun_0.52            zoo_1.8-14          
#> [76] pkgconfig_2.0.3

Bibliografia

Collaboration, O. S. (2015). Estimating the reproducibility of psychological science. Science, 349(6251), aac4716.
Yu, B., & Barter, R. L. (2024). Veridical data science: The practice of responsible data analysis and decision making. MIT Press.