2014-07-04 4 views
5

Quando si utilizza , è frequente il caso in cui si desideri generare automaticamente frammenti di testo, in particolare gli elementi dell'elenco in uso . Per esempio;Modo semplice per visualizzare l'elenco di output nello stile "V, W, X, Y e Z" in R

The species of iris examined were `r cat(as.character(unique(iris$Species)), sep = ", ")`. 

che produrrebbe

Le specie di iris esaminati hanno setosa, versicolor, virginica.

Per leggere correttamente dovrebbe essere

Le specie di iris esaminate erano setosa, versicolor, e virginica.

C'è un modo semplice per farlo?

+0

Forse provare a recuperare i valori in anticipo e quindi utilizzare la formattazione corrente per tutti tranne l'ultimo valore e quindi concatenarlo con un "e" e il valore finale del tuo elenco? – ydaetskcoR

+1

Sì, fare una funzione per farlo non sarebbe troppo difficile. Potresti anche avere un parametro oxford.comma. Questo dovrebbe chiaramente essere impostato su true;) – Dason

+1

perché non si dovrebbe usare una virgola oxford? "setosa, veriscolor e virginica" implicano che versicolor e virginica sono entrambi setosa che probabilmente non è quello che vuoi – rawr

risposta

9

Questo è uno degli strumenti utili nel pacchetto pander

pander::p

p unisce elementi di un vettore in una stringa per il gusto di una stampa in linea. I parametri predefiniti vengono letti dai valori delle opzioni appropriate (vedere la descrizione dell'argomento per i dettagli). Questa funzione consente di inserire i risultati di un'espressione che restituisce una variabile inline, avvolgendo gli elementi vettoriali con la stringa fornita in wrap e separando gli elementi per separatore principale e finale (sep e copula). Nel caso di un vettore a due lunghezze, il valore specificato nella copula verrà utilizzato come separatore. È anche possibile controllare la lunghezza del vettore fornito modificando un valore intero specificato nell'argomento limite (predefinito su Inf).

esempio:

devtools::install_github('Rapporter/pander') 
## also available on cran: 
# install.packages('pander') 

library(pander) 

p(levels(iris$Species), wrap = '') 
# "setosa, versicolor and virginica" 

p(levels(iris$Species), wrap = '', copula = ', and ') 
# "setosa, versicolor, and virginica" 
4

Ecco una tale funzione

wordlist<-function(w, oxford=F) { 
    if(length(w)==1) return(w); 
    if(length(w)==2) return(paste(w[1],"and",w[2])); 
    paste0(paste(w[-length(w)], collapse=", "), 
     ifelse(oxford,",","")," and ", w[length(w)]) 
} 

wordlist(unique(iris$Species)) 
# [1] "setosa, versicolor and virginica" 

(con oxford impostato su false per esempio del PO)

+2

[pander :: p] (https://github.com/Rapporter/pander/blob/master/R/helpers.R#L39:L89) – rawr

+0

@rawr che p la funzione sembra esattamente quello che stavo cercando - puoi farne una risposta? Mentre questo è buono (+1), preferirei accettare pander :: p - imparare l'esistenza di pander :: p è più prezioso di una soluzione one off. – Corone

4

funzione ricorsiva per gestire gli ultimi due elementi diversamente:

wordlist <- function(w) { 
          if (length(w) <= 2) { 
          paste(w, collapse=' and ') # Or collapse=', and ' 
          } else { 
          paste(w[1], Recall(w[-1]), sep=', ') 
          } 
         } 
wordlist(LETTERS[1:6]) 
## [1] "A, B, C, D, E and F" 
3

Prova questo:

toStringAnd <- function(s) { 
    n <- length(s) 
    if (n < 2) s else toString(s[-n], paste("and", s[n])) 
} 

# test 
toStringAnd(tail(LETTERS)) 
## [1] "U, V, W, X, Y, and Z" 

Nota: Le risposte al di sopra della domanda, ma solo nel caso in cui si cambia idea e decidere di non avere una virgola prima il and quindi:

toStringAnd2 <- function(s) { 
    n <- length(s) 
    if (n < 2) s else paste(toString(s[-n]), "and", s[n]) 
} 

# test 
toStringAnd2(tail(LETTERS)) 
## [1] "U, V, W, X, Y and Z" 

Altre varianti sono possibili a seconda di ciò che si desidera, ad esempio non utilizzando una virgola se ci sono solo due componenti di input e utilizzando una virgola se ce ne sono più di due, ma il modello generale di combinazione di toString e paste dovrebbe essere chiaro a questo punto.

Aggiornamento Nota aggiunta e alcuni miglioramenti.

Problemi correlati