使用调度器调用函数时,如何检查DataFrame是否存在并合并?
问题分析与解决方案
你的代码存在两个核心问题:
- 调度器调用错误:
tclTaskSchedule的第二个参数需要传入函数对象,而你传的是run_once()(直接执行函数并传递返回值),导致调度器只会执行一次函数,后续不会重复调用。 - 变量作用域问题:函数内部的
exists检查默认只看当前函数环境,无法识别全局环境中的mydf1_all;同时直接赋值mydf1_all <- ...只会创建局部变量,无法修改全局存储的合并数据。
修正方案1:使用全局变量存储合并数据
library(tcltk2) library(dplyr) # 必须加载dplyr以使用bind_rows run_once <- function() { # 生成新的DataFrame mydf1 <- data.frame( Fruit = c("apple", "pear"), Price = c(60, 45) ) # 检查全局环境中是否存在合并后的DataFrame if (exists("mydf1_all", envir = .GlobalEnv)) { # 修改全局变量,合并新数据 mydf1_all <<- bind_rows(mydf1_all, mydf1) print("rows binded") } else { # 初始化全局变量 mydf1_all <<- mydf1 print("rows not binded") } print(Sys.time()) return(mydf1_all) } # 启动调度:传入函数对象run_once而非run_once() tclTaskSchedule(1000, run_once, id = "run_once", redo = TRUE) # 停止调度(按需执行) # tclTaskDelete("run_once")
修正方案2:使用自定义环境存储(更推荐,避免全局变量污染)
library(tcltk2) library(dplyr) # 创建独立环境存储数据,不干扰全局命名空间 data_store <- new.env() run_once <- function() { mydf1 <- data.frame( Fruit = c("apple", "pear"), Price = c(60, 45) ) # 检查自定义环境中的数据 if (exists("mydf1_all", envir = data_store)) { data_store$mydf1_all <- bind_rows(data_store$mydf1_all, mydf1) print("rows binded") } else { data_store$mydf1_all <- mydf1 print("rows not binded") } print(Sys.time()) return(data_store$mydf1_all) } # 启动调度 tclTaskSchedule(1000, run_once, id = "run_once", redo = TRUE) # 停止调度(按需执行) # tclTaskDelete("run_once") # 查看合并后的数据:data_store$mydf1_all
关键修正点
- 调度器参数必须传入函数本身(不带括号),确保每秒重复调用函数。
- 明确指定变量存储的环境(全局环境或自定义环境),让函数能正确读取和修改历史合并数据。
- 使用
<<-修改全局变量,或直接操作自定义环境的变量,确保数据在函数调用间持续保留。
内容的提问来源于stack exchange,提问作者user2165379
相关产品推荐
相关产品推荐

