Shiny是R里面一個非常出名的包,有了它,可以用R語言方便開發交互式web應用。Shiny程序是個簡單的目錄,里面包括前端頁面腳本ui.R
、服務端腳本server.R
以及起支持作用的其他數據、腳本和資源。當然也可以將ui.R
和server.R
整合為一個app.R
腳本。Shiny程序的運行可在R窗口放置前后端腳本的工作目錄下運行runApp()
或者在命令行終端窗口或者控制臺窗口,執行命令:R -e "shiny::runApp()"
。
shiny dashboard是一個shiny的框架包,shiny中的頁面布局相對較為繁瑣,而shinydashboard則更加友好,容易上手。shinydashboard示意圖如下:
shiny dashboard網頁框架結構如下:
dashboardPage( # 總函數。
dashboardHeader(), # 標題欄
dashboardSidebar(), # 側邊欄
dashboardBody() # 主體
)
上面主要大體介紹了Shiny以及shiny dashboard的結構,下面步入正題;假如生成Shiny網頁,怎樣部署形成本地html呢?我們知道shiny是一個交互式的web應用,但有時如果基于成本或者某些特定的需求,我們并不想將Shiny應用程序部署到服務器,如某些項目的測序數據分析結項report,或者只想搭建本地html,發送給客戶直接觀看,對于未安裝R客戶訪問shiny的頁面,該怎么實現呢?
基于這個問題,我試了好幾種辦法,分別介紹如下:
1. 利用R markdown生成html報告
如上圖所示,但對于這種格式的報告,更適合于代碼過程記錄展現,不方便于客戶直接閱讀,如下圖所示(來源于Shiny example):
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-Portable
和GoogleChromePortable
:
1)R Portable
2)Google Chrome Portable
新建文件夾test
,將上述兩個工具裝到test
文件夾下,同時此目錄下新建shiny
文件夾,將shiny需要運行的腳本app.R
以及腳本所需的資源文件夾www
一起放入到shiny
文件夾下,目前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
文件夾下結構如下:
以上操作完成了基本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的使用也比較簡單,在這里就不講了,需要的可自行查閱。