我需要在已绘制的ggplot对象中添加一些行。在泛型方法中,我们可以在创建绘图后使用函数lines
,并将线添加到此绘图中。
使用ggplot2
,我们可以在创建geom_line()
对象的同时使用ggplot
参数来添加行。例如:
test_data <- data.frame(var0 = 100 + c(0, cumsum(runif(49, -20, 20))),
var1 = 150 + c(0, cumsum(runif(49, -10, 10))),
var3 = 1:100)
P1 <- ggplot(test_data, aes(var3)) + geom_line(aes(y = var0, colour = "var0")) +
geom_line(aes(y = var1, colour = "var1"))
P1
但是,在我的情况下,我绝对需要在对象中保存第一个绘图,绘制他,并在第二次绘制线条(由其他程序创建其他数据)。
所以,我可以创建三个不同的对象:
P1 <- ggplot(test_data, aes(var3))
L1 <- geom_line(aes(y = var0, colour = "var0"))
L2 <- geom_line(aes(y = var1, colour = "var1"))
我可以在那里画:
P1 + L1 + L2
就像我在泛型方法中绘制P1并在之后使用lines
(对于L1和L2)。
但是我不知道为什么我不能在我添加两行而不是一行的情况下创建这个对象:
L3 <- L1 + L2
P1 + L3
我收到此消息:
L1 + L2中的错误:二元运算符的非数字参数。
我无法拆分L3对象,因为它只能由一个返回一个对象的函数创建。
我的问题是如何在绘制P1之后返回L3对象或等效对象以将其添加到P1?
答案 0 :(得分:2)
正如@Roland所指出的那样,确实有必要使用这种方式。然而,问题仍然存在:我们可以拥有像这样灵活的东西吗?答案是肯定的,我们可以通过使用非标准评估。
f <- function(x) {deparse(substitute(x))}
g <- function(x) {eval(parse(text=x))}
g(paste0(f(P1), " + ", f(L1))) # first line
g(paste0(f(P1), " + ", f(L2))) # second line
g(paste0(f(P1), " + ", f(L1 + L2))) # both lines
fL3 <- f(L1 + L2)
g(paste0(f(P1), " + ", fL3)) # both lines with defined variable
为什么我们必须覆盖+
内ggplot
运算符的标准评估?好吧,因为我们可以将geom
添加到ggplot
,结果又是ggplot
。但是,我们无法将geom
添加到geom
,结果未定义。我们可以手动添加这个功能,将上面的脏黑客包装成漂亮的东西,但我认为这不值得付出努力。
编辑:我认为一个或多或少干净的解决方案是为+
类定义proto
运算符,这不应该破坏基本ggplot
评估。可能值得一试。
Edit2:实际上,一切都更多,更简单,我正在过度思考(提示here}:
P1 + list(L1, L2)
L3 <- list(L1, L2)
P1 + L3