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

如何监测Data子目录变化并自动运行R脚本生成Rmd报告?

解决方案:基于目录状态校验的自动化报告生成流程

一、核心思路

用目录状态指纹(子目录的文件列表、总大小、最后修改时间的哈希值)判断是否有变化,避免重复生成报告。每次运行脚本时,对比当前状态和上次记录的状态,仅在状态不一致时执行报告生成。

二、具体实现步骤

1. 记录目录状态

创建dir_status.rds状态文件,存储每个运动项目子目录的关键状态信息:

library(dplyr)
library(digest)

# 定义路径
data_root <- "./Data"
status_file <- "./dir_status.rds"

# 获取当前子目录状态
get_current_status <- function() {
  sport_dirs <- list.dirs(data_root, recursive = FALSE, full.names = TRUE)
  
  dir_status <- lapply(sport_dirs, function(dir) {
    csv_files <- list.files(dir, pattern = "\\.csv$", full.names = TRUE)
    if(length(csv_files) == 0) return(NULL)
    
    total_size <- sum(file.size(csv_files))
    latest_mtime <- max(file.mtime(csv_files))
    fingerprint <- digest(list(dir, total_size, latest_mtime), algo = "md5")
    
    data.frame(
      sport_dir = basename(dir),
      full_path = dir,
      total_size = total_size,
      latest_mtime = as.character(latest_mtime),
      fingerprint = fingerprint,
      stringsAsFactors = FALSE
    )
  }) %>% bind_rows()
  
  return(dir_status)
}

# 首次运行初始化状态文件
if(!file.exists(status_file)) {
  initial_status <- get_current_status()
  saveRDS(initial_status, status_file)
}

2. 对比状态并触发报告生成

读取历史状态,找出变化的子目录,针对性生成报告:

# 读取历史与当前状态
prev_status <- readRDS(status_file)
current_status <- get_current_status()

# 筛选状态变化或新增的目录
changed_dirs <- anti_join(current_status, prev_status, by = "sport_dir") %>%
  bind_rows(filter(current_status, !fingerprint %in% prev_status$fingerprint))

# 为变化目录生成报告
if(nrow(changed_dirs) > 0) {
  library(rmarkdown)
  
  for(i in 1:nrow(changed_dirs)) {
    dir_path <- changed_dirs$full_path[i]
    sport_name <- changed_dirs$sport_dir[i]
    report_path <- file.path("./reports", paste0(sport_name, "_report.html"))
    
    # 调用Rmd模板生成报告(模板需支持sport_dir参数)
    render(
      input = "./your_report_template.Rmd",
      output_file = report_path,
      params = list(sport_dir = dir_path)
    )
  }
  
  # 更新状态文件
  saveRDS(current_status, status_file)
}

3. 每日调度设置

  • Windows环境:用taskscheduleR创建定时任务:
library(taskscheduleR)

taskscheduler_create(
  taskname = "SportReportGenerator",
  rscript = "./auto_report_generator.R",
  schedule = "DAILY",
  starttime = "08:00",
  startdate = Sys.Date()
)
  • Linux/macOS环境:用cronR配置cron任务:
library(cronR)

cron_add(
  command = "Rscript /path/to/auto_report_generator.R",
  frequency = "daily",
  at = "08:00",
  id = "sport_report_generator"
)

三、实时监听替代方案

如果需要实时响应目录变化(而非每日调度),用fs包的文件监听功能(需脚本持续后台运行):

library(fs)
library(rmarkdown)

data_root <- "./Data"
status_file <- "./dir_status.rds"

# 初始化状态文件(首次运行)
if(!file.exists(status_file)) {
  saveRDS(get_current_status(), status_file)
}

watch_dir <- function() {
  while(TRUE) {
    # 监听目录变化,超时1小时
    changes <- dir_watch(data_root, recursive = TRUE, timeout = 3600)
    if(length(changes) > 0) {
      # 提取变化对应的运动子目录
      changed_sport_dirs <- unique(dirname(changes$path)) %>%
        grep(paste0("^", data_root, "/"), ., value = TRUE) %>%
        basename() %>% unique()
      
      # 生成对应报告
      for(sport in changed_sport_dirs) {
        dir_path <- file.path(data_root, sport)
        report_path <- file.path("./reports", paste0(sport, "_report.html"))
        render(
          input = "./your_report_template.Rmd",
          output_file = report_path,
          params = list(sport_dir = dir_path)
        )
      }
      
      # 更新状态文件
      saveRDS(get_current_status(), status_file)
      Sys.sleep(60) # 避免短时间内重复触发
    }
  }
}

watch_dir()

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.26 22:43:11