如何使用for循环在ggplot中添加图层

new*_*w2R 15 r ggplot2

我想将数据帧的每一列绘制到ggplot2中的单独层.逐层构建绘图效果很好:

df<-data.frame(x1=c(1:5),y1=c(2.0,5.4,7.1,4.6,5.0),y2=c(0.4,9.4,2.9,5.4,1.1),y3=c(2.4,6.6,8.1,5.6,6.3))

ggplot(data=df,aes(df[,1]))+geom_line(aes(y=df[,2]))+geom_line(aes(y=df[,3]))
Run Code Online (Sandbox Code Playgroud)

有没有办法使用单个函数绘制所有可用列?

我尝试这样做但它不起作用:

    plotAllLayers<-function(df){
    p<-ggplot(data=df,aes(df[,1]))
    for(i in seq(2:ncol(df))){ 
        p<-p+geom_line(aes(y=df[,i]))
        }
        return(p)
    }

plotAllLayers(df)
Run Code Online (Sandbox Code Playgroud)

Did*_*rts 15

一种方法是使用melt()库中的函数将数据帧从宽格式重新整形为长格式reshape2.在新数据框中,您将拥有x1值,variable这些值确定来自哪个列数据,并且value包含所有原始y值.

现在,您可以使用一个绘制所有数据ggplot()geom_line()调用并使用variable例如每行的单独颜色.

 library(reshape2)
 df.long<-melt(df,id.vars="x1")
 head(df.long)
  x1 variable value
1  1       y1   2.0
2  2       y1   5.4
3  3       y1   7.1
4  4       y1   4.6
5  5       y1   5.0
6  1       y2   0.4
 ggplot(df.long,aes(x1,value,color=variable))+geom_line()
Run Code Online (Sandbox Code Playgroud)

在此输入图像描述

如果你真的想使用for()循环(不是最好的方法)那么你应该使用names(df)[-1]而不是seq().这将生成列名称的向量(第一列除外).然后在内部geom_line()使用aes_string(y=i)按名称选择列.

plotAllLayers<-function(df){
  p<-ggplot(data=df,aes(df[,1]))
  for(i in names(df)[-1]){ 
    p<-p+geom_line(aes_string(y=i))
  }
  return(p)
}

plotAllLayers(df)
Run Code Online (Sandbox Code Playgroud)

在此输入图像描述


Hen*_*nry 8

我在大型凌乱的数据集上尝试了融化方法,并希望获得更快,更清洁的方法.此for循环使用eval()来构建所需的绘图.

fields <- names(df_normal) # index, var1, var2, var3, ...

p <- ggplot( aes(x=index), data = df_normal)
for (i in 2:length(fields)) { 
  loop_input = paste("geom_smooth(aes(y=",fields[i],",color='",fields[i],"'))", sep="")
  p <- p + eval(parse(text=loop_input))  
}
p <- p + guides( color = guide_legend(title = "",) )
p
Run Code Online (Sandbox Code Playgroud)

当我测试时,这比一个大的熔化数据集运行得快得多.

我也尝试使用aes_string(y = fields [i],color = fields [i])方法的for循环,但无法区分颜色.

  • 我见过的这个问题的唯一答案是真正循环并且确实有效。诚然,许多人认为 'eval' 是一种大罪,但它存在是有原因的:P (2认同)
  • 谢谢你!!作为对后来访问者的说明,我发现使用迭代器将数据分配给变量(例如“subset_of_data &lt;- some_data_frame[i]”)似乎不起作用。没有向`p`添加越来越多的组件,似乎只有最后一个生效。 (2认同)