使用R web框架Shiny輕松構(gòu)建生信交互式網(wǎng)站

做生信需要懂 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)用。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
禁止轉(zhuǎn)載,如需轉(zhuǎn)載請通過簡信或評論聯(lián)系作者。
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 227,428評論 6 531
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 98,024評論 3 413
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 175,285評論 0 373
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經(jīng)常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 62,548評論 1 307
  • 正文 為了忘掉前任,我火速辦了婚禮,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當(dāng)我...
    茶點故事閱讀 71,328評論 6 404
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 54,878評論 1 321
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 42,971評論 3 439
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 42,098評論 0 286
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 48,616評論 1 331
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 40,554評論 3 354
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 42,725評論 1 369
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 38,243評論 5 355
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 43,971評論 3 345
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 34,361評論 0 25
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 35,613評論 1 280
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 51,339評論 3 390
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 47,695評論 2 370

推薦閱讀更多精彩內(nèi)容