1

我正在使用ggplotgridExtra用不同的数据并排制作两个图,并且在使用矢量而不是数据框制作图时,我观察到了意外的行为。

这是我的问题的MWE:

library(ggplot2)
library(dplyr)
library(gridExtra)

cases <- c(1, 2)

df <- data.frame(
  case=cases,
  y1=c(1, 2),
  y2=c(2, 4),
  y3=c(3, 8),
  y4=c(4, 16),
  y5=c(5, 32)
)

x <- c(1, 2, 3, 4, 5)

plot_list <- list()
for(caso in cases){
  data <- df %>% filter(case == caso)
  y <- data %>% dplyr::select(starts_with('y')) %>% unlist(use.name=FALSE)
  dd <- data.frame(xdf=x, ydf=y)
  graph <- (
    ggplot()
    + geom_line(data=dd, aes(x=xdf, y=ydf))
    ## + geom_point(data=dd, aes(x=xdf, y=ydf)) # this line works
    + geom_point(aes(x=x, y=y)) # this line doesn't
  )
  plot_list[[length(plot_list)+1]] <- graph
}

grid.arrange(grobs=plot_list, ncol=2)

这段代码绘制了一个左边有一条线,右边有一条抛物线的图。我标记了两行调用geom_point. 如果我将这条线与数据框一起使用,一切都会按预期工作。但是,如果我使用带有向量的线(实际用于创建数据框),则抛物线的点会绘制在所有图形中。

这是结果图:

显然,问题是通过使用数据帧而不是向量来解决的,但我想首先了解为什么会发生这种行为。所以我很感激任何关于为什么 R 以这种看似违反直觉(至少对我而言)的方式表现的见解。

4

1 回答 1

1

有趣的发现。这是因为您使用的是 for 循环,而且它们对我来说也经常难以理解有关对象创建和评估的行为。在您的情况下, ggplot 直到最后一个结束才绘制图,然后将最后一个向量 'y' 用于绘图。我发现避免这个问题的最简单方法是使用另一种循环方式。我更喜欢申请家庭。

也就是说——我的建议是避免在其中使用向量aes()——这只会让人头疼。

我刚刚发现这个线程更好地解释了这个问题。建议将此问题作为副本关闭。"for" 循环只添加最后的 ggplot 层

library(ggplot2)
library(dplyr)

df <- data.frame( case=1:2, y1=c(1, 2), y2=c(2, 4), y3=c(3, 8), y4=c(4, 16), y5=c(5, 32))

x <- 1:5

plot_list <- lapply(1:2, function(i){
  data <- df %>% dplyr::filter(case == i)
  y <- data %>% dplyr::select(starts_with('y')) %>% unlist(use.name=FALSE)
  graph <- ggplot() + 
    geom_point(aes(x=x, y=y)) 
  graph
})

gridExtra::grid.arrange(grobs=plot_list, ncol=2)

reprex 包于 2022-02-08 创建(v2.0.1)

于 2022-02-08T17:03:12.457 回答