2016-07-26 12 views
3

Я хотел бы сделать метки с надписью с надписью, как в mylabels, в следующем примере. Тем не менее, я не хочу, чтобы передать код их, я хочу, чтобы идти до 3^УРОВНЕЙ, где Уровни постояннойR: Генерировать метки осевой осевой линии с надписями программно (акцент на программном)

library(ggplot2) 

LEVELS = 4 

mylabels = c(
    expression(paste(3^4,"= 81")), 
    expression(paste(3^3,"= 27")), 
    expression(paste(3^2,"= 9")), 
    expression(paste(3^1,"= 3")), 
    expression(paste(3^0,"= 1"))) 
mylabels 
length(mylabels) 


df=data.frame(x=runif(40),y=(runif(40)*10)%%5) 
p = ggplot(df,aes(x,y)) + 
    geom_point() + 
    scale_y_continuous(breaks = 0:LEVELS, labels = mylabels) 
p 

жестких кодированный verison работает отлично. Но я не могу получить его программно. Следующее:

mylabels=c(paste("expression(paste(3^",LEVELS:0,'," = ',3^(LEVELS:0),'"))',sep="")) 

не правильно оценить в таблице (например, он пишет слово «выражение» и т.д. на этикетке). Она создает:

[1] "expression(paste(3^4,\" = 81\"))" "expression(paste(3^3,\" = 27\"))" "expression(paste(3^2,\" = 9\"))" 
[4] "expression(paste(3^1,\" = 3\"))" "expression(paste(3^0,\" = 1\"))" 

и то, что я хочу это:

expression(paste(3^4, "= 81"), paste(3^3, "= 27"), paste(3^2, 
"= 9"), paste(3^1, "= 3"), paste(3^0, "= 1")) 

ли возился с распадом, noquote, Eval, Sprintf и т.д.

ответ

3

Вы должны построить вектор экспрессии в виде сначала, а затем проанализировать его с помощью parse(), который возвращает вектор выражения, соответствующий вектору входных символов. Застройка вектор символов лучше всего делать с sprintf():

mylabels <- parse(text=sprintf('paste(3^%d,\' = %d\')',LEVELS:0,3^(LEVELS:0))); 
mylabels; 
## expression(paste(3^4,' = 81'), paste(3^3,' = 27'), paste(3^2,' = 9'), 
##  paste(3^1,' = 3'), paste(3^0,' = 1')) 

plot


Другие советы:

1: Предоставляя пример кода, который зависит от генерации случайных чисел, пожалуйста, позвоните set.seed() прежде чем генерировать какую-либо случайность.

2: Функция является переменной и возвращает вектор выражения, элементы которого соответствуют входным аргументам. Таким образом, вы можете заменить

c(
    expression(paste(3^4,"= 81")), 
    expression(paste(3^3,"= 27")), 
    expression(paste(3^2,"= 9")), 
    expression(paste(3^1,"= 3")), 
    expression(paste(3^0,"= 1")) 
) 

с

expression(
    paste(3^4,"= 81"), 
    paste(3^3,"= 27"), 
    paste(3^2,"= 9"), 
    paste(3^1,"= 3"), 
    paste(3^0,"= 1") 
) 

3: Избегайте избыточных вызовов c(). Вы можете заменить

c(paste("expression(paste(3^",LEVELS:0,'," = ',3^(LEVELS:0),'"))',sep="")) 

с

paste("expression(paste(3^",LEVELS:0,'," = ',3^(LEVELS:0),'"))',sep="") 
+1

plus1 хорошо сделано .. Я тратил слишком много времени на это. (похоже, вы можете упростить его 'mylabels <- parse (text = sprintf ('3 ^% d ==% d', LEVELS: 0, 3^(LEVELS: 0)))', но я не знаю, придет ли это назад и укусить – user20650

+1

@ user20650 Отличная точка, ваше упрощение работает здесь. Единственное предостережение заключается в том, что если фрагмент метки справа от '3 ^% d' недействителен синтаксисом R, то это не сработает, потому что 'parse()' не сможет анализировать его в действительное дерево синтаксического анализа R. Но поскольку в этом случае это синтаксис, он работает. – bgoldst