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

Posted

技术标签:

【中文标题】使用循环在 ggplot 中创建具有不同 Y 轴值的多个图【英文标题】:Creating multiple plots in ggplot with different Y-axis values using a loop 【发布时间】:2016-11-08 10:58:12 【问题描述】:

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

因此,我需要为每个绘图创建新名称,以反映所绘制的 y 值。下面是示例代码,其中月份是 x 轴上的变量,我想要三个单独的月份图与三个附加变量(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 值之间不同的值列表,并在该列表上循环,如下所示:

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 值。它只输出最后一个循环的值(对于变量 lag9_var)。

我无法弄清楚为什么会发生这种情况,以及为什么它只发生在 Y 值而不是标题或情节名称上。我一直在 SAS 中编程并且对 R 不熟悉,所以我认为我是从 SAS 的角度来处理这个问题,而不是以“R”的方式思考它。

注意:在上面的代码中,我在 ggplot 语句之外创建了对象“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")))

        

感谢您的帮助!

【问题讨论】:

【参考方案1】:

我认为您遇到的问题可能是 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 不适用于您使用的方法,但这似乎是一种解决方法,所以我希望它有所帮助。

【讨论】:

【参考方案2】:

上面的代码适用于我使用的一项更改 names(yval)&lt;-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 )

【讨论】:

setnames (无大写)是一个data.table 函数,所以如果你附加了这个包应该可以工作吗?我经常使用data.table,所以习惯使用它的功能,因此将其包含在我的答案中。 啊,有道理,我刚刚发现了data.table,所以我仍然不熟悉它的所有功能。谢谢! 欢迎您。如果您的问题已经解决,请不要忘记接受答案,以便其他人在需要时可以找到它,或者如果他们仍在尝试提供帮助,请忽略您的问题。【参考方案3】:

下面的代码展示了如何使用'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

【讨论】:

以上是关于使用循环在 ggplot 中创建具有不同 Y 轴值的多个图的主要内容,如果未能解决你的问题,请参考以下文章

在 ggplot2 中创建具有不同数据集的图例

使用 ggplot2 和 R 创建帕累托图

如何根据 ggplot2 绘制的图上的 y 轴值覆盖构面标签?

ggplot:绘图标题和绘图相互重叠

带有所有x轴值的ggplot x轴标签

ggplot2 如何显示具有相同 y 但不同 x 的两条不同的回归线