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