做生信需要懂 R web框架 Shiny嗎?
答案:不懂R Shiny的生信科研工作者不是好生信科研者
說說這幾年我用web框架參與構(gòu)建生信網(wǎng)站的項目(就是我搬的磚),1.某病的分型網(wǎng)站,就是輸入某人的一些臨床特征和基因信息,然后判斷出此病人屬于此病的那個亞型;2.遺傳風(fēng)險評估,就是輸入某人的基因文件,判斷評估此人在各種病上的遺傳風(fēng)險;3.藥物查詢/推薦系統(tǒng),也是根據(jù)某人的基因信息,判斷使用某藥物的安全性、代謝劑量和療效等;4.某單細胞數(shù)據(jù)庫構(gòu)建。··……
用處還是很多的,再來看看使用網(wǎng)站來投文章也是可以用的!用好了,投個NAR 的數(shù)據(jù)庫或web 工具就是好幾十分;或者作為某工具或算法的使用網(wǎng)站,也是文章的一大亮點啊!
不得不說web 網(wǎng)站框架也不是那么好學(xué)的,各種語言的web框架都有,但是作為生信人,強烈推薦大家使用 R shiny 開始, 用它搭建交互式網(wǎng)站入門只需3分鐘,今天必須學(xué)會,以后需要就可以用起來了,免費的實操課,希望大家用心學(xué),帶大家入門并且把我構(gòu)建好的網(wǎng)站目錄結(jié)構(gòu)送給大家,以后大家做網(wǎng)站就可以利用這個為基礎(chǔ)框架做自己的網(wǎng)站,趕緊收藏起來哈!
Shiny 簡介
Shiny(https://shiny.rstudio.com/app-stories/)是RStudio公司開發(fā)的R包,在R中使用它可以輕松開發(fā)交互式web應(yīng)用
如果你還沒有安裝 Shiny 包,打開一個 R 會話,連接到互聯(lián)網(wǎng),然后運行
install.packages("shiny")
就可以安裝。
特點
? 只用幾行代碼就可以構(gòu)建有用的web應(yīng)用程序—不需要用JavaScript
? Shiny用戶界面可以用純R語言構(gòu)建,有許多現(xiàn)成的小工具來展示圖形、表格、輸入框或輸入對象,如果想更靈活,還可以直接用HTML、CSS和JavaScript來寫
? 采用反應(yīng)式(reactive)編程模型,摒棄了繁雜的事件處理代碼,這樣你可以集中精力于真正關(guān)心的算法或功能的代碼上
Shiny官方例子——使用Shiny say hello
運行 “say hello” 這個例子,
library(shiny)
runExample("01_hello")
繪制的直方圖是基于faithful數(shù)據(jù)集。用戶可以使用滑動條更改bins的數(shù)量,應(yīng)用程序?qū)⒘⒓错憫?yīng)輸入。
Shiny 包有11 個內(nèi)置示例,每個示例都演示了 Shiny 的工作原理,都是一個獨立的 Shiny 應(yīng)用程序。我們來看01 實例,了解此應(yīng)用的web結(jié)構(gòu),瀏覽一下源代碼,可以獲得對shiny的初始印象。也可以通過認真閱讀注釋來進一步了解。
Shiny應(yīng)用程序分為:用戶界面定義(ui)、服務(wù)端腳本(Server)和 shinyApp
通信函數(shù)。這三部分的源代碼都包含在app.R腳本里。用戶界面 ( ui) 的對象控制應(yīng)用程序的布局和外觀,server函數(shù)包含您構(gòu)建應(yīng)用程序所需的響應(yīng)函數(shù)。最后, shinyApp函數(shù)創(chuàng)建UI和服務(wù)器,構(gòu)建 Shiny 應(yīng)用程序。
ui
Hello Shiny示例的ui對象
library(shiny)
# Define UI for app that draws a histogram ----
ui <- fluidPage(
# App title ----
titlePanel("Hello Shiny!"),
# Sidebar layout with input and output definitions ----
sidebarLayout(
# Sidebar panel for inputs ----
sidebarPanel(
# Input: Slider for the number of bins ----
sliderInput(inputId = "bins",
label = "Number of bins:",
min = 1,
max = 50,
value = 30)
),
# Main panel for displaying outputs ----
mainPanel(
# Output: Histogram ----
plotOutput(outputId = "distPlot")
)
)
)
server
Hello Shiny示例的server函數(shù)
# Define server logic required to draw a histogram ----
server <- function(input, output) {
# Histogram of the Old Faithful Geyser Data ----
# with requested number of bins
# This expression that generates a histogram is wrapped in a call
# to renderPlot to indicate that:
#
# 1. It is "reactive" and therefore should be automatically
# re-executed when inputs (input$bins) change
# 2. Its output type is a plot
output$distPlot <- renderPlot({
x <- faithful$waiting
bins <- seq(min(x), max(x), length.out = input$bins + 1)
hist(x, breaks = bins, col = "#75AADB", border = "white",
xlab = "Waiting time to next eruption (in mins)",
main = "Histogram of waiting times")
})
}
該腳本會進行一個函數(shù)定義renderPlot,它使用請求的 bin 數(shù)量來計算繪制直方圖
最后在app.R文件中,從加載 Shiny 包開始,并以調(diào)用結(jié)束shinyApp:
library(shiny)
# See above for the definitions of ui and server
ui <- ...
server <- ...
shinyApp(ui = ui, server = server)
每個 Shiny 應(yīng)用程序都具有相同的結(jié)構(gòu):一個app.R包含ui和server. 你可以通過創(chuàng)建一個新目錄并在其中保存一個app.R文件來創(chuàng)建一個 Shiny 應(yīng)用程序。建議每個應(yīng)用程序都位于唯一的目錄中。
走一個通用的應(yīng)用app
跑通了官方例子后,加快你學(xué)習(xí)腳步的方式就是應(yīng)用,給大家走一個通用的應(yīng)用框架,然后就可以按需使用起來,差什么做什么就可以很快的學(xué)會了!
先建立一個應(yīng)用目錄,其目錄下的文件夾和r應(yīng)用程序的腳本如下:
前面提到的ui 和server 在這里被我拆分成 ui.r 和 server.r, 這樣能更好擴展應(yīng)用結(jié)構(gòu),分別還建有 data 、docs、和www 目錄,用來分別存放web 應(yīng)用所需要的數(shù)據(jù)表、文檔和圖片。
下面我們一起來看 ui.r ,首先加載了應(yīng)用中所用到的包,除 shiny 外,還應(yīng)用了shinydashboard 包(http://rstudio.github.io/shinydashboard/index.html)來構(gòu)建網(wǎng)站的頁面結(jié)構(gòu),可以免去設(shè)計頁面布局的一些煩惱,以及應(yīng)用了reactable(https://github.com/glittershark/reactable)來可視化表格數(shù)據(jù),和利用ggplot2來展示可視化圖表,一個基礎(chǔ)級的應(yīng)用網(wǎng)站僅使用這些包就可以完成了,其具體用法見如下注釋的腳本,如果要個性化自己的應(yīng)用,看R包的使用方法修改就可以應(yīng)用起來了。
ui.r:
#加載應(yīng)用所需包
library(shiny)
library(shinydashboard)
library(reactable)
library(ggplot2)
shinyUI(dashboardPage(
## 指定主題色
skin = "blue",
## 指定應(yīng)用名稱
dashboardHeader(title = "DrugDB"),
## 指定頁面菜單欄內(nèi)容
dashboardSidebar(
sidebarMenu(
## 添加的菜單欄
menuItem("主頁", tabName = "dashboard", icon = icon("home")),
menuItem("瀏覽", tabName = "widgets", icon = icon("th")),
menuItem("搜索", tabName = "charts",icon = icon("search")),
menuItem("關(guān)于我們", tabName = "about",icon = icon("dashboard"))
)
),
## Body content
dashboardBody(
tabItems(
#第一個菜單欄的頁面內(nèi)容
tabItem(tabName = "dashboard",
h1("歡迎來到DrugDB"),
p('DrugDB目的在于給用戶提供與基因突變相關(guān)聯(lián)的藥*****'),
#在dashboard的tab欄加入應(yīng)用程序www文件夾中的圖片
div(img(src="home_pic.jpg",height = 400,width=700)),
p('藥物基因組學(xué)基因功能學(xué)與分子藥理學(xué)的有機結(jié)合******。
我們致力于歸納總結(jié)這些藥物基因組學(xué)的研究成果,為用藥者提供重要的研究信息,提供用藥指導(dǎo)。'),
div("圖片來自:"),
a("Deep learning in pharmacogenomics: from gene regulation to patient stratification",)
),
# 第二個菜單欄的頁面內(nèi)容
tabItem(tabName = "widgets",
h1("用藥基因"),
fluidRow(
box(
title = "MTHFR", status = "primary", solidHeader = TRUE,
collapsible = TRUE,
div(class = "my-class", "該基因****")
),
box(
title = "XRCC1", status = "primary", solidHeader = TRUE,
collapsible = TRUE,
div(class = "my-class", "該基因編碼**")
),
),
p("更多基因見本網(wǎng)站搜索欄"),
h1("藥物統(tǒng)計"),
fluidRow(
sidebarPanel(
title = "藥物類型",
radioButtons("inCheckboxGroup", "選擇藥物類型",
c("化療藥物", "抗腫瘤藥物", "抗凝藥物",
"高血脂藥物","高血壓藥物","高血糖藥物")),
),
mainPanel(plotOutput("plot2", height = 250)),
)
),
# 第三個菜單欄內(nèi)容
tabItem(tabName = "charts",
h1("藥物查詢"),
reactableOutput("table")
),
# 第四個菜單欄內(nèi)容
tabItem(tabName = "about",
h1("關(guān)于我們"),
fluidRow(
# 在第四個菜單欄頁面中放入展示docs文件下內(nèi)容About.md
column(10,includeMarkdown("docs/About.md"))
)
)
)
)
)
)
server .r中定義了與用戶交互響應(yīng)的函數(shù),server .r 腳本具體內(nèi)容如下:
library(shiny)
library(shinydashboard)
library(reactable)
library(ggplot2)
shinyServer(function(input, output,session) {
observe({
x <- input$inCheckboxGroup
#讀取應(yīng)用程序data下的數(shù)據(jù)文件 drug_info=read.delim('./data/drug_info.txt',check.names=TRUE, stringsAsFactors=FALSE,sep = '\t')
output$plot2 <- renderPlot({
drug_info = drug_info[which(drug_info$drug_type==x),]
drug_name = paste(x,'作用基因',sep='')
data = table(na.omit(drug_info$gene))
data=data.frame(data)
ggplot(data,aes(x=Var1, y=Freq)) +
geom_bar(stat="identity",fill="lightblue")+
theme(text = element_text(family = "STHeiti"),axis.text.x = element_text(angle=90, hjust=1, vjust=1))+
labs(x =drug_name, y = "作用基因的snp數(shù)")
})
output$table <- renderReactable({
reactable(
drug_info,
###指定所有列的格式
defaultColDef = colDef(
align = "center",
headerStyle = list(background = "lightblue")
),
columns = list(
c_drugname = colDef(name = "藥物名稱"),
drug_type = colDef(name = "藥物大類"),
main_categroy = colDef(name = "藥物子類"),
clinical_level =colDef(name = "藥物臨床等級"),
rs = colDef(name = "基因位點"),
chr=colDef(name = "染色體號"),
ref=colDef(name = "位點參考"),
alt=colDef(name = "位點變化"),
pubmed_id = colDef(name = "PMID"),
gene=colDef(name = "基因"),
genotype_1=colDef(name ='基因型1',width = 100),
genotype_2=colDef(name ='基因型2',width = 100),
genotype_3=colDef(name ='基因型3',width = 100),
annotation_1 =colDef(name ='藥物療效1',width = 300),
annotation_2 =colDef(name ='藥物療效2',width = 300),
annotation_3 =colDef(name ='藥物療效3',width = 300),
rs = colDef(align = "center")
),
bordered = TRUE, ###邊線
highlight = TRUE, ###高亮
searchable=TRUE, ###搜索
filterable=TRUE, ###過濾
defaultPageSize=15, ###分頁
pageSizeOptions=c(10,15,20),
showPageSizeOptions=TRUE,
paginationType="jump"
)
})
})
})
在server.r或ui.r 里run App后,用戶的界面如下所示, 整個頁面及菜單欄的就是利用dashbord來搭建的,在主頁的菜單欄內(nèi)容里給大家示例了如何插入圖片和超鏈接。具體代碼在ui.r 里,不涉及與用戶的交互,是一個靜態(tài)展示的頁面。
瀏覽頁面如下,示例了如何插入交互式圖表,就是結(jié)合server的output$plot2來定義了響應(yīng)函數(shù);
搜索頁面如下,示例了分頁展示表格數(shù)據(jù),并且提供篩選框和搜索框,又是使用server的 output$table來定義響應(yīng)函數(shù);
關(guān)于我們?nèi)缦拢话憔褪谴藨?yīng)用的使用說明或作者說明,示例了利用md 在頁面上展示,
測試運行的伙伴在應(yīng)用程序的docs里文件創(chuàng)建一個md文件即可,可以參考如下本示例文檔,使用markerdown語法就行。
總結(jié)
Shiny 里 ui 涉及的就是用戶頁面可視化設(shè)計的代碼,server里就是負責(zé)完成交互函數(shù)和讀取數(shù)據(jù)等功能的代碼,這個通用的app框架適用大多數(shù)基礎(chǔ)應(yīng)用,搞懂后即可定制化成自己的web應(yīng)用。