使用R web框架Shiny轻松构建生信交互式网站

做生信需要懂 R web框架 Shiny吗?
答案:不懂R Shiny的生信科研工作者不是好生信科研者


说说这几年我用web框架参与构建生信网站的项目(就是我搬的砖),1.某病的分型网站,就是输入某人的一些临床特征和基因信息,然后判断出此病人属于此病的那个亚型;2.遗传风险评估,就是输入某人的基因文件,判断评估此人在各种病上的遗传风险;3.药物查询/推荐系统,也是根据某人的基因信息,判断使用某药物的安全性、代谢剂量和疗效等;4.某单细胞数据库构建。··……

用处还是很多的,再来看看使用网站来投文章也是可以用的!用好了,投个NAR 的数据库或web 工具就是好几十分;或者作为某工具或算法的使用网站,也是文章的一大亮点啊!


不得不说web 网站框架也不是那么好学的,各种语言的web框架都有,但是作为生信人,强烈推荐大家使用 R shiny 开始, 用它搭建交互式网站入门只需3分钟,今天必须学会,以后需要就可以用起来了,免费的实操课,希望大家用心学,带大家入门并且把我构建好的网站目录结构送给大家,以后大家做网站就可以利用这个为基础框架做自己的网站,赶紧收藏起来哈!

Shiny 简介

Shiny(https://shiny.rstudio.com/app-stories/)是RStudio公司开发的R包,在R中使用它可以轻松开发交互式web应用
如果你还没有安装 Shiny 包,打开一个 R 会话,连接到互联网,然后运行

install.packages("shiny")

就可以安装。

特点

 只用几行代码就可以构建有用的web应用程序—不需要用JavaScript
 Shiny用户界面可以用纯R语言构建,有许多现成的小工具来展示图形、表格、输入框或输入对象,如果想更灵活,还可以直接用HTML、CSS和JavaScript来写
 采用反应式(reactive)编程模型,摒弃了繁杂的事件处理代码,这样你可以集中精力于真正关心的算法或功能的代码上

Shiny官方例子——使用Shiny say hello

运行 “say hello” 这个例子,

library(shiny)
runExample("01_hello")

绘制的直方图是基于faithful数据集。用户可以使用滑动条更改bins的数量,应用程序将立即响应输入。


Shiny 包有11 个内置示例,每个示例都演示了 Shiny 的工作原理,都是一个独立的 Shiny 应用程序。我们来看01 实例,了解此应用的web结构,浏览一下源代码,可以获得对shiny的初始印象。也可以通过认真阅读注释来进一步了解。

Shiny应用程序分为:用户界面定义(ui)、服务端脚本(Server)和 shinyApp
通信函数。这三部分的源代码都包含在app.R脚本里。用户界面 ( ui) 的对象控制应用程序的布局和外观,server函数包含您构建应用程序所需的响应函数。最后, shinyApp函数创建UI和服务器,构建 Shiny 应用程序。

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函数

# 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")

    })

}

该脚本会进行一个函数定义renderPlot,它使用请求的 bin 数量来计算绘制直方图
最后在app.R文件中,从加载 Shiny 包开始,并以调用结束shinyApp:

library(shiny)

# See above for the definitions of ui and server
ui <- ...

server <- ...

shinyApp(ui = ui, server = server)

每个 Shiny 应用程序都具有相同的结构:一个app.R包含ui和server. 你可以通过创建一个新目录并在其中保存一个app.R文件来创建一个 Shiny 应用程序。建议每个应用程序都位于唯一的目录中。

走一个通用的应用app

跑通了官方例子后,加快你学习脚步的方式就是应用,给大家走一个通用的应用框架,然后就可以按需使用起来,差什么做什么就可以很快的学会了!
先建立一个应用目录,其目录下的文件夹和r应用程序的脚本如下:


