Access fields by name in a loop with ggplot

Viewed 35

Let's make up some data, which is a noisy sine:

xx <- sort(runif(125, 0, 2 * pi))
yy <- sin(xx) + rnorm(length(xx), sd = 0.3)
data <- data.frame(x = xx, y = yy)

Append a fit by lowess for different parameters:

ff <- c(2/3, 1/3, 1/10)
for (n in 1:length(ff)) {
  data[[paste("f", n, sep="")]] <- lowess(data$y ~ data$x, f = ff[n])$y
}

Now plot in one chart:

ggplot(data) + 
  geom_point(aes(x = x, y = y, color = "samples")) +
  geom_function(fun = sin, aes(x = x, color = "original sine")) +
  geom_line(aes(x = x, y = f1, color = "f1")) + 
  geom_line(aes(x = x, y = f2, color = "f2")) +
  geom_line(aes(x = x, y = f3, color = "f3"))

There are multiple issues with this.

Foremostly though, how replace the last part by a for loop? I.e. something like:

p <- ggplot(data) + 
  geom_point(aes(x = x, y = y, color = "samples")) +
  geom_function(fun = sin, aes(x = x, color = "original sine"))

for (f in ff) {
  p <- p + geom_line(aes(x = x, y = f))
}

p

Second, this color = does not feel like the right way to attach a legend label. How to get different colors and attach a label?

Finally, I'd like to change the line type to dashed for the lines in the loop.

Thank you.

1 Answers

Get the columns that start with "f" in long format and then plot :

library(tidyr)
library(ggplot2)

data %>%
  pivot_longer(cols = starts_with('f')) %>%
  ggplot() + geom_point(aes(x = x, y = y, color = "samples")) +
  geom_function(fun = sin, aes(x = x, color = "original sine")) +
  geom_line(aes(x = x, y = value, color = name), linetype = 'dashed')

enter image description here

Related