Che cosa accade eseguendo l'istruzione seguente?

ggplot(utenti, aes(x = eta, y = anno_iscrizione)) |>
  geom_point()

In ggplot2 un grafico si costruisce sommando dei layer con l'operatore +: ggplot() definisce i dati e le corrispondenze estetiche, geom_point() aggiunge lo strato dei punti. Con la pipe, il risultato di ggplot() verrebbe passato come primo argomento di geom_point(), che invece si aspetta una corrispondenza estetica: R restituisce un errore, e ggplot2 suggerisce esplicitamente di usare + al posto della pipe.

La seconda opzione è il risultato che si otterrebbe con +. La terza è la più insidiosa: un grafico con i soli assi è quello che si ottiene eseguendo ggplot(...) senza alcun layer geometrico, ma qui la chiamata a geom_point() produce un errore. La quarta è priva di fondamento.

  • True
  • False
  • False
  • False

Che differenza c'è tra i due grafici seguenti?

ggplot(utenti, aes(x = eta, y = anno_iscrizione)) +
  geom_point(aes(color = "blue"))

ggplot(utenti, aes(x = eta, y = anno_iscrizione)) +
  geom_point(color = "blue")

All'interno di aes() si indicano le corrispondenze tra le variabili dei dati e le caratteristiche estetiche del grafico (mapping). Scrivendo aes(color = "blue"), ggplot2 tratta "blue" come il valore di una variabile costante: le assegna il primo colore della sua tavolozza e crea una legenda. Per fissare un colore uguale per tutti i punti (setting) bisogna indicarlo fuori da aes(), come argomento del layer.

La seconda e la quarta opzione sono le più insidiose: il codice sembra chiedere i punti blu in entrambi i casi, ma solo il secondo grafico li disegna davvero di quel colore. La terza inverte la regola.

  • False
  • True
  • False
  • False

La tibble freq contiene la distribuzione degli utenti per categoria, con le colonne categoria e n (frequenze assolute). Quale istruzione produce il diagramma a barre corretto?

geom_col disegna barre la cui altezza è indicata da una variabile dei dati (qui n): è adatto quando le frequenze sono già state calcolate. geom_bar, invece, calcola le frequenze contando le righe della tabella per ciascuna modalità di x: si usa sui dati originari, ad esempio ggplot(utenti, aes(x = categoria)) + geom_bar().

La seconda opzione è la più insidiosa: applicata a freq, geom_bar conta le righe, una per categoria, e disegna barre tutte alte 1. La terza restituisce un errore, perché geom_bar non accetta un'estetica y (a meno di indicare stat = "identity", cioè di fare ciò che fa geom_col). La quarta rappresenta la distribuzione delle frequenze, non quella delle categorie.

  • False
  • False
  • True
  • False

Che cosa rappresenta il seguente grafico?

ggplot(prestiti_completo, aes(x = categoria, fill = genere_letterario)) +
  geom_bar(position = "fill")

Con position = "fill" le barre impilate vengono riscalate in modo da avere tutte altezza 1: ogni barra mostra la composizione percentuale della propria modalità di x (la categoria) secondo la variabile di fill (il genere letterario). È l'equivalente grafico di adorn_percentages("row") sulla tabella con la categoria in riga.

La seconda opzione descrive la posizione di default, position = "stack". La terza descrive position = "dodge". La quarta è la più insidiosa: descrive il grafico che si otterrebbe scambiando le variabili assegnate a x e a fill.

  • False
  • False
  • True
  • False

Che cosa fa il layer facet_wrap(vars(categoria)) aggiunto a un istogramma dell'età?

Le funzioni facet_wrap e facet_grid suddividono il grafico in più pannelli (facet), uno per ciascuna modalità della variabile indicata all'interno di vars(). Ogni pannello rappresenta il sottoinsieme dei dati della propria modalità, e per default tutti i pannelli condividono le stesse scale, il che facilita il confronto.

La seconda opzione è la più insidiosa: descrive l'effetto di aes(fill = categoria), che sovrappone i gruppi in un unico pannello. La terza e la quarta attribuiscono a facet_wrap funzioni che non ha.

  • True
  • False
  • False
  • False

Nel grafico seguente i punti e i boxplot rappresentano gli stessi dati:

ggplot(utenti, aes(x = categoria, y = eta)) +
  geom_jitter(width = 0.2) +
  geom_boxplot()

Che cosa si osserva?

In ggplot2 i layer si sovrappongono come fogli trasparenti, nell'ordine in cui vengono aggiunti con +: ogni layer viene disegnato sopra i precedenti. Qui i boxplot, aggiunti per ultimi, coprono i punti. Per vedere i punti sopra i boxplot si invertono i due layer, oppure si rende il boxplot trasparente (ad esempio con alpha = 0.5).

La seconda opzione è la più insidiosa: è l'impressione che si ha guardando molti grafici, in cui i punti sono stati aggiunti per ultimi. La terza è errata: l'ordine dei layer non produce errori. La quarta è errata: tutti i layer vengono disegnati.

  • True
  • False
  • False
  • False

Eseguendo ggplot(utenti, aes(x = eta)) + geom_histogram(), R stampa il messaggio `stat_bin()` using `bins = 30`. Pick better value with `binwidth`. Che cosa significa?

Il messaggio non è un errore: il grafico viene disegnato, ma con un numero di classi (30) fissato per default. Il numero e l'ampiezza delle classi influenzano molto la forma dell'istogramma, e la scelta va fatta guardando i dati e la loro unità di misura: per l'età, ad esempio, sono naturali classi di 5 o 10 anni.

La seconda opzione è la più insidiosa: confonde un messaggio informativo con un errore. La terza e la quarta attribuiscono al numero 30 un significato che non ha.

  • False
  • False
  • False
  • True

Nella grammatica dei grafici di ggplot2, che cosa stabilisce lo strato delle estetiche, definito con aes()?

Le estetiche (aesthetics) descrivono la corrispondenza tra le variabili dei dati e le caratteristiche visive del grafico: ad esempio aes(x = eta, y = anno_iscrizione, color = categoria) associa l'età all'asse orizzontale, l'anno di iscrizione a quello verticale e la categoria al colore. Per ogni estetica ggplot2 costruisce una scala e, quando serve, una legenda.

La seconda opzione descrive lo strato del tema (theme_*() e theme()), la terza quello delle geometrie (geom_*()). La quarta è la più insidiosa, perché titolo ed etichette degli assi riportano per default i nomi delle variabili indicate in aes(); si modificano però con labs().

  • False
  • False
  • False
  • True

Che differenza c'è tra aggiungere a un diagramma di dispersione con una curva di regressione (geom_smooth()) il layer coord_cartesian(xlim = c(0, 40000)) e il layer scale_x_continuous(limits = c(0, 40000))?

Lo strato delle coordinate stabilisce lo spazio in cui i dati vengono disegnati: coord_cartesian(xlim = ...) funziona come uno zoom, e tutti i calcoli (ad esempio la curva di geom_smooth()) usano tutti i dati. I limiti di una scala, invece, agiscono sui dati prima dei calcoli: i valori fuori dall'intervallo diventano mancanti e vengono esclusi (R lo segnala con un avvertimento), quindi la curva può cambiare.

La seconda opzione è la più insidiosa: la parte di grafico visibile è la stessa, ma i calcoli no. La terza inverte i due comportamenti. La quarta confonde coord_cartesian con coord_polar.

  • False
  • True
  • False
  • False

Dove compare la legenda nel grafico seguente?

ggplot(utenti, aes(x = eta, y = anno_iscrizione, color = categoria)) +
  geom_point() +
  theme(legend.position = "bottom") +
  theme_minimal()

I temi completi (theme_minimal(), theme_bw(), theme_classic(), ...) impostano tutti gli elementi non legati ai dati; la funzione theme() ne modifica invece solo alcuni. Come per gli altri layer, conta l'ordine: un tema completo aggiunto dopo theme() ne annulla le modifiche. Per spostare la legenda in basso bisogna scrivere prima theme_minimal() e poi theme(legend.position = "bottom").

La seconda opzione è la più insidiosa, perché sarebbe vera invertendo l'ordine dei due layer. La terza attribuisce a theme_minimal() un effetto che non ha. La quarta è errata: l'ordine sbagliato non produce errori, e proprio per questo il risultato va controllato.

  • False
  • False
  • True
  • False

Dopo aver disegnato un grafico ggplot2, si esegue l'istruzione ggsave("grafico.png", width = 7, height = 4). Che cosa succede?

Se l'argomento plot non viene indicato, ggsave salva l'ultimo grafico ggplot2 mostrato. Le dimensioni sono espresse per default in pollici (inches); si possono usare altre unità con l'argomento units, ad esempio units = "cm". Il formato del file viene ricavato dall'estensione del nome (.png, .pdf, .jpg, ...).

La terza opzione è la più insidiosa: indicare esplicitamente il grafico (ggsave("grafico.png", g, ...)) è una buona abitudine, ma non è obbligatorio. La seconda e la quarta sbagliano l'unità di misura di default.

  • False
  • False
  • False
  • True

