3 Chiedere aiuto

v1.2 30/10/2023

3.1 Cosa c’è da imparare in questo capitolo.

Cercare aiuto in R è una necessità costante, anche per utenti esperti: la documentazione, prevalentemente in inglese, è dispersa in un gran numero di fonti e cercare una funzione che permetta di raggiungere un determinato scopo e poi impararne la sintassi e i valori che restituisce non è sempre facile.
In questo capitolo cercherò di:

  • dare il minimo di informazioni indispensabili per utilizzare le funzioni di aiuto (Help) di R e in particolare su come sfruttare al meglio il tab Help di RStudio

  • fornire un elenco delle risorse (siti web, forum, blog, etc.) più utili

  • dare qualche piccolo suggerimento per sviluppare una strategia di ricerca di aiuto efficace

Non tutto il materiale di questo capitolo è essenziale, benché leggerlo con attenzione potrebbe facilitare l’apprendimento di R. Se proprio hai fretta, puoi leggere solo il paragrafo 3.2.1 sul tab Help di RStudio e quello sulle strategie per cercare aiuto, e magari tornare a questo capitolo in seguito. I paragrafi con il titolo in corsivo sono degli approfondimenti.

3.1.1 Premessa 1: nessuno legge i manuali (figuriamoci i pigRi)!

Diciamo le cose come stanno: al giorno d’oggi ci aspettiamo che il software sia a prova di idiota (tipicamente noi) e che per imparare ad usarlo sia sufficiente fare qualche tentativo. Purtroppo, anche se molte funzioni di R sono abbastanza intuitive, anche nel nome56 e hanno parametri semplici da utilizzare, senza conoscerne l’ortografia (come si scrive il nome di una funzione o di un comando) e la sintassi (quali parametri sono necessari e come vanno forniti alla funzione) non si va proprio da nessuna parte. Insomma, un po’ di cose vi tocca leggerle. Prendi la figura 3.1 come un’amichevole esortazione: che tu sia pigR* o troppo occupat*, questo libro è il posto giusto per trovare il minimo indispensabile di informazioni su come cercare aiuto in R.


Leggi il f*****o manuale.

Figura 3.1: Leggi il f*****o manuale.


3.1.2 Premessa 2: ci sono molti modi di pelare un gatto (e documentarlo).

Un altro aspetto che può confondere le idee ai principianti è che in R lo stesso risultato può essere ottenuto in molti modi diversi. In pratica, anche per le cose più semplici, ci sono molti modi per pelare un gatto: questo dipende dal fatto che persone diverse hanno stili diversi di programmazione o usano per lo stesso scopo pacchetti diversi. Comprendere il codice scritto da altri è molto importante nell’apprendimento di R.


La pelle del gatto.

Figura 3.2: La pelle del gatto.


Immaginiamo di voler calcolare la mediana (un indicatore di tendenza centrale, adatto a descrivere un gran numero di distribuzioni continue, vedi capitolo 7) per un certo numero di vettori (vedi capitolo 4) della stessa lunghezza, riuniti in una tabella (in realtà un tipo particolare di data frame, una tibble, vedi capitolo 4). Si tratta di un’operazione banale, che richiede una sola funzione, ma il problema può essere approcciato in molti modi diversi, più o meno efficienti (in termini di tempo di calcolo) e più o meno leggibili (in termini di comprensibilità del codice). Un modo semplice per confrontare l’efficienza è quella di misurare il tempo necessario per svolgere un determinato calcolo. Nell’esempio successivo confronterò 5 modi diversi di calcolare la mediana sulle colonne di una tabella (qui di 8 colonne e 10.000 righe, ma puoi aumentare arbitrariamente sia il numero di righe che di colonne) usando funzioni di R base e del pacchetto tidyverse. Non preoccuparti ora di capire fino in fondo la sintassi, ma nota come nell’ouptput le mediane siano sempre uguali57, mentre cambia il tempo di esecuzione.

