Shiny本地网页部署与实现

Shiny是R里面一个非常出名的包,有了它,可以用R语言方便开发交互式web应用。Shiny程序是个简单的目录,里面包括前端页面脚本ui.R、服务端脚本server.R以及起支持作用的其他数据、脚本和资源。当然也可以将ui.Rserver.R整合为一个app.R脚本。Shiny程序的运行可在R窗口放置前后端脚本的工作目录下运行runApp()或者在命令行终端窗口或者控制台窗口,执行命令:R -e "shiny::runApp()"

shiny dashboard是一个shiny的框架包,shiny中的页面布局相对较为繁琐,而shinydashboard则更加友好,容易上手。shinydashboard示意图如下:

shiny dashboard

shiny dashboard网页框架结构如下:

dashboardPage( # 总函数。
dashboardHeader(), # 标题栏
dashboardSidebar(), # 侧边栏
dashboardBody() # 主体
)

上面主要大体介绍了Shiny以及shiny dashboard的结构,下面步入正题;假如生成Shiny网页,怎样部署形成本地html呢?我们知道shiny是一个交互式的web应用,但有时如果基于成本或者某些特定的需求,我们并不想将Shiny应用程序部署到服务器,如某些项目的测序数据分析结项report,或者只想搭建本地html,发送给客户直接观看,对于未安装R客户访问shiny的页面,该怎么实现呢?

基于这个问题,我试了好几种办法,分别介绍如下:

1. 利用R markdown生成html报告

Compiling a report template to PDF/HTML/Word,

如上图所示,但对于这种格式的报告,更适合于代码过程记录展现,不方便于客户直接阅读,如下图所示(来源于Shiny example):
markdown

2. Shiny部署到Shiny Server或者shinyapps.io上

这种主要是基于将Shiny应用部署到个人服务器上供访问或者部署到shinyapps.io(Host your Shiny apps on the web in minutes with Shinyapps.io. It is easy to use, secure, and scalable. No hardware, installation, or annual purchase contract required. Free and paid options available.),但由于我们的目标是想形成本地html,因此暂不考虑公开部署。

3. Windows本地封装打包部署

本部分参考Lee Pang的建议,主要过程如下:

  • 部署基本框架:Shiny的运行需要R环境,浏览器以及脚本,因此封装需要R-Portable,GoogleChromePortable,以及前端页面脚本ui.R和服务端脚本server.R(或者整合为一个的app.R)。
    因此首先下载R-PortableGoogleChromePortable
    1)R Portable
    2)Google Chrome Portable

新建文件夹test,将上述两个工具装到test文件夹下,同时此目录下新建shiny文件夹,将shiny需要运行的脚本app.R以及脚本所需的资源文件夹www一起放入到shiny文件夹下,目前test文件夹下结构如下:

test文件夹

  • 安装shiny脚本需要的依赖包:
    将以下代码添加到 test文件夹下的R-Portable/App/R-Portable/etc/Rprofile.site文件末尾中:
.First = function(){
.libPaths(.Library)
}

原因:目的为了将shiny所依赖的包安装到R-Portable中,而不影响原来系统R软件所装载的包;
然后打开 R-Portable,安装你的shiny程序所依赖的包:

.libPaths() #检测上面设置的R-Portable的Library是否可用
install.packages('shiny')
install.packages('shinydashboard')
install.packages('ggplot2')
  • 创建运行shiny的程序:
    1) 创建一个程序runShinyApp.R运行shiny程序app.R
    该程序主要实现以下几点:
    --- 设置 .libPaths() 指向本地的R-Portable library库
    --- 设置shiny运行打开的浏览器为本地安装的GoogleChromePortable
    --- 运行shiny脚本app.R, runApp()
    因此,runShinyApp.R 该程序的主要内容如下:
message('library paths:\n', paste('... ', .libPaths(), sep='', collapse='\n'))

chrome.portable = file.path(getwd(),
'GoogleChromePortable/App/Chrome-bin/chrome.exe')

launch.browser = function(appUrl, browser.path=chrome.portable) {
    message('Browser path: ', browser.path)
    shell(sprintf('"%s" --app=%s', browser.path, appUrl))
}

shiny::runApp('./shiny/', launch.browser=launch.browser)

2) 创建shell脚本运行
创建run.vbs文件windows下直接双击即可调用以上程序实现界面展示,run.vbs内容如下:

Rexe           = "R-Portable\App\R-Portable\bin\Rscript.exe"
Ropts          = "--no-save --no-environ --no-init-file --no-restore --no-Rconsole"
RScriptFile    = "runShinyApp.R"
Outfile        = "ShinyApp.log" 
strCommand     = Rexe & " " & Ropts & " " & RScriptFile & " 1> " & Outfile & " 2>&1"

intWindowStyle = 0     ' Hide the window and activate another window.'
bWaitOnReturn  = False ' continue running script after launching R   '

' the following is a Sub call, so no parentheses around arguments'
CreateObject("Wscript.Shell").Run strCommand, intWindowStyle, bWaitOnReturn

目前test文件夹下结构如下:

test文件夹

以上操作完成了基本shiny本地的框架,下面我们运行程序进行测试,测试之前,请将如下代码添加到shiny程序的服务器端脚本server.R中,这样做的目的保证了如果shiny::runApp()运行后网页关闭,则程序停止运行。

shinyServer(function(input, output, session){
    session$onSessionEnded(function() {
        stopApp()
})
})

bingo! 部署完成,双击run.vbs ,正常情况下会打开shiny的网页展示,跟在R中运行显示的一样,如果没有显示,请检查ShinyApp.log

最简单的方式,如果想将此本地shiny发送给客户,则直接打包zip test文件夹,发送给客户后解压unzip,双击run.vbs即可。
当然更专业点,可以生成可执行的安装文件,发送给客户直接安装便可运行,可以使用InnoSetup工具生成可执行的.exe文件。InnoSetup的使用也比较简单,在这里就不讲了,需要的可自行查阅。

最后,shiny是R开发交互式web应用的包,其在交互式数据展示上比较容易上手,但是对于本地html的实现,虽然上述操作可以达到目的,但是我们也发现其封装了R-PortableGoogleChromePortable等shiny运行需要的环境,因此整个最终结果文件比较大,基于这个缺陷,Python的网页开发着实是一种很好的优势展现,需要接下来去研究使用。

你可能感兴趣的:(Shiny本地网页部署与实现)