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

时间:2016-07-06 11:43:44

标签: r for-loop ggplot2 assign

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

因此,我需要为每个绘图创建新名称,以反映绘制的y值。下面是示例代码,其中month是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")))

        }

感谢您的帮助!

3 个答案:

答案 0 :(得分: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不能使用您使用的方法,但这似乎是一种解决方法,所以我希望它有所帮助。

答案 1 :(得分:0)

上面的代码适用于我使用的一个更改 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 )
}

答案 2 :(得分:0)

下面的代码显示了如何使用'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)中将不会绘制所需的图。相反,它会多次绘制最后一个情节。我还没弄清楚原因 - 可能需要aesaes_string调用ggplot