Reputation: 2126
I am trying to generate plots from a for-loop using ggplot
in R
.
Let's create a dataset:
# Libraries
library(tidyverse)
# Set seed
set.seed(123)
# Create data frame
df <- data.frame(
time = c( rep(1,20), rep(2, 20), rep(3, 20) ),
value_a =c(rnorm(n = 60, mean = 50, sd = 10)),
value_b =c(rnorm(n = 60, mean = 50, sd = 10)),
value_c =c(rnorm(n = 60, mean = 50, sd = 10))
)
I can generate a plot using ggplot
.
ggplot(data = df) +
geom_jitter(aes(x = time, y = value_a), position = position_jitter(width = 0.1)) +
scale_y_continuous(limits = c(0, 100))
Next, I would like to generate these plots for every column of the data frame (with time on the x-axis and value_n on the y-axis). I thought a for loop would do the trick:
for(i in colnames(df)[-1]){
print(
ggplot(df_a, aes(x= time, y = i)) +
geom_jitter(position=position_jitter(width=0.1)) +
scale_y_continuous(limits = c(0,100))
)
}
It provides the following error:
Error: Discrete value supplied to continuous scale
The error arises because the i
from the for loop is seen as a character vector, and I can (logically) not provide a continuous scale to a discrete value.
Reproduction of the error outside the for-loop:
ggplot(df_a, aes(x= time, y = "value_a")) + # value_a is provided as character vector
geom_jitter(position=position_jitter(width=0.1)) +
scale_y_continuous(limits = c(0,100))
Question
Is there a way to prevent 'value_a' to be interpreted as a character vector, so that I will be able to control the scale in the loop? Or is there another way to conveniently generate plots from different columns in dataframe?
Upvotes: 1
Views: 61
Reputation: 23757
I agree with PoGibas's comment - reshaping to long format and using facet
is likely the better way to go. However, If you need it for creating different plots/images etc, use eval(sym(i))
instead, like so:
library(tidyverse)
# Set seed
set.seed(123)
# Create data frame
df <- data.frame(
time = c( rep(1,20), rep(2, 20), rep(3, 20) ),
value_a =c(rnorm(n = 60, mean = 50, sd = 10)),
value_b =c(rnorm(n = 60, mean = 50, sd = 10)),
value_c =c(rnorm(n = 60, mean = 50, sd = 10))
)
for(i in colnames(df)[-1]){
print(
ggplot(df, mapping = aes(x= time, y = eval(sym(i)))) +
geom_jitter(position=position_jitter(width=0.1)) +
scale_y_continuous(limits = c(0,100)) +
labs(y = i) #added automatic y-label
)
}
Created on 2019-11-29 by the reprex package (v0.3.0)
Upvotes: 1