如何在每日24:00自动创建带表头的空CSV文件以延续数据采集
问题描述
我有如下结构的tibble数据集:
# A tibble: 20 × 2 collectionDate collectionTime <date> <dttm> 1 2022-09-18 2022-09-18 20:52:56 2 2022-09-18 2022-09-18 20:52:56 3 2022-09-18 2022-09-18 20:52:56 4 2022-09-18 2022-09-18 20:52:15 5 2022-09-18 2022-09-18 20:51:38 6 2022-09-18 2022-09-18 20:49:15 7 2022-09-18 2022-09-18 20:49:15 8 2022-09-18 2022-09-18 20:49:15 9 2022-09-18 2022-09-18 20:48:34 10 2022-09-18 2022-09-18 20:46:35 11 2022-09-18 2022-09-18 20:46:35
数据按collectionDate分日存储为CSV文件,每日一个。目前需要手动创建次日空CSV才能继续写入数据,我希望实现每日24:00准时或之后立即创建带表头的次日空CSV(比如/myDir/2022_19_09.csv)。
现有代码逻辑:
- 读取最新数据(按文件修改时间取最新):
files = file.info(list.files("myDir/myDir2", full.names = T)) mostRecentlySavedFile = rownames(files)[which.max(files$mtime)] data = read_csv(mostRecentlySavedFile)
- 追加数据到当日文件:
write_csv(., append = TRUE, paste("myDir", gsub("-", "_", Sys.Date()), ".csv", sep = "_"))
生成的文件路径示例:/myDir/2022_18_09.csv
之前尝试过提前1分钟创建文件,但会导致读取到错误日期的空文件:
myDataNew = tibble( collectionDate = NA, collectionTime = NA ) if(Sys.time() + lubridate::minutes(1) == paste(Sys.Date(), "24:00:00")){ file.create(myDataNew) }
核心需求:该功能要嵌入到每40秒执行一次的持续更新函数中,每次迭代检查系统时间,精准在24:00创建次日文件,同时避免读取错误文件的问题。
数据集结构的完整定义:
data = structure(list(collectionDate = structure(c(19253, 19253, 19253, 19253, 19253, 19253, 19253, 19253, 19253, 19253, 19253, 19253, 19253, 19253, 19253, 19253, 19253, 19253, 19253, 19253), class = "Date"), collectionTime = structure(c(1663534376, 1663534376, 1663534376, 1663534335, 1663534298, 1663534155, 1663534155, 1663534155, 1663534114, 1663533995, 1663533995, 1663533995, 1663533878, 1663533800, 1663533762, 1663533722, 1663533722, 1663533684, 1663533449, 1663533449), tzone = "UTC", class = c("POSIXct", "POSIXt"))), row.names = c(NA, -20L), class = c("tbl_df", "tbl", "data.frame"))
解决方案
1. 精准判断次日文件创建时机
在每次40秒迭代时,检查当前时间是否已进入次日,且次日CSV文件尚未创建。既不会提前创建导致读取错误,也能在跨天后第一时间生成文件。
2. 修复读取数据的逻辑
之前按修改时间取最新文件的问题在于,跨天后新建的空文件修改时间是最新的,但我们需要读取当日数据对应的文件。直接根据当前日期拼接路径读取,彻底避免依赖修改时间的风险。
完整嵌入代码
将以下逻辑放到你的40秒循环函数中:
library(tidyverse) library(lubridate) # 检查并创建次日文件的函数 check_and_create_tomorrow_file <- function() { dir_path <- "myDir" today <- Sys.Date() tomorrow <- today + days(1) tomorrow_file <- file.path(dir_path, paste0(gsub("-", "_", tomorrow), ".csv")) # 仅当进入次日且文件不存在时创建 if (Sys.time() >= as.POSIXct(paste(today, "23:59:59"), tz = Sys.timezone()) + 1 & !file.exists(tomorrow_file)) { # 创建带正确表头的空文件 empty_tibble <- tibble(collectionDate = Date(), collectionTime = POSIXct()) write_csv(empty_tibble, tomorrow_file) message(paste("已创建次日文件:", tomorrow_file)) } } # 读取当日数据的函数(替换原有读取逻辑) read_today_data <- function() { dir_path <- "myDir/myDir2" today_file <- file.path(dir_path, paste0(gsub("-", "_", Sys.Date()), ".csv")) # 若当日文件不存在(如凌晨刚过还未写入数据),返回空结构 if (!file.exists(today_file)) { return(tibble(collectionDate = Date(), collectionTime = POSIXct())) } read_csv(today_file) } # 持续更新循环示例 continuous_update_loop <- function() { while(TRUE) { # 检查并创建次日文件 check_and_create_tomorrow_file() # 读取当日数据 data <- read_today_data() # 这里编写你的数据采集、处理逻辑 # ... # 追加数据到当日文件(保留原有逻辑即可) # write_csv(new_data, append = TRUE, file.path("myDir", paste0(gsub("-", "_", Sys.Date()), ".csv"))) # 等待40秒 Sys.sleep(40) } }
关键说明
- 无提前创建风险:只有系统时间确实进入次日,且文件不存在时才创建,彻底解决提前创建导致的读取错误。
- 读取逻辑更可靠:直接按当日日期读取文件,不再依赖修改时间,从根源避免跨天后读取空文件的问题。
- 表头格式正确:用
Date()和POSIXct()创建空列,保证CSV表头与数据类型匹配,后续追加数据不会出错。
内容的提问来源于stack exchange,提问作者user113156
相关产品推荐
相关产品推荐

