eal*_*ns1 1 plot for-loop r heatmap ggplot2
我正在处理调查数据。调查项目有两组,每组三个项目。我的调查样本中有两名受访者。
我正在尝试按调查项目组生成热图,其中:
这是一个完全可重现的示例:
wd <- "D:/Desktop/"
setwd(wd)
#--create dataframe
respondent = c("Respondent_1", "Respondent_1", "Respondent_1","Respondent_1", "Respondent_1", "Respondent_1",
"Respondent_2", "Respondent_2", "Respondent_2","Respondent_2", "Respondent_2", "Respondent_2")
item = c("Item_1", "Item_2", "Item_3","Item_1", "Item_2", "Item_3",
"Item_1", "Item_2", "Item_3","Item_1", "Item_2", "Item_3")
item_group = c("Group_1","Group_1","Group_1","Group_2","Group_2","Group_2",
"Group_1","Group_1","Group_1","Group_2","Group_2","Group_2")
score = c(1, 40, 100, 100, 30, 12,
2, 15, 80, 77, 44, 10)
high_value_color = c("darkred", "darkred", "darkred",
"brown3", "brown3", "brown3")
plot_df = data.frame(respondent, item, item_group, score, high_value_color)
#--write function
#--inspired from this: http://www.reed.edu/data-at-reed/resources/R/loops_with_ggplot2.html
plot_list <- unique(plot_df$item_group)
survey_items.graph <- function(df, na.rm = TRUE, ...) {
#--loop to generate heatmaps for each group
for (i in seq_along(plot_list)) {
plot <- ggplot(aes(x = df$item[df$item_group == plot_list[i]],
y = df$respondent[df$item_group==plot_list[i]]),
data = subset(df, df$item_group == plot_list[i])) +
geom_tile(aes(fill = df$score[df$item_group == plot_list[i]]), colour = "black") +
scale_fill_gradient2(low = "azure1",
high = df$high_value_color[df$item_group == plot_list[i]],
guide = "colorbar") +
geom_text(aes(label = df$score[df$item_group==plot_list[i]],
hjust = 0.5,
angle = 90),
size = 4) +
ggtitle(df$item_group[df$item_group==plot_list[i]]) +
theme(panel.grid.major = element_blank(),
panel.grid.minor = element_blank(),
panel.background = element_blank(),
plot.title = element_text(size = 7, face="bold"),
axis.text.y = element_text(size = 7, face ="bold"),
axis.text.x = element_text(angle=90, hjust=1),
axis.title = element_blank(),
legend.position = "none")
# save plots as .png
ggsave(plot, file=paste(wd,"plots/heatmap for ", plot_list[i], ".png", sep=""), scale=2)
print(plot)
}
}
#--load ggplot2
library(ggplot2)
#--execute function on plot dataframe
survey_items.graph(plot_df)
Run Code Online (Sandbox Code Playgroud)
当我执行代码时,我得到以下两个图:
我的直觉告诉我,我没有对代码中“scale_fill_gradient2”部分的“high”参数做正确的事情。
作为测试,当我用可接受的颜色字符串值(例如“brown3”,可以在此处找到其他颜色)替换“high”参数的值时,我得到的图的行为符合我的要求。
我想要的是“scale_fill_gradient2”的“high”参数接受数据的“high_value_color”变量中找到的相应项目的值。
好的。主要问题是将颜色传递给scale_fill_gradient2
. 但是,您的代码中还有很多可以改进的地方。具体来说,您只想将裸变量名称传递给aes
. 我也不明白为什么你不断地到处重复你的子集。你很可能会让自己陷入麻烦。
以下是我可能会如何解决这样的问题:
首先,我们创建一个更简单的函数:它只直接接受一个数据参数,并简单地用该数据绘制所需的图(无循环)。
survey_items.graph <- function(dat) {
ggplot(aes(x = item, y = respondent), data = dat) +
geom_tile(aes(fill = score), colour = "black") +
scale_fill_gradient2(low = "azure1",
high = dat$high_value_color[1],
guide = "colorbar") +
geom_text(aes(label = score), hjust = 0.5, angle = 90, size = 4) +
ggtitle(dat$item_group[1]) +
theme(panel.grid.major = element_blank(),
panel.grid.minor = element_blank(),
panel.background = element_blank(),
plot.title = element_text(size = 7, face="bold"),
axis.text.y = element_text(size = 7, face ="bold"),
axis.text.x = element_text(angle=90, hjust=1),
axis.title = element_blank(),
legend.position = "none")
}
Run Code Online (Sandbox Code Playgroud)
然后,我们split
将您的数据存储在 data.frames 列表中,每个item_group
:
split_data <- split(plot_df, plot_df$item_group)
Run Code Online (Sandbox Code Playgroud)
然后我们将函数应用于列表中的每个条目,创建一个绘图列表:
plot_list <- lapply(split_data, survey_items.graph)
Run Code Online (Sandbox Code Playgroud)
为了方便起见,我习惯grid.arrange
将两个图快速拼接在一起:
library(gridExtra)
do.call(grid.arrange, plot_list)
Run Code Online (Sandbox Code Playgroud)
如果你想保存它们,你可以使用类似的东西:
Map(function(x, i, ...) ggsave(paste0('plot', i, '.png'), x, ...),
plot_list, seq_along(plot_list), scale = 2)
Run Code Online (Sandbox Code Playgroud)