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

R语言函数调用与逐行执行生成SVG图结果不一致问题

问题:批量执行R脚本生成空白SVG,逐行执行正常

在main.R中调用eda(ds)时,批量执行整个脚本会导致输出的density_age.svg为空白文件,但逐行选中代码按Ctrl+Enter执行时,能生成正常的图像。已确认两次执行使用的ds数据一致,代码全程无报错。


相关代码

主调用代码

ds <- eda(ds)

eda函数定义

eda <- function(ds){
  log4r.info(eda_logger, "Prepping data")
  ds <- prep.data(ds)
  
  log4r.info(eda_logger, "Feature selection")
  ds <- feature.selection(ds)
  
  log4r.info(eda_logger, "Univariate Descriptive Statistics Graph")
  univariate.descriptive.statistics.graph(ds)
  
  return(ds)
}

(注:原代码函数名误写为teda,已修正为调用时的eda)

绘图函数定义

univariate.descriptive.statistics.graph <- function(ds){
  # Density
  out_density_path <- paste0(out_graph, "/density_age.svg") #line 1
  svg(out_density_path)  #line 2
  lattice::densityplot(ds$age, xlab="Age")  #line 3
  dev.off()  #line 4
}

补充数据样本

> dput(head(ds, 20)) 

structure(list(gender = structure(c(2L, 1L, 2L, 1L, 1L, 2L, 2L, 
1L, 1L, 1L, 1L, 1L, 1L, 2L, 1L, 1L, 2L, 2L, 1L, 2L), .Label = c("Female", 
"Male", "Other"), class = "factor"), age = c(67, 61, 80, 49, 
79, 81, 74, 69, 59, 78, 81, 61, 54, 78, 79, 50, 64, 75, 60, 57
), hypertension = c(0L, 0L, 0L, 0L, 1L, 0L, 1L, 0L, 0L, 0L, 1L, 
0L, 0L, 0L, 0L, 1L, 0L, 1L, 0L, 0L), heart_disease = c(1L, 0L, 
1L, 0L, 0L, 0L, 1L, 0L, 0L, 0L, 0L, 1L, 0L, 1L, 1L, 0L, 1L, 0L, 
0L, 1L), avg_glucose_level = c(228.69, 202.21, 105.92, 171.23, 
174.12, 186.21, 70.09, 94.39, 76.15, 58.57, 80.43, 120.46, 104.51, 
219.84, 214.09, 167.41, 191.61, 221.29, 89.22, 217.08), bmi = c(36.6, 
NA, 32.5, 34.4, 24, 29, 27.4, 22.8, NA, 24.2, 29.7, 36.8, 27.3, 
NA, 28.2, 30.9, 37.5, 25.8, 37.8, NA), smoking_status = structure(c(1L, 
2L, 2L, 3L, 2L, 1L, 2L, 2L, NA, NA, 2L, 3L, 3L, NA, 2L, 2L, 3L, 
3L, 2L, NA), .Label = c("formerly smoked", "never smoked", "smokes"
), class = "factor"), stroke = c(1L, 1L, 1L, 1L, 1L, 1L, 1L, 
1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L)), row.names = c(NA, 
20L), class = "data.frame")

原因与解决方法

这是lattice绘图系统在函数内批量执行时的典型问题:lattice绘图默认采用延迟求值,在函数内部如果没有显式触发打印,绘图对象不会被渲染到输出设备上。逐行执行时R会自动打印绘图对象,所以能正常生成图像;但批量执行函数时,这个自动打印步骤被跳过,导致dev.off()关闭设备前没有实际绘制内容,最终生成空白文件。

有两种简单的修复方式:

方法1:显式打印lattice绘图对象

修改绘图函数,将densityplot的结果赋值给变量并打印:

univariate.descriptive.statistics.graph <- function(ds){
  out_density_path <- paste0(out_graph, "/density_age.svg")
  svg(out_density_path)
  # 显式打印绘图对象
  p <- lattice::densityplot(ds$age, xlab="Age")
  print(p)
  dev.off()
}

方法2:全局启用lattice自动打印

在脚本开头添加一行代码,全局开启lattice绘图的自动打印功能:

lattice::trellis.device()

这种方法无需修改现有绘图函数,适合存在多个lattice绘图的场景。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.18 15:05:35