使用循环在 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)<-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
中调用 aes
和 aes_string
。
【讨论】:
以上是关于使用循环在 ggplot 中创建具有不同 Y 轴值的多个图的主要内容,如果未能解决你的问题,请参考以下文章