I would like to be able to plot each of "X1 by grpA", "X2 by grpA", "X3 by grpB", "X1 by grpB", "X2 by grpB", and "x3 by grpB" using ggplot2::ggplot() in conjunction with a for loop.
So far, I can get it to almost work, but the argument for the column of the grouping variable in the facet_grid() function does not resolve correctly when I try to use tidy_eval properties. It does work, however, when I type the column name explicitly, but of course, having to type the name explicitly would make it so I would not be able to dynamically change the grouping variable.
I provide the following data-set returned by the following code snippet to give context to my question:
set.seed(1)
dfr <- tibble(x1 = factor(sample(letters[1:7], 50, replace = T), levels=letters[1:7]),
x2 = factor(sample(letters[1:7], 50, replace = T), levels=letters[1:7]),
x3 = factor(sample(letters[1:7], 50, replace = T), levels=letters[1:7]),
grpA = factor(sample(c("grp1","grp2"),50, prob=c(0.3, 0.7) ,replace=T), levels = c("grp1", "grp2")),
grpB = factor(sample(c("grp1","grp2"),50, prob=c(0.6, 0.4) ,replace=T), levels = c("grp1", "grp2"))
)
head(df)
I also provide a function that creates the plotting data I need to make the grouped plots. It accepts strings as arguments for the parameters 'groupvar' and 'mainvar':
plot_data_prepr <- function(dat, groupvar, mainvar){
groupvar <- sym(groupvar)
mainvar <- sym(mainvar)
plot_data <- dat %>%
group_by(!!groupvar) %>%
count(!!mainvar, .drop = F) %>% drop_na() %>%
mutate(pct = n/sum(n),
pct2 = ifelse(n == 0, 0.005, n/sum(n)),
grp_tot = sum(n),
pct_lab = paste0(format(pct*100, digits = 1),'%'),
pct_pos = pct2 + .02)
return(plot_data)
}
here is normal usage of the function:
plot_data_prepr(dat = dfr, groupvar = "grpA", mainvar = "x1")
Now I share my for loop that fails when I try to use tidy_eval in the facet_grid() function in the context of ggplot(); the returned error = "Error in !sgvar : invalid argument type"
"FAILING EXAMPLE:"
for (i in seq_along(names(dfr)[1:3])){
mvar <- names(dfr)[i]
print(mvar)
gvar <- names(dfr[4])
print(gvar)
smvar <- sym(mvar)
sgvar <- sym(gvar)
plot <- ggplot(data=plot_data_prepr(dfr, gvar, mvar),
mapping = aes(x=!!smvar, y = pct2, fill = !!smvar)) +
geom_bar(stat = 'identity') +
ylim(0,1) +
geom_text(aes(x=!!smvar, label=pct_lab, y = pct_pos + .02)) +
facet_grid(. ~ !!sgvar) +
ggtitle(paste0(mvar," by ",gvar))
print(plot)
}
When I run the loop by explicitly typing grpA in place of !!sgvar in the facet_grid() function, it works for some reason:
"FUNCTIONING BUT NOT WHAT I WANT EXAMPLE:"
for (i in seq_along(names(dfr)[1:3])){
mvar <- names(dfr)[i]
print(mvar)
gvar <- names(dfr[4])
print(gvar)
smvar <- sym(mvar)
sgvar <- sym(gvar)
plot <- ggplot(data=plot_data_prepr(dfr, gvar, mvar),
mapping = aes(x=!!smvar, y = pct2, fill = !!smvar)) +
geom_bar(stat = 'identity') +
ylim(0,1) +
geom_text(aes(x=!!smvar, label=pct_lab, y = pct_pos + .02)) +
facet_grid(. ~ grpA) +
ggtitle(paste0(mvar," by ",gvar))
print(plot)
}
Of course, if I wanted to loop through a set of grouping variables, then needing to explicitly type each one would not allow for looping. Could someone explain why my code with the 'bang bang' operator inside facet_gric() doesn't work properly in the 'FAILING EXAMPLE' and also suggest how to remedy this error?
Thank you.
It's difficult to piece together exactly what you're looking for, since your example code has errors, unassigned variable names and pieces of code missing. However, I think you're wanting the loop to print all of the pairs of grouping variables and main variables by cycling through the names of your data frame.
So that there is no dubiety, here is a full reprex:
Load packages and create reproducible data:
library(dplyr)
library(ggplot2)
set.seed(1)
df <- tibble(x1 = factor(sample(letters[1:7], 50, replace = TRUE)),
x2 = factor(sample(letters[1:7], 50, replace = TRUE)),
x3 = factor(sample(letters[1:7], 50, replace = TRUE)),
grpA = factor(sample(c("grp1", "grp2"), 50,
prob = c(0.3, 0.7), replace=TRUE)),
grpB = factor(sample(c("grp1", "grp2"), 50,
prob = c(0.6, 0.4), replace=TRUE)))
Define data preparation function
plot_data_prepr <- function(dat, groupvar, mainvar)
{
groupvar <- sym(groupvar)
mainvar <- sym(mainvar)
plot_data <- dat %>%
group_by(!!groupvar) %>%
count(!!mainvar, .drop = F) %>% tidyr::drop_na() %>%
mutate(pct = n/sum(n),
pct2 = ifelse(n == 0, 0.005, n/sum(n)),
grp_tot = sum(n),
pct_lab = paste0(format(pct*100, digits = 1),'%'),
pct_pos = pct2 + .02)
return(plot_data)
}
Loop to create all 6 plots
for(gvar in names(df)[4:5]){
for(mvar in names(df)[1:3])
{
print(ggplot(plot_data_prepr(df, gvar, mvar),
aes(x = !!sym(mvar), y = pct2, fill = !!sym(mvar))) +
geom_bar(stat = 'identity') +
ylim(0,1) +
geom_text(aes(label=pct_lab, y = pct_pos + .02)) +
facet_grid(as.formula(paste0(".~", gvar))) +
ggtitle(paste0(mvar, " by ", gvar))
)
}
}
Output:
Created on 2020-06-30 by the reprex package (v0.3.0)
Related
I am working with the R programming language.
I simulated the following data:
set.seed(123)
myFun <- function(n = 5000) {
a <- do.call(paste0, replicate(5, sample(LETTERS, n, TRUE), FALSE))
paste0(a, sprintf("%04d", sample(9999, n, TRUE)), sample(LETTERS, n, TRUE))
}
name = myFun(400)
variable = rnorm(400, 50,10)
part1 = data.frame(name,variable)
name = myFun(10)
variable = rnorm(10, 130,10)
part2 = data.frame(name,variable)
final = rbind(part1, part2)
final$name = substr(final$name,1,3)
Then, I made a barplot of this data:
library(ggplot2)
p<-ggplot(data=final, aes(x=name, y=variable)) +
geom_bar(stat="identity") + ggtitle(" Title of Barplot")
Is there a way I can take the "names" with the ten largest values of "variable" and place them as labels on top of the corresponding bars?
I saw this link over here that shows how to do this for all bars (https://www.geeksforgeeks.org/how-to-add-labels-over-each-bar-in-barplot-in-r/) - but is there a way to do this only for the 10 largest bars?
Thanks!
Note: Is there some way to better "center" the labels and prevent them from overlapping?
Another option using geom_text_repel which has a lot of options for positioning your labels. Here is a reproducible example:
set.seed(123)
myFun <- function(n = 5000) {
a <- do.call(paste0, replicate(5, sample(LETTERS, n, TRUE), FALSE))
paste0(a, sprintf("%04d", sample(9999, n, TRUE)), sample(LETTERS, n, TRUE))
}
name = myFun(400)
variable = rnorm(400, 50,10)
part1 = data.frame(name,variable)
name = myFun(10)
variable = rnorm(10, 130,10)
part2 = data.frame(name,variable)
final = rbind(part1, part2)
library(dplyr)
# Create subset dataframe
final_10 <- final %>%
arrange(desc(variable)) %>%
slice(1:10)
library(ggplot2)
library(ggrepel)
ggplot(data=final, aes(x=name, y=variable)) +
geom_bar(stat="identity") +
geom_text_repel(data = final_10, aes(x = name, y = variable, label = variable), size = 2, segment.color = "grey50") +
ggtitle(" Title of Barplot")
Created on 2022-08-24 with reprex v2.0.2
Here you go, just create a new variable with the name for the top 10 and NA otherwise
# Setup
library(tidyverse)
# Create a label column
final <-
final %>%
arrange(desc(variable)) %>%
mutate(label = ifelse(row_number() <= 10, name, NA))
# Add geom_text() for label
p <-
ggplot(
data = final,
aes(
x = name,
y = variable,
label = label)) +
geom_bar(stat="identity") +
geom_text() +
ggtitle(" Title of Barplot")
I am using the R programming language. I created the following data set for this example:
var_1 <- rnorm(1000,10,10)
var_2 <- rnorm(1000, 5, 5)
var_3 <- rnorm(1000, 6,18)
favorite_food <- c("pizza","ice cream", "sushi", "carrots", "onions", "broccoli", "spinach", "artichoke", "lima beans", "asparagus", "eggplant", "lettuce", "cucumbers")
favorite_food <- sample(favorite_food, 1000, replace=TRUE, prob=c(0.5, 0.45, 0.04, 0.001, 0.001, 0.001, 0.001, 0.001, 0.001, 0.001, 0.001, 0.001, 0.001))
response <- c("a","b")
response <- sample(response, 1000, replace=TRUE, prob=c(0.3, 0.7))
data = data.frame( var_1, var_2, var_3, favorite_food, response)
data$favorite_food = as.factor(data$favorite_food)
data$response = as.factor(data$response)
From here, I want to make histograms for the two categorical variables in this data set and put them on the same page:
#make histograms and put them on the same page (note: I don't know why the "par(mfrow = c(1,2))" statement is not working)
par(mfrow = c(1,2))
histogram(data$response, main = "response"))
histogram(data$favorite_food, main = "favorite food"))
My question : Is it possibly to automatically produce histograms for all categorical variables (without manually writing the "histogram()" statement for each variable) in a given data set and print them on the same page? Is it better to the use the "ggplot2" library instead for this problem ?
I can manually write the "histogram()" statement for each individual categorical variables in the data set, but I was looking for a quicker way to do this. Is it possible to do this with a "for loop"?
Thanks
A ggplot2/tidyverse solution is to lengthen each column into data and then use faceting to plot them all in the same page:
(with edit to plot only factor variables)
factor_vars <- sapply(data, is.factor)
varnames <- names(data)
deselect_not_factors <- varnames[!factor_vars]
library(tidyr)
library(ggplot2)
data_long <- data %>%
pivot_longer(
cols = -deselect_not_factors,
names_to = "category",
values_to = "value"
)
ggplot(data_long) +
geom_bar(
aes(x = value)
) +
facet_wrap(~category, scales = "free")
Here's a base R alternative using barplot in for loop :
cols <- names(data)[sapply(data, is.factor)]
#This would need some manual adjustment if number of columns increase
par(mfrow = c(1,length(cols)))
for(i in cols) {
barplot(table(data[[i]]), main = i)
}
As an alternative, you can capitalize on the fantastic DataExplorer package.
Note that histograms are for continuous variables and hence, you wanted to create bar plots for your categorical variables. This can be done as follows:
if(require(DataExplorer)==FALSE) install.packages("DataExplorer"); library(DataExplorer)
DataExplorer::plot_histogram(data) # plots histograms for continuous variables
DataExplorer::plot_bar(data) # bar plots for categorical variables
Please refer to the package manual for more details.
Here is a try using cowplot & ggplot2
library(ggplot2)
library(dplyr)
library(foreach)
library(cowplot)
list_variables <- c("response", "favorite_food")
all_plot <- foreach(current_var = c(list_variables)) %do% {
# need to do this to avoid ggplot reference to same summary data afterward.
data_summary_name <- paste0(current_var, "_summary")
eval(substitute(
{
graph_data <- data %>%
group_by(!!sym(current_var)) %>%
summarize(count = n(), .groups = "drop") %>%
mutate(share = count / sum(count))
plot <- ggplot(graph_data) +
geom_bar(mapping = aes(x = !!sym(current_var), y = share), width = 1,
fill = "#00FFFF", color = "#000000", stat = "identity") +
scale_y_continuous(labels = scales::percent) +
ggtitle(current_var) + ylab("Perecent of Total") +
theme_bw()
}, list(graph_data = as.name(data_summary_name))
))
return(plot)
}
plot_grid(plotlist = all_plot, ncol = 2)
Note: For reference about why I use eval & substitue you can reference to this question on ggplot2 generate same plot for different variables in a for loop
Using facet_wrap as approach similar to QuishSwash with data calculated in share instead
list_variables <- c("response", "favorite_food")
# Calculate share for choosen variables defined in list_variables
# You can adjust by having some variables selection based on some condition
summary_df <- bind_rows(foreach(current_var = c(list_variables)) %do% {
data %>%
group_by(variable = !!sym(current_var)) %>%
summarize(count = n(), .groups = "drop") %>%
mutate(share = count / sum(count),
variable_name = current_var)
})
ggplot(summary_df) +
geom_bar(
aes(x = variable, y = share),
fill = "#00FFFF", color = "#000000", stat = "identity") +
facet_wrap(~variable_name, scales = "free") +
scale_y_continuous(labels = scales::percent) +
theme_bw()
Created on 2021-04-29 by the reprex package (v2.0.0)
Here is the data that I will be using to give context to my question:
library(dplyr)
library(tidyr)
library(ggplot2)
set.seed(1)
f1 <- sample(c(letters[1:3],NA),100, prob = c(rep((0.9/3),times = 3),0.1),replace = T)
f2 <- sample(c(letters[1:3],NA),100, prob = c(rep((0.8/3),times = 3),0.2),replace = T)
f3 <- sample(c(letters[1:3],NA),100, prob = c(rep((0.95/3),times = 3),0.01),replace = T)
sample_dat <- tibble(
x1 = factor(f1, level=letters[1:3]),
x2 = factor(f2, level=letters[1:3]),
x3 = factor(f3, level=letters[1:3]),
grpA = factor(sample(c("grp1","grp2"),100, prob=c(0.3, 0.7) ,replace=T),
levels = c("grp1", "grp2"))
)
sample_dat
here is a function that I created to prepare the data for plotting:
plot_data_prepr <- function(dat, groupvar, mainvar){
groupvar <- sym(groupvar)
mainvar <- sym(mainvar)
plot_data <- dat %>%
group_by(!!groupvar) %>%
count(!!mainvar, .drop = F) %>% drop_na() %>%
mutate(pct = n/sum(n),
pct2 = ifelse(n == 0, 0.005, n/sum(n)),
grp_tot = sum(n),
pct_lab = paste0(format(pct*100, digits = 1),'%'),
pct_pos = pct2 + .02)
return(plot_data)
}
here is the application of the function to produce the data sets I will use for plotting
plot_data_prepr(dat = sample_dat, groupvar = "grpA", mainvar = "x1")
plot_data_prepr(dat = sample_dat, groupvar = "grpA", mainvar = "x2")
plot_data_prepr(dat = sample_dat, groupvar = "grpA", mainvar = "x3")
here I use a for loop to plot the data and dynamically change the labels of the facets -- if one runs this in
rstudio as an RMarkdown file, one can see that the plots are produced and the labels for the facets are
each distinct as they should be given the different degrees of missingness and sampling densities for the
'grpA' variable.
plot_list <- vector('list', length = 0)
for (fct in names(sample_dat)[1:3]){
mvar <- fct
smvar <- sym(mvar)
gvar <- "grpA"
sgvar <- sym(gvar)
dd <- plot_data_prepr(dat = sample_dat, groupvar = gvar, mainvar = mvar)
pre_lookup <- dd %>%
select(!!sgvar, grp_tot) %>%
group_by(!!sgvar) %>%
summarise(lookup = mean(grp_tot))
lookup <- pre_lookup$lookup
my_label <- function(x) {
var <- names(x)[1]
list(paste0(x[[var]], " (N = ", lookup, ")"))
}
plot <- ggplot(dd,
mapping = aes(x=!!smvar, y = pct2, fill = !!smvar)) +
geom_bar(stat = 'identity') +
ylim(0,1.3) +
geom_text(aes(x=!!smvar, label=pct_lab, y = pct_pos + .02)) +
facet_grid(as.formula(paste0(".~", gvar)), labeller = my_label) +
ggtitle(paste(gvar,"by",mvar))
plot_list[[fct]] <- plot
print(plot)
}
Here's my problem -- when I print the plots which are stored in the list,
they all seem to retain the facet label from the last plot, instead of retaining
the distinct facet-labels they displayed when they were originally generated.
for (name in names(sample_dat)[1:3]){
print(plot_list[[name]])
}
Basically, I would like to be able to print the plots from the list
when I need them and have them display their distinct facet labels
as they had been displayed when the plots were originally produced.
Perhaps someone in the community could help me?
I would suggest you try to avoid the loop for the plots building. It uses to create that kind of issues as you have with labels or sometimes with data. Here, I have packaged your loop in a function and stored the results in a list. Also, you can use lapply() with the names of your data in order to directly create the list with the plots. Here the code:
#Function for plot
myplotfun <- function(fct)
{
mvar <- fct
smvar <- sym(mvar)
gvar <- "grpA"
sgvar <- sym(gvar)
dd <- plot_data_prepr(dat = sample_dat, groupvar = gvar, mainvar = mvar)
pre_lookup <- dd %>%
select(!!sgvar, grp_tot) %>%
group_by(!!sgvar) %>%
summarise(lookup = mean(grp_tot))
lookup <- pre_lookup$lookup
my_label <- function(x) {
var <- names(x)[1]
list(paste0(x[[var]], " (N = ", lookup, ")"))
}
plot <- ggplot(dd,
mapping = aes(x=!!smvar, y = pct2, fill = !!smvar)) +
geom_bar(stat = 'identity') +
ylim(0,1.3) +
geom_text(aes(x=!!smvar, label=pct_lab, y = pct_pos + .02)) +
facet_grid(as.formula(paste0(".~", gvar)), labeller = my_label) +
ggtitle(paste(gvar,"by",mvar))
return(plot)
}
Now, we create a list:
#Create a list
plot_list <- lapply(names(sample_dat)[1:3],myplotfun)
Finally, the plots as you used in the last loop:
#Loop
for (i in 1:length(plot_list)){
plot(plot_list[[i]])
}
Outputs:
The problem is your my_label function has a free variable lookup that's only resolved when you actually plot the function. After your for-loop runs, then you it only contains the last value in the loop. To capture the current loop value, you can place it inside an enclosure. So you could change the my_label function to
my_labeler <- function(lookup) {
function(x) {
var <- names(x)[1]
list(paste0(x[[var]], " (N = ", lookup, ")"))
}
}
and then call facet_grid with
facet_grid(as.formula(paste0(".~", gvar)), labeller = my_labeler(lookup))
But I agree with #Duck that avoiding the for-loop in this case would be easier.
data set for my question:
set.seed(1)
dfr2 <- tibble(x1 = factor(sample(letters[1:3], 50, replace = T), levels=letters[1:3]),
x2 = factor(sample(letters[1:2], 50, replace = T), levels=letters[1:2]),
x3 = factor(sample(letters[1:3], 50, replace = T), levels=letters[1:3]),
grpA = factor(sample(c("grp1","grp2"),50, prob=c(0.3, 0.7) ,replace=T), levels = c("grp1", "grp2")),
grpB = factor(sample(c("grp1","grp2"),50, prob=c(0.6, 0.4) ,replace=T), levels = c("grp1", "grp2"))
)
head(dfr2)
function to prepare my data for plotting:
plot_data_prepr <- function(dat, groupvar, mainvar){
groupvar <- sym(groupvar)
mainvar <- sym(mainvar)
plot_data <- dat %>%
group_by(!!groupvar) %>%
count(!!mainvar, .drop = F) %>% drop_na() %>%
mutate(pct = n/sum(n),
pct2 = ifelse(n == 0, 0.005, n/sum(n)),
grp_tot = sum(n),
pct_lab = paste0(format(pct*100, digits = 1),'%'),
pct_pos = pct2 + .02)
return(plot_data)
}
normal usage of data prep function:
plot_data_prepr(dat = dfr2, groupvar = "grpA", mainvar = "x1")
creating custom color scales for the 3-level factors ("x1", "x3") and 2-level factor ("x2"):
factor_3lev <- levels(dfr2$x1)
factor_3lev_col <- c(brewer.pal(11,"RdBu")[c(2,7,9)])
names(factor_3lev_col) <- factor_3lev
factor_3lev_col_scale <- scale_fill_manual(values=factor_3lev_col)
show_col(factor_3lev_col)
factor_2lev <- levels(dfr2$x2)
factor_2lev_col <- c(brewer.pal(11,"RdBu")[c(2,7)])
names(factor_2lev_col) <- factor_2lev
factor_2lev_col_scale <- scale_fill_manual(values=factor_2lev_col)
show_col(factor_2lev_col)
assigning the custom color scale names to the name 'col_scales2':
col_scales2 <- grep("factor.*_col_scale", ls(), value = T)
calling the class() function on the color scale names reveals that color scales are ScaleDiscrete objects:
class(factor_3lev_col_scale)
class(factor_2lev_col_scale)
calling the class function on the string representation of the color scales reveals that these objects are character objects:
class(col_scales2[1])
class(col_scales2[2])
it then follows that these are not identical:
identical(factor_3lev_col_scale, col_scales2[1])
identical(factor_2lev_col_scale, col_scales2[2])
and that when I try assign the string representation of the custom color scale to 'col_scal' and then subsequently use 'col_scal' with ggplot2::ggplot(), it fails:
for(gvar in names(dfr2)[4]){
for(mvar in names(dfr2)[1:3]) {
if (mvar %in% names(dfr2[c(1,3)])) {
col_scal <- col_scales2[1]
} else {
col_scal <- col_scales2[2]
}
print(ggplot(plot_data_prepr(dfr2, gvar, mvar),
aes(x = !!sym(mvar), y = pct2, fill = !!sym(mvar))) +
geom_bar(stat = 'identity') +
ylim(0,1) +
geom_text(aes(label=pct_lab, y = pct_pos + .02)) +
col_scal +
facet_grid(as.formula(paste0(".~", gvar))) +
ggtitle(paste0(mvar, " by ", gvar)))
}
}
but that when I assign the actual name of the custom color scale to 'col_scal' and then subsequently use 'col_scal' with ggplot2::ggplot(), it works:
for(gvar in names(dfr2)[4]){
for(mvar in names(dfr2)[1:3]) {
if (mvar %in% names(dfr2[c(1,3)])) {
col_scal <- factor_3lev_col_scale
} else {
col_scal <- factor_2lev_col_scale
}
print(ggplot(plot_data_prepr(dfr2, gvar, mvar),
aes(x = !!sym(mvar), y = pct2, fill = !!sym(mvar))) +
geom_bar(stat = 'identity') +
ylim(0,1) +
geom_text(aes(label=pct_lab, y = pct_pos + .02)) +
col_scal +
facet_grid(as.formula(paste0(".~", gvar))) +
ggtitle(paste0(mvar, " by ", gvar)))
}
}
Is there a way to get the character representation of the color scales to resolve correctly to a ScaleDiscrete object so that I may use it in ggplot? I want to do this so I can dynamically select color scales from a vector of color scale names (like 'col_scales2') and choose a color scale based on the factor that is selected for the 'mainvar' argument in the plot_data_prepr() function.
Thanks.
Please use this. It works fine.
if (mvar %in% names(dfr2[c(1,3)])) {
col_scal <- eval_tidy(as.name(col_scales2[2]))
} else {
col_scal <- eval_tidy(as.name(col_scales2[1]))
}
You get the following output:
There is a good discussion about using ggplot in loop and other creative ways at Looping over variables in ggplot. However, the discussion does not quite solve my problem.
I have a vertical dataset that I need to create plots from in a loop. There is no error in the code but my code only prints the last plot. Can't figure out why. Here is a reproducible example:
df <- cbind.data.frame(var = sample(c('a','b'), size = 100, replace = TRUE),
grp = sample(c('x','y'), size = 100, replace = TRUE), value = rnorm(100))
for (i in 2) {
plot.df <- df[which(df$var == c('a','b')[i]),]
print(ggplot(plot.df, aes(x = 1:nrow(plot.df), y = value, color = grp)) +
geom_line() + ggtitle(c('a','b')[i]))
}
As an alternative, you might also consider using lapply, as it makes the code a lot more readable.
If I am not mistaken you want to produce plots for each of the levels of the variable var.
You can firstly define your function, and then apply it to all levels
my_plot <- function(x){
# debug: x <- "a"
plot.df <- df[df$var %in% x,]
ggplot(plot.df, aes(x = 1:nrow(plot.df), y = value, color = grp)) +
geom_line() + ggtitle(x)
}
lapply(unique(df$var), my_plot)
The comment by #EJJ is correct, your loop isn't you need something like
for (i in seq_along(1:nlevels(factor(df$var))))
library(ggplot2)
library(dplyr)
df <- cbind.data.frame(var = sample(c('a','b'), size = 100, replace = TRUE),
grp = sample(c('x','y'), size = 100, replace = TRUE), value = rnorm(100))
for (i in seq_along(1:nlevels(factor(df$var)))) {
plot.df <- df[which(df$var == c('a','b')[i]),]
print(ggplot(plot.df, aes(x = 1:nrow(plot.df), y = value, color = grp)) +
geom_line() + ggtitle(c('a','b')[i]))
}