Rscript 检测 R 脚本是否被调用/来自另一个脚本 [英] Rscript detect if R script is being called/sourced from another script

查看:28
本文介绍了Rscript 检测 R 脚本是否被调用/来自另一个脚本的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我编写了一个脚本,在获取脚本时检查脚本是否正在使用 interactive() 以交互方式运行.如果它以交互方式运行,则不会搜索命令行参数.但是,如果它不是以交互方式运行,它会搜索命令行参数并抛出错误.

I have a written a script that when it is sourced checks if the script is being run interactively using interactive(). If it is run interactively, it does not search for command line arguments. However, if it is not run interactively, it searches for command line arguments and throws an error.

这通常很好,但有时我会编写第二个 R 脚本,我想独立运行该脚本来处理一些数据.因此 Script2 获取 Script1 的来源,而 Script1 检测到它没有以交互方式运行,并开始搜索命令行参数并抛出错误.

This is normally fine, but sometimes I write a second R script that I want to run independently just to process some data. So Script2 sources Script1, and Script1 detects that it is not being run interactively, and begins searching for command line arguments and throwing errors.

除了 interactive() 之外,还有其他方法可以让脚本检测其上下文吗?例如,当它直接运行时与加载它以访问其内部函数之一时,我想要单独的行为.使用包,我可以执行诸如 dplyr::arrange() 之类的操作来访问 arrange,而无需加载所有 dplyr.

Is there a way besides interactive() that a script can detect its context? For example, I would want separate behavior when it is being run directly vs when it is being loaded for access to one of its internal functions. With packages I could do something like dplyr::arrange() to access arrange without having to load all of dplyr.

我目前非常糟糕的解决方法是启动交互式会话,源 Script1,使用 save.image() 保存函数,然后在 Script2 中使用 load 加载保存的 .RData 文件.但显然这不是……优雅.

My current very janky workaround has been to start an interactive session, source Script1, use save.image() to save the functions, and then in Script2 use load to load the saved .RData file. But obviously this is not...elegant.

我不认为我使用的确切代码是相关的,但包括它以防有人认为这对答案很重要......

精简示例代码:

#!/usr/bin/env Rscript

library(optparse)

function1 <- function(etc,etc) {}
function2 <- function(etc,etc) {}

if(!interactive()) { 

    # example call
    # Rscript create_reference_file.R -c cd4cd8 -o /home/outputfolder/ 

    option_list = list(
        make_option(c('-c', '--cell'), type = 'character', default = NULL,
                    help = 'the name of the cell',
                    metavar = 'character'),
        make_option(c('-o','--outdir'), type = 'character', default = NULL, 
                    help = 'the location where you wish to store your output',
                    metavar = 'character'),
    )

    opt_parser <- OptionParser(option_list = option_list)
    opt <- parse_args(opt_parser)

    function1(opt); function2(opt) # etc etc, I do stuff with the opt inputs
}

推荐答案

EDIT

好的,这更像是 Python 的 __name__ 技巧.(以下先前的答案,因历史原因保留.)

EDIT

Okay, this is a LOT more like python's __name__ trick. (Previous answer below, kept for historical reasons.)

function1 <- function(etc,etc) {}
function2 <- function(etc,etc) {}

if (sys.nframe() == 0L) {
    library(optparse)
    # ...
}

它就像人们所希望的那样极简,不需要 sourceing 脚本了解它的任何信息,并且即使在嵌套时似乎也能很好地工作.

It is about as minimalist as one could hope for, does not require the sourceing script to know anything about it, and seems to work well even when nested.

根据Rscript:确定执行脚本的路径.那里存在许多合理的(一些非常好的)解决方案,但它们都需要一个未在基本包中定义的预定义函数(或包含在要获取的脚本中的非平凡代码).如果您想假设安装了包 X",那么您的脚本可能变得不可移植.

Other possible mechanisms could be used (additional functions required) by looking at script names, per Rscript: Determine path of the executing script. Many plausible (some really good) solutions exist there, but they all require a pre-defined function not defined in a base package (or non-trivial code included in the script to be sourced). If you want to "assume package X is installed", then your script becomes potentially non-portable.

(以前的答案,我建议你使用上面的.)

(Previous answer, I suggest you use above.)

我将把它作为一个 hack 扔掉......它只比你的解决方法少一点janky,但它依赖于调用ing脚本知道什么调用ed 脚本正在测试.

I'll throw this out as a hack ... it's only slightly less janky than your workaround, but it relies on the calling script knowing something of what the called script is testing for.

如果调用ing脚本设置了一个变量:

If the calling script sets a variable:

BEING_SOURCED_FROM_SOMEWHERE <- TRUE

然后调用ed脚本可以检查它:

then the called script can check for it:

function1 <- function(etc,etc) {}
function2 <- function(etc,etc) {}

if (! exists("BEING_SOURCED_FROM_SOMEWHERE")) {
  library(optparse)
  # ...
}

我不喜欢.不如python灵活

I don't like it. It isn't as flexible as python's

if __name__ == "__main__":
    import optparse
    # ...

但我想我不喜欢它比你使用 saveload 来定义函数.

But I think I dislike it less than your use of save and load for function definitions.

这篇关于Rscript 检测 R 脚本是否被调用/来自另一个脚本的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