# creo un data frame (in realtà una tibble) con numeri casuali 
# estratti da una distribuzione uniforme
# installa il pacchetto e caricalo se necessario rimuovendo il segno di commento
# ed eseguendo i due comandi successivi
# install.packages ("tidyverse")
# require(tidyverse)
# numero di righe o casi nella tabella df
n_casi <- 10000
# creo la tibble
df <- tibble( a = rnorm(n_casi), b = rnorm(n_casi),
              c = rnorm(n_casi), d = rnorm(n_casi),
              e = rnorm(n_casi), f = rnorm(n_casi),
              g = rnorm(n_casi), h =rnorm(n_casi))

# il data frame
df
## # A tibble: 10,000 × 8
##          a      b       c      d      e      f      g      h
##      <dbl>  <dbl>   <dbl>  <dbl>  <dbl>  <dbl>  <dbl>  <dbl>
##  1 -0.613  -1.41  -0.648   2.07  -1.66  -0.209  0.565  1.13 
##  2 -0.467   1.23   1.17   -0.166 -0.553 -1.22   1.14  -0.961
##  3  0.774   0.337  0.0334 -1.86   2.02  -1.36   0.547 -0.656
##  4 -0.326   1.18  -0.609  -0.476 -0.717 -0.969  0.617 -2.35 
##  5  1.27   -0.676  0.480  -0.204  1.27   0.135  1.29   1.21 
##  6 -0.651   0.457  0.413  -0.789 -1.05  -0.286 -0.556 -2.30 
##  7  0.0842 -1.42   0.344   0.370 -0.212  2.57   0.529 -0.122
##  8  0.840  -1.05  -0.394  -1.22  -0.838  0.393  1.95   1.33 
##  9 -2.48    0.253  0.331  -1.11   1.69  -0.340  0.338  0.753
## 10  0.509   0.429  1.68    1.05   0.304  1.49   1.03   1.24 
## # ℹ 9,990 more rows
tempo0 <- Sys.time() # inizializza it tempo con il tempo di sistema
# 1. uso la stessa funzione su ciascuna colonna e unisco i risultati
# in un vettore con la funzione c()
mediane <- c(median(df$a), 
             median(df$b),
             median(df$c),
             median(df$d),
             median(df$e),
             median(df$f),
             median(df$g),
             median(df$h))
# memorizzo il valore del tempo trascorso
chiamate_multiple <- Sys.time()-tempo0
# stampo a console un messaggio informativo con la funzione cat(); \n crea
# un ritorno a capo
cat("mediane con chiamate singole\n")
## mediane con chiamate singole
# "stampo" a console il risultato
mediane
## [1]  0.011721821 -0.003522343  0.008740360  0.021575367  0.007703442
## [6]  0.007912362  0.003686531  0.012488419
# il risultato è un vettore, privo dell'attributo nomi 
# (identificante ogni elemento del vettore), 
# che poteva essere aggiunto usando, per esempio a = median(df$a)

# 2. uso di un loop sulle colonne
tempo0 <- Sys.time()
# inizializzo un vettore che riceverà i risultati
output <- vector("double", length = ncol(df))
# creo l'output con un loop for 
for (i in seq_along(df)) { # la sequenza 
  output[[i]] <- median(df[[i]]) # il corpo del loop 
} 
uso_un_loop <- Sys.time()-tempo0
cat("mediane con loop for\n")
## mediane con loop for
output
## [1]  0.011721821 -0.003522343  0.008740360  0.021575367  0.007703442
## [6]  0.007912362  0.003686531  0.012488419
# 3. uso di apply()
tempo0 <- Sys.time()
# apply "applica" la funzione median alla dimensione 2 (le colonne) di df
mediane_apply <- apply(df, 2, median)
uso_apply <- Sys.time()-tempo0
cat("mediane con apply\n")
## mediane con apply
mediane_apply
##            a            b            c            d            e            f 
##  0.011721821 -0.003522343  0.008740360  0.021575367  0.007703442  0.007912362 
##            g            h 
##  0.003686531  0.012488419
# 4. uso la funzione map_dbl() del pacchetto purrr del tidyverse
tempo0 <- Sys.time()
# map_dbl "applica" la funzione median alle colonne di df
le_mie_mediane <- map_dbl(df, median)
con_purrr <- Sys.time()-tempo0
cat("\nmediane con purrr:map_dbl()\n")
## 
## mediane con purrr:map_dbl()
le_mie_mediane
##            a            b            c            d            e            f 
##  0.011721821 -0.003522343  0.008740360  0.021575367  0.007703442  0.007912362 
##            g            h 
##  0.003686531  0.012488419
# creo un vettore con i tempi calcolati per ciascuna modalità
tempi <- c(multiple = chiamate_multiple, loop = uso_un_loop, 
                   apply = uso_apply, purrr = con_purrr)
