2015-09-27 6 views
4

Я хотел бы запустить R-код в двух местах, в Rnw-файле и в виде интерактивного блестящего документа R markdown.Обнаруживает ли блестящие пробеги код 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?

Что безопаснее всего?

+0

Не уверен, что, если я правильно понять вас: так как вы говорите о двух отдельных файлах, поставив интерактивные компоненты в '.Rmd' и статические компоненты в' .Rnw' не вариант? –

+1

Предоставление примерного кода того, что именно вы пытаетесь, поможет.-> [воспроизводимый пример] (http://stackoverflow.com/questions/5963269/how-to-make-a-great-r-reproducible-example) –

+0

Ну, ваше предложение возможно. Тем не менее, я хотел бы сохранить код в одном месте, который принадлежит вместе, и, скорее, иметь настройки по умолчанию, которые переопределяются интерактивной частью, которая запускается только блестящим образом. – Xiphias

ответ

2

Вы можете сделать следующее:

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() в коде и получить логическое значение обратно, указывающее, является ли документ работать как Блестящая приложение.

Это, вероятно, наилучший способ, согласно discussion on Shiny the mailing list - но обратите внимание на предостережения, упомянутые в обсуждении.

Адаптировано из code in the “modules” package.

В качестве альтернативы, следующие работы. Это может быть лучше подходит для использования Shiny/RMarkdown, но требует наличия переднего элемента YAML: он работает, читая значение runtime.

shiny_running = function() 
    identical(rmarkdown::metadata$runtime, 'shiny') 
2

Обновление: После комментария Konrad Rudolphs я переосмыслил свой подход. Мой первоначальный ответ можно найти ниже.

Мой подход отличается от Konrad Rudolphs и может отличаться от первоначальных мыслей OPs. Код говорит сам за себя:

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

Я бы не запустить этот код внутри приложения, но использовать его в качестве обертки вокруг приложения. Если код находится в пределах .Rmd с runtime: shiny в лицевой части YAML, он запустит приложение, если нет, он покажет статическую часть.

Я предполагаю, что он должен делать то, что вы хотели, и быть таким же стабильным, как мог.


Моя первоначальная мысль была бы жестко закодировать, были ли вы в интерактивном документе:

Хотя возможно, это может привести к проблемам и, следовательно, был бы менее стабильным, чем другие подход с rmarkdown::metadata$runtime.

+0

«Я сомневаюсь, что имитация его поведения более стабильна, чем просто жестко кодировать результат» - На самом деле, почему вы так думаете? * Конечно * он более стабилен, он тривиально предотвращает несчастные случаи, когда пользователь забыл обновить переменную вручную. На самом деле, я думаю, что это жизнеспособная альтернатива моему ответу (что является более общим, а также работает в коде, отличном от RMarkdown). –

+0

@ KonradRudolph может быть, он более стабилен, если вы делаете это правильно. ;) Я сделаю попытку и уточню свой ответ. –

+0

Достаточно честный. См. Мой обновленный ответ. Это немного разочаровывает то, что Knitr не дает пользователю доступ к конфигурации YAML front-matter напрямую, но разбор его вручную далеко не так, как показывает код. –

 Смежные вопросы

  • Нет связанных вопросов^_^