2012-11-01 7 views
8

Ich möchte Vektoren von lateinischen und griechischen Text zusammenführen, um Plottitel, Achsenbeschriftungen, Legendeneinträge usw. zu generieren. Ich habe ein Trivial zur Verfügung gestellt Beispiel unten. Ich kann nicht herausfinden, wie man die griechischen Buchstaben in ihrer ursprünglichen Form wiedergeben kann. Ich habe verschiedene Kombinationen von expression, parse und apply zum paste Befehl versucht, aber ich war nicht in der Lage, den Code zu vektorisieren, der leicht gemischten lateinischen/griechischen Text für den Fall eines einzelnen Ausdruckes erzeugt (zB expression("A ("*alpha*")") ist im Fall passend eines einzelnen Ausdrucks). innerhalb der legend() AnweisungR: Erstellen von Vektoren lateinischen/griechischen Ausdruck für Plot Titel, Achsenbeschriftungen oder Legenden

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)) 

Könnten Sie mir bitte mit der apply() Aussage helfen? Es erfordert eine gewisse Modifikation, um die gewünschte Ausgabe zu erzeugen (d. H. A (α), B (β), C (γ), D (δ)). Danke im Voraus.

Antwort

7

Hier ist eine Alternative, die parse() vermeidet, und arbeitet mit dem Beispiel in Ihrem ersten Kommentar erwähnt @ MNEL die nette Antwort:

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

Danke, Josh. Ihre Lösung ist sehr robust für verschiedene Eingaben. Könnten Sie erklären, warum 'A (B)', 'A * B' und' A ~ B' in der 'substitutive'-Anweisung funktionieren, während' A B' nicht funktioniert? Könnten Sie auch für die neuen Benutzer kommentieren, warum die 'as.'-Syntax benötigt wird? Ich habe gelesen, dass "substitute" einen unausgewerteten Ausdruck zurückgibt, daher ist es sinnvoll, auf den Ausdruck "substitute" mit "as.expression" einzuwirken. Was ist mit 'as.name'? – user001

+1

@ user001 - Wie Sie wahrscheinlich wissen, [[dieser Abschnitt] (http://cran.r-project.org/doc/manuals/R-lang.html#Computing-on-the-language) der "R-Sprache Definition "ist ein guter Ausgangspunkt, um sich an Rs Sprachelementen zu orientieren und sie zu manipulieren. 'substitute()' kann als erstes Argument eine syntaktisch gültige Aussage nehmen. 'A B' ist nicht" erlaubt ", weil es syntaktisch gültig ist. (Können Sie sich irgendeine R-Anweisung vorstellen, die an der Befehlszeile mit dieser Form eingegeben wurde? Ich dachte nicht!). –

+1

@ user001 - 'substitute()' gibt * generell * keine Objekte der Klasse "expression" zurück. (Siehe den "Value" -Abschnitt von "? Substitute", und spiele mit "class (substitute())", um zu sehen, was ich meine: "class (substitute (x)); class (substitute (x (y))) ; class (substitute ({x; y})); class (substitute (expression (x))) usw.) Ich benutze 'as.expression()', um * was auch immer * zu einem Expression-Objekt zurückzuholen. Ausdrücke sind ein Typ eines Vektors, so dass 'sapply()' nur die mehreren länge-1-Ausdrücke zu einem einzigen Länge-4-Expressionsvektor verkettet. Siehe '? As.name', um etwas über' as.name() 'zu erfahren. Hoffe das hilft! –

3

Verwenden Sie nicht apply erstellen Sie einen Vektor von Ausdrücken.

Verwenden Sie stattdessen 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

Wenn Sie ~ innerhalb der Ausdrücke enthalten. Angesichts Ihrer aktuellen Workflow, so scheint es am einfachsten sep = '' mit sep = '~' im Aufruf 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

Es könnte zu ersetzen noch deutlicher sein sprintf zu verwenden, um die Zeichenketten zu bilden, die Ihre Expressionsvektor werden wird .

Wenn Sie Zeichenfolgen mit Leerzeichen einfügen möchten, müssen Sie diese Zeichenfolgen in Anführungszeichen innerhalb der Zeichenfolge einschließen. Beispielsweise.

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

Vielen Dank für Ihre sehr hilfreiche Lösung. Können Sie mir sagen, wie Leerzeichen in die Labels eingefügt werden können, ohne explizit '~' Zeichen zu verwenden? Zum Beispiel ist die Neudefinition von 'Spaltennamen (Daten)' in 'c (" A ~ a "," B ~ b "," C ~ c "," D ~ d ") akzeptabel, während die Neudefinition in' c ("A a "," B "," C c "," D d ")" ist nicht (unter Verwendung der letzteren Definition ergibt sich ein 'unerwarteter Symbol'-Fehler, wenn die Anweisung 'parse' ausgeführt wird). Vielleicht, wenn ich die Tilde-Zeichen in den Spaltennamen nicht will, sollte ich eine String-Ersetzungsfunktion verwenden, um alle Leerzeichen durch Tilden vor der 'Parse'-Anweisung zu ersetzen? – user001

+1

Siehe meine Bearbeitung ...... – mnel

+0

Danke @Mnel. Ich möchte in der Lage sein, Leerzeichen in die Spaltennamen einzubeziehen (z. B. "A a" anstelle von "A"). Die 'Parse'-Anweisung schlägt jedoch fehl, wenn' Spaltennamen 'ein Leerzeichen enthält. Wenn der Platz durch eine Tilde ersetzt wird (z. B. "A ~ a" anstelle von "A a"), schlägt die Anweisung "Parse" nicht mehr fehl. Die Verwendung von '~' als 'sep' in' paste' funktioniert immer noch nicht für 'colname' mit einem Leerzeichen wie" A a ". – user001