我正在尝试使用putplot来改变ggpairs图的对角线上的图。我可以逐个做到这一点,但是当我使用循环时,对角元素是相同的!
library(ggplot2)
library(GGally)
p=ggpairs(iris,
columns=, c("Sepal.Length", "Sepal.Width", "Petal.Length", "Petal.Width"),
colour='Species',
lower=list(continuous='points'),
axisLabels='none',
upper=list(continuous='blank')
)
for (i in 1:4) {
p <- putPlot(p, ggplot(iris, aes(x=iris[,i], colour=Species)) + stat_ecdf(), i,i)
}
print(p)
解开循环有效......为什么......?
p <- putPlot(p, ggplot(iris, aes(x=iris[,1], colour=Species)) + stat_ecdf(), 1,1)
p <- putPlot(p, ggplot(iris, aes(x=iris[,2], colour=Species)) + stat_ecdf(), 2,2)
p <- putPlot(p, ggplot(iris, aes(x=iris[,3], colour=Species)) + stat_ecdf(), 3,3)
p <- putPlot(p, ggplot(iris, aes(x=iris[,4], colour=Species)) + stat_ecdf(), 4,4)
答案 0 :(得分:3)
这是ggplot
中所谓的懒惰评估的结果。对各种ggplot
函数的调用实际上并不创建绘图,它们定义了绘图的绘制方式。该图仅使用例如print(p)
创建。
问题是aes(...)
的参数在绘图定义中存储为表达式,并且这些表达式仅在渲染绘图时进行评估。因此,在您的情况下,对ggplot
的四次调用都以相同的方式存储,x=iris[,i]
。渲染绘图时,i=4
和所有四个对角线插槽都使用x=iris[,4]
进行渲染。
那么如何应对呢?我们必须将x
的定义置于aes(...)
的调用之外。这段代码实现了:
for (i in 1:4) {
p <- putPlot(p,ggplot(data=data.frame(x=iris[,i],Species=iris$Species),
aes(x=x,colour=Species)) + stat_ecdf(), i,i)
}
print(p)
这里我们使用适当的xis iris列将ggplot
的默认数据集设置为每个图中的不同数据框。这样做的原因是,在x=iris[,i]
的调用中,aes(...)
的重新声明不是。
请参阅this link了解一个密切相关的问题,并提供几乎相同的解决方案。