come aggiungere strati in ggplot usando un ciclo for

Vorrei tracciare ogni colonna di un dataframe su un livello separato in ggplot2. Costruire la trama strato per strato funziona bene:

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

C’è un modo per tracciare tutte le colonne disponibili con una sola funzione?

Ho provato a farlo in questo modo ma non funziona:

  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) 

Un approccio potrebbe essere quello di rimodellare il frame di dati dal formato wide al formato lungo usando la funzione melt() dalla libreria reshape2 . Nel nuovo frame di dati si avranno valori x1 , variable che determina da quale colonna provengono i dati e value che contiene tutti i valori y originali.

Ora puoi tracciare tutti i dati con una ggplot() e geom_line() e usare la variable per avere ad esempio un colore separato per ogni riga.

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

inserisci la descrizione dell'immagine qui

Se vuoi davvero usare il ciclo for () (non nel modo migliore), dovresti usare names(df)[-1] invece di seq() . Questo renderà il vettore dei nomi delle colonne (eccetto la prima colonna). Quindi all'interno di geom_line() usa aes_string(y=i) per selezionare la colonna in base al loro nome.

 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) 

inserisci la descrizione dell'immagine qui

Ho provato il metodo di fusione su un grande set di dati disordinato e ho desiderato un metodo più veloce e più pulito. Questo ciclo utilizza eval () per build la trama desiderata.

 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 

Questo è andato molto più veloce di un grande insieme di dati fuso quando ho provato.

Ho anche provato il ciclo for con il metodo aes_string (y = fields [i], color = fields [i]), ma non sono riuscito a differenziare i colors.