Che effetto ha il layer scale_x_log10() su un diagramma di dispersione del PIL pro capite (asse x) e dell'aspettativa di vita (asse y)?

Le scale stabiliscono come i valori delle variabili diventano posizioni, colori o dimensioni. Con scale_x_log10() le posizioni sull'asse orizzontale sono proporzionali al logaritmo dei valori: le variabili molto asimmetriche, come il reddito, vengono "aperte" e le relazioni moltiplicative diventano lineari. I dati non vengono modificati e le etichette dell'asse mostrano i valori originali.

La prima e la terza opzione distrattrici confondono la scala con una trasformazione dei dati, che si otterrebbe ad esempio con aes(x = log10(gdp_per_cap)): in quel caso sull'asse comparirebbero i logaritmi. La quarta è priva di fondamento.

  • False
  • True
  • False
  • False

Che grafico produce il codice seguente?

ggplot(utenti, aes(x = eta)) +
  geom_histogram(binwidth = 10) +
  facet_grid(rows = vars(genere), cols = vars(categoria))

facet_grid() dispone i pannelli in una griglia: la variabile indicata in rows definisce le righe, quella indicata in cols le colonne. Qui si ottengono 2 righe (Femmina, Maschio) e 5 colonne (le categorie). facet_wrap(vars(variabile)), invece, usa una sola variabile e "avvolge" i pannelli su più righe per riempire lo spazio.

La seconda opzione è la più insidiosa, perché inverte righe e colonne. La terza descrive piuttosto facet_wrap(vars(genere, categoria), nrow = 1). La quarta descrive l'effetto di un'estetica di riempimento, non dei facet.

  • False
  • False
  • False
  • True

La tabella prestiti_mese_bib contiene il numero di prestiti n per ciascuna biblioteca (B01, B02, B03, B04) e mese (da 1 a 12). Che cosa disegna il codice seguente?

ggplot(prestiti_mese_bib, aes(x = mese, y = n)) +
  geom_line()

geom_line() collega i punti in ordine di x all'interno di ciascun gruppo. I gruppi sono definiti dalle variabili qualitative associate a un'estetica (ad esempio color = biblioteca) oppure esplicitamente con group = biblioteca. Qui non c'è nessuna estetica di questo tipo: le 48 righe formano un unico gruppo, e la linea passa per tutti i punti, con tratti verticali in corrispondenza di ciascun mese.

La seconda opzione si otterrebbe con aes(group = biblioteca), la terza con aes(color = biblioteca). La quarta è la più insidiosa: geom_line() non calcola medie, rappresenta i valori così come sono nella tabella.

  • False
  • True
  • False
  • False

Che cosa si trova nel portale ggplot2 extensions (exts.ggplot2.tidyverse.org)?

Grazie alla sua struttura a layer, ggplot2 può essere esteso da altri package che aggiungono nuovi layer, temi, scale o modi di combinare i grafici: ad esempio ggridges (curve di densità sovrapposte), ggrepel (etichette che non si sovrappongono), patchwork (composizione di più grafici), gganimate (animazioni). Il portale ne raccoglie un'ampia selezione, con un'immagine di esempio e il link alla documentazione di ciascuno.

La quarta opzione è la più insidiosa: le estensioni sono package a sé stanti, che vanno installati con install.packages() e caricati con library(). La seconda confonde il portale con la documentazione di ggplot2, la terza con gli strumenti di intelligenza artificiale.

  • False
  • True
  • False
  • False

Dopo aver caricato il package patchwork, che cosa produce l'istruzione g1 / g2, dove g1 e g2 sono due grafici ggplot2?

Il package patchwork ridefinisce alcuni operatori aritmetici per comporre più grafici in un'unica figura: g1 + g2 (o g1 | g2) li affianca, g1 / g2 li mette uno sopra l'altro, e le parentesi permettono composizioni più complesse, come (g1 | g2) / g3. Il layer plot_annotation() aggiunge un titolo complessivo e le lettere che identificano i singoli grafici.

La seconda opzione è la più insidiosa, perché descrive l'operatore + (o |). La terza confonde la composizione di grafici con l'aggiunta di layer a un unico grafico. La quarta ignora che patchwork ridefinisce l'operatore / per i grafici.

  • True
  • False
  • False
  • False

Che cosa fa la funzione ggplotly() del package plotly, applicata a un grafico ggplot2 salvato nell'oggetto g?

