我对for loop
中的ggplot2
感到困惑。
我正在尝试通过ggplot2中的for循环向每个绘图标题添加Species
和categ
名称以及文件名。不知何故,循环似乎只有一个物种名称标题。
library(dplyr)
data_iris <- iris%>%
mutate(categ=ifelse(Petal.Width<0.4,"A",ifelse(Petal.Width>=0.4&Petal.Width<=1.0, "B","C")))
> head(data_iris)
Sepal.Length Sepal.Width Petal.Length Petal.Width Species categ
1 5.1 3.5 1.4 0.2 setosa A
2 4.9 3.0 1.4 0.2 setosa A
3 4.7 3.2 1.3 0.2 setosa A
4 4.6 3.1 1.5 0.2 setosa A
5 5.0 3.6 1.4 0.2 setosa A
6 5.4 3.9 1.7 0.4 setosa B
PLOT PART
for (i in unique(data_iris$Species)) {
for (j in unique(data_iris$categ)) {
p = ggplot(data_iris[data_iris$categ==j,], aes(x=Sepal.Length, y=Sepal.Width)) +
geom_point(size=3, aes(colour=categ))+
labs(title=paste( i,j, "species_categ",sep="_")) #this part is not working!!!
plot_list[[j]] = p
}
}
# Save plots to tiff. Makes a separate file for each plot.
library(ggplot2)
for (i in unique(data_iris$Species)) {
for (j in unique(data_iris$categ)) {
file_name = paste(i,j, "iris_plot_", ".tiff", sep="_")
tiff(file_name)
print(plot_list[[j]])
dev.off()
}
}
ant输出是这样的(我没有添加所有的图和名称。但是你会在工作目录中看到它们)
所以,正如我们可以看到问题在这里,我无法为每个情节获得正确的Species
名称。我无法得到它?为什么会这样?
答案 0 :(得分:2)
试试这个。 你的索引是错误的。我可能会首先以不同的方式存储图表 - 可能在列表列表中。
ind <- 1 # initialise the index for storing
for (i in unique(data_iris$Species)) {
for (j in unique(data_iris$categ)) {
p <- ggplot(data_iris[data_iris$categ==j,], aes(x=Sepal.Length, y=Sepal.Width)) +
geom_point(size=3, aes(colour=categ))+
labs(title=paste( i,j, "species_categ",sep="_"))
plot_list[[ind]] <- p # stor the plot
ind <- ind + 1 # increment
}
}
ind <- 1
for (i in unique(data_iris$Species)) {
for (j in unique(data_iris$categ)) {
file_name = paste(i,j, "iris_plot_", ".tiff", sep="_")
tiff(file_name)
print(plot_list[[ind]]) # use the same index to retrieve the plot
ind <- ind + 1
dev.off()
}
}
答案 1 :(得分:1)
purrr::map, walk & iwalk
框架中使用tidyverse
的解决方案
library(tidyverse)
data_iris <- iris%>%
as_tibble() %>%
mutate(categ = ifelse(Petal.Width < 0.4, "A",
ifelse(Petal.Width >= 0.4 & Petal.Width <= 1.0, "B", "C")))
data_iris
#> # A tibble: 150 x 6
#> Sepal.Length Sepal.Width Petal.Length Petal.Width Species categ
#> <dbl> <dbl> <dbl> <dbl> <fct> <chr>
#> 1 5.1 3.5 1.4 0.2 setosa A
#> 2 4.9 3 1.4 0.2 setosa A
#> 3 4.7 3.2 1.3 0.2 setosa A
#> 4 4.6 3.1 1.5 0.2 setosa A
#> 5 5 3.6 1.4 0.2 setosa A
#> 6 5.4 3.9 1.7 0.4 setosa B
#> 7 4.6 3.4 1.4 0.3 setosa A
#> 8 5 3.4 1.5 0.2 setosa A
#> 9 4.4 2.9 1.4 0.2 setosa A
#> 10 4.9 3.1 1.5 0.1 setosa A
#> # ... with 140 more rows
# Split based on species and categories
# Remove lists having 0 row
data_iris %>%
split(list(.$Species, .$categ)) %>%
discard(function(x) nrow(x) == 0) -> df_split
# For all species and categories
plots <- map(df_split,
~ ggplot(.x, aes(x = Sepal.Length, y = Sepal.Width)) +
geom_point(size = 3, aes(colour = categ))+
theme_bw(base_size = 16) +
labs(title = paste0("Species: ", .x$Species, " | Category: ", .x$categ)))
# Check the 1st plot
plots[[1]]
# Display all plots using purrr::walk
walk(plots, print)
# Save all plots using purrr::iwalk
iwalk(plots,
~ ggsave(plot = .x,
filename = paste0("./img/", .y, ".tiff"))
)
由reprex package(v0.2.0)创建于2018-05-16。
答案 2 :(得分:0)
我想通过添加Species_categ
列并在循环中运行它似乎不太复杂。
data_iris <- iris%>%
mutate(categ=ifelse(Petal.Width<0.4,"A",ifelse(Petal.Width>=0.4&Petal.Width<=1.0, "B","C")))%>%
unite(Species_categ,Species,categ,remove=F) #added this line
plot_list = list()
for (i in unique(data_iris$Species_categ)) {
p = ggplot(data_iris[data_iris$Species_categ==i,], aes(x=Sepal.Length, y=Sepal.Width)) +
geom_point(size=3, aes(colour=categ))+
labs(title=paste( i, "species_categ",sep="_"))
plot_list[[i]] = p
}
# Save plots to tiff. Makes a separate file for each plot.
for (i in unique(data_iris$Species_categ)) {
file_name = paste(i, "iris_plot_2", ".tiff", sep="_")
tiff(file_name)
print(plot_list[[i]])
dev.off()
}