how to add layers in ggplot using a for-loop

匿名 (未验证) 提交于 2019-12-03 02:11:02

问题:

I would like to plot each column of a dataframe to a separate layer in ggplot2. Building the plot layer by layer works well:

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])) 

Is there a way to plot all available columns at ones by using a single function?

I tried to do it this way but it does not work:

    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) 

回答1:

One approach would be to reshape your data frame from wide format to long format using function melt() from library reshape2. In new data frame you will have x1 values, variable that determine from which column data came, and value that contains all original y values.

Now you can plot all data with one ggplot() and geom_line() call and use variable to have for example separate color for each line.

 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() 

If you really want to use for() loop (not the best way) then you should use names(df)[-1] instead of seq(). This will make vector of column names (except first column). Then inside geom_line() use aes_string(y=i) to select column by their name.

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) 



回答2:

I tried the melt method on a large messy dataset and wished for a faster, cleaner method. This for loop uses eval() to build the desired plot.

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 

This ran a lot faster then a large melted dataset when I tested.

I also tried the for loop with aes_string(y=fields[i], color=fields[i]) method, but couldn't get the colors to be differentiated.



标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!