cat("\ntempi di esecuzione\n")
## 
## tempi di esecuzione
tempi
## Time differences in secs
##    multiple        loop       apply       purrr 
## 0.003331900 0.006615162 0.003798962 0.003101110

Confronta la velocità di esecuzione dei diversi approcci (che potrebbe differire solo di pochi millisecondi).58 I diversi chunk di codice hanno una differente leggibilità: per alcuni è molto facile, anche per un principiante, capire qual’é l’intenzione di chi ha scritto il codice (e quindi è relativamente facile adattarlo alle proprie esigenze), altri (come l’uso di map_dbl()) sono piuttosto criptici ma molto concisi.
Quindi, quando (fra pochissimo!) sarai un* programmat* espert* cerca di avere pietà del tuo io passato e futuro (o dei pigri come te) e cerca di scrivere codice chiaro e interpretabile.
Nel frattempo vorrei rassicurare tutte e tutti che nessun gatto è stato scuoiato per realizzare questo libro.

3.2 L’aiuto di R.

Disclaimer questa sezione è veramente noiosa ma ti tocca leggerla, anche se frettolosamente.

R base e i diversi pacchetti sono documentati in molti modi diversi. Per ogni funzione è disponbile una descrizione, che comprende diversi elementi. Ogni pacchetto, sul sito del CRAN è accompagnato da un documento .pdf che descrive, in ordine alfabetico, tutte le funzioni. Per alcuni pacchetti, inoltre, sono disponibili dei documenti più descrittivi, generalmente disponibili come .pdf e/o .html, chiamati vignette. Tutti questi elementi possono essere raggiunti dall’interno di R o RStudio. La documentazione è tutta in inglese, ma usando Google translate in qualche caso è possibile ottenere una ragionevole traduzione. In realtà una conoscenza anche minima dell’inglese tecnico ti permetterà di comprendere abbastanza facilmente i documenti di aiuto. Tuttavia, devi tenere presente che i documenti di aiuto sono scritti da programmatori che possono essere più o meno capaci di comunicare in maniera semplice e efficace e sono, talvolta, pigRi e fRettolosi.

3.2.1 Il tab Help di RStudio.

Il tab Help del pannello Plot di RStudio (in genere in basso a destra, vedi capitolo 2) è il punto di accesso principale all’aiuto di R facilita enormemente la ricerca di informazione sulle funzioni.
Se clicchi sull’icona a forma di casetta in alto a sinistra nel tab (vedi figura 3.3) puoi raggiungere la home page dell’aiuto, con una serie di link utili.


Il tab Help.

Figura 3.3: Il tab Help.


In realtà, al di là dei suggerimenti contestuali che offre RStudio quando si digita qualcosa nella Console o in uno script, ti troverai frequentemente a cercare aiuto su una funzione specifica. È possibile farlo digitandone il nome nel campo di ricerca in alto a destra nel tab Help. Prova a digitare apply nel campo di ricerca, come mostrato nella figura 3.4.59.


L'aiuto sulla funzione apply.

Figura 3.4: L’aiuto sulla funzione apply.


