启动时加载的自定义函数中this.path返回路径异常问题
问题解决:启动加载的函数无法正确获取调用脚本路径
通过R/R-4.3.2/etc/Rprofile.site加载OnStart.R中的RelPath()函数时,在Script.R里调用RelPath(0)返回的是OnStart.R的路径,而非预期的Script.R路径,但手动加载该函数时正常。
相关代码
Rprofile.site 代码
source("D:/.../OnStart.R")
OnStart.R 代码
RelPath = function(MoveUpLevels = 1, Subdir){ Path = this.path::this.path() # Move up x levels towards root directory to access directories of current R file MoveUpLevels = MoveUpLevels + 1 if(MoveUpLevels > 0){ for(i in 1:MoveUpLevels){ Path = sub("/[^/]+$", "", Path) } } # If sub directory is given, then check if it is exists # If so, then add, else throw warning if(!missing(Subdir)){ if(file.exists(file.path(Path,Subdir))){ Path=file.path(Path,Subdir) }else{ warning(paste0("Given subdirectory is not found on system: ", file.path(Path,Subdir))) } } return(Path) }
Script.R 调用代码
RelPath(0) > "D:/.../OnStart.R"
预期输出:"E:/.../Script.R"
问题原因
问题出在this.path::this.path()的默认行为——它默认返回函数定义所在脚本的路径。当函数通过Rprofile.site启动加载时,函数的定义环境绑定在OnStart.R的加载环境中,所以调用时会返回该文件路径;而手动加载时,函数是在当前Script.R的环境下定义的,因此能正确获取当前脚本路径。
解决方案
要让函数获取调用者所在脚本的路径,修改RelPath函数中this.path的调用参数,指定追踪调用栈到调用者的层级:
# 替换原有的 Path 赋值语句 Path = this.path::this.path(toplevel = FALSE, n = 1)
toplevel = FALSE:不限制到顶层调用环境,允许追踪到调用者的环境n = 1:指定获取调用栈中第1层(即直接调用该函数的脚本)的路径
修改后的完整RelPath函数:
RelPath = function(MoveUpLevels = 1, Subdir){ Path = this.path::this.path(toplevel = FALSE, n = 1) # Move up x levels towards root directory to access directories of current R file MoveUpLevels = MoveUpLevels + 1 if(MoveUpLevels > 0){ for(i in 1:MoveUpLevels){ Path = sub("/[^/]+$", "", Path) } } # If sub directory is given, then check if it is exists # If so, then add, else throw warning if(!missing(Subdir)){ if(file.exists(file.path(Path,Subdir))){ Path=file.path(Path,Subdir) }else{ warning(paste0("Given subdirectory is not found on system: ", file.path(Path,Subdir))) } } return(Path) }
修改后在Script.R中调用RelPath(0),即可正确返回Script.R的路径。
内容的提问来源于stack exchange,提问作者qms
相关产品推荐
相关产品推荐