plotly è una libreria JavaScript per la grafica interattiva, accessibile da R con l'omonimo package. Il modo più semplice per usarla è costruire il grafico con ggplot2 e trasformarlo con ggplotly(g), senza imparare una nuova sintassi. Il risultato è un htmlwidget, che si visualizza nel pannello Viewer o nel browser e si salva in un file html.

La terza opzione è la più insidiosa: la conversione avviene direttamente, senza dover riscrivere il grafico. La seconda descrive piuttosto ggsave(). La quarta è errata: ggplotly() lavora proprio sui grafici ggplot2.

  • False
  • False
  • True
  • False

Il grafico g è stato costruito con ggplot2 usando il layer geom_point_interactive(aes(tooltip = id_utente)) del package ggiraph. Che cosa si ottiene stampando semplicemente g?

ggiraph fornisce le versioni interattive delle geometrie di ggplot2 (geom_point_interactive, geom_col_interactive, geom_jitter_interactive, ...), con nuove estetiche come tooltip e data_id. Il grafico si costruisce come un normale grafico ggplot2, e stampato da solo resta statico: diventa interattivo solo quando viene passato alla funzione girafe(), che lo trasforma in un htmlwidget.

La seconda opzione è la più insidiosa, perché descrive il risultato di girafe(ggobj = g). La terza è errata: i layer interattivi sono pensati proprio per essere sommati agli altri layer di ggplot2. La quarta descrive l'effetto di geom_text().

  • True
  • False
  • False
  • False

In un grafico ggiraph dei singoli utenti, i punti sono disegnati con geom_jitter_interactive(aes(tooltip = id_utente, data_id = categoria)). Che cosa succede passando il mouse su un punto?

In ggiraph l'estetica tooltip stabilisce il testo dell'etichetta che compare passando il mouse su un elemento, mentre data_id identifica gli elementi da evidenziare insieme: tutti gli elementi con lo stesso valore di data_id vengono evidenziati contemporaneamente. Con data_id = categoria, passando il mouse su uno studente si evidenziano tutti gli studenti; con data_id = id_utente si evidenzierebbe solo il punto corrente. L'aspetto degli elementi evidenziati si modifica con le opzioni di girafe(), ad esempio opts_hover().

La seconda opzione è la più insidiosa, perché scambia i ruoli delle due estetiche. La terza e la quarta attribuiscono a data_id effetti che non ha.

  • True
  • False
  • False
  • False

Nell'istruzione hchart(prestiti_cat_genere, "column", hcaes(x = categoria, y = n, group = genere_letterario)) del package highcharter, qual è il ruolo di hcaes()?

highcharter dà accesso da R alla libreria JavaScript Highcharts. La funzione hchart() riceve la tabella dei dati, il tipo di grafico ("column", "bar", "line", "scatter", ...) e le corrispondenze tra variabili ed elementi del grafico, indicate con hcaes(), l'analogo di aes(); group crea una serie per ciascuna modalità. Il grafico si modifica poi con le funzioni hc_*() concatenate con la pipe, ad esempio hc_title() o hc_plotOptions().

La terza opzione è la più insidiosa: hchart() con il tipo "column" rappresenta valori già calcolati (come geom_col), e le frequenze vanno calcolate prima, ad esempio con count(). La seconda descrive hc_add_theme(), la quarta piuttosto ggplotly().

  • False
  • False
  • True
  • False

Per rappresentare con dygraph() l'andamento mensile dei prestiti delle quattro biblioteche, in quale forma devono essere organizzati i dati?

dygraphs è pensato per le serie storiche: rappresenta una o più serie, una per colonna, rispetto a un indice temporale. I dati vanno quindi portati in formato largo (ad esempio con pivot_wider(), una colonna per biblioteca) e trasformati in un oggetto xts con xts(colonne, order.by = date). Al grafico si aggiungono poi altre funzionalità con le funzioni dy*(), ad esempio dyRangeSelector() per scegliere l'intervallo temporale da visualizzare.

La seconda opzione è la più insidiosa: è il formato tidy richiesto da ggplot2, non quello richiesto da dygraph(). La terza confonde dygraphs con plotly. La quarta perde l'informazione sulle date e sulle biblioteche.

  • False
  • True
  • False
  • False

Come si salva in un file un grafico interattivo costruito con plotly, ggiraph, highcharter o dygraphs?

I quattro package producono htmlwidgets: grafici costruiti in R ma disegnati da librerie JavaScript, che funzionano in una pagina web. Per questo si salvano in file html con htmlwidgets::saveWidget(grafico, "file.html"), e si possono inserire in un documento Quarto in formato html o in un sito.

