2012-11-01 16 views
8

Chciałbym scalić wektory tekstu łacińskiego i greckiego, aby wygenerować tytuły działek, etykiety osi, wpisy do legend itp. Dostarczyłem trywialne przykład poniżej. Nie wiem, jak wyrenderować greckie litery w ich rodzimej postaci. Próbowałem różnych kombinacji expression, parse i do polecenia , ale nie udało mi się wektoryzować kodu, który łatwo generuje mieszany tekst łaciński/grecki dla przypadku pojedynczego wyrażenia (np. expression("A ("*alpha*")") jest odpowiedni w przypadku pojedynczego wyrażenia).R: tworzenie wektorów wyrażenia łacińskiego/greckiego dla tytułów działek, etykiet osi lub legend

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

mógłbyś mi pomóc z rachunku apply() w rachunku legend()? Wymaga pewnych modyfikacji w celu wytworzenia pożądanego wyniku (tj. A (α), B (β), C (γ), D (δ)). Z góry dziękuję.

Odpowiedz

7

Oto alternatywa, która pozwala uniknąć parse() i współpracuje z przytoczonym przykładzie w pierwszym komentarzu do użytkownika @ mnel miłą odpowiedź:

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

Dzięki, Josh. Twoje rozwiązanie jest bardzo odporne na różne dane wejściowe. Czy możesz wyjaśnić, dlaczego 'A (B)', 'A * B' i' A ~ B' działają w wyrażeniu 'substitute', a' A B' nie? Czy mógłbyś również skomentować nowych użytkowników, dlaczego wymagana jest składnia 'as'? Czytałem, że 'substitute' zwraca nieuznane wyrażenie, więc działanie na wyjściu' substitute' z 'as.expression' ma sens. A co z 'as.name'? – user001

+1

@ user001 - Jak zapewne wiesz, [ta sekcja] (http://cran.r-project.org/doc/manuals/R-lang.html#Computing-on-the-language) w języku "R" Definicja "jest dobrym punktem wyjścia do oparcia się na elementach języka R i jak nimi manipulować. 'substitute()' może przyjąć jako swój pierwszy argument dowolne składniowo poprawne wyrażenie. 'A B' nie jest" dozwolone ", ponieważ jest poprawne składniowo. (Czy możesz wymyślić jakieś polecenie R wpisane w wierszu poleceń, który ma tę formę? Myślałem, że nie!). –

+1

@ user001 - 'substitute()' nie * ogólnie * zwraca obiekty klasy "expression". (Zobacz sekcję "Value" w '? Substitute' i baw się z' class (substitute()) ', aby zobaczyć co mam na myśli:' class (substitute (x)); class (substitute (x (y))) class (substitute ({x; y})); class (substitute (expression (x))) 'itp.) Używam' as.expression() 'do wymuszania * tego, co * zwraca do obiektu wyrażenia. wyrażenia są rodzajem wektora, więc 'sapply()' po prostu łączy kilka wyrażeń długości-1 w jeden wektor ekspresyjny o długości 4. Zobacz '? As.name', aby dowiedzieć się więcej o' as.name() '. Mam nadzieję że to pomoże! –

3

Nie używaj apply, aby utworzyć wektor wyrażeń.

Zamiast tego należy użyć 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

Jeśli chcesz dołączyć ~ w wyrażeniach. Biorąc pod uwagę Twój aktualny przepływ pracy, wydaje się najłatwiejszy do zastąpienia sep = '' z sep = '~' w ramach wezwania do 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

może być jeszcze wyraźniejsze w użyciu sprintf tworząc ciągi znaków, które staną się wektor ekspresyjny .

Jeśli chcesz dołączyć ciągi znaków zawierające spacje, musisz zawinąć te ciągi w cudzysłowy w ciągu znaków. Na przykład.

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

Dzięki za bardzo pomocne rozwiązanie. Czy możesz mi powiedzieć, w jaki sposób spacje mogą zostać włączone do etykiet bez jawnego używania znaków '~? Na przykład, przedefiniowanie 'colnames (data)' do 'c (" A ~ a "," B ~ b "," C ~ c "," D ~ d ")' jest dopuszczalne, a przedefiniowanie do 'c (" A a "," B b "," C c "," D d ")' nie jest (użycie tej ostatniej definicji daje błąd "nieoczekiwanego symbolu" podczas wykonywania instrukcji 'parse'). Być może, jeśli nie chcę znaków tyldy w nazwach kolumn, powinienem użyć funkcji zamiany ciągów, aby zastąpić wszystkie spacje tyldami przed wyrażeniem 'parsować'? – user001

+1

Zobacz moją edycję ...... – mnel

+0

Dzięki @mnel. Chcę móc umieszczać spacje w 'colnames' (np." A a "zamiast" A "). Jednak instrukcja 'parsować' nie działa, gdy' colnames' zawiera spację. Jeśli miejsce zostanie zastąpione tyldą (np. "A ~ a" zamiast "A a"), to instrukcja 'parsowania' nie zawiedzie. Użycie '~' jako 'sep' w' paste' nadal nie działa dla 'colname' z spacją typu" A a ". – user001

Powiązane problemy