可以将文章内容翻译成中文,广告屏蔽插件可能会导致该功能失效(如失效,请关闭广告屏蔽插件后再试):
问题:
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.