Menu

Stampare output e leggere input in R (print, cat, readline)

Come funziona l'output in R, tra stampa automatica, print() contro cat() e message(), e come leggere l'input dell'utente con readline() e readLines().

Questa pagina include editor eseguibili: modifica, esegui e vedi subito l'output.

Come funziona la stampa in R

R ha un'abitudine che nessun altro linguaggio diffuso condivide: in console non ti serve affatto un'istruzione di stampa. Scrivi il nome di una variabile, premi invio e R ne stampa il valore. È la stampa automatica (auto-printing), ed è il motivo per cui i tutorial di R sono pieni di espressioni isolate.

Ma la stampa automatica ha un confine rigido: scatta solo per le espressioni al livello più esterno. Dentro un ciclo for o il corpo di una funzione, un valore isolato viene valutato e buttato via in silenzio:

La x da sola viene stampata (è al livello più esterno), il primo ciclo non stampa proprio niente, e il secondo stampa 1, 2, 3 perché lo chiede in modo esplicito. "Il mio ciclo gira ma non mostra niente" è una delle domande più frequenti su R, e questa è tutta la risposta: dentro cicli e funzioni, stampare è sempre compito tuo. (Lo stesso vale quando esegui uno script con Rscript: ciò che funzionava riga per riga in console può ammutolire dentro un ciclo.)

print() mostra un valore come lo vede R, il che lo rende lo strumento giusto per ispezionare i dati e quello sbagliato per un output curato:

Saltano all'occhio due cose. Le stringhe mantengono le virgolette: print() ti mostra una rappresentazione fedele, e le virgolette ti dicono che è un valore di tipo carattere. E ogni riga inizia con un numero tra parentesi quadre come [1]: è l'indice del primo elemento su quella riga, quindi quando un vettore lungo va a capo, la parentesi di ogni riga ti dice da quale elemento riprende. È un aiuto alla lettura per i vettori, non rumore.

Se vuoi un output in stile print() ma senza virgolette, lo fanno sia print(x, quote = FALSE) sia noquote(x), ma di solito a quel punto quello che vuoi davvero è cat().

cat(): output per le persone

cat() (concatena e stampa) scrive testo grezzo: niente virgolette, niente prefissi di indice, e gli argomenti uniti da spazi. Il prezzo di questo controllo è che niente viene aggiunto al posto tuo, nemmeno l'a capo:

Dimenticare il "\n" è il rito di passaggio universale di cat(): senza, il pezzo di output successivo si incolla sulla stessa riga. Fai diventare un riflesso chiudere le chiamate a cat() con "\n".

La differenza di virgolette tra le due funzioni è in realtà una differenza in ciò che mostrano. print() mostra le sequenze di escape come le hai scritte; cat() le interpreta:

print() mostra \t e \n letteralmente tra virgolette: utile quando stai verificando cosa contiene esattamente una stringa. cat() li trasforma in una vera tabulazione e in un vero a capo: utile quando produci output. Scegli in base allo scopo: print() per ispezionare, cat() per presentare.

Report formattati: sprintf() + cat()

Gli argomenti separati da spazi di cat() arrivano fino a un certo punto. Per un output allineato e formattato, con decimali fissi e contatori riempiti, costruisci la stringa con sprintf() e passala a cat():

%-8s riempie ogni nome fino a 8 caratteri e %6.2f dà a ogni punteggio la stessa larghezza e due decimali, così le colonne si allineano. Questa coppia è il cavallo da tiro di R base per messaggi di avanzamento e piccoli report testuali (i codici di formato sono trattati in stringhe).

message() e warning(): l'altro canale

cat() e print() scrivono sullo standard output, il flusso che contiene i risultati del programma. message() e warning() scrivono sullo standard error, il flusso per i commenti sull'esecuzione:

