我正在尝试复制ggplot对象,然后将新复制对象的某些属性更改为,例如,将颜色线更改为红色.
假设这段代码:
df = data.frame(cbind(x=1:10, y=1:10))
a = ggplot(df, aes(x=x, y=y)) + geom_line()
b = a
Run Code Online (Sandbox Code Playgroud)
然后,如果我改变变量行的颜色 a
a$layers[[1]]$geom_params$colour = "red"
Run Code Online (Sandbox Code Playgroud)
它也改变了颜色 b
> b$layers[[1]]$geom_params$colour
[1] "red" # why it is not "black"?
Run Code Online (Sandbox Code Playgroud)
我希望我可以有两个不同的对象a
和b
不同的特征.因此,为了以正确的方式执行此操作,我需要再次调用绘图以供b
使用b = ggplot(df, aes(xy, y=z)) + geom_line()
.但是,此时在算法中,无法知道绘图命令ggplot(df, aes(x=x, y=y)) + geom_line()
你知道这有什么问题吗?ggplot对象是以不同的方式处理的吗?
谢谢!
这里的问题是ggplot
使用proto
库来模仿OO风格的对象.该proto
库依赖于环境来收集对象的变量.环境通过引用传递,这就是您看到自己行为的原因(也是没有人建议以这种方式更改图层属性的原因).
无论如何,从proto
文档中调整一个例子,我们可以尝试对ggplot
对象的laters进行深度复制.这应该"断开"它们.这是一个辅助函数
duplicate.ggplot<-function(x) {
require(proto)
r<-x
r$layers <- lapply(r$layers, function(x) {
as.proto(as.list(x), parent=x)
})
r
}
Run Code Online (Sandbox Code Playgroud)
所以,如果我们跑
df = data.frame(cbind(x=1:10, y=1:10))
a = ggplot(df, aes(x=x, y=y)) + geom_line()
b = a
c = duplicate.ggplot(a)
a$layers[[1]]$geom_params$colour = "red"
Run Code Online (Sandbox Code Playgroud)
然后绘制所有三个,我们得到
这表明我们可以独立于"a"改变"c"