前面提到的ui 和server 在这里被我拆分成 ui.r 和 server.r, 这样能更好扩展应用结构,分别还建有 data 、docs、和www 目录,用来分别存放web 应用所需要的数据表、文档和图片。
下面我们一起来看 ui.r ,首先加载了应用中所用到的包,除 shiny 外,还应用了shinydashboard 包(http://rstudio.github.io/shinydashboard/index.html)来构建网站的页面结构,可以免去设计页面布局的一些烦恼,以及应用了reactable(https://github.com/glittershark/reactable)来可视化表格数据,和利用ggplot2来展示可视化图表,一个基础级的应用网站仅使用这些包就可以完成了,其具体用法见如下注释的脚本,如果要个性化自己的应用,看R包的使用方法修改就可以应用起来了。
ui.r:

#加载应用所需包
library(shiny)
library(shinydashboard)
library(reactable)
library(ggplot2)

shinyUI(dashboardPage(
    ## 指定主题色
        skin = "blue",
        ## 指定应用名称
        dashboardHeader(title = "DrugDB"),
        ## 指定页面菜单栏内容
        dashboardSidebar(
          sidebarMenu(
            ## 添加的菜单栏
            menuItem("主页", tabName = "dashboard", icon = icon("home")),
            menuItem("浏览", tabName = "widgets", icon = icon("th")),
            menuItem("搜索", tabName = "charts",icon = icon("search")),
            menuItem("关于我们", tabName = "about",icon = icon("dashboard"))        
          )
        ),
        ## Body content
        dashboardBody(
          tabItems(
            
        #第一个菜单栏的页面内容
            tabItem(tabName = "dashboard",
                    h1("欢迎来到DrugDB"),
                    p('DrugDB目的在于给用户提供与基因突变相关联的药*****'),
    #在dashboard的tab栏加入应用程序www文件夹中的图片
                    div(img(src="home_pic.jpg",height = 400,width=700)),
                    p('药物基因组学基因功能学与分子药理学的有机结合******。
                      我们致力于归纳总结这些药物基因组学的研究成果,为用药者提供重要的研究信息,提供用药指导。'),
                    div("图片来自:"),
                    a("Deep learning in pharmacogenomics: from gene regulation to patient stratification",href="https://www.google.com/")
                    
            ),
            
            # 第二个菜单栏的页面内容
            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("更多基因见本网站搜索栏"),
                    h1("药物统计"),
                    fluidRow(
                      sidebarPanel(
                        title = "药物类型",
                        radioButtons("inCheckboxGroup", "选择药物类型",
                                     c("化疗药物", "抗肿瘤药物", "抗凝药物",
                                       "高血脂药物","高血压药物","高血糖药物")),
                      ),
                      mainPanel(plotOutput("plot2", height = 250)),
                    )   
            ),
        
        # 第三个菜单栏内容
            tabItem(tabName = "charts",
                    h1("药物查询"),
                    reactableOutput("table")
            ),
        # 第四个菜单栏内容
            tabItem(tabName = "about",
                    h1("关于我们"),
                    fluidRow(
        # 在第四个菜单栏页面中放入展示docs文件下内容About.md
column(10,includeMarkdown("docs/About.md"))
                   )
            )
          )
        )
      )
)

server .r中定义了与用户交互响应的函数,server .r 脚本具体内容如下:

library(shiny)
library(shinydashboard)
library(reactable)
library(ggplot2)

shinyServer(function(input, output,session) {
    observe({
      x <- input$inCheckboxGroup
#读取应用程序data下的数据文件      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数")
      })

      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来搭建的,在主页的菜单栏内容里给大家示例了如何插入图片和超链接。具体代码在ui.r 里,不涉及与用户的交互,是一个静态展示的页面。


浏览页面如下,示例了如何插入交互式图表,就是结合server的output$plot2来定义了响应函数;


搜索页面如下,示例了分页展示表格数据,并且提供筛选框和搜索框,又是使用server的 output$table来定义响应函数;


关于我们如下,一般就是此应用的使用说明或作者说明,示例了利用md 在页面上展示,


测试运行的伙伴在应用程序的docs里文件创建一个md文件即可,可以参考如下本示例文档,使用markerdown语法就行。


总结

Shiny 里 ui 涉及的就是用户页面可视化设计的代码,server里就是负责完成交互函数和读取数据等功能的代码,这个通用的app框架适用大多数基础应用,搞懂后即可定制化成自己的web应用。

你可能感兴趣的:(使用R web框架Shiny轻松构建生信交互式网站)