【问题标题】:Switch R script from non-interactive to interactive将 R 脚本从非交互式切换到交互式
【发布时间】:2012-02-02 22:55:42
【问题描述】:

我有一个 R 脚本,它接受命令行参数,第一行是:

#!/usr/bin/Rscript --slave

我想中断函数的执行(这样我就可以交互地使用此时已加载的数据变量来计算我需要编写的下一段代码)。我在有问题的函数中添加了这个:

browser()

但它被忽略了。一些搜索表明这可能是因为程序在非交互模式下运行。但是更多的搜索还没有找到我如何将脚本切换到非交互模式以便 browser() 可以工作。类似于browser_yes_I_really_mean_it() 函数。

附:如果可能的话,我想避免更改脚本的其余部分。我目前的方法是将准备数据所需的代码块复制并粘贴到交互式会话中;但是随着脚本变得越来越复杂,这变得越来越不合理。

更新:对于其他有相同问题的人,实际问题的答案似乎是不可能的。一旦你在非交互模式下启动 R,你就会投下骰子。因此,给出的答案是变通方法:要么破解代码(记得在之后解开它),要么重构以使调试更容易。 (此评论无意批评答案;建议的重构使代码更清晰。)

【问题讨论】:

  • 中断一个非常复杂的函数?如果这些是几个函数,您可以按照 mdsumner 下面的建议进行操作,并将一堆脚本放在另一个脚本中。然后在每个合理的断点之后,将数据写入磁盘。
  • 我认为你在这里试图违背基本逻辑。您的第一行意味着“无论脚本怎么说,不要互动”。这就是重点。改变那条线 - 有多难?
  • @reinierpost 谢谢,尽管对Rscript --slave 的解释似乎没有记录。手册页只是说--slave 是为了让它安静。但是要改成什么呢?当我单独使用Rscript 时,browser() 确实会触发,但它会退出脚本,而不是给我一个交互式会话。
  • @DarrenCook,您可以将问题的标题更改为例如“调试通过 Rscript 运行的 R 脚本”并稍微调整您的问题。我不知道大家对编辑问题的看法是什么,结果发现焦点随着答案而改变。
  • @PaulHiemstra 我认为编辑问题很好,但就我个人而言,我喜欢失败的问题,并且 Google 会找到它们:知道无法完成的事情比知道可以做不同的事情更有用。 (因为在搜索时我不会搜索“something different”)

标签: r


【解决方案1】:

您可以直接启动 R 并获取文件吗?

R
source("script.R")

【讨论】:

  • 谢谢,但我试过了。它抱怨缺少命令行参数然后退出。
  • 那么为什么不直接first将命令行参数粘贴到活动的R会话中,然后then在“script.R”中输入源代码。加上这一细节,@mdsumner 的建议似乎很合理。
  • 或者创建两个 R 脚本,一个读取 cmd 行参数并获取第二个。在第一个脚本中,您可以设置一个名为 interactive 的全局选项(使用 options 函数)。在第二个脚本中,您可以检查此选项(我认为使用 getOption),如果它为 FALSE,请为您通过 cmdline 传递的选项提供一些默认值。通过这种方式,您可以交互式地调试您的第二个,然后与第一个一起批量运行。
  • 我在自己的答案中扩展了这个答案和 Josh O'Brien 的评论。
  • 在我看来,能够启动 R 并拥有像 --SOURCE "source.R" 这样的命令行参数会很有用,这与手动将垃圾输入 R 的作用相同.我们是程序员还是秘书?
【解决方案2】:

除了上一个答案之外,我将创建一个顶级函数(例如 doStuff),它执行您想要批量执行的分析。该函数将 cmd 行选项作为输入。在批处理脚本中,您获取包含此函数的脚本并调用它。通过这种方式,您可以轻松地在交互模式下运行该功能并使用例如浏览器()。

【讨论】:

    【解决方案3】:

    按照 mdsumner 的回答,我编辑了这样的脚本:

    if(!exists("argv")){
        argv=commandArgs(TRUE)
        if(length(argv)!=4)usage_and_exit()
        }else{
        if(length(argv)!=4){
            stop("Must set argv as a 4 element vector. E.g. argv=c(...)")
            }
        }
    

    然后不需要其他更改,我能够做到:

    R
    > argv=c('a','b','c','d')
    > source("script.R")
    

    【讨论】:

      【解决方案4】:

      在某些情况下,建议的解决方案(解决方法)可能不起作用 - 例如,当 R 代码需要作为现有 bash 脚本的一部分运行时。对于这些情况,我建议使用 here document 将您的 R 脚本写入 bash 脚本:

      #!/bin/bash
      
      R --interactive << EOT
      
      # R code starts here
      argv=c('a','b','c','d')
      print(interactive())
      # Rest of script contents
      
      quit("no")
      # R code ends here
      
      EOT
      

      这样,上面的print(interactive()) 将产生TRUE

      旁注:确保在 R 代码中避免使用 $ 字符,因为这将无法正确处理 - 例如,使用 df[["X1"]] 而不是 df$X1data.frame() 检索列。

      【讨论】:

        猜你喜欢
        • 2021-09-23
        • 2020-08-17
        • 2012-10-18
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2011-12-21
        • 1970-01-01
        • 2014-09-23
        相关资源
        最近更新 更多