A schermo sembrano simili, ma la separazione conta nel momento in cui l'output viene reindirizzato: manda lo stdout del tuo script in un file e il 42 finisce nel file mentre la nota di stato resta nel terminale. Ecco la regola pratica: risultati su stdout con cat(), commenti su stderr con message(). È anche il motivo per cui message() (e non cat()) è il modo educato con cui funzioni e pacchetti parlano ai loro utenti: chi li chiama può zittirli con suppressMessages() senza perdere l'output vero.

warning() è più forte, del tipo "qualcosa non va, ma sono andato avanti", e quando uno script gira con Rscript gli avvisi vengono raccolti e mostrati tutti insieme alla fine invece che sul momento (vedi debug degli errori per capire come leggerli).

Leggere l'input dell'utente: readline() e readLines()

Per fare una domanda all'utente in una sessione interattiva (la console di R o RStudio), usa readline(). Questi esempi non si possono eseguire nell'editor integrato, perché l'esecutore della pagina non ha un pannello di input, quindi provali in una console locale:

# Interactive sessions only:
name <- readline("What is your name? ")
cat("Hello,", name, "\n")

age <- as.numeric(readline("Your age? "))
cat("Next year you'll be", age + 1, "\n")

Due cose da ricordare. readline() restituisce sempre una stringa: convertila con as.numeric() prima di fare calcoli, e controlla se il risultato è NA nel caso l'utente abbia scritto qualcosa che non è un numero. E in uno script non interattivo, readline() non aspetta affatto l'input: restituisce subito "".

Per uno script eseguito con Rscript che deve leggere input passato con una pipe o digitato, leggi invece dallo standard input:

# In a script run as: echo "Ada" | Rscript greet.R
line <- readLines(con = "stdin", n = 1)
cat("Hello,", line, "\n")

readLines(con = "stdin") senza n legge tutte le righe fino alla fine dell'input: la forma standard per gli script che fanno da filtro. Leggere file di dati è un altro lavoro, con strumenti migliori; parti da read-csv quando il tuo input è un dataset e non una tastiera.

Cosa ti porti a casa

  • La stampa automatica avviene solo al livello più esterno: dentro cicli e funzioni, chiama tu print() o cat().
  • print() ispeziona: virgolette sulle stringhe, prefissi di indice [1], sequenze di escape mostrate letteralmente.
  • cat() presenta: testo grezzo, argomenti uniti da spazi, e il "\n" lo metti tu.
  • sprintf() + cat() è lo schema di R base per un output formattato e allineato.
  • I risultati vanno su stdout (cat), i commenti su stderr (message, warning).
  • readline() per l'input interattivo (sempre una stringa!); readLines(con = "stdin") per Rscript.

Prossimo passo: gli operatori, cioè aritmetici, di confronto e gli operatori logici che guidano ogni condizione che scriverai.

Domande frequenti

Qual è la differenza tra print() e cat() in R?

print() mostra un valore come R lo rappresenta: le stringhe mantengono le virgolette e ogni riga riceve un prefisso di indice come [1]. cat() scrive testo grezzo senza virgolette, senza indici e senza andare a capo da solo (aggiungi tu "\n"). Usa print() per ispezionare oggetti, cat() per produrre output destinato alle persone.

Perché il mio ciclo in R non stampa niente?

La stampa automatica avviene solo per le espressioni al livello più esterno. Dentro un ciclo for o il corpo di una funzione, una x da sola viene valutata e scartata in silenzio. Avvolgila in modo esplicito: print(x) oppure cat(x, "\n").

Come si legge l'input dell'utente in R?

In una sessione interattiva, readline("prompt: ") legge una riga digitata come stringa (convertila con as.numeric() se ti serve un numero). In uno script eseguito con Rscript, readline() non aspetta: leggi invece dallo standard input con readLines(con = "stdin", n = 1).

Come si stampa senza virgolette in R?

Usa cat("hello\n"): non aggiunge mai virgolette. Se vuoi proprio il comportamento di print() senza virgolette, funzionano anche print("hello", quote = FALSE) o noquote("hello").

Illustrazione dei linguaggi di programmazione di Coddy

Impara a programmare con Coddy

INIZIA