Come ho detto all’inizio di questo corso, R non è solo un software per fare analisi dei dati, ma può essere visto come un toolkit comprensivo che vi assiste per tutto il corso del vostro progetto, dalla raccolta dati alla fase di reporting. Oggi vedremo come R può essere utile in quest’ultima fase, quando volete sviluppare un prodotto sulla base del vostro lavoro di analisi dei dati. Tale “prodotto” può essere qualsiasi tipo di documento che usate per riportare il vostro lavoro. Può essere una pagina HTML (da caricare sul vostro blog), un documento PDF, un documento MS Word, una presentazione (anche in HTML o PDF), e così via.
Lo strumento che useremo è R Markdown, una libreria che produce documenti sulla base di file sintassi in formato .Rmd
. La cosa più importante di R Markdown è che permette di integrare la sintassi di diversi linguaggi di programmazione, quindi lo stesso file .Rmd
può contenere la sintassi per analizzare i dati (con R, ma non solo) e il testo che apparirà nel report.
Inoltre, R Markdown permette di scegliere se visualizzare la sintassi delle analisi o solo il risultato di tale analisi (per esempio una figura o una tabella). In questo modo è possibile produrre documenti che altre persone possono utilizzare per riprodurre le vostre analisi dati (assumendo che abbiano i dati).
Il linguaggio in cui è scritta la parte testuale di un documento R Markdown è chiamato markdown. Il compiler che R Markdown usa per integrare tutti i diversi linguaggi è la libreria knitr
.
La sessione di oggi riguarderà le basi di R Markdown. Naturalmente imparare a usare R Markdown con una certa confidenza è una questione di pratica, come tutto quello che abbiamo visto in questo corso. Ci sono molte risorse online per aiutarvi a usare R Markdown. Per esempio:
Prima di tutto, per ogni cosa che faremo oggi, RStudio diventa estremamente utile – non è strettamente necessario, ma non ha assolutamente senso fare queste cose con la GUI base di R. Inoltre, per creare documenti in così tanti formati diversi, R Markdown fa uso dell’applicazione Pandoc, che è già integrata in RStudio. Se non avete RStudio, dovrete installare Pandoc separatamente.
In secondo luogo, per usare R Markdown, occorre prima installare il pacchetto rmarkdown
. In RStudio, cliccando su File -> New File -> R Markdown...
, vi verrà chiesto se volete installare alcune nuove librerie. Confermando installerete rmarkdown
. Ovviamente questo può anche essere fatto manualmente nel solito modo:
In terzo luogo, per poter produrre documenti PDF, è necessario avere LaTeX. Questo è un po’ più complicato, perché LaTeX non viene fornito insieme a RStudio. Tuttavia, la libreria tinytex
(che è una dipendenza di rmarkdown
) permette di installare TinyTex, una distribuzione LaTeX leggera e multipiattaforma che non occuperà troppo spazio sul vostro computer, ed è facilmente integrata con R. Potete installare TinyTex con la funzione install_tinytex()
.
Ora siete pronti a lavorare con R Markdown.
La sintassi di R Markdown essenzialmente è composta da tre elementi:
È la prima cosa che si mette all’inizio di ogni file R Markdown. Include le informazioni che si vogliono mettere all’inizio del documento (il titolo, l’autore, tutto ciò che viene chiamato “front matter”) e le opzioni globali che saranno applicate all’intero documento. L’intestazione utilizza la sintassi YAML.
Include:
Per esempio, l’intestazione YAML di questo file che state visualizzando è la seguente:
---
title: "Laboratorio R per le scienze sociali -- Giorno 8"
author: Federico Vegetti
output:
html_document:
toc: true
theme: spacelab
highlight: pygments
---
In generale potete produrre documenti in HTML, PDF or MS Word cambiando l’opzione output
. Per produrre un file HTML (da aprire con un web browser):
---
title: "Questo è un documento HTML"
author: Federico Vegetti
output: html_document
---
Per produrre un file PDF:
---
title: "Questo è un documento PDF"
author: Federico Vegetti
output: pdf_document
---
Per produrre un file Word:
---
title: "Questo è un documento Word"
author: Federico Vegetti
output: word_document
---
Potete anche usare R Markdown per fare slide per una presentazione. Queste possono essere in PDF (usando il motore LaTeX Beamer) o HTML (da aprire con un browser web ed eventualmente salvare in PDF usando ioslides o Slidy). Generalmente preferisco esportare direttamente in PDF usando Beamer. In questo caso l’intestazione sarà:
---
title: "Questa è una presentazione in PDF"
author: Federico Vegetti
output: beamer_presentation
---
Tuttavia, le persone che non usano LaTeX tendono a preferire Slidy, che produce slide che si possono aprire con qualsiasi browser e salvare comunque in PDF:
---
title: "Questa è una presentazione in HTML"
author: Federico Vegetti
output: slidy_presentation
---
Questa parte riguarda il corpo del documento. Il contenuto ovviamente dipende da voi, ma ci sono alcune dritte di formattazione che è utile sapere.
*corsivo*
(asterisco singolo ai lati della parola) verrà rappresentato come: corsivo.**grassetto**
(asterisco doppio ai lati della parola) verrà rappresentato come: grassetto`codice` nel testo
(accento grave ai lati della parola) verrà rappresentato come: codice
nel testo[testo da visualizzare](URL)
quindi il link [UniTo](https://www.unito.it/)
sarà visualizzato come: UniTo$
, quindi la formula $\sum_{i=1}^n x_i$
verrà visualizzata come: \(\sum_{i=1}^n x_i\)Per dare un titolo alle diverse sezioni del documento occorre usare i cancelletti #
in un numero variabile a seconda del “livello” dell’intestazione (se è la sezione principale, una sottosezione, ecc.). La logica è la seguente.
# Titolo 1
## Titolo 2
### Titolo 3
Per esempio, il titolo della sezione principale di questo documento (“Scrivere report con R Markdown”) ha un singolo cancelletto, quello della sezione “Corpo del testo” ha due cancelletti, e quello della sezione “Titoli di sezione” ha tre cancelletti.
Notare che il singolo cancelletto si usa anche per i titoli delle slide.
Per fare elenchi puntati si utilizza il singolo trattino, e per i punti secondari occorre una indentatura di 4 spazi (o 2 tab). Per esempio, l’elenco qui sotto:
- item 1
- item 2
- item 3
- subitem 1
- subitem 2
viene rappresentato nel seguente modo:
Stessa logica si applica acli elenchi numerati, con la differenza che si possono usare diversi tipi di numerazioni (incluse le lettere):
1. item 1
2. item 2
3. item 3
a. subitem 1
b. subitem 2
L’elenco qui sopra viene rappresentato nel seguente modo:
La sintassi per includere immagini nel testo è strutturata nel seguente modo: ![didascalia](nome_file.estensione)
(la parte [didascalia]
può anche essere lasciata vuota, in quel caso non ci sarà didascalia).
Lo stesso approccio funziona con immagini prese direttamente da internet. Per esempio il seguente codice:
![Fonte: https://xkcd.com/1796/](https://imgs.xkcd.com/comics/focus_knob.png)
diventa:
Uno dei punti di forza di R Markdown è che si può scrivere codice R (o in altri linguaggi) direttamente nel testo, e questo sarà valutato e renderizzato esattamente allo stesso modo del testo. La struttura è relativamente semplice: è necessario aprire e chiudere la parte di testo in cui scriviamo il codice con tre accenti gravi ```
, e specificare il nome del linguaggio in cui si scrive il codice tra parentesi graffe. Per esempio, se vogliamo scrivere codice R:
```{r}
Qui si scrive la sintatti
```
Per esempio lo snippet seguente:
```{r}
x <- sample(0:10, 1)
x
```
viene rappresentato in questo modo:
## [1] 3
Notare che R Markdown funziona anche con altri linguaggi di programmazione. Per esempio possiamo usare Python! Il seguente codice:
```{python}
x = 6*3
print(x)
```
viene rappresentato in questo modo:
## 18
Tenete solo conto che se volete usare Python con R Markdown dovrete (1) avere Python installato sul vostro computer e (2) installare la libreria reticulate
in R.
Le parentesi graffe con il nome del linguaggio di programmazione scelto servono anche per dire a R come comportarsi con i code snippets. Ad esempio, potremmo voler mostrare solo il risultato delle operazioni svolte con il codice R, senza mostrare il codice stesso. Al contrario, potremmo voler solo mostrare il codice senza che R lo elabori. In molti casi queste opzioni riguardano il rendering del codice (cosa mostrare, come mostrarlo). Ecco le più importanti:
echo
: è l’opzione tramite la quale diciamo a R Markdown di mostrare il codice assieme ai risultati o meno. In caso vogliate mostrare solo i risultati occorre aggiungere l’opzione echo = FALSE
nell’intestazione dello snippet. Per esempio, il seguente codice:```{r, echo = F}
x <- sample(0:10, 1)
x
```
farà in modo che R Markdown mostri solo il risultato, senza visualizzare il codice utilizzato per produrlo:
## [1] 0
eval
: al contrario, se volete mostrarte del codice ma non volete che R lo elabori, dovete specificare l’opzione eval = FALSE
. In tal caso R tratterà il codice come se fosse un commento alla sintassi. Quindi il seguente snippet:```{r, eval = F}
x <- sample(0:10, 1)
x
```
Verrà renderizzato nel seguente modo (senza mostrare il risultato sotto):
results
: questa opzione dice a R Markdown se mostrare i risultati dell’elaborazione e come mostrarli. Si può scegliere di non mostrare per nulla i risultato con l’opzione con results = 'hide'
(che produrrà un risultato simile a eval = F
, tuttavia in questo caso il codice sarà elaborato e produrrà dei risultati “internamente”). Lo snippet qui sotto:```{r, results = 'hide'}
x <- sample(0:10, 1)
x
```
Verrà renderizzato nel seguente modo (senza mostrare il risultato sotto):
È anche possibile chiedere a R Markdown di mostrare il risultato dell’elaborazione in formato codice Markdown (o HTML), che verrà quindi valutato e renderizzato nel file come se fosse testo. In altre parole, il risultato in tal caso non verrà mostrato all’interno del pannello in cui R Markdown mostra i risultati di un’elaborazione, ma entrerà a far parte del testo. Questo effetto si ottiene con l’opzione results = 'asis'
.
Per fare un esempio, in condizioni normali il seguente snippet:
```{r}
print("Alcune **parole** a caso")
```
Verrà visualizzato come:
## [1] "Alcune **parole** a caso"
Tuttavia, specificando l’opzione results = 'asis'
, la stringa di caratteri mostrata da R verrà trattata come input testuale da renderizzare in Markdown. Quindi il seguente snippet:
```{r, results = 'asis'}
print("Some **Markdown** code")
```
Verrà visualizzato come:
[1] “Some Markdown code”
warning
, error
e message
sono opzioni tramite le quali si dice a R Markdown come trattare, rispettivamente, i messaggi di avviso, i messaggi di errore, e tutti gli altri messaggi che vengono prodotti dall’elaborazione del codice (ad esempio quelli che compaiono quando si carica la libreria dplyr
). Questo non significa che R non elaborerà il vostro codice. Quindi in caso specifichiate error = FALSE
e R incontri un errore nel vostro codice, si rifiuterà comunque di proseguire nella compilazione del file R Markdown (e riporterà un errore in console).Se fate un grafico, questo sarà mostrato direttamente nel documento. Dipende poi da voi se mostrare anche il codice usato per produrre il grafico o solamente il risultato, in ogni caso avete la possibilità di mostrare tutto. Facciamo un esempio usando il data frame cars
(che è sempre presente nella memoria di R base). Lo snippet seguente:
```{r}
plot(cars, pch = 20)
```
Verrà visualizzato come:
Potete anche aggiungere alcune opzioni riguardanti il grafico nell’intestazione dello snippet. Per esempio, nel codice seguente chiediamo che la dimensione del grafico sia il 50% di quella predefinita (che è stata impostata nell’intestazione YAML all’inizio del documento), che l’immagine sia posizionata al centro del documento, e vogliamo aggiungere una didascalia al grafico:
```{r, out.width = '50%', fig.align = 'center', fig.cap = 'Uno scatter plot'}
plot(cars, pch = 20)
```
E verrà visualizzato come:
Le tabelle sono difficili da gestire in ogni software di scrittura di documenti, e R Markdown purtroppo non fa eccezione. Tuttavia, ci sono alcune funzioni per semplificare la vita.
Prima di tutto, è possibile mostrare l’output semplicemente come risultato in R.
Nell’esempio qui sotto, usiamo il dataset iris
per estrarre la larghezza e la lunghezza media di sepali e petali per diverse specie di piante di iris. Usiamo dplyr
per farlo, e per evitare di ottenere tutti i messaggi di caricamento impostiamo l’opzione message = FALSE
. Il seguente codice:
```{r, message = F, echo = F}
library(dplyr)
iris %>%
group_by(Species) %>%
summarize_all(~mean(.))
```
Verrà visualizzato come:
## # A tibble: 3 x 5
## Species Sepal.Length Sepal.Width Petal.Length Petal.Width
## <fct> <dbl> <dbl> <dbl> <dbl>
## 1 setosa 5.01 3.43 1.46 0.246
## 2 versicolor 5.94 2.77 4.26 1.33
## 3 virginica 6.59 2.97 5.55 2.03
È possibile utilizzare la funzione kable()
dalla libreria knitr
(il “traduttore” di R Markdown) per convertire la tabella in linguaggio Markdown, in modo da renderizzarla automaticamente (notate che se usate kable
non occorre specificare result = 'asis'
). Quindi il seguente codice:
```{r, message = F, echo = F}
library(knitr)
iris %>%
group_by(Species) %>%
summarize_all(~mean(.)) %>%
kable()
```
Verrà visualizzato come:
Species | Sepal.Length | Sepal.Width | Petal.Length | Petal.Width |
---|---|---|---|---|
setosa | 5.006 | 3.428 | 1.462 | 0.246 |
versicolor | 5.936 | 2.770 | 4.260 | 1.326 |
virginica | 6.588 | 2.974 | 5.552 | 2.026 |