R中visNetwork包visSave指定非当前路径报normalizePath错误如何解决
R visNetwork 自定义路径保存网络图报错解决方案
报错信息
运行visSave保存网络图时抛出如下错误:
Error in normalizePath(target_dir, "/", TRUE) : path[1]="query/htmlwidgets-1.2": No such file or directory
触发场景
复现代码如下:
visNetwork(nodes = nodes, edges = edges, width = "100%", height = 900, main = list( style = 'font:caption;font-weight:bold;font-size:15px;text-align:center;')) %>% visPhysics(solver = "forceAtlas2Based", stabilization = T, timestep=0.25, forceAtlas2Based = list(gravitationalConstant = -50, avoidOverlap = 0.95)) %>% visOptions(highlightNearest = TRUE) %>% visEdges(smooth = T) %>% visNodes(scaling = list(min = 10, max = 40))%>% visSave(file = save_name, background = "white",selfcontained = T)
当visSave的file参数(即代码中save_name变量)设置为非当前工作目录(./)的自定义路径时,必现上述报错,且系统中找不到生成的目标文件。
问题原因
这是旧版visNetwork搭配htmlwidgets 1.x版本的已知路径处理bug:
- 函数内部不会自动递归创建目标路径的父级目录
- 传入非当前目录的保存路径时,内部拼接htmlwidgets依赖资源的路径逻辑错误,会在错误的目录下查找依赖文件,触发路径不存在的报错
解决方案
按优先级推荐以下3种可直接落地的方法:
方法1:升级依赖包到最新版本
新版visNetwork已经修复了非当前目录保存的路径拼接bug,直接运行命令升级包即可,升级后直接传入合法保存路径就能正常输出:install.packages(c("visNetwork", "htmlwidgets"))注意:即使升级版本,也需要确保保存路径的父目录真实存在,R不会自动创建多级不存在的目录
方法2:提前创建目标目录+传入标准化绝对路径
不升级包的情况下,在运行绘图代码前先手动创建目标路径的父目录,再用normalizePath把保存路径转成标准绝对路径传入visSave:# 示例:自定义保存路径 save_name <- "./my_output/network/first_plot.html" # 递归创建所有不存在的父目录 dir.create(dirname(save_name), recursive = TRUE, showWarnings = FALSE) # 转成标准绝对路径再传入 save_name <- normalizePath(save_name, mustWork = FALSE) # 原有绘图、保存代码保持不变即可 visNetwork(nodes = nodes, edges = edges, width = "100%", height = 900, main = list( style = 'font:caption;font-weight:bold;font-size:15px;text-align:center;')) %>% visPhysics(solver = "forceAtlas2Based", stabilization = T, timestep=0.25, forceAtlas2Based = list(gravitationalConstant = -50, avoidOverlap = 0.95)) %>% visOptions(highlightNearest = TRUE) %>% visEdges(smooth = T) %>% visNodes(scaling = list(min = 10, max = 40))%>% visSave(file = save_name, background = "white",selfcontained = T)方法3:临时切换工作目录适配旧版函数逻辑
如果上述两种方法都不生效,可以临时把R的工作目录切换到目标保存文件夹,保存完成后再切回原工作目录,完全规避路径拼接错误:# 配置目标目录和保存文件名 target_dir <- "./my_output/network/" target_file <- "first_plot.html" # 创建目标目录 dir.create(target_dir, recursive = TRUE, showWarnings = FALSE) # 记录当前原始工作目录 origin_wd <- getwd() # 切换到目标保存目录 setwd(target_dir) # 保存文件时只传文件名,不传路径 visNetwork(nodes = nodes, edges = edges, width = "100%", height = 900, main = list( style = 'font:caption;font-weight:bold;font-size:15px;text-align:center;')) %>% visPhysics(solver = "forceAtlas2Based", stabilization = T, timestep=0.25, forceAtlas2Based = list(gravitationalConstant = -50, avoidOverlap = 0.95)) %>% visOptions(highlightNearest = TRUE) %>% visEdges(smooth = T) %>% visNodes(scaling = list(min = 10, max = 40))%>% visSave(file = target_file, background = "white",selfcontained = T) # 切回原始工作目录 setwd(origin_wd)
避坑提示
- 传入
visSave的file参数必须带.html后缀,函数不会自动补全文件名 - 路径中不要包含中文、特殊空格字符,避免旧版函数路径解析失败
selfcontained = T参数会把所有依赖资源打包到单个html文件里,不需要额外拷贝依赖文件夹,分享文件更方便
内容的提问来源于stack exchange,提问作者Yaovi
相关产品推荐
相关产品推荐

