通过数据框进行动态迭代,以使用 R 创建自定义箱线图

问题描述 投票:0回答:1

早上好,

尝试创建一个 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)]
}
r for-loop ggplot2 boxplot
1个回答
0
投票

特别是在创建

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

© www.soinside.com 2019 - 2024. All rights reserved.