【发布时间】:2017-11-26 17:22:41
【问题描述】:
背景
我正在尝试使用 ggplot2 加速 an R package that plots high-resolution maps 的函数。函数 basemap 使用大的 shapefile(每个 15 Mb)绘制斯瓦尔巴地图。该地图是使用两个不同的 shapefile 图层、土地和冰川以及一组“定义”(例如主题、轴比例和网格线)创建的。按照现在编写的代码,绘制地图大约需要 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
}
【问题讨论】: