使用循环在具有不同 Y-axis 值的 ggplot 中创建多个图

Creating multiple plots in ggplot with different Y-axis values using a loop

我正在尝试在 ggplot 中创建多个具有相同结构但具有不同 Y-value 的散点图。我需要将它们分开(因此不使用 facet_wrap),因为在后面的步骤中我使用 grid_arrange 将图形的不同组合排列到一个布局中。

因此,我需要为每个绘图创建新名称,以反映正在绘制的 y-value。下面是示例代码,其中月份是 x-axis 上的变量,我想要三个单独的月份图与三个附加变量(lag1_var、lag3_var 和 lag9_var) .

df <- data.frame (month= c(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12), 
                lag1_var=  c (10, 20, 30, 40, 10, 40, 30, 50, 70, 90, 100, 100),
                lag3_var= c(90, 70, 50, 40, 70, 50, 20, 50, 70, 90, 10, 10),
                lag9_var = c(50, 20,90, 100, 90, 10, 40, 90, 100, 20, 30, 70))

我的方法是创建一个包含 y-value 之间不同的值的列表,然后循环遍历该列表,如下所示:

loop.list <- c("1", "3", "9")

for (val in loop.list) {

  yval<- paste0("lag", val, "_var")

  ptitle <-paste0("graph plot lag", val, "_Var")

  assign(paste0("plot", val), ggplot(data=df, aes(x=month, y=get(yval))) 

+geom_point(color="red", size=2) + ggtitle(ptitle))

    }

当我这样做时,我得到了三个具有三个不同名称(plot1、plot3、plot9)和正确标题的地块(因此地块 1 的标题为 "graph plot lag1",地块 3 的标题为 "graph plot lag3", 等), 但它们都是相同的图。所以循环适用于情节名称和情节标题,但不适用于 y-value。它只是输出最后一个循环的值(对于变量 lag9_var)。

我不明白为什么会这样,为什么它只发生在 Y-value 而不是标题或情节名称。我一直在 SAS 中编程并且是 R 的新手,所以我认为我是从 SAS 的角度来处理这个问题的,而不是以 "R" 的方式来考虑它。

注意:在上面的代码中,我在 ggplot 语句之外创建了 objects "yval" 和 "ptitle",但这只是为了帮助解决问题。如果我将它们包含在 ggplot 语句中,也会发生同样的事情,如下所示:

 for (val in loop.list) {

      assign(paste0("plot", val), ggplot(data=df,aes(x=month,y=get(paste0("lag", val, "_var")))) + 

    geom_point(color="red", size=2) + 

    ggtitle(paste0("graph plot lag", val, "_Var")))

        }

感谢您的帮助!

我认为您遇到的问题可能是 ggplot 在您调用显示每个图时尝试重建它,并且它从最后给出的参考中检索数据,而不是在创建每个图时给出的参考。我不是很懂,所以如果有人能阐明那个主题就太好了。

无论哪种方式,按照这个推理,我尝试将每个图的数据分离到它自己的数据框中,并且似乎已经开始工作了:

library(data.table)
library(ggplot2)
loop.list <- c("1", "3", "9")
for (val in loop.list) {
    col <- grep( paste0("lag", val, "_var"), colnames(df) )
    yval <- df[,c(1,col)]
    setnames( yval, c( "month", "var" ) )
    frameval <- paste0("frame", val)
    assign( paste0("frame", val), yval )
    ptitle <-paste0("graph plot lag", val, "_Var")

    plotval <- ggplot( data = get(frameval), aes(x=month,y=var) ) +
           geom_point( color="red", size=2) +
               ggtitle(ptitle)
    assign( paste0("plot",val), plotval )
}

请注意,grep 调用正在查找要用于该图的列号,然后将该列与其余列分开作为其自己的数据框。

我无法解释为什么 ggplot 不适用于您使用的方法,但这似乎是一种解决方法,所以我希望它能有所帮助。

上面的代码与我使用的一个变化一起工作 names(yval)<-c("month", "var") 而不是 setNames。由于某些原因 setNames 没有工作,所以 ggplot 语句没有要绘制的 y 值,因为每个帧中的变量名称仍然是 lag3_var、lag6_var 和 lag9_var。谢谢!!!

library(data.table)
library(ggplot2)
loop.list <- c("1", "3", "9")
for (val in loop.list) {
    col <- grep( paste0("lag", val, "_var"), colnames(df) )
    yval <- df[,c(1,col)]
    **names(yval)<-  c( "month", "var")** 
    frameval <- paste0("frame", val)
    assign( paste0("frame", val), yval )
    ptitle <-paste0("graph plot lag", val, "_Var")

    plotval <- ggplot( data = get(frameval), aes(x=month,y=var) ) +
           geom_point( color="red", size=2) +
               ggtitle(ptitle)
    assign( paste0("plot",val), plotval )
}

下面的代码显示了如何使用 'multiplot()' 函数执行此操作,此处提供了其源代码:http://www.cookbook-r.com/Graphs/Multiple_graphs_on_one_page_(ggplot2)

plotAllCounts <- function (dt){   
  plots <- list();
  for(i in 1:ncol(dt)) {
    strX = names(dt)[i]
    print(sprintf("%i: strX = %s", i, strX))
    plots[[i]] <- ggplot(dt) + xlab(strX) +
      geom_point(aes_string(strX),stat="count")
  }

  columnsToPlot <- floor(sqrt(ncol(dt)))
  multiplot(plotlist = plots, cols = columnsToPlot)
}

现在 运行 函数 - 获取使用 ggplot 在一页上打印的所有变量的计数:

dt = ggplot2::diamonds
plotAllCounts(dt)

这是我在分析新数据集时经常做的第一步。 希望你会发现它有用。

需要注意的一件事是:在上面的代码中使用 aes(get(strX)),在使用 ggplot 时通常会在循环中使用,而不是 aes_string(strX) 将不会绘制想要的地块。相反,它会多次绘制最后一个图。我还没有弄清楚为什么 - 它可能必须在 ggplot.

中调用 aesaes_string