Gli elementi importanti del testo che si ottiene invocando l’aiuto sono:

  • il nome della funzione e il pacchetto cui appartiene (in alto a sinistra, in questo caso apply {base})

  • un titolo descrittivo

  • una breve descrizione (Description) testuale della funzione

  • la sezione Usage, con la sintassi della funzione

  • la sezione Arguments con l’elenco degli argomenti della funzione, ed, eventualmente, dei loro nomi

  • la sezione Details che fornisce dettagli sull’uso della funzione ed eventuali richiami ad altre funzioni

  • la sezione Value, particolarmente importante perché descrive con precisione quello che la funzione restituisce60

  • la sezione References con riferimenti bligliografici per la funzione

  • la sezione See Also con richiami ipertestuali ad altre funzioni correlate

  • la sezione Examples, con esempi dell’uso della funzione61

  • un piè di pagina con la versione del pacchetto cui appartiene la funzione e un link ipertestuale all’indice del pacchetto62.

3.2.2 Funzioni per chiedere aiuto.

Oltre che utilizzando il tab Help in RStudio è ovviamente possibile accedere all’aiuto usando una serie di comandi dalla Console. Il blocco di codice successivo mostra una serie di comandi che permettono di accedere:

  • alla pagina di partenza dell’aiuto (help.start())

  • all’aiuto per una specifica funzione, il cui nome è noto (help() o ? seguito dal nome della funzione)

  • ad una ricerca generale nelle pagine di aiuto (help.search() o ?? seguito dalla parola chiave)

  • a tutte le funzioni che contengono una determinata parola chiave (apropos())

  • agli esempi per una determinata funzione (example())

  • ad una determinata vignetta di un dato pacchetto (vignette())

  • ad una ricerca sul sito di R, comprese le discussioni e i forum (RSiteSearch())

Prova a scrivere (o a copiare e incollare) i seguenti comandi in uno script e ad eseguirli uno alla volta (con command-invio alla fine di ogni comando):

# aprire la pagina di aiuto
help.start()
# aprire la pagina di aiuto per una pagina specifica
help("plot") 
# le virgolette sono opzionali; se non si usa l'opzione package verrà mostrato 
# l'aiuto per l'ultimo pacchetto  caricato in memoria (vedi capitolo 4)
?plot
# cercare nell'aiuto con una parola chiave
help.search("array") 
# in questo caso le virgolette sono obbligatorie
??array
# far girare il codice degli esempi di una funzione
example("pretty") 
# caricare una vignetta 
vignette("embedding", package = "car") 
# cercare le funzioni il cui nome contiene la parola ("plot")
apropos("plot", mode = "function")
# cercare nel sito di R una parola chiave
RSiteSearch("scatterplot")
# ottenere una lista dei data set presenti nei pacchetti caricati in memoria
data()

Ovviamente, in maniera piuttosto ricorsiva, puoi cercare aiuto su ciascuna di queste funzioni: prova a scrivere nella Console:

>help(help)

Un caveat: il risultato della funzione help(), se non usi l’opzione package potrebbe dipendere dall’ordine con il quale sono caricati i pacchetti; per esempio help("filter") restituirà un risultato diverso se è stato caricato, direttamente o indirettamente, il pacchetto dplyr; prova a scrivere ed eseguire le seguenti linee di codice (se library(dplyr) non funziona prova prima install.packages("tidyverse")):

library(dplyr)  
help(filter)  
help(filter, package ="dplyr")  
help(filter, package ="stats")  

3.3 Strategie per cercare aiuto (anche senza parere).

