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

RMarkdown循环生成多PDF但图表重复问题排查求助

批量生成班级PDF报告的错误分析与修正

核心错误点

1. RMarkdown未使用传递的参数,全局读取全量数据

执行脚本通过params给每个报告传递了当前班级的t1/t2文件路径及班级名称,但RMarkdown完全忽略这些参数,直接读取固定的Dataframe.csv全量数据,导致所有报告基于同一数据源生成。

2. RMarkdown内循环遍历所有班级,仅保留最后一次循环的图表

RMarkdown里写了遍历所有班级的循环,每次循环都会覆盖text_plot变量,最后只输出循环结束时text_plot存储的最后一个班级的图表,因此所有PDF显示的都是最后一个班级的结果。

3. 拼写错误导致数据处理异常

代码中textscores_long$school_class <- as.character(textscores_long$schoolclass)存在拼写错误:schoolclass应为school_class,这会导致班级列转换失败,后续过滤逻辑失效。


修正后的代码

执行脚本(路径确认正确即可,无需修改)

# Path to the data
data_path <- "Datapath"

# Function for rendering PDFs
render_pdf <- function(csv_file_t1, csv_file_t2) {
  # Extract file name (without path and extension)
  class <- tools::file_path_sans_ext(basename(csv_file_t1))
  
  # Remove the suffix “_work_t1” from the variable “class”
  class <- gsub("_work_t1$", "", class)
  
  # Debugging: Check whether class was defined correctly
  print(paste("Class:", class))  
  
  # Render R Markdown document with parameters
  rmarkdown::render(
    input = "Datapath/report.Rmd", # Path to the Rmd file
    output_file = paste0("Report_", class, ".pdf"),
    params = list(
      class = class,
      file_t1 = csv_file_t1,
      file_t2 = csv_file_t2
    ),
    envir = new.env(parent = globalenv())
  )
}


# List of CSV files for t1
csv_files_t1 <- list.files(path = data_path, pattern = "*_work_t1.csv", full.names = TRUE)

# Loop for rendering all PDFs for t1 and t2
for (file_t1 in csv_files_t1) {
  # Find the corresponding t2 file
  file_t2 <- gsub("_t1.csv$", "_t2.csv", file_t1)
  
  if (file.exists(file_t2)) {
    print(paste("Process file:", file_t1, "and", file_t2))
    render_pdf(file_t1, file_t2)  # Use current file_t1 and file_t2
  } else {
    print(paste("No corresponding t2 file found for:", file_t1))
  }
}

修正后的RMarkdown绘图代码

# ---
# params:
#   class: ""
#   file_t1: ""
#   file_t2: ""
# ---

# 1. 使用传递的参数读取当前班级的t1和t2数据
t1_data <- read.csv2(params$file_t1)
t2_data <- read.csv2(params$file_t2)

# 合并t1和t2数据(替换为实际主键,如student_id)
Dataframe <- merge(t1_data, t2_data, by = "student_id")

# 2. 过滤当前班级且consent=1的记录
textscores <- subset(Dataframe, consent == 1 & school_class == params$class) %>%
  select(school_class, ExCon, text_scores_T1, text_scores_T2)

# 3. 转换为长格式
textscores_long <- textscores %>%
  rename("August 2023" = text_scores_T1,
         "February 2024" = text_scores_T2) %>%
  pivot_longer(cols = c("August 2023", "February 2024"), names_to = "MP", values_to = "Textscores")

# 修正拼写错误
textscores_long$school_class <- as.character(textscores_long$school_class)

# 4. 生成当前班级的图表(无需遍历所有班级)
# 当前班级均值
df1 <- textscores_long %>%
  group_by(school_class, MP) %>%
  summarise(Mean = mean(Textscores, na.rm = TRUE)) %>%
  mutate(grp = "school_class") %>%
  rename("name" = school_class) %>%
  mutate(name = "Your class")

# 读取全量数据计算实验组/对照组均值
full_data <- read.csv2("Dataframe.csv")
full_textscores <- subset(full_data, consent == 1) %>%
  select(school_class, ExCon, text_scores_T1, text_scores_T2) %>%
  rename("August 2023" = text_scores_T1,
         "February 2024" = text_scores_T2) %>%
  pivot_longer(cols = c("August 2023", "February 2024"), names_to = "MP", values_to = "Textscores")

df2 <- full_textscores %>%
  group_by(ExCon, MP) %>%
  summarise(Mean = mean(Textscores, na.rm = TRUE)) %>% 
  mutate(grp = "ExCon") %>%
  rename("name" = ExCon) %>%
  mutate(name = ifelse(name == "实验", "Experimental group", "Control group")) # 替换为实际分组值

# 合并数据并绘图
text_plot <- rbind(df1, df2) %>%
  ggplot(aes(x = MP, y = Mean, fill = name)) +
  geom_col(position = position_dodge()) +
  scale_fill_manual(values = c("orange", "steelblue", "steelblue1"),
                    name = NULL) +
  theme_classic()

# 输出图表
text_plot

关键说明

  • RMarkdown开头必须声明params参数,确保能接收执行脚本传递的值。
  • 每个报告仅处理当前班级的数据,无需遍历所有班级,避免变量被覆盖。
  • 实验组/对照组的全局均值需从全量数据计算,保证对比基准正确。
  • 合并t1和t2数据时,务必使用正确的主键(如学生ID),避免数据错位。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.17 22:24:53