La seconda opzione è la più insidiosa: ggsave() salva i grafici ggplot2 in formati statici, nei quali l'interattività non può esistere. La terza riguarda le animazioni di gganimate. La quarta è errata, come mostra la prima opzione.

  • False
  • False
  • False
  • True

Qual è la differenza principale tra transition_time(year) e transition_states(year) in un grafico animato con gganimate?

Entrambe le funzioni mostrano i dati un "momento" alla volta, interpolando le posizioni nei fotogrammi intermedi. transition_states() è pensata per variabili qualitative (o numeriche con pochi valori): gli argomenti transition_length e state_length regolano la durata dei passaggi e delle pause, e nel titolo si usa {closest_state}. transition_time() è pensata per una variabile temporale: non ci sono pause e nel titolo si usa {frame_time}.

La seconda opzione è la più insidiosa, perché per anni equidistanti e senza pause le due animazioni si assomigliano molto. La terza e la quarta attribuiscono alle due funzioni limiti e comportamenti che non hanno.

  • True
  • False
  • False
  • False

In un'animazione costruita con transition_time(year) sui dati gapminder (anni dal 1952 al 2007, ogni 5 anni), il titolo labs(title = "Anno: {frame_time}") mostra valori come Anno: 1953.27. Perché?

Per default l'animazione ha 100 fotogrammi, mentre gli anni sono 12: gganimate calcola le posizioni nei fotogrammi intermedi interpolando tra un anno e l'altro, e {frame_time} riporta il tempo di ciascun fotogramma, che quasi sempre cade tra due anni. Tra le parentesi graffe si può scrivere un'espressione R, ad esempio {round(frame_time)}.

La terza opzione è la più insidiosa: aumentando il numero di fotogrammi i fotogrammi intermedi diventano ancora di più. La seconda è errata, perché year contiene numeri interi. La quarta confonde il tempo dei dati con la durata dell'animazione.

  • False
  • True
  • False
  • False

In un'animazione con transition_states(continent) i paesi di un continente vengono mostrati uno stato alla volta. Senza indicazioni particolari, nel passaggio da un continente all'altro i punti si spostano e cambiano colore, come se un paese africano "diventasse" un paese americano. Come si evita questo effetto?

Per costruire i fotogrammi intermedi gganimate abbina le righe di uno stato a quelle dello stato successivo e le sposta gradualmente. L'abbinamento si basa sui gruppi: indicando group = country, ogni paese è un oggetto distinto e, poiché compare in un solo stato, non viene abbinato a nessun altro. Gli oggetti senza corrispondenti entrano ed escono dall'animazione: enter_fade(), enter_grow(), exit_shrink(), ... stabiliscono il modo.

La seconda opzione è la più insidiosa: ease_aes() cambia l'andatura del movimento, non gli oggetti che si muovono. La terza aggiunge una traccia degli stati passati, ma non cambia gli abbinamenti. La quarta è errata.

  • False
  • True
  • False
  • False

Quanto dura l'animazione prodotta da animate(p, nframes = 100, fps = 20)?

In animate() l'argomento nframes stabilisce il numero di fotogrammi e fps (frames per second) quanti fotogrammi vengono mostrati ogni secondo: la durata è quindi nframes / fps = 100 / 20 = 5 secondi. In alternativa a fps si può indicare direttamente la durata con l'argomento duration. Più fotogrammi rendono l'animazione più fluida, ma richiedono più tempo di calcolo.

La seconda opzione confonde la durata con il numero di fotogrammi al secondo, la terza con il numero di fotogrammi, la quarta moltiplica invece di dividere.

  • False
  • True
  • False
  • False

Che cosa mostra, in ciascun fotogramma, l'animazione seguente?

ggplot(prestiti_mese_bib, aes(x = mese, y = n, color = biblioteca)) +
  geom_line() +
  geom_point() +
  transition_reveal(mese)

transition_reveal() "scopre" i dati progressivamente lungo la variabile indicata, ed è l'animazione naturale per un grafico a linee: la linea mostra il percorso compiuto fino al momento corrente. I punti, invece, rappresentano singole osservazioni: in ogni fotogramma viene mostrato solo quello del momento corrente. Per lasciare visibili anche i punti precedenti si può aggiungere shadow_mark().

La seconda opzione è la più insidiosa, perché descrive il risultato che si otterrebbe aggiungendo shadow_mark(). La terza ignora geom_line(). La quarta descrive un grafico in cui le linee sono già interamente visibili, mentre transition_reveal() le disegna progressivamente.

  • False
  • False
  • True
  • False