7

我想在两个位置运行 R 代码,在 Rnw 文件中和作为交互式闪亮 R 降价文档。

因此,由于交互式闪亮组件在 Rnw 文件中不起作用,我需要的是 R 中的一个代码片段,用于检测是否加载交互式代码。

似乎可行,但感觉就像一个快速破解:

if (exists("input")) { # input is provided by shiny
    # interactive components like renderPlot for shiny
} else {
    # non-interactive code for Rnw file
}

是否有一个稳定的解决方案或类似全局变量的东西,我可以访问它来说明闪亮是否正在运行?或者我应该检查shiny包是否已加载?

什么最安全?

4

3 回答 3

11

现在有一个功能shiny::isRunning()

于 2019-02-19T03:34:04.020 回答
3

此信息直接通过 Shiny 的isRunning功能提供。


以下过时的答案:

您可以执行以下操作:

shiny_running = function () {
    # Look for `runApp` call somewhere in the call stack.
    frames = sys.frames()
    calls = lapply(sys.calls(), `[[`, 1)
    call_name = function (call)
        if (is.function(call)) '<closure>' else deparse(call)
    call_names = vapply(calls, call_name, character(1))

    target_call = grep('^runApp$', call_names)

    if (length(target_call) == 0)
        return(FALSE)
    
    # Found a function called `runApp`, verify that it’s Shiny’s.
    target_frame = frames[[target_call]]
    namespace_frame = parent.env(target_frame)
    isNamespace(namespace_frame) && environmentName(namespace_frame) == 'shiny'
}

现在您可以简单地shiny_running()在代码中使用并返回一个逻辑值,该值指示文档是否作为 Shiny 应用程序运行。

根据Shiny the mailing list 上的讨论,这可能是(接近)最好的方式 ——但请注意讨论中提到的警告。

改编自“模块”包中的代码

或者,以下工作。它可能更适合 Shiny/RMarkdown 用例,但需要存在 YAML 前端:它通过从中读取runtime值来工作。

shiny_running = function ()
    identical(rmarkdown::metadata$runtime, 'shiny')
于 2015-09-28T16:47:25.980 回答
2

更新:康拉德鲁道夫评论后,我重新考虑了我的方法。我的原始答案可以在下面找到。

我的方法与 Konrad Rudolphs 不同,也可能与 OP 最初的想法不同。代码不言自明:

if (identical(rmarkdown::metadata$runtime, "shiny")) {
  "shinyApp" 
} else {
  "static part"
}

我不会从应用程序内部运行此代码,而是将其用作应用程序的包装器。如果代码位于 YAML 前端的.Rmdwithruntime: shiny中,它将启动应用程序,如果不是,它将显示静态部分。

我想这应该做你想要的,并且尽可能稳定。


无论您是否在交互式文档中,我最初的想法都是硬编码:

document_is_interactive <- TRUE

if (document_is_interactive) {
    # interactive components like renderPlot for shiny
} else {
    # non-interactive code for Rnw file
}

尽管可能,但这可能会导致问题,因此比其他方法更不稳定rmarkdown::metadata$runtime

于 2015-09-27T21:30:57.360 回答