A seconda del tuo grado di “ignoranza” potrebbe essere opportuno usare strategie diverse per cercare aiuto:

  • se conosci il nome della funzione sulla quale vuoi cercare aiuto e sai di che pacchetto fa parte: usa il tab Help o la funzione help(): in RStudio l’aiuto apparirà nel tab Help, leggi almeno le sezioni Description e Usage; è sicuramente utile leggere Arguments e Value e, se non sei certo di aver capito, provare a far girare gli esempi con example()

  • se conosci il nome della funzione (anche approssimativamente) ma non sei cert* del pacchetto cui appartiene: in questo caso help() potrebbe non funzionare, perché restituisce un risultato solo se il pacchetto cui appartiene la funzione è caricato, cosa che è sempre vera con i pacchetti che vengono caricati con R base (base, datasets, graphics, grDevices, methods, stats, utils). In questo caso hai due opzioni:

    • usare help.search() o apropos(): il risultato potrebbe essere difficile da gestire, con un output lungo e non sempre chiarissimo.

    • usare siti di documentazione; ce ne sono due principali, che hanno i vantaggio di condurre la ricerca su praticamente tutti i pacchetti esistenti: RDocumentation ricerca il CRAN e Bioconductor e restituisce risultati sia per i pacchetti che per le funzioni; rdrr.io è molto più completo (ma afflitto da molti più banner pubblicitari) e, fra le altre cose, consente di far girare brevi scripts (snippets) direttamente nel browser.

  • se non conosci nemmeno il nome della funzione che stai cercando ma hai almeno una vaga idea su cosa vuoi fare: qui le cose si fanno difficili, specialmente se non hai una buona conoscenza della lingua inglese, però non disperare, perché hai diverse opzioni:

    • usare Google o il tuo motore di ricerca preferito per condurre una ricerca nel web; prova per esempio a digitare “ANOVA con R” o “aprire un file di testo con R” o “analisi dei network con R”: troverai un discreto numero di hits che, generalmente, ti rimanderanno ai pochi blog o siti su R in italiano o al materiale didattico di qualche corso universitario. Naturalmente la ricerca in inglese è decisamente più produttiva: prova con “ANOVA with R”, “importing text files with R”, “network analysis with R”. In entrambi i casi, con poco sforzo troverai probabilmente la soluzione che cerchi ed avrai il vantaggio di sfruttare l’algoritmo di Google per ottenere per primi i risultati più rilevanti

    • condurre la ricerca su uno dei molti forum o blog su R (vedi la sezione 3.5): in generale i risultati saranno un tantino più pertinenti e le spiegazioni più dettagliate.

    • studiare uno dei molti eccellenti libri (compreso questo) su R: lo so, richiede tempo, ma è un buon investimento

In molti casi potresti avere necessità più specifiche, come capire il significato di un messaggio di errore o risolvere un problema di programmazione specifico: anche in questo caso, a parte la lettura di un buon libro, una ricerca libera sul web, specialmente se condotta in inglese, ti permetterà di trovare rapidamente quello che cerchi. Se non lo trovi, puoi persino provare ad avviare un nuovo argomento su un forum: il principale vantaggio di R è probabilmente quello di avere una vasta comunità di utenti, che rispondono (quasi sempre) con gentilezza anche alle domande più stupide. Una lista dei forum e blog più importanti è nella sezione 3.5. Ricorda però che riceverai delle risposte chiare se poni il tuo problema in maniera chiara, per esempio con quello che si chiama reproducible example. Un po’ di traduzioni in italiano di post su questo tema sono qui.

3.4 Esercizi.

In attesa di tutorial e esercizi veri e propri realizzati con learnR prova a rispondere a queste domande:

  • Cosa restituisce il comando >help("library")?63 Dove appare l’output in RStudio? In R?

  • cosa succede se digiti nella Console >??library. Come potrai notare l’output di questo comando è piuttosto lungo (dipende da quanti pacchetti hai installato). Ti viene in mente qualche strategia per cercare più rapidamente i risultati più rilevanti?

  • quale comando useresti per trovare una funzione il cui nome contiene una determinata parola chiave (magari anche con una espressione regolare)?

  • che importanti informazioni riporta la sezione Value di una determinata pagina di aiuto? Prova con ?mean, ?saveRDS, ?points e confronta i risultati.

  • quale importante sito sulla documentazione di R consente anche di eseguire frammenti di codice?

3.5 Altre risorse.

