如何用withr包同时清理临时变量与par()图形参数?
问题翻译
我有一个无法修改的遗留函数bad_function,它依赖未作为输入参数传入的对象。为了对其进行文档化,我希望用withr包在隔离环境中临时修改状态,但发现临时定义的example_df、example_text仍留在执行环境,仅par()参数被清理。请问如何同时清理这些变量?是否需要编写自定义withr函数?
# 依赖全局环境参数的遗留函数 bad_function <- function(){ plot(example_df) } par_1 <- par() # 执行代码 withr::with_par( new = list(oma = c(rep(2, 4)), cex = 0.55), code = { example_df <- mtcars example_text <- "whatever" bad_function() text(x = 1, y = 2,labels = example_text) } )
par_2 <- par() # 绘图参数已被清理 identical(par_1, par_2) #> [1] TRUE # 不希望保留的临时变量仍存在 ls() #> [1] "bad_function" "example_df" "example_text" "par_1" "par_2"
解决方案
不需要自定义withr函数,用local()或withr::with_tempvars就能解决变量泄漏问题:
方法1:用local()隔离临时变量
withr::with_par仅负责恢复绘图参数,不会处理你定义的临时变量。local()会创建一个临时局部环境,代码块内的变量仅存在于该环境中,执行完毕后自动销毁,不会泄漏到全局环境。
修改后的代码:
bad_function <- function(){ plot(example_df) } par_1 <- par() withr::with_par( new = list(oma = c(rep(2, 4)), cex = 0.55), code = local({ example_df <- mtcars example_text <- "whatever" bad_function() text(x = 1, y = 2,labels = example_text) }) )
验证效果:
par_2 <- par() identical(par_1, par_2) #> [1] TRUE ls() #> [1] "bad_function" "par_1" "par_2"
方法2:用withr::with_tempvars精准控制临时变量
如果你需要明确指定要清理的变量,可使用withr::with_tempvars,它会临时创建变量并在执行后自动删除:
withr::with_par( new = list(oma = c(rep(2, 4)), cex = 0.55), code = withr::with_tempvars( vars = c("example_df", "example_text"), code = { example_df <- mtcars example_text <- "whatever" bad_function() text(x = 1, y = 2,labels = example_text) } ) )
这种方式需要你明确列出变量名,适合精准控制的场景;而local()更简洁通用,推荐优先使用。
内容的提问来源于stack exchange,提问作者Balthasar
相关产品推荐
相关产品推荐

