在具有 facet 和多个 geom 的函数中使用 ggplot
Using ggplot within a function with facet and multiple geoms
我正在尝试编写一个使用 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")
我得到以下 "Error: Aesthetics must be either length 1 or the same as the data (1): x, ymin, max"。
我尝试过使用 as_string
和 filter_
的各种方法,但都没有成功。
非常感谢任何帮助。
此致
尼克
您需要按预期切换到 aes_string
并更改 facet_wrap
代码以将 facets
参数作为公式或删除波浪号,如 answers to this question。您还需要切换到使用 filter_
,它可以与包 lazyeval.
中的 interp
一起使用
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")
我正在尝试编写一个使用 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")
我得到以下 "Error: Aesthetics must be either length 1 or the same as the data (1): x, ymin, max"。
我尝试过使用 as_string
和 filter_
的各种方法,但都没有成功。
非常感谢任何帮助。
此致
尼克
您需要按预期切换到 aes_string
并更改 facet_wrap
代码以将 facets
参数作为公式或删除波浪号,如 answers to this question。您还需要切换到使用 filter_
,它可以与包 lazyeval.
interp
一起使用
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")