Reputation: 201
I want to run through six similar dataframes and print out six plots using ggplot.
My code works when I run the plots separately but I can't get ggplot to run six times using a for loop. My six dataframes are the six animals listed in gg_pets.
cat <- data.frame(Breed = c("American Shorthair","Ragdoll","Persian","Sphynx","Maine Coon"),
Longevity = c("17","19","15","17","20"))
dog <- data.frame(Breed = c("Havanese","Bulldog","Beagle","Chihuahua","Poodle"),
Longevity = c("20","11","12","15","16"))
#etc for types of birds, fish, snakes, and ferrets
#the following works
plot <- ggplot(data = cat, aes(x = Breed, y = Longevity, fill = Breed)) +
geom_bar(stat = "identity", position = position_dodge()) +
xlab("Breed") +
ylab("Longevity") +
ggtitle("cat") +
geom_text(aes(label = Longevity), vjust = -0.3, color = "black", size = 3.5) +
theme(axis.line = element_line(color = "black"), axis.text = element_text(color = "black"),
legend.position = "none", plot.title = element_text(hjust = .5),
panel.grid.minor = element_blank(), panel.grid.major = element_blank(),
panel.border = element_rect(color = "black", fill = NA, size = 0.8),
panel.background = element_rect(fill = NA), text = element_text(size=10))
print(plot)
gg_pets <- c("cat","dog","bird","fish","snake","ferret")
#the following does not work
for (i in 1:length(gg_pets)){
plot <- ggplot(data = [i], aes(x = Breed, y = Longevity, fill = Breed)) +
geom_bar(stat = "identity", position = position_dodge()) +
xlab("Breed") +
ylab("Longevity") +
ggtitle([i]) +
geom_text(aes(label = Longevity), vjust = -0.3, color = "black", size = 3.5) +
theme(axis.line = element_line(color = "black"), axis.text = element_text(color = "black"),
legend.position = "none", plot.title = element_text(hjust = .5),
panel.grid.minor = element_blank(), panel.grid.major = element_blank(),
panel.border = element_rect(color = "black", fill = NA, size = 0.8),
panel.background = element_rect(fill = NA), text = element_text(size=10))
print(plot)
}
Upvotes: 2
Views: 3262
Reputation: 833
An alternative to the list
approach mentioned in the other answers would be to first have everything in the same data.frame
, since apparently all the tables have the same variables; and then have one more variable indicating what kind of pet does the observation correspond to. As follows:
pets_df <- bind_rows(cat %>% add_column(pet = 'cat'),
dog %>% add_column(pet = 'dog'))
> pets_df
Breed Longevity pet
1 American Shorthair 17 cat
2 Ragdoll 19 cat
3 Persian 15 cat
4 Sphynx 17 cat
5 Maine Coon 20 cat
6 Havanese 20 dog
7 Bulldog 11 dog
8 Beagle 12 dog
9 Chihuahua 15 dog
10 Poodle 16 dog
Then, in each iteration of the loop you only have to filter the one data.frame
. For example:
for (i in 1:length(gg_pets)) {
plot <- ggplot(data = filter(pets_df, pet == gg_pets[i]),
aes(x = Breed, y = Longevity, fill = Breed)) +
geom_bar(stat = "identity", position = position_dodge()) +
xlab("Breed") +
ylab("Longevity") +
ggtitle(gg_pets[i]) +
geom_text(aes(label = Longevity), vjust = -0.3, color = "black", size = 3.5) +
theme(axis.line = element_line(color = "black"), axis.text = element_text(color = "black"),
legend.position = "none", plot.title = element_text(hjust = .5),
panel.grid.minor = element_blank(), panel.grid.major = element_blank(),
panel.border = element_rect(color = "black", fill = NA, size = 0.8),
panel.background = element_rect(fill = NA), text = element_text(size=10))
print(plot)
}
Upvotes: 1
Reputation: 3824
In your example gg_pets is just a vector of strings. You need to concatenate the data frames in order to iterated over them in the for-loop. You can do it with a list. As follows. You can use the names of the items as a title.
...
gg_pets <- list(cat=cat, dog=dog)
#the following does not work
for (i in 1:length(gg_pets)) {
plot <- ggplot(data = gg_pets[[i]], aes(x = Breed, y = Longevity, fill = Breed)) +
geom_bar(stat = "identity", position = position_dodge()) +
xlab("Breed") +
ylab("Longevity") +
ggtitle(names(gg_pets)[i]) +
geom_text(aes(label = Longevity), vjust = -0.3, color = "black", size = 3.5) +
theme(axis.line = element_line(color = "black"), axis.text = element_text(color = "black"),
legend.position = "none", plot.title = element_text(hjust = .5),
panel.grid.minor = element_blank(), panel.grid.major = element_blank(),
panel.border = element_rect(color = "black", fill = NA, size = 0.8),
panel.background = element_rect(fill = NA), text = element_text(size=10))
print(plot)
}
Upvotes: 3
Reputation: 226801
I think you need
ggplot(data = get(i), ...)
but it would probably be more idiomatic/better practice to put your data sets in a named list (my_data_list <- list(cat=cat, dog=dog, ...)
or even my_data_list <- mget(gg_pets)
) and use data = my_data_list[[i]]
...
Upvotes: 1