2012-11-01 16 views
8

Vorrei unire i vettori di testo latino e greco per generare titoli di trama, etichette degli assi, voci delle legende, ecc. Ho fornito un banale esempio sotto. Non riesco a capire come rendere le lettere greche nella loro forma nativa. Ho provato varie combinazioni di expression, parse e apply al comando paste ma non sono stato in grado di vettorializzare il codice che genera facilmente testo misto Latino/Greco per il caso di una singola espressione (ad esempio, expression("A ("*alpha*")") è adatto nel caso di una singola espressione).R: creazione di vettori di espressioni latine/greche per titoli di plot, etichette degli assi o legende

data<-matrix(seq(20),nrow=5,ncol=4,byrow=TRUE) 
colnames(data)<-c("A","B","C","D") 
greek<-c(" (alpha)"," (beta)"," (gamma)"," (delta)") 
matplot(data) 
legend(1,max(data),fill=c("black","red","green","blue"),apply(matrix(paste(colnames(data),greek,sep=""),nrow=4,ncol=1),1,expression)) 

La prego di aiutarmi con la apply() dichiarazione all'interno dell'istruzione legend()? Richiede qualche modifica per produrre l'uscita desiderata (cioè A (α), B (β), C (γ), D (δ)). Grazie in anticipo.

risposta

7

Ecco un'alternativa che evita parse(), e funziona con l'esempio citato nel suo primo commento alla bella risposta di @ mnel:

greek <- c("alpha", "beta", "gamma", "delta") 
cnames <- paste(LETTERS[1:4], letters[1:4]) 

legend_expressions <- 
sapply(1:4, function(i) { 
    as.expression(substitute(A (B), 
        list(A = as.name(cnames[i]), B = as.name(greek[i])))) 
}) 

matplot(data) 
legend(1,max(data),fill=c("black","red","green","blue"),legend_expressions) 

enter image description here

+0

Grazie, Josh. La tua soluzione è molto robusta per diversi input. Potresti spiegare perché 'A (B)', 'A * B' e' A ~ B' funzionano nell'istruzione 'sostitutiva', mentre' A B' no? Puoi anche commentare per i nuovi utenti perché è necessaria la sintassi 'as'? Ho letto che 'sostituto' restituisce un'espressione non valutata, quindi agire sull'output di' sostituto' con 'as.expression' ha senso. Che dire di 'as.name'? – user001

+1

@ user001 - Come probabilmente saprai, [questa sezione] (http://cran.r-project.org/doc/manuals/R-lang.html#Computing-on-the-language) del "R Language Definizione "è un buon punto di partenza per appoggiarsi sugli elementi del linguaggio di R e su come manipolarli. 'sostituto()' può prendere come primo argomento qualsiasi affermazione sintatticamente valida. 'A B' non è" permesso "perché è sintatticamente valido. (Riesci a pensare a qualsiasi istruzione R digitata sulla riga di comando che ha quel modulo? Non pensavo!). –

+1

@ user001 - 'sostituto()' non * generalmente * restituisce oggetti di classe "espressione". (Vedi la sezione "Valore" di "? Sostituto', e gioca con' class (sostituto()) 'per vedere cosa intendo:' class (sostituto (x)); class (sostituto (x (y))) ; class (sostituto ({x; y})); class (sostituto (expression (x))) 'ecc.) Uso' as.expression() 'per forzare * qualunque * ritorna a un oggetto espressione. le espressioni sono un tipo di vettore, quindi 'sapply()' concatena le diverse espressioni length-1 in un singolo vettore di espressione length-4. Vedi '? As.name' per informazioni su' as.name() '. Spero che questo ti aiuti! –

3

Non utilizzare apply creare un vettore di espressioni.

Utilizzare invece parse(text = ...).

.expressions <- paste(colnames(data),greek,sep="") 
legend_expressions <-parse(text = .expressions) 

matplot(data) 
legend(1,max(data),fill=c("black","red","green","blue"),legend_expressions) 

enter image description here

Se si desidera includere ~ all'interno delle espressioni. Dato il flusso di lavoro attuale, sembrerebbe più semplice per sostituire sep = '' con sep = '~' all'interno della chiamata a paste

.expressions <- paste(colnames(data),greek,sep="~") 
legend_expressions <-parse(text = .expressions) 

matplot(data) 
legend(1,max(data),fill=c("black","red","green","blue"),legend_expressions) 

enter image description here

Potrebbe anche essere più chiaro di utilizzare sprintf per formare le stringhe di caratteri che diventerà il vostro vettore di espressione .

Se si desidera includere stringhe di caratteri che includono spazi, sarà necessario racchiudere queste stringhe tra virgolette all'interno della stringa. Per esempio.

greek <- c("alpha", "beta", "gamma", "delta") 
other_stuff <- c('hello world','again this','and again','hello') 

.expressions <- mapply(sprintf, colnames(data), other_stuff, greek, 
         MoreArgs = list(fmt = '"%s %s"~(%s)')) 

.expressions 
##       A       B       C       D 
## "\"A hello world\"~(alpha)" "\"B again this\"~(beta)" "\"C and again\"~(gamma)"  "\"D hello\"~(delta)" 

legend_expressions <-parse(text = .expressions) 

matplot(data) 
legend(1,max(data),fill=c("black","red","green","blue"),legend_expressions) 

enter image description here

+0

Grazie per il vostro molto soluzione utile. Potresti dirmi come gli spazi potrebbero essere incorporati nelle etichette senza usare esplicitamente i caratteri '~'? Ad esempio, ridefinendo 'colnames (data)' a 'c (" A ~ a "," B ~ b "," C ~ c "," D ~ d ")" è accettabile mentre ridefinendo in 'c (" A a "," B b "," C c "," D d ")' non lo è (usando quest'ultima definizione si dà un errore 'inaspettato di simbolo' quando si esegue l'istruzione' parse'). Forse se non voglio i caratteri tilde nei nomi delle colonne, dovrei usare una funzione di sostituzione delle stringhe per sostituire tutti gli spazi con tilde prima dell'istruzione 'parse'? – user001

+1

Vedere la mia modifica ...... – mnel

+0

Grazie a @mnel. Voglio essere in grado di includere degli spazi nei 'colnames' (ad es." A a "anziché" A "). Tuttavia, l'istruzione 'parse' fallisce quando' colnames' include uno spazio. Se lo spazio viene sostituito con una tilde (ad es. "A ~ a" anziché "A a"), allora l'istruzione 'parse' non fallisce più. L'uso di '~' come 'sep' in' paste' continua a non funzionare per un 'colname' con uno spazio come" A a ".I nomi di – user001

Problemi correlati