【问题标题】:Replace dataset(s) of an existing ggplot having multiple datasets替换具有多个数据集的现有 ggplot 的数据集
【发布时间】:2017-05-15 19:36:46
【问题描述】:

主要目标是精细控制每个刻面行的刻面 ggplot 的 y 尺度。我的策略是为每一行构建一个单独的图并将它们绑定在一起。

我想从现有的 ggplot 对象开始。为了为每个构面行构建一个图,我计划对原始数据进行子集化,并使用运算符%+% 替换数据集。 但是,当不同层上有多个数据集时,这似乎是不可能的。

是否有可能使用%+% 替换多个/所有 ggplot 中的数据集?

MWE 下面:此方法适用于 plot ga,其中第二个数据集 dat2a 不包含 facetting 变量。但是它不适用于第二个示例gb

library(ggplot2)
dat1 <- data.frame(x=runif(9),y=runif(9), b=rep(1:3,3)  )
dat2a <- data.frame(a=c(1,2),c=c(1,1))
dat2b <- data.frame(a=c(0.5,1,2),c=c(0.5,1,1),b=c(1,2,3))

ga   <- ggplot(dat1, aes(x,y)) + 
    geom_point() + 
    facet_grid(b~.) +
    geom_point(data=dat2a, aes(x=a, y=c), color='red')
gb   <- ggplot(dat1, aes(x,y)) + 
    geom_point() + 
    facet_grid(b~.) +
    geom_point(data=dat2b, aes(x=a, y=c), color='red')

# example a) working
    ga
    #Replot ga using the altered data frame
    ga %+% dat1[dat1$b==2,]
# example b) not working
    gb
    #Replot g using the altered data frame
    gb %+% dat1[dat1$b==2,]

【问题讨论】:

  • 什么是dat?您确定要在方括号中调用dat 而不是dat1,例如。 gb %+% dat1[dat1$b==2,].
  • 确实dat 应该是dat1,很好看。我用更正编辑了代码。 (还添加了库 ggplot2)。现在该示例应该正在运行。

标签: r ggplot2


【解决方案1】:

编辑:下面的解决方法可以达到预期的效果。但是,它也修改了原始 ggplot 对象的数据。不知何故,复制的 ggplot 对象仍然链接到原始对象。虽然解决方法回答了问题,但并没有解决问题。


在 ggplot 对象上使用 str 给了我一些提示。每一层都可以通过gb$layers 访问,每一层都有一个元素$data。这允许找出哪个层有自己的data.frame:

lapply(gb_new2$layers, function(layer) is.data.frame(layer$data))

事实证明,替换这些 data.frames 将达到预期的结果。

(虽然我不确定此替换是否会产生不良后果,例如错误的轴缩放。或者有人可以确认此类计算仅在调用ggplot_build() 时在稍后的步骤中执行?即是我们仍在处理与初始绘图定义非常相似的对象gb?)

以下几行提供了ggplot 对象gb 所需的更改。

gb_new <- gb
dat2b_extracted <- gb_new$layers[[2]]$data
gb_new$layers[[2]]$data <- dat2b_extracted[dat2b_extracted$b==2,]

gb_new %+% dat1[dat1$b==2,]

这可以使用以下自动化。虽然我不得不承认它仍然感觉很hacky。

# copy ggplot object
gb_new2 <- gb

# edit copy of ggplot
for (it in seq_along(gb_new2$layers)){
    # get data.frame of layer
        temp_df <- gb_new2$layers[[it]]$data
    # subset and replace it
        if(is.data.frame(temp_df)) { gb_new2$layers[[it]]$data <- temp_df[temp_df$b==2,] }
}
# plot
gb_new2 %+% dat1[dat1$b==2,]

【讨论】:

  • 我刚刚注意到这会导致我的预期用例出现一些错误。似乎复制 ggplot 对象不会复制基础数据。然后改变ggplot对象gb_new2的数据也会改变原来gb的数据。另见stackoverflow.com/questions/11431861/…
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-05-24
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多