R : Shiny|搭建单细胞数据分析云平台

2020-03-27 13:44:07 浏览数 (1)

分享是一种态度

作者 | 周运来

男,

一个长大了才会遇到的帅哥,

稳健,潇洒,大方,靠谱。

一段生信缘,一棵技能树,

一枚大型测序工厂的螺丝钉,

一个随机森林中提灯觅食的津门旅客。

前言

shiny官网(https://shiny.rstudio.com/)

R for data science这本书中,作者提出数据分析的一个流程,在数据转换、可视化以及建模之后,来到数据分析的新阶段:与别人分享我们的数据。之前我们分享了许多单细胞数据分析的教程cellranger拆库定量、seurat质控分析,monocle轨迹推断,R语言给单细胞数据分析带来更多可能。那么,在数据分析进入下游之后,如何给自己的研究增加更多可交付的内容呢?Shiny会是一个不错的选择。

R for data science

有不少文章在发表的最后也会附上数据探索的一个Shiny程序,方便读者再利用文章的数据。对于单细胞这样的研究领域更是如此,这群激情、好奇、技术控的科学家会把许多相关的技术应用到这个领域中来。

也许很多朋友从来没有想过去写APP毕竟不是学计算机的嘛,其次,根本没有产生这方面的刚需:我为什么要写APP啊,我一个做单细胞的!

刚需才是问题的根本。shiny是一个R包,它可以让你很容易地直接基于R语言构建交互式web应用程序。你可以在网页上托管独立的应用程序,或者将它们嵌入R Markdown文档或构建仪表盘。您还可以使用CSS主题、htmlwidgets和JavaScript动作来扩展您的应用程序。

想一想,把自己的研究成功部署为一个APP,数据不仅仅是paper的二维图表,在行业会议上别人都在用PPT,我却打开了APP,是不是很帅?

当然,这些都是次要的,主要的是节约时间。其实在我们用Seurat分析过数据之后,许多结果直接保存在了Seurat对象中了,如果每次想看某个基因在UMAP图上的表达情况都要找一番代码,有没有一点糟心。特别是,当实验室有好几个师弟师妹,研究不同的通路一会画一个小提琴图一会画一个tsne图,为什么不给你们实验室写一个Shiny!

其实,并不难。

建立Shiny程序

在Rstudio中像新建文件一样,建立Shiny文件:

image

根据自己的喜好,我选择的是Multiple File(ui.R/server.R),主要是给人一种前端和后端分开的感觉,其实app.R也是一样的通过两个函数来分别控制,我起的名字是seuratreport

创建之后,第一个应用程序就应运而生了,在Rstudio控制台运行:

代码语言:javascript复制
library(Shiny) # 没有安装的同学安装一下
runApp('H:\singlecell\SCshiny\seuratreport')

就可以看到:

我是第一个shiny程序

Shiny 基本结构

是不是很简单?其实Shiny可以有许多可以控制的,一个基本的结构如下:

代码语言:javascript复制
 --- 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:

代码语言:javascript复制
#
# 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 ,这个可以根据自己的设计天赋来设计:

代码语言:javascript复制
#
# 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 程序

代码语言:javascript复制
runApp('H:\singlecell\SCshiny\seuratreport')

我就是你们家的云平台

大家看到了吗?其实后台调用的都是Seurat的绘图函数,所以才叫做SeuratReport的嘛。其实我们可以把他写更符合我们的需求,界面不仅可以展示图片,还是显示图表。其实在降维图那里我的本意是要写一个可以更改每个cluster名称的功能,这个留作课后作业吧·^_^·.

还可以添加函数实现图片下载功能哦~

部署我们的云平台

故事远没有结束。本地的Shiny平台每次启动都要经过RStudio,一个人都能用RStudio了,为什么还要强推Shiny呢?人家都是给一个网址就可以自己分析数据了。所以我们也来看看如何把我们的SeuratReport部署到“云上”。

其实没有想的那么复杂:

当然,我们可以把shiny放在github上供大家享用,其实就是创建一个仓库,把我们的文件放上去,用runGitHub()来运行。这里我们演示另一种方法:部署在shinyapps.io 上。

首先,我们注册一下:https://www.shinyapps.io/

image

基本上和Windows上面安装软件一样,只要一步一步 next就好了。注册好之后:

image

其实这很像一个微信公众号的后台,有用户的基本设置,还可以我们的程序的应用情况:

image

在RStudio中运行一下:

代码语言:javascript复制
rsconnect::setAccountInfo(name='注册的名字',token='注册后会得到', secret='注册后会得到')

没有问题的话基本就可以了,之差最后一步:

代码语言:javascript复制
library(rsconnect)
rsconnect::deployApp('H:\singlecell\SCshiny\seuratreport')

下面是创建的过程:

代码语言:javascript复制
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在内。

祝大家学习愉快。

0 人点赞