You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何通过循环索引调用变量并批量生成ggplot图表?

Solution

First, fix the initial data setup by defining n (your sample code was missing this):

n <- 100
d <- data.frame(
  school = rep(LETTERS[1:4], times = c(25, 25, 25, 25)),
  student = rep(1:25, times = 4),
  week = rep(seq(from = 1, to = 25, by = 5), each = 25), # Adjusted to match school/student counts
  crit1fl = sample(0:1, n, replace = TRUE),
  crit2fl = sample(0:1, n, replace = TRUE),
  crit3fl = sample(0:1, n, replace = TRUE)
)

Working Loop for Batch Plotting

Use the .data pronoun to reference string variable names correctly, and store/print all plots:

library(tidyverse)
library(scales)

# Define list of criteria variables
critvars <- paste0("crit", 1:3, "fl")

# Create a list to store plots (optional but useful)
plot_list <- list()

for (varname in critvars) {
  # Calculate proportions for current criteria
  d2 <- d %>%
    count(school, week, .data[[varname]]) %>%
    group_by(school, week) %>%
    mutate(prop = n / sum(n)) %>%
    ungroup()
  
  # Generate plot
  current_plot <- d2 %>%
    ggplot(aes(x = as.factor(week), y = n, fill = .data[[varname]])) +
    geom_bar(position = "fill", stat = "identity") +
    facet_wrap(~school) +
    geom_text(
      aes(label = percent(prop)),
      position = position_fill(vjust = 1.5),
      color = "white",
      data = d2 %>% filter(.data[[varname]] == 1)
    ) +
    labs(
      title = paste("Proportion meeting", varname),
      y = "Proportion",
      x = "Week"
    ) +
    scale_fill_discrete(name = varname) # Update legend title
  
  # Print plot to display it
  print(current_plot)
  
  # Store plot in list for later use
  plot_list[[varname]] <- current_plot
  
  # Optional: Save plot to file
  # ggsave(paste0(varname, "_plot.png"), current_plot, width = 10, height = 6)
}

Key Fixes Explained

  1. Correct Variable Reference:

    • Your original {{ varname }} didn't work because varname is a string, and {{ }} expects a bare variable name. Using .data[[varname]] lets you access columns directly by string, which is perfect for loops with dynamic variable names.
  2. Display/Store All Plots:

    • You were overwriting the g variable each iteration, so only the last plot was retained. By printing each plot inside the loop and storing them in a list (plot_list), you'll see all plots and can access them later.
  3. Dynamic Filter for geom_text:

    • Replaced the hardcoded crit1fl == 'Y' with .data[[varname]] == 1 (matching your 0/1 variable values) to filter the text data correctly for each criteria.
  4. Clearer Plot Labels:

    • Updated the title and legend name to include the current criteria variable, making each plot's purpose obvious.

Alternative: Using Symbol Conversion

If you prefer tidy evaluation with symbols instead of .data, you can convert the string to a symbol with sym() and unquote it with !!:

for (varname in critvars) {
  crit_sym <- sym(varname)
  
  d2 <- d %>%
    count(school, week, !!crit_sym) %>%
    group_by(school, week) %>%
    mutate(prop = n / sum(n)) %>%
    ungroup()
  
  current_plot <- d2 %>%
    ggplot(aes(x = as.factor(week), y = n, fill = !!crit_sym)) +
    geom_bar(position = "fill", stat = "identity") +
    facet_wrap(~school) +
    geom_text(
      aes(label = percent(prop)),
      position = position_fill(vjust = 1.5),
      color = "white",
      data = d2 %>% filter(!!crit_sym == 1)
    ) +
    labs(
      title = paste("Proportion meeting", varname),
      y = "Proportion",
      x = "Week"
    ) +
    scale_fill_discrete(name = varname)
  
  print(current_plot)
  plot_list[[varname]] <- current_plot
}

This achieves the same result—choose whichever syntax you find more readable.

内容的提问来源于stack exchange,提问作者glor

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.30 10:17:59