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

如何在RMarkdown生成的PDF中正确展示循环生成的DataFrame?

解决RMarkdown循环生成课程KPI表格不显示的问题

核心问题原因

RMarkdown中循环内的表格输出不会自动触发渲染,必须明确调用适配PDF的渲染函数;另外你代码里的effectif计算存在错误,会导致统计结果失真。

修复步骤与代码

1. 修正统计逻辑错误

把effectif = nrow(test_colonne_no_na[1])改为effectif = nrow(test_colonne_no_na),否则你得到的永远是1,无法正确统计有效人数。

2. 收集结果后统一渲染(推荐方案)

循环内先把每个课程的统计结果存入列表,循环结束后用knitr::kable统一生成适配PDF的表格,这是最稳定的方式:

library(dplyr)
library(knitr)
library(kableExtra)

## CREATION DE LA BOUCLE/FONCTION
# Tableau par cours 
cours_subset = subset(data, select = (num_inscr_prog_ulb+1):ncol(data))
cours_subset = cours_subset[, colSums(is.na(cours_subset[1, ])) == 0]
moyenne_cours = cours_subset[5,]
cours_subset = cours_subset[-1:-5,]

# 初始化列表存储所有课程的统计结果
course_summaries <- list()

# début de la boucle
for (a in 1:ncol(cours_subset)) {
  test_colonne = cours_subset[,a] #boucler sur le nombre de colonne
  nom_colonne = colnames(test_colonne[1])
  test_colonne_no_na = subset(test_colonne, !is.na(test_colonne[,1]))
  
  # 修正effectif计算
  effectif = nrow(test_colonne_no_na)
  count_abs = 0
  count_abj = 0
  count_ndp = 0
  count_ann = 0
  count_else = 0
  grades = NULL
  
  for (i in 1:effectif) {
    valeur = test_colonne_no_na[i, 1]
    if (valeur == "ABS") {
      count_abs = count_abs + 1
    }
    else if (valeur == "ABJ") {
      count_abj = count_abj + 1
    }
    else if (valeur == "NDP") {
      count_ndp = count_ndp + 1
    }
    else if (valeur == "ANN") {
      count_ann = count_ann + 1
    }
    else {
      count_else = count_else + 1
      grades = c(grades, valeur)
    }
  }
  
  grades = gsub(",", ".", grades)
  grades_num = as.numeric(grades)
  nombre_de_zero = length(subset(grades_num, grades_num == 0))
  moyenne_du_cours = round(mean(na.omit(grades_num)),3)
  moyenne_du_cours_sans_zero = round(mean(subset(grades_num, grades_num != 0)), 3)
  
  noms_df = c("Cours analysé", "Effectif", "NDP", "ABS", "ABJ", "ANN", "Elèves ayant passé l'examen",
              "Moyenne", "Nombre d'élèves ayant eu 0", "Moyenne sans les 0")
  valeurs_df = c(nom_colonne, effectif, count_ndp, count_abs, count_abj, count_ann, count_else, moyenne_du_cours, 
                 nombre_de_zero, moyenne_du_cours_sans_zero)
  summary_cours = data_frame(Description = noms_df, Valeur = valeurs_df)
  
  # 将当前课程的统计结果加入列表
  course_summaries[[nom_colonne]] <- summary_cours
}

# 循环输出所有课程的表格
for (course_name in names(course_summaries)) {
  # 添加课程标题
  cat(paste0("## KPI du cours : ", course_name, "\n"))
  # 生成PDF适配的表格
  print(
    kable(course_summaries[[course_name]], 
          format = "latex",
          booktabs = TRUE,
          caption = paste("Statistiques détaillées pour", course_name)) %>%
      kable_styling(latex_options = c("striped", "hold_position"))
  )
  # 添加空行分隔表格
  cat("\n\n")
}

3. 循环内实时输出(备选方案)

如果坚持在循环内输出每个表格,需用knitr::kable配合print,并确保输出格式正确:
在循环内替换print(pander(summary_cours))为:

cat(paste0("### ", nom_colonne, "\n"))
print(knitr::kable(summary_cours, format = "latex", booktabs = TRUE))
cat("\n")

额外优化建议

替换内层循环统计状态的逻辑,用向量操作更高效:

# 统计各状态人数
count_abs = sum(test_colonne_no_na[,1] == "ABS", na.rm = TRUE)
count_abj = sum(test_colonne_no_na[,1] == "ABJ", na.rm = TRUE)
count_ndp = sum(test_colonne_no_na[,1] == "NDP", na.rm = TRUE)
count_ann = sum(test_colonne_no_na[,1] == "ANN", na.rm = TRUE)
# 提取成绩
grades = test_colonne_no_na[!test_colonne_no_na[,1] %in% c("ABS","ABJ","NDP","ANN"), 1]
count_else = length(grades)

这样可以去掉内层的for循环,大幅提升代码运行效率。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.17 21:15:26