# PUNTO 1 ------------------------------------------------
HW 04 - Manipolazione, sintesi e pivoting dei dati
Data di consegna: giovedì 22 ottobre 2026
Introduzione
In questo compito lavorerai sui dati (fittizi) di una rete di dodici musei di una provincia: le informazioni sui musei, il numero mensile di visitatori nel 2024 e nel 2025 e le risposte a un questionario di gradimento compilato dai visitatori nel 2025.
In questo compito utilizzerai i comandi utili per:
- selezionare colonne e filtrare righe con
selectefilter - trasformare una tabella dal formato largo al formato lungo e viceversa con
pivot_longerepivot_wider - calcolare sintesi per gruppi con
group_byesummarise - imputare i valori mancanti con
group_byemutate - trasformare dati annidati in tabelle (rectangling) e annidare le righe di una tabella (nesting)
- confrontare le funzioni di R base con quelle del
tidyverse
Obiettivi di apprendimento
Lo svolgimento di questo compito ti permetterà di:
- riconoscere quando una tabella è in formato tidy e trasformarla nel formato più adatto all’analisi o alla presentazione
- scegliere il livello di raggruppamento adatto a una domanda
- valutare le conseguenze dei valori mancanti sulle sintesi e scegliere un metodo di imputazione ragionevole
- leggere codice scritto in R base e tradurlo con i verbi del
tidyverse, e viceversa
Istruzioni per l’uso
Crea un progetto RStudio di nome
hw04(in Positron: crea una cartellahw04e aprila con File → Open Folder) e lavora all’interno del progetto per tutto il compito.All’interno della cartella del progetto crea una sottocartella
datie salva al suo interno i tre file dei dati che trovi su Teams, allegati al compito:musei.csvvisitatori.csvquestionario.xlsx
Nello script indica i file sempre con un percorso relativo alla cartella del progetto, ad esempio
"dati/musei.csv".Rispondi ai vari punti salvando le risposte in un file R con il nome “hw04_cognome_nome.R”: ad esempio nel mio caso il nome del file sarebbe “hw04_vistocco_domenico.R”. Salva lo script nella cartella del progetto.
Inizia lo script con un commento che riporti titolo del compito, nome, cognome e data.
Per rispondere ad ogni punto inserisci un’etichetta di sezione (che puoi inserire nello script usando la combinazione di tasti CTRL/CMD + SHIFT + R) utilizzando il punto cui stai rispondendo. Ad esempio, per rispondere al punto 1 del compito, usa un’etichetta di sezione:
Utilizza i commenti per rispondere alle domande in cui viene chiesta un’interpretazione da parte tua: nei commenti concentrati sul comportamento di R e sul significato dei risultati, con parole tue.
Lo script deve essere funzionante quando si eseguono tutti i comandi con il pulsante Source. I comandi che restituiscono un errore vanno lasciati nello script ma commentati, riportando subito sotto, sempre come commento, il messaggio di errore ottenuto.
Rispetta le regole di stile viste in aula: nomi degli oggetti in snake case,
<-per l’assegnazione, spazi attorno agli operatori e dopo le virgole, una istruzione per riga, un a capo dopo ogni pipe.Lo script viene valutato sia in base alla correttezza del codice che in base alla qualità (stile utilizzato per rendere lo script leggibile ed ordinato).
I dati
musei.csv (campi separati da ;): una riga per museo, con codice, nome, tipologia (Archeologia, Arte, Scienza, Storia), tipo di gestione (Statale, Comunale, Privato), comune e prezzo del biglietto intero in euro.
visitatori.csv (campi separati da ,): una riga per museo e anno, con il codice del museo, l’anno e una colonna per ciascun mese (gen, feb, …, dic) con il numero di visitatori. Le celle vuote corrispondono a dati che il museo non ha trasmesso.
questionario.xlsx: il foglio Risposte contiene una riga per ogni questionario compilato, con il codice del museo, la fascia di età e la provenienza del visitatore e i punteggi (da 1 a 5) assegnati a cinque aspetti della visita, nelle colonne D1, …, D5; il foglio Domande contiene il testo delle cinque domande.
Nel 2025 il Museo del Risorgimento è rimasto chiuso da marzo a giugno per lavori di restauro.
Esercizi
Ricordati di utilizzare i commenti per le risposte aperte e di commentare i comandi che restituiscono un errore. Quando una domanda chiede “quanti” o “quali”, rispondi con il codice che produce il risultato e riporta la risposta anche in un commento.
Parte 1: Importazione dei dati
Carica i package
tidyverse,readxlejanitorImporta il file
musei.csvin un oggettomuseie pulisci i nomi delle colonne. Verifica che la colonna del prezzo del biglietto sia numerica
Prima di scegliere la funzione di importazione, apri il file come testo e osserva il separatore delle colonne e il separatore decimale.
- Importa il file
visitatori.csvin un oggettovisitatorie pulisci i nomi delle colonne. Stampa a video le dimensioni della tabella e spiega perché non è in formato tidy
Per i dettagli su cosa si intenda per formato tidy e sui principi che lo definiscono, fai riferimento a:
- Hadley Wickham (2014), “Tidy Data”, Journal of Statistical Software, 59(10): https://www.jstatsoft.org/article/view/v059i10
- il capitolo 5, “Data tidying”, del libro R for Data Science (2nd edition) di Hadley Wickham, Mine Çetinkaya-Rundel e Garrett Grolemund: https://r4ds.hadley.nz/data-tidy
Importa i due fogli del file
questionario.xlsxin due oggettirisposteedomande, pulendo i nomi delle colonneStampa a video le dimensioni delle quattro tabelle importate. Quanti musei diversi compaiono nella tabella
risposte?Quali musei non hanno partecipato al questionario di gradimento?
Parte 2: Selezione di colonne e filtro di righe
Seleziona dalla tabella
museile colonne del nome, della tipologia e del prezzo del biglietto, rinominando quest’ultimaprezzonella stessa istruzioneSeleziona dalla tabella
museitutte le colonne tranne la gestione e il comune. Seleziona poi dalla tabellavisitatoriil museo, l’anno e i soli mesi estivi (giugno, luglio e agosto)
In select l’operatore : permette di indicare un intervallo di colonne contigue, ad esempio giu:ago.
Quali musei d’arte hanno un biglietto intero che costa al massimo 8 euro?
Quali musei si trovano nei comuni di Marina o di Borgo Antico? Usa l’operatore
%in%Quali musei sono gratuiti oppure a gestione statale?
Quali musei hanno avuto più di 5000 visitatori nel luglio 2025?
Usando un’unica sequenza di istruzioni collegate dalla pipe, ottieni l’elenco dei musei d’arte con il solo nome e il prezzo del biglietto, ordinati dal più caro al più economico
Parte 3: Pivoting
Trasforma la tabella
visitatoriin formato lungo, in un oggettovisitatori_longcon le colonnemuseo,anno,meseevisitatori. Stampa a video le dimensioni della nuova tabella e spiega come si ottiene il numero di righe. Quanti valori mancanti contiene la colonnavisitatori?Stampa a video la classe della colonna
mesee ordinavisitatori_longper museo, anno e mese: in che ordine compaiono i mesi? Trasforma poi la colonnamesein un factor con i livelli nell’ordine del calendario, ripeti l’ordinamento e commenta la differenza
Per non riscrivere più volte l’elenco dei mesi, salvalo in un vettore: mesi <- c("gen", "feb", "mar", "apr", "mag", "giu", "lug", "ago", "set", "ott", "nov", "dic").
Mostra le righe di
visitatori_longin cui i visitatori sono pari a 0 e quelle in cui il valore è mancante. Commenta la differenza tra i due casi alla luce delle informazioni sui datiTrasforma
visitatori_longin un oggettovisitatori_annicon una riga per museo e mese e una colonna per ciascun anno, e stampa a video i nomi delle colonne. Aggiungi poi una colonnavar_perccon la variazione percentuale dei visitatori tra il 2024 e il 2025, risolvendo il problema dei nomi delle colonne in entrambi i modi descritti nel suggerimento. Prova infine a calcolare la variazione scrivendo i nomi delle colonne senza apici inversi, cioè(2025 - 2024) / 2024 * 100, e commenta il risultato: R segnala un errore?
Con names_from = anno le nuove colonne prendono come nome i valori della colonna anno, cioè 2024 e 2025. Poiché iniziano con una cifra, non sono nomi validi secondo le regole di nomenclatura viste nella prima settimana. Ci sono due modi per gestirli:
- lasciare i nomi così come sono e richiamarli racchiudendoli tra apici inversi, ad esempio
`2025` - `2024` - ottenere direttamente nomi validi con l’argomento
names_prefixdipivot_wider, che aggiunge un prefisso ai nomi delle nuove colonne: connames_prefix = "anno_"le colonne si chiamanoanno_2024eanno_2025
Quali sono le cinque combinazioni museo-mese con la crescita percentuale più alta? E le cinque con il calo più forte? Commenta il risultato
Riporta
visitatori_longin formato largo, con una colonna per mese, e verifica consetequalche il risultato contenga le stesse righe della tabellavisitatoridi partenzaCommenta brevemente: per quali operazioni è più comodo il formato lungo, e per quali il formato largo?
Parte 4: Sintesi per gruppi
Calcola il totale annuo dei visitatori per ciascun museo e anno in tre modi: con
sum(visitatori), consum(visitatori, na.rm = TRUE)e contando il numero di mesi mancanti. Mostra solo le combinazioni museo-anno con almeno un mese mancante e commenta: quale dei due totali è più affidabile?Unisci a
visitatori_longle informazioni sui musei, salvando il risultato in un oggettovisitatori_completo. Stampa a video le dimensioni della tabella ottenutaPer ciascuna tipologia di museo e per ciascun anno, calcola il numero di musei e il totale dei visitatori. Commenta l’andamento della tipologia Storia
Per ciascuna tipologia, qual è stato nel 2025 il mese con più visitatori? Commenta il risultato
Dopo aver calcolato il totale per tipologia e mese, la tabella resta raggruppata per tipologia: un successivo filter(totale == max(totale)) lavora quindi all’interno di ciascuna tipologia.
Per il 2025, calcola il totale dei visitatori di ciascun museo e la sua quota sul totale dei visitatori della propria tipologia. Spiega perché le quote sommano a 1 all’interno di ciascuna tipologia
Supponendo che tutti i visitatori abbiano pagato il biglietto intero, calcola l’incasso stimato del 2025 per ciascun museo e ordina i musei dall’incasso più alto al più basso. Commenta i limiti di questa stima
Per ciascun tipo di gestione, calcola il numero di musei, il prezzo medio e il prezzo massimo del biglietto
Parte 5: Imputazione dei valori mancanti
In questa parte confronterai tre modi di sostituire i valori mancanti della colonna visitatori di visitatori_long. Salva i risultati in un oggetto visitatori_imp, aggiungendo una nuova colonna per ciascun metodo.
Aggiungi una colonna
imp_generalein cui i valori mancanti sono sostituiti con la media di tutti i valori disponibili della colonna. Mostra le righe con valore originale mancante e commenta: il valore imputato è plausibile per tutti i musei?Aggiungi una colonna
imp_museoin cui i valori mancanti sono sostituiti con la media dei valori disponibili dello stesso museo. Mostra di nuovo le righe con valore originale mancante e confronta i due metodiAggiungi una colonna
imp_mesein cui i valori mancanti sono sostituiti con la media dei valori disponibili dello stesso museo nello stesso mese. Dato che i dati coprono due anni, a cosa corrisponde in pratica il valore imputato? Perché questo metodo è più adatto dei precedenti per i musei con forte stagionalità?
Usa group_by seguito da mutate (e non da summarise), in modo da conservare tutte le righe. Ricorda di chiudere la sequenza con ungroup().
Per le sole combinazioni museo-anno con almeno un mese mancante, confronta in un’unica tabella il totale annuo senza imputazione (con
na.rm = TRUE) e i totali ottenuti con i tre metodi. Commenta le differenzePerché gli zeri del Museo del Risorgimento non vanno trattati come valori mancanti? Cosa accadrebbe se li trasformassi in
NAe li imputassi con il metodo del punto 30?Usando i valori imputati con il metodo del punto 30, calcola il totale annuo dei visitatori di ciascun museo nel 2024 e nel 2025, con una colonna per anno, e la variazione percentuale tra i due anni. Aggiungi il nome del museo subito dopo il codice e ordina i musei dalla crescita più alta alla più bassa. Commenta il risultato del Museo del Risorgimento
Parte 6: Il questionario di gradimento
Trasforma la tabella
rispostein formato lungo, in un oggettorisposte_longcon una riga per ogni risposta e le colonnecodice(codice della domanda) epunteggio, eliminando le risposte mancanti. Quante risposte mancanti sono state eliminate?Unisci a
risposte_longil testo delle domande contenuto nella tabelladomande. Conta le righe in cui il testo della domanda è mancante, spiega il problema e correggilo
Confronta i valori della colonna codice nelle due tabelle. La funzione toupper trasforma le lettere di una stringa in maiuscole.
Per ciascuna domanda calcola il numero di risposte e il punteggio medio. Quale aspetto della visita è valutato peggio? E quale meglio?
Costruisci una tabella con una riga per museo e una colonna per ciascuna domanda, contenente il punteggio medio. Aggiungi il nome del museo subito dopo il codice e ordina i musei per soddisfazione complessiva (
D5) decrescenteIl giudizio sul rapporto qualità/prezzo (
D4) cambia a seconda della provenienza dei visitatori? E la soddisfazione complessiva (D5) a seconda della fascia di età?Affianca, per ciascun museo che ha partecipato al questionario, il prezzo del biglietto e il punteggio medio sul rapporto qualità/prezzo. Ordinando per prezzo, osservi una relazione tra le due variabili?
Quanti questionari sono stati raccolti in ciascun museo? Ordina il risultato in senso decrescente
La funzione count(tabella, colonna, sort = TRUE) equivale a group_by(colonna) seguito da summarise(n = n()) e da un ordinamento decrescente.
Parte 7 (facoltativa): Rectangling e nesting
Questa parte riguarda argomenti accennati solo brevemente in aula. È facoltativa: provala dopo aver completato le altre parti, partendo dall’esempio che segue.
Finora abbiamo lavorato con tabelle in cui ogni cella contiene un singolo valore. Una colonna di una tibble può però essere anche una lista (list-column), in cui ogni cella contiene un oggetto più complesso: un vettore, una lista o perfino un’altra tabella. Dati di questo tipo sono frequenti quando si scaricano informazioni dal web o da un database, e vengono detti annidati.
Il rectangling consiste nel trasformare dati annidati in una tabella rettangolare, con un valore per cella. Si procede di solito in due passi:
unnest_longer“allunga” la tabella: ogni elemento della lista diventa una riga, e i valori delle altre colonne vengono ripetutiunnest_wider“allarga” la tabella: ogni elemento con nome diventa una colonna
Nel seguente esempio, per ciascuno studente la colonna esami contiene una lista di esami, e ogni esame è a sua volta una lista con due elementi, corso e voto:
library(tidyverse)
studenti <- tibble(
nome = c("Anna", "Luca"),
esami = list(
list(list(corso = "Statistica", voto = 28),
list(corso = "R Lab", voto = 30)),
list(list(corso = "Statistica", voto = 25))
)
)
studenti# A tibble: 2 × 2
nome esami
<chr> <list>
1 Anna <list [2]>
2 Luca <list [1]>
# primo passo: una riga per esame
esami_righe <- unnest_longer(studenti, esami)
esami_righe# A tibble: 3 × 2
nome esami
<chr> <list>
1 Anna <named list [2]>
2 Anna <named list [2]>
3 Luca <named list [2]>
# secondo passo: una colonna per ciascun elemento dell'esame
unnest_wider(esami_righe, esami)# A tibble: 3 × 3
nome corso voto
<chr> <chr> <dbl>
1 Anna Statistica 28
2 Anna R Lab 30
3 Luca Statistica 25
Il nesting è l’operazione inversa: nest raccoglie le righe di una tabella per gruppi, memorizzando ciascun gruppo in una tabella contenuta in una list-column (chiamata per default data); unnest ricostruisce la tabella di partenza:
voti <- tibble(nome = c("Anna", "Luca", "Sara"),
corso = c("A", "B", "A"),
voto = c(28, 24, 30))
voti_annidati <- nest(voti, .by = corso)
voti_annidati# A tibble: 2 × 2
corso data
<chr> <list>
1 A <tibble [2 × 2]>
2 B <tibble [1 × 2]>
voti_annidati$data[[1]]# A tibble: 2 × 2
nome voto
<chr> <dbl>
1 Anna 28
2 Sara 30
unnest(voti_annidati, data)# A tibble: 3 × 3
corso nome voto
<chr> <chr> <dbl>
1 A Anna 28
2 A Sara 30
3 B Luca 24
- Copia ed esegui nello script il seguente codice, che crea una tibble con le mostre temporanee organizzate nel 2025 da alcuni musei. Stampa a video la tabella e la classe della colonna
mostre, e descrivine la struttura
mostre <- tibble(
codice_museo = c("M02", "M03", "M05", "M12"),
mostre = list(
list(list(titolo = "Il paesaggio nell'Ottocento", mesi = 4, visitatori = 8200),
list(titolo = "Ritratti di famiglia", mesi = 3, visitatori = 3100)),
list(list(titolo = "Dinosauri in città", mesi = 6, visitatori = 9800)),
list(list(titolo = "Astrattismo italiano", mesi = 5, visitatori = 12400)),
list(list(titolo = "Il cielo d'inverno", mesi = 2, visitatori = 5600),
list(titolo = "Robot e intelligenza artificiale", mesi = 4, visitatori = 15300))
)
)Trasforma
mostrein una tabella rettangolare con una riga per mostra e le colonnecodice_museo,titolo,mesievisitatori, procedendo in due passi: prima conunnest_longere poi conunnest_wider. Stampa a video il risultato intermedio e quello finale e commenta cosa fa ciascuna delle due funzioniPer ciascun museo calcola il numero di mostre, il totale dei visitatori delle mostre e il numero medio di visitatori per mese di apertura delle mostre; aggiungi il nome del museo
Annida la tabella
museiper tipologia con la funzionenest. Stampa a video il risultato e il contenuto del primo elemento della colonnadata. Verifica poi consetequalche, riportando la tabella annidata alla forma originale conunnest, si ottengano le stesse righe dimusei
Parte 8: R base e tidyverse a confronto
- Ottieni il risultato del punto 9 (con il solo nome e il prezzo dei musei) usando R base, in due modi: con il puntamento con le parentesi quadre e con la funzione
subset
La funzione subset(tabella, condizione, select = colonne) di R base filtra le righe e seleziona le colonne in un’unica chiamata.
Seleziona da
visitatori_longle righe con più di 10000 visitatori, una volta con il puntamento con le parentesi quadre e una volta confilter. Confronta i due risultati e spiega la differenzaCalcola il numero medio di visitatori per mese (su tutti i musei e gli anni) con la funzione
tapplydi R base e congroup_byesummarise. Confronta la forma dei due risultati
tapply(vettore, gruppi, funzione, ...) applica la funzione ai valori del vettore separatamente per ciascun gruppo; gli argomenti successivi (ad esempio na.rm = TRUE) vengono passati alla funzione.
Calcola il totale annuo dei visitatori per museo e anno con l’istruzione
aggregate(visitatori ~ museo + anno, data = visitatori_long, FUN = sum). Confronta i totali dei musei con mesi mancanti con quelli ottenuti al punto 21: come trattaaggregatei valori mancanti?Ripeti il join del punto 22 con la funzione
mergedi R base. Confronta dimensioni, classe e ordine delle righe del risultato con quelli divisitatori_completo
Quando le colonne chiave hanno nomi diversi, in merge si indicano con gli argomenti by.x e by.y.
- Mostra le sei righe di
visitatori_longcon il maggior numero di visitatori, una volta con la funzioneorderdi R base e una volta conarrange. Alla luce dei punti 45-50, commenta brevemente vantaggi e svantaggi dei due approcci
Consegna
Per inviare la tua soluzione:
- Carica il file
hw04_cognome_nome.Rsu Teams, in risposta al compito assegnato
Valutazione
Totale punti disponibili: 110 punti
| Component | Punti |
|---|---|
| Es 1 - 40 e 45 - 50 | 100 |
| Es 41 - 44 (facoltativi) | - |
| Workflow & formattazione | 101 |
Footnotes
La valutazione al “Workflow & formattazione” tiene conto del rispetto delle regole di stile e del principio di riproducibilità del codice: lo script caricato deve funzionare senza errori su qualunque PC, eseguendolo con Source in una sessione con workspace vuoto e con i file dei dati nella sottocartella
datidel progetto, dando gli stessi risultati↩︎