Reputation: 697
I would like to create a named list containing plots. I create a list from a vector containing unique IDs that I use to filter a master dataframe containing all the info.
I then have a function that I use in lapply to loop through the list of unique IDs to filter the master dataframe and create the plots. I then want to append each plot to an (originally) initialized list and I would like the names of the list entry to be equal to the list value passed in lapply.
My code below creates the plots, however the appended list does not have the corresponding names of the passed list id values.
Do I have the wrong approach? I have seen questions/answer that use names(list) etc. but the list passed into lapply is not named, I want passed list entries to become the names of the new list.
Thanks in advance!
library(ggplot2)
library(dplyr)
unique_names = as.list(c("apple", "banana", "carrots"))
listy = list()
dframe = data.frame(x_var = seq(1:9)) %>%
mutate(y_var = x_var^3)
temp = data.frame(id = c("apple", "apple", "apple", "banana", "banana", "banana", "carrots", "carrots", "carrots"))
dframe = bind_cols(dframe,
temp)
fun_plots = function(my_list,
my_df,
my_appending_list) {
a = filter(my_df,
id == my_list)
plt = ggplot() +
geom_line(data = a,
aes(x = x_var,
y = y_var))
my_appending_list$my_list = plt
}
plot_list = lapply(unique_names,
fun_plots,
my_df = dframe,
my_appending_list = listy)
Upvotes: 0
Views: 767
Reputation: 1200
You can avoid writing a function and mutating a list with a little bit more dplyr
magic. If I understand correctly you want a separate plot object for each value of the "id" variable - if so you can perform a group_by
on "id" and then generate a ggplot object for each set. Here's how
plot_df <- dframe %>%
group_by(id) %>%
do(plot = ggplot(.data) + geom_line(aes(x = x_var, y = y_var)) + ggtitle(.data$id))
plot_df
#> Source: local data frame [3 x 2]
#> Groups: <by row>
#>
#> # A tibble: 3 x 2
#> id plot
#> * <fctr> <list>
#> 1 apple <S3: gg>
#> 2 banana <S3: gg>
#> 3 carrots <S3: gg>
You can facet on the id variables to have one ggplot2. For instance:
ggplot(dframe) + geom_line(aes(x = x_var, y = y_var)) + facet_wrap(~ id)
Upvotes: 2
Reputation: 305
You can use dplyr group_by to accomplish this:
library(ggplot2)
library(dplyr)
unique_names = as.list(c("apple", "banana", "carrots"))
listy = list()
dframe = data.frame(x_var = seq(1:9)) %>%
mutate(y_var = x_var^3)
temp = data.frame(id = c("apple", "apple", "apple", "banana", "banana", "banana", "carrots", "carrots", "carrots"))
dframe = bind_cols(dframe,
temp)
dframe <- group_by(dframe, id) %>% do(plots=ggplot(data=.) +
aes(x=x_var, y=y_var) + geom_line() + ggtitle(unique(.$id)))
mylist <- as.list(dframe$plots)
mylist
HTH James
Upvotes: 0
Reputation: 60140
You can take out the my_appending_list
argument as it doesn't actually achieve anything at the moment, you aren't modifying the listy
object within the function. You can just do:
fun_plots = function(my_list,
my_df) {
a = filter(my_df,
id == my_list)
plt = ggplot() +
geom_line(data = a,
aes(x = x_var,
y = y_var))
plt
}
plot_list = lapply(unique_names,
fun_plots,
my_df = dframe)
names(plot_list) = unique_names
Upvotes: 1