R : Shiny|搭建单细胞数据分析云平台
男,
一个长大了才会遇到的帅哥,
稳健,潇洒,大方,靠谱。
一段生信缘,一棵技能树,
一枚大型测序工厂的螺丝钉,
一个随机森林中提灯觅食的津门旅客。
前言
shiny官网(https://shiny.rstudio.com/)
在R for data science这本书中,作者提出数据分析的一个流程,在数据转换、可视化以及建模之后,来到数据分析的新阶段:与别人分享我们的数据。之前我们分享了许多单细胞数据分析的教程cellranger拆库定量、seurat质控分析,monocle轨迹推断,R语言给单细胞数据分析带来更多可能。那么,在数据分析进入下游之后,如何给自己的研究增加更多可交付的内容呢?Shiny会是一个不错的选择。
有不少文章在发表的最后也会附上数据探索的一个Shiny程序,方便读者再利用文章的数据。对于单细胞这样的研究领域更是如此,这群激情、好奇、技术控的科学家会把许多相关的技术应用到这个领域中来。
也许很多朋友从来没有想过去写APP毕竟不是学计算机的嘛,其次,根本没有产生这方面的刚需:我为什么要写APP啊,我一个做单细胞的!
刚需才是问题的根本。shiny是一个R包,它可以让你很容易地直接基于R语言构建交互式web应用程序。你可以在网页上托管独立的应用程序,或者将它们嵌入R Markdown文档或构建仪表盘。您还可以使用CSS主题、htmlwidgets和JavaScript动作来扩展您的应用程序。
想一想,把自己的研究成功部署为一个APP,数据不仅仅是paper的二维图表,在行业会议上别人都在用PPT,我却打开了APP,是不是很帅?
当然,这些都是次要的,主要的是节约时间。其实在我们用Seurat分析过数据之后,许多结果直接保存在了Seurat对象中了,如果每次想看某个基因在UMAP图上的表达情况都要找一番代码,有没有一点糟心。特别是,当实验室有好几个师弟师妹,研究不同的通路一会画一个小提琴图一会画一个tsne图,为什么不给你们实验室写一个Shiny!
其实,并不难。
建立Shiny程序
在Rstudio中像新建文件一样,建立Shiny文件:
根据自己的喜好,我选择的是Multiple File(ui.R/server.R),主要是给人一种前端和后端分开的感觉,其实app.R也是一样的通过两个函数来分别控制,我起的名字是seuratreport
创建之后,第一个应用程序就应运而生了,在Rstudio控制台运行:
library(Shiny) # 没有安装的同学安装一下
runApp('H:\\singlecell\\SCshiny\\seuratreport')
就可以看到:
Shiny 基本结构
是不是很简单?其实Shiny可以有许多可以控制的,一个基本的结构如下:
+--- data # 存放app用到的数据
| +--- pbmc3k_final.rds # 我的可爱的pbmc3k数据
+--- rsconnect # 稍后会讲,我把我的app托管在 shiny服务器上
| +--- shinyapps.io
| | +--- novoscrna
| | | +--- novoscreport.dcf
+--- server.R # 基本后台文件
+--- ui.R # 界面控制文件
+--- www # 可以放一些我的界面修饰文件css,help.R之类的
| +--- header.html
| +--- styles.css
其实我们应该停下来,慢慢看看我们第一个shiny的代码。。。。
编写 server.R 以及ui.R
然后就可以开始写我们自己的shiny程序了,先来看一下我的server.R:
#
# This is the server logic of a Shiny web application. You can run the
# application by clicking 'Run App' above.
#
# Find out more about building applications with Shiny here:
#
# http://shiny.rstudio.com/
#
library(shiny)
library(Seurat)
options(shiny.maxRequestSize=70*1024^2)
#library(shinydashboard)
pb<-readRDS("data/pbmc3k_final.rds")
# Define server logic required to draw a histogram
IdentRename<-function(pb,oldname,newname){
cluster.ids <-levels(pb)
cluster.ids[which(cluster.ids == oldname)] <- newname
names(cluster.ids) <- levels(pb)
pb <- RenameIdents(pb, cluster.ids)
#pbmc<-IdentRename(pb,oldname,newname)
}
shinyServer(function(input, output) {
output$contents <- DT::renderDataTable({
inFile <- input$file1
if (is.null(inFile)){
return(NULL)
}else{
pb<- readRDS(inFile$datapath)
pb
req(pb)
}
})
output$distPlot <- renderPlot({
DimPlot(IdentRename(pb,input$Choosecluster,input$clustername), label = TRUE,reduction = input$comment) + NoLegend()
})
output$VlnPlot<-renderPlot({
VlnPlot(pb, features = input$gene, pt.size = 0.2, ncol = 1)
})
output$FeaturePlot<-renderPlot({
FeaturePlot(IdentRename(pb,input$Choosecluster,input$clustername), features = input$gene, reduction= input$comment, pt.size = 0.2, ncol = 1)
})
output$table<-renderDataTable(
#iris,
df <-data.frame( KKKK = input$clustername),
options = list(
pageLength = 5,
initComplete = I("function(settings, json) {alert('Done.');}")
))
output$cluster<-renderUI({
clusterlist<-unique(pb@meta.data$seurat_clusters)
selectInput("ChooseCluster",'ChooseCluster',list=as.vector(clusterlist))
})
})
再来看一下,我的ui.R ,这个可以根据自己的设计天赋来设计:
#
# This is the user-interface definition of a Shiny web application. You can
# run the application by clicking 'Run App' above.
#
# Find out more about building applications with Shiny here:
#
# http://shiny.rstudio.com/
#
library(shiny)
library(Seurat)
#library(shinydashboard)
pb<-readRDS("data/pbmc3k_final.rds")
# Define UI for application that draws a histogram
shinyUI(fluidPage(
# Application title
titlePanel(p("SeuratReport" , style = "color:#3474A7")),
# Sidebar with a slider input for number of bins
sidebarLayout(
sidebarPanel(
fileInput('file1', 'Choose Seurat object RDS File',
accept=c('rds',
'',
'.rds')),
conditionalPanel(
condition = "input.smoother == ture",
selectInput("comment","reduction:",list("umap","tsne","pca"))
),
textInput(inputId = "clustername",
label = "clusterName",
value = "HERE"
),
conditionalPanel(
condition = "input.cluster == ture",
selectInput("Choosecluster",'ChooseCluster',as.list( levels(pb) )) # levels(pb) as.list(pb@meta.data$seurat_clusters)
),
conditionalPanel(
condition = "input == ture",
selectInput("gene",'ChooseGene',as.list( rownames(pb) ))
)
),
# Show a plot of the generated distribution
mainPanel(
#h3("DimPlot"),
tabsetPanel(
#tableOutput('contents'),
imageOutput("p1", width = "100%", height = "400px", click = NULL,
dblclick = NULL, hover = NULL, hoverDelay = NULL,
hoverDelayType = NULL, brush = NULL, clickId = NULL, hoverId = NULL,
inline = FALSE),
tabPanel("Reduction",plotOutput("distPlot")),
tabPanel("VlnPlot",plotOutput("VlnPlot")),
tabPanel("FeaturePlot",plotOutput("FeaturePlot"))
#tabPanel('table',dataTableOutput('table'))
)
)
)
))
#runApp('H:\\singlecell\\SCshiny\\seuratreport') # 我是为了记住这个路径来随时启动我们的APP
如果用到一些自己写的函数可以放到www文件下,在调用的时候source进来。把文件放到正确的位置就可以启动我们的shiny了:
本地Shiny 程序
runApp('H:\\singlecell\\SCshiny\\seuratreport')
我就是你们家的云平台
大家看到了吗?其实后台调用的都是Seurat的绘图函数,所以才叫做SeuratReport的嘛。其实我们可以把他写更符合我们的需求,界面不仅可以展示图片,还是显示图表。其实在降维图那里我的本意是要写一个可以更改每个cluster名称的功能,这个留作课后作业吧·^_^·.
还可以添加函数实现图片下载功能哦~
部署我们的云平台
故事远没有结束。本地的Shiny平台每次启动都要经过RStudio,一个人都能用RStudio了,为什么还要强推Shiny呢?人家都是给一个网址就可以自己分析数据了。所以我们也来看看如何把我们的SeuratReport部署到“云上”。
其实没有想的那么复杂:
当然,我们可以把shiny放在github上供大家享用,其实就是创建一个仓库,把我们的文件放上去,用runGitHub()来运行。这里我们演示另一种方法:部署在shinyapps.io 上。
首先,我们注册一下:https://www.shinyapps.io/
基本上和Windows上面安装软件一样,只要一步一步 next就好了。注册好之后:
其实这很像一个微信公众号的后台,有用户的基本设置,还可以我们的程序的应用情况:
在RStudio中运行一下:
rsconnect::setAccountInfo(name='注册的名字',token='注册后会得到', secret='注册后会得到')
没有问题的话基本就可以了,之差最后一步:
library(rsconnect)
rsconnect::deployApp('H:\\singlecell\\SCshiny\\seuratreport')
下面是创建的过程:
Preparing to deploy application...DONE
Uploading bundle for application: 1603412...DONE
Deploying bundle: 2671862 for application: 1603412 ...
Waiting for task: 676619160
building: Building image: 2917926
building: Installing packages
building: Installing files
building: Pushing image: 2917926
unstaging: Stopping old instances
Application successfully deployed to https://XXXXXXXX.shinyapps.io/seuratreport/ # 不要试,这个是假的
最后在浏览器输入网址,就可以在线操作啦。不过,基础版的服务内存很小,可能会卡。
结语
数据分析的不同阶段都需要好好总结,把我们的经验打包成一个web界面,一方面可以丰富我们的数据呈现内容,也可以有利于我们课题组数据共享交流。同时,把一个Shiny程序打包在一个人R包内也越来越受到开发者的喜爱,比如monocle3 就有Shiny在内。
祝大家学习愉快。