Come sempre, ti indicherò soltanto le risorse minime che, in maniera forse arbitraria, ritengo migliori o più efficaci da un punto di vista didattico. Sentiti liber* di esplorare secondo il tuo estro il vasto mare della documentazione su R.

3.5.1 Risorse in italiano.

Documenti e pagine web

Ci sono pochissimi forum e wiki in Italiano e, purtroppo, non vengono aggiornati molto di frequente. La ragione principale è, probabilmente, che anche i programmatori e gli utenti italiani preferiscono l’inglese (e non hanno tutti i torti). Prova con questi blog e Wiki:

3.5.2 Risorse in inglese.

Documenti e pagine web.

I libri, documenti, pagine, forum e wiki su R in inglese sono talmente tanto numerosi che è difficile trovare la propria strada. A parte i due siti fondamentali sulla documentazione (RDdocumentation e rdrr.io), giusto per fare un po’ di ordine provo a citare almeno i 5 link principali per le categorie più importanti (tralasciando ovviamente la documentazione presente sul sito del CRAN). Il criterio di ordinamento è, semplicemente, quello del mio personale livello di gradimento.

  • Libri: eh, sì, ci sono i libri prima di tutto; con un po’ di abilità potete cercare nell’indice quello che vi serve e trovare rapidamente soluzioni ben strutturate. Provate innanzitutto questi (l’ultimo è per utenti avanzati):

  • Blog e forum: cito quelli che io visiterei (e visito) per primi se sto cercando risposte alle domande fondamentali; fra le altre cose, blog e forum hanno i “mi piace”65

    • R bloggers: il blog migliore su R con migliaia di contributori. Incidentalmente, qui trovate un interessante post sul cercare aiuto su R.

    • RStudio community decisamente più specializzato su RStudio e tidyverse

    • Stack Overflow: non è specifico su R ma qui potete trovare risposte alle vostre domande (se fate le domande giuste)

    • Applied R: un blog per utenti decisamente più esperti

  • siti web per l’apprendimento di R:

3.5.3 Niente video?

Come avrai notato, da questo capitolo non metto più riferiementi a video didattici: sono troppo volatili e, soprattutto ce ne sono tanti di pessimi e la tortura di guardarli per trovare quelli “buoni” è davvero insopportabile. Canali YouTube come DataCamp(https://www.youtube.com/@DataCamp) e Posit offrono video di corsi e seminari gratuiti preparati in maniera professionale. Se ritieni che guardare video sia un buon modo di apprendere, puoi partire da lì.


  1. in realtà questo non è proprio vero per la versione di base di R: molti pacchetti, specialmente quelli del tidyverse (vedi capitolo 1 e 4)↩︎

  2. cioé ciascuno dei modi di esecuzione restituisce lo stesso risultato; il realtà, se fai girare lo script diverse volte senza fissare il seme dei numeri casuali il data frame sarà sempre diverso, proprio perché è ottenuto estraendo, in modo casuale, numeri da una distribuzione uniforme!↩︎

  3. un modo più efficace per fare il confronto è usare la funzione microbenchmark() del pacchetto omonimo↩︎

  4. mentre digiti, se il pacchetto che contiene la funzione è caricato in memoria, vedrai apparire dei suggerimenti, che potrai completare scorrendo la lista con le frecce e premendo <invio> per confermare↩︎

  5. alcune funzioni, come quelle che salvano oggetti in una posizione di memoria non restituiscono valori, ma hanno quelli che si chiamano effetti collatelari, come il salvataggio di un file o la “stampa” di qualcosa in Console↩︎

  6. questo codice può essere fatto girare nella console usando la funzione example(), vedi dopo, anche se le versioni più recenti di RStudio forniscono un link Run example↩︎

  7. prova a cliccare su Index e ad esplorare la finestra che appare seguendo i diversi link↩︎

  8. ricordati che se digiti qualcosa nella console devi omettere il prompt, che già appare nella console…↩︎

  9. se vi sentite più orientati alla pirateria provate YaRrr!, che ha un approccio simile↩︎

  10. se è quello che usate per guidare la vostra vita↩︎