Подтвердить что ты не робот

Как добавить слои в ggplot, используя for-loop

Я хотел бы построить каждый столбец кадра данных на отдельный слой в 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]))

Есть ли способ построить все доступные столбцы на одном с помощью одной функции?

Я пытался сделать это таким образом, но это не сработало:

    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)
4b9b3361

Ответ 1

Один из подходов состоит в том, чтобы переформатировать ваш фрейм данных из широкого формата в длинный формат с помощью функции 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()

enter image description here

Если вы действительно хотите использовать цикл 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)

enter image description here

Ответ 2

Я попробовал метод расплава на большом беспорядочном наборе данных и пожелал более быстрого и чистого метода. Для цикла 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

Это было намного быстрее, чем большой расплавленный набор данных, когда я тестировал.

Я также пробовал цикл for с помощью метода aes_string (y = fields [i], color = fields [i]), но не смог получить различия между цветами.