背景
我正在尝试使用ggplot2加速an R package that plots high-resolution maps的功能 . 函数 basemap
使用大的shapefile(每个15 Mb)绘制Svalbard的映射 . 使用两个不同的shapefile,land和glaciers以及一组"definitions"(例如主题,轴刻度和网格线)创建 Map . 在现在编写代码时绘制 Map 大约需要30秒 .
我的想法是,如果我可以打破代码片段中的层并允许用户不绘制冰川的可能性,那么该函数的执行速度会快两倍 . 此外,如果我可以将ggplot2语法指定为文本字符串并仅评估所需的字符串,则R不会浪费时间制作该函数未使用的ggplot2对象 .
我知道如何使用 if else
语句执行此操作,但我想避免多次编写定义 . 似乎可以将 scale_x_continuous()
分配给对象,但分配 scale_x_continuous() + scale_y_continuous()
会产生错误:
scale_x_continuous()中的错误scale_y_continuous():二元运算符的非数字参数
问题
如何将ggplot2轴定义分配给文本字符串并将它们与数据层粘贴在一起?
示例
我使用 iris
数据集作为示例,这样您就不必下载大而且非常混乱的PlotSvalbard包 . 请注意,我知道如何将颜色映射到变量 . 这里的要点只是将shapefile作为 iris
数据集的两个子集来说明:
library(ggplot2)
data(iris)
## Datasets to imitate the shapefile layers
ds1 <- subset(iris, Species == "setosa")
ds2 <- subset(iris, Species == "versicolor")
## Example how the basemap function works at the moment:
ggplot() + geom_point(data = ds1, aes(x = Sepal.Length, y = Sepal.Width), color = "red") +
geom_point(data = ds2, aes(x = Sepal.Length, y = Sepal.Width), color = "blue") +
scale_x_continuous("Longitude", breaks = seq(3, 8, by = 0.5)) +
scale_y_continuous("Latitude", breaks = seq(1,5, by = 1)) + theme_bw()
## Now I would like to plot ds2 only if user defines "keep.glaciers = TRUE"
land <- ggplot() + geom_point(data = ds1, aes(x = Sepal.Length,
y = Sepal.Width), color = "red")
glacier <- geom_point(data = ds2, aes(x = Sepal.Length, y = Sepal.Width),
color = "blue")
def <- scale_x_continuous("Longitude", breaks = seq(3, 8, by = 0.5)) +
scale_y_continuous("Latitude", breaks = seq(1,5, by = 1)) + theme_bw() ## Error!
# Error in +scale_x_continuous("Longitude", breaks = seq(3, 8, by = 0.5)) :
# invalid argument to unary operator
## The ultimate goal:
keep.glaciers = TRUE
if(keep.glaciers) {
land + glacier + def # error, see above
} else {
land + def
}
2 回答
您可以将图层保留在
list
中,并将+
运算符与ggplot
一起使用 .例如,函数
plot_glaciers
将land
,def
和glacier
图层保留在列表中 .if
语句控制glacier
图层的构造 . 该函数将返回带有所需图层的ggplot
对象 .您可以将ggplot2图层分配给字符串,并在将它们粘贴在一起后评估字符串:
使用嵌套的
switch
方法可以使"modules"可以轻松地粘贴在绘图函数的if else
语句中,使代码更容易阅读,如果要将许多 Map 图层传递给绘图函数 .