早上好,
尝试创建一个 for 循环来迭代数据帧并为数值变量创建箱线图。不幸的是,我陷入了迭代。
下面的代码将显示我到目前为止所拥有的内容。我计划将绘图保存在列表中,然后在第二个循环中将它们一次性绘制在 .Rmd 文件中。
问题是,我在迭代中有两个动态值。首先,绘图变量的名称应采用 plt_x 的形式,其中 x 代表数据帧中的列数。第二个是每个箱线图的标题,应在其中粘贴列名称。
没有循环的箱线图工作得很好,在plot_name上创建也很好,但由于某些原因,for循环返回各种错误。
有人可以帮忙吗?我可能对plot_safe变量有逻辑错误,但毕竟我不知道它是什么。
plot_safe = list()
for (col in names(data)) {
if (is.numeric(data[[col]])) {
max_val = max(data[[col]])
min_val = min(data[[col]])
median_val = median(data[[col]])
iqr_val = IQR(data[[col]])
plot_name = paste("plt_", grep(col, names(data)), sep = "")
plot_safe[[plot_name]] =
ggplot(data, aes(x =NA,
y = data[[col]])) +
stat_boxplot(geom = "errorbar", color = "grey20") +
geom_boxplot() +
stat_summary(fun.y = mean, geom = "point", colour = "red") +
scale_color_brewer(palette = "Dark2", guide = FALSE) +
labs(title = sprintf("Boxplot of the Variable: %s", col)) +
theme_bw() +
annotate("text", x = 0.5, y = min_val, label = min_val, color = "grey50", size = 3) +
annotate("text", x = 0.5, y = max_val, label = max_val, color = "grey50", size = 3) +
annotate("text", x = 0.5, y = median_val, label = median_val, color = "grey50", size = 3) +
annotate("text", x = 0.5, y = median_val - iqr_val/2, label = median_val - iqr_val/2, color = "grey50", size = 3) +
annotate("text", x = 0.5, y = median_val + iqr_val/2, label = median_val + iqr_val/2, color = "grey50", size = 3) +
theme(axis.ticks.x = element_blank(), axis.title.x = element_blank(), axis.text.x = element_blank())
}
}
for (plot in plot_safe) {
plot_safe[sprintf("%s",plot)]
}
特别是在创建
ggplot
列表时,您可以使用 lapply
而不是 for
循环更轻松地获得结果。我还建议将绘图代码放在一个函数中,这样可以更轻松地进行测试和调试。最后,我通过将箱线图统计数据放入数据框中来稍微简化了您的代码,以便我们可以仅使用一个geom_text
来添加标签。
注意:请注意
.data
中使用的 aes()
代名词,这是在美学上映射作为字符串传递的列名称的推荐方法。
使用
iris
作为示例数据:
library(ggplot2)
data <- iris
plot_fun <- function(col) {
if (is.numeric(data[[col]])) {
box_stats <- data.frame(
stats = c("min", "p25", "median", "p75", "max"),
value = boxplot.stats(data[[col]])[["stats"]]
)
ggplot(data, aes(
x = NA,
y = .data[[col]]
)) +
stat_boxplot(geom = "errorbar", color = "grey20") +
geom_boxplot() +
stat_summary(fun = mean, geom = "point", colour = "red") +
scale_color_brewer(palette = "Dark2", guide = "none") +
labs(
title = sprintf("Boxplot of the Variable: %s", col)
) +
theme_bw() +
geom_text(
data = box_stats,
aes(x = .5, y = value, label = value),
color = "grey50", size = 3
) +
theme(
axis.ticks.x = element_blank(),
axis.title.x = element_blank(),
axis.text.x = element_blank()
)
}
}
plot_safe <- lapply(
names(data),
plot_fun
)
names(plot_safe) <- paste("plt", names(data), sep = "_")
plot_safe$plt_Sepal.Length