2015-11-05 4 views
2

Я пытаюсь написать функцию, которая использует ggplot, но позволяет пользователю специфицировать несколько переменных графика. Однако мне не удается заставить его работать как функция (получение сообщения об ошибке: см. Ниже).Использование ggplot в функции с фасеткой и несколькими геометрами

Ниже приведен небольшой набор данных и рабочая реализация, а также моя попытка выполнить функцию и связанную с ней ошибку. Я уверен, что это связано с нестандартной оценкой (NSE), но я не уверен, как обойти это, используя мое использование фильтра внутри функции, и мои различные попытки были напрасны.

library(dplyr) 
library(ggplot2) 

df<-data.frame(Date=c(seq(1:50),seq(1:50)), SRI=runif(100,-2,2), SITE=(c(rep("A",50), rep("B", 50)))) 

ggplot() + 
geom_linerange(aes(x = Date, ymin = 0, ymax = SRI), colour = I('blue'), data = filter(df, SRI>0)) + 
geom_linerange(aes(x = Date, ymin = SRI, ymax = 0), colour = I('red'), data = filter(df, SRI<=0)) + 
facet_wrap(~SITE) + 
labs(x = 'Date', y = "yvar", title = "Plot title") 

Вышеуказанные работы, но когда реализован в виде функции:

plot_fun <- function(df, x, y, ylab="y-lab", plot_title="Title", facets) { 
ggplot() + 
geom_linerange(aes(x = x, ymin = 0, ymax = y), colour = I('blue'), data = filter(df, y > 0)) + 
geom_linerange(aes(x = x, ymin = y, ymax = 0), colour = I('red'), data = filter(df, y <= 0)) + 
facet_wrap(~ facets) + 
labs(x = 'Date', y = ylab, title = plot_title) 
return(p) 
} 

plot_fun(df, x="Date", y="SRI", ylab="y-lab", plot_title="Title", facets="SITE") 

я получаю следующее «Ошибка: Эстетика должна быть либо длина 1 или же, как данные (1): х, ymin, max ".

Я пробовал различные подходы, используя as_string и filter_, но все они не увенчались успехом.

Любая помощь очень ценится.

С уважением

Ник

+0

Вы не используете 'x' аргумент в функции вы публикуемую, что вероятно, что вызывает сообщение об ошибке. Ваша текущая функция дает другое сообщение об ошибке и не будет запускаться из-за 'facet_wrap'/вашего аргумента' facets', который вы можете решить одним из ответов на [этот вопрос] (http://stackoverflow.com/questions/ 10004847/make-plot-functions-with-ggplot-and-aes-string) – aosmith

+0

Кроме того, [это] (http://stackoverflow.com/questions/26492280/non-standard-evaluation-nse-in-dplyrs-filter -pulling-data-from-mysql) является хорошим примером того, как использовать 'filter_' (но похоже, что в ближайшем будущем может быть меньше подробностей (https://github.com/hadley/dplyr/issues/1012)). – aosmith

+0

Спасибо, aosmith, я только что просмотрел его, и вы правы, произошла ошибка в том, как функция была закодирована - x не был передан .... я обошел кругами извините. Я отредактировал код к тому, что, по моему мнению, теперь является правильной отправной точкой, хотя и с той же ошибкой. Теперь я посмотрю на другое сообщение, которое вы упомянули. Спасибо, Ник. – nickb

ответ

2

Вам нужно переключиться на aes_string, как вы ожидали, и изменить свой facet_wrap код либо взять facets аргумент в качестве формулы или удалить тильды как в answers to this question. Вам также необходимо переключиться на использование filter_, который может использоваться вместе с interp из пакета lazyeval.

library(lazyeval) 

Вот ваша функция с изменениями, я изложил и в результате заговора:

plot_fun <- function(df, x, y, ylab = "y-lab", plot_title = "Title", facets) { 
    ggplot() + 
     geom_linerange(aes_string(x = x, ymin = 0, ymax = y), colour = I('blue'), 
        data = filter_(df, interp(~var > 0, var = as.name(y)))) + 
     geom_linerange(aes_string(x = x, ymin = y, ymax = 0), colour = I('red'), 
        data = filter_(df, interp(~var <= 0, var = as.name(y)))) + 
     facet_wrap(facets) + 
     labs(x = 'Date', y = ylab, title = plot_title) 
} 

plot_fun(df, x="Date", y="SRI", facets="SITE") 

enter image description here

+0

Большое спасибо. Мне нравится использование lazyeval, чтобы сделать код очень читаемым. Очень признателен! – nickb