10

通过将 ggplot() 对象分配给变量,可以轻松地重用该对象并制作具有几何图层变化的绘图的多个版本,而无需为每个绘图编写冗余代码。但是,我想知道是否有办法在交换全局美学映射的同时重用几何图层。

一个用例是我想制作几个具有相同几何表示的图,但想换出映射到其中一个维度的变量。另一个用例是我想制作两个图,其中数据来自两个不同的数据框。

解决此问题的直观方法是 1) 将几何图层的组合保存到变量而不分配 ggplot() 对象或 2) 通过添加另一个变量来覆盖变量中现有 ggplot() 对象的数据和美学ggplot() 对象。做这些事情中的任何一个都会导致错误(对于 1-“二元运算符的非数字参数,对于 2-“不知道如何将 o 添加到绘图中”)。

例如,假设在下面的图中,我想重新使用 gg 变量,但将 x 变量重新映射到数据框中的其他内容:

  dsamp <- diamonds[sample(nrow(diamonds), 1000), ]
  gg <- 
    (ggplot(data = dsamp, aes(x = carat, y = price, color = clarity))
     + geom_point()
     + facet_wrap(~ cut))
  print(gg)

在实践中,绘图定义的长度可能远远超过 3 行,这就是为什么这开始成为代码维护的烦恼。

4

2 回答 2

20

交换与美学相关的变量和与绘图相关的数据都很简单。使用gg您在问题中定义的,单独使用aes来改变美学:

gg + aes(x=table, y=depth)

要更改用于绘图的数据,请使用%+%运算符。

dsamp2 <- head(diamonds, 100)
gg %+% dsamp2
于 2012-08-17T21:02:54.307 回答
3

就像joran提到的那样,我猜......但是:

您可以做两件事之一,编辑 ggplot2 对象(坏主意)或将绘图包装在一个函数中。

让我们使用以下数据和绘图调用:

dat <- data.frame(x=1:10, y=10:1, z=1, a=letters[1:2], b=letters[3:4])

# p <- ggplot(dat, aes_string(x=xvar, y=yvar, color=colorvar)) + geom_point()

请注意,我使用aes_string了所以我可以传递变量而不是列名。

xvar <- 'y'
yvar <- 'z'
colorvar <- 'a'

p <- ggplot(dat, aes_string(x=xvar, y=yvar, color=colorvar)) + geom_point()

的结构p如下,我将把它留给你来整理编辑它。相反,将 ggplot 包装在一个函数中:

plotfun <- function(DF, xvar, yvar, colorvar) {
  ggplot(DF, aes_string(x=xvar, y=yvar, color=colorvar)) + geom_point()
}

p <- plotfun(dat, 'z', 'x', 'a')
p

str(p)


 List of 8
     $ data       :'data.frame':    10 obs. of  5 variables:
      ..$ x: int [1:10] 1 2 3 4 5 6 7 8 9 10
      ..$ y: int [1:10] 10 9 8 7 6 5 4 3 2 1
      ..$ z: num [1:10] 1 1 1 1 1 1 1 1 1 1
      ..$ a: chr [1:10] "a" "b" "a" "b" ...
      ..$ b: chr [1:10] "c" "d" "c" "d" ...
     $ layers     :List of 1
      ..$ :Classes 'proto', 'environment' <environment: 0x34d5628> 
     $ scales     :Reference class 'Scales' [package "ggplot2"] with 1 fields
      ..$ scales: list()
      ..and 20 methods, of which 9 are possibly relevant:
      ..  add, clone, find, get_scales, has_scale, initialize, input, n, non_position_scales
     $ mapping    :List of 3
      ..$ x     : symbol y
      ..$ y     : symbol x
      ..$ colour: symbol a
     $ options    :List of 1
      ..$ labels:List of 3
      .. ..$ x     : chr "z"
      .. ..$ y     : chr "x"
      .. ..$ colour: chr "a"
     $ coordinates:List of 1
      ..$ limits:List of 2
      .. ..$ x: NULL
      .. ..$ y: NULL
      ..- attr(*, "class")= chr [1:2] "cartesian" "coord"
     $ facet      :List of 1
      ..$ shrink: logi TRUE
      ..- attr(*, "class")= chr [1:2] "null" "facet"
     $ plot_env   :<environment: R_GlobalEnv> 
     - attr(*, "class")= chr "ggplot"
于 2012-08-17T19:56:04.413 回答