美文网首页
把数据整理和画图代码嵌入shiny

把数据整理和画图代码嵌入shiny

作者: chaupak | 来源:发表于2018-11-23 17:14 被阅读0次

    之前师兄把数据整理和画图的代码给了我,由此开始了漫长的挣扎之路...
    一开始,他说用source来直接source整段代码进server.R中,但是我到现在都还没有搞懂怎么source
    既然不会就只能用笨方法了,直接复制粘贴到server里面吧!要把直接在Rstudio中跑的代码变成app中里面的一个功能,首先要做的就是把固定的文件替换成用户上传的文件,试验中就是input$file1啦。所以,首先先把数据整理的一段代码复制到server里面:

    library("readr")
    library(Biobase)
    source("D:/Hard work/R_function.R")
    options(stringsAsFactors=F)
    
    
    ########cut off init
    p_value <- 0.05 # p value of FDR
    lfc <- 0.58  #logFC
    args <-commandArgs(T)
    args[1] <- input$file1
    
    ########load data
    countData1 <- as.data.frame(read_delim(args[1],delim = "\t"))
    dim(countData1)
    rownames(countData1) <- countData1$id
    countData=countData1[,-1]
    
    ###########pheno data loading
    colData <- get_pheno(x = colnames(countData),label1 = "T",label2 = "N",group1 = "Tumor",group2 = "Normal")
    countData <- countData[,as.character(rownames(colData))]
    colData$Type <- as.factor(colData$Type)
    type_level <- levels(as.factor(colData$Type))
    comb <- combn(type_level,2)
    
    #########filter low-abandance circRNA ; the step has been done in node1:filter_circ
    # countData <- countData[which(rowSums(countData > 0) >= 2),] #a Count>0 in at least 2 samples
    # dim(countData)
    
    # ###############type specific
    
    ##############edgeR
    #source("./R_function.R")
    
    #sharedCirc_edgeR_tmp <- edgeR_test(expre_mat = shared_circ,group_mat = colData,test_method = "LRT" )
    sharedCirc_edgeR <-edgeR_test(expre_mat = countData,group_mat = colData)
    
    DE_sharedCirc_res = subset(sharedCirc_edgeR,FDR <= p_value & abs(logFC) >= lfc)
    select <- DE_sharedCirc_res[order(DE_sharedCirc_res$logFC, decreasing = TRUE),]
    Circ_norm_edgeR=cpm(countData) ###norm expres_mat
    rownames(Circ_norm_edgeR)=countData1$id
    sharedCirc_DE_edgeR=Circ_norm_edgeR[rownames(select),]
    #all DE
    DE_list <- c(rownames(DE_sharedCirc_res))
    

    然而发现自己太年轻,系统直接报错,找不到“input”,想了一下这不是废话吗,刚打开怎么会有input,然后要别人怎么整理数据嘛
    所以我就想着弄一个条件语句,把数据整理打包成一个功能,且在有input的时候才会动,至于有没有必要打包成一个功能,还要靠后面试验一下。
    想来想去觉得一时半会想不出来,所以先试一下最笨的方法:在每个tab的output代码里都加进这一段,只不过是最后图不一样而已
    所以拿火山图试了一下,代码是

    output$dmplot <- renderPlot{
        if(is.null(input$file2)){return()}
        ...
        args[1] <- input$file2$datapath
        ...
        volcanoplot()
    }
    

    实际上,最重要的是中间args[1]那一句,通过这个方法, 结果是可行的,只不过终于明白了当初加进度条的目的,实在是太慢了。而且如果每个模块的每个tab里面都塞这么一段代码的话,整个应用的速度会不会被严重拖慢,这都是要考虑的问题。现在再尝试一下把它弄整洁一点。
    可能可以在每一个模块前面加一个reactive()

    解决方案①(只能完成但是不能控制):

    output$dmplot <- renderPlot({
        if(is.null(input$file2)){return()}
        ########cut off init
        p_value <- 0.05 # p value of FDR
        lfc <- 0.58  #logFC
        args <-commandArgs(T)
        #args[1] <- "matrix/11_7//filter_input_count.mat"
        args[1] <- input$file2$datapath
        
        ########load data
        countData1 <- as.data.frame(read_delim(args[1],delim = "\t"))
        dim(countData1)
        rownames(countData1) <- countData1$id
        countData=countData1[,-1]
        
        ###########pheno data loading
        colData <- get_pheno(x = colnames(countData),label1 = "T",label2 = "N",group1 = "Tumor",group2 = "Normal")
        countData <- countData[,as.character(rownames(colData))]
        colData$Type <- as.factor(colData$Type)
        type_level <- levels(as.factor(colData$Type))
        comb <- combn(type_level,2)
        
        
        sharedCirc_edgeR <-edgeR_test(expre_mat = countData,group_mat = colData)
        
        DE_sharedCirc_res = subset(sharedCirc_edgeR,FDR <= p_value & abs(logFC) >= lfc)
        select <- DE_sharedCirc_res[order(DE_sharedCirc_res$logFC, decreasing = TRUE),]
        Circ_norm_edgeR=cpm(countData) ###norm expres_mat
        rownames(Circ_norm_edgeR)=countData1$id
        sharedCirc_DE_edgeR=Circ_norm_edgeR[rownames(select),]
        #all DE
        DE_list <- c(rownames(DE_sharedCirc_res))
        volcano_plot(sharedCirc_edgeR,c("Normal","Tumor"))
      })
    

    当上传了文件,就开始算,但其实这个最后是不可行的,因为:1. 到时可能会上传多个文件;2. 没有控制按钮是不行的,你以为想画图就画?
    解决方案②(添加actionButton()):
    然后失败了
    解决解决方案②:用eventReactive()对pl赋值,并用actionButton进行控制,然后直接在renderPlot()中写上pl(),就可以生成图表。这样起码可以在每个tab中加上一个开始按钮,然后需要时再计算画图,每个tab之间相互独立,但是这样的坏处是,每作一张图就要重复计算数据,很不必要并且浪费时间。不过怎么说总算有了一种可行的方法。
    解决方案③(最完美):
    只用reactive():先用一个example把需要计算的文件位置占住,使得不会报错,然后再通过conditionalPanel来实现上传文件的切换,这样就不用考虑先后顺序的问题。上传和计算的部分用reactive分开,最后用list返回多个对象,给下面作图做准备。但是这样做的缺点是一打开那个页面它就会自动运算,比如想直接上传文件计算,还要等example先算一遍。所以有一个更加独立封闭的方法。
    eventReactive():上传文件部分不变,计算部分加一个控制的actionButton(),在按下按钮之后才会开始运算,这样就会提高网站的速度。
    例如:

    dmdataprocess <- eventReactive(input$dmbutton,{
    ....
     plots <- list(a=sharedCirc_edgeR, b=DE_sharedCirc_res, c=colData,  d=Circ_norm_edgeR, e=sharedCirc_DE_edgeR, f=DE_list)
        return(plots)
    })
    

    接着,在下面画图时,需要用到的参数就可用dmdataprocess()$a诸如此类的表达来表示,注意,因为dmdataprocess是在eventReactive表达中,因此结构是和函数一样的,所以用的时候要在后面加一个括号。通过这样处理,运算一次便可以生成三张图。
    其实较早之前就能正确运用eventReactive了,但是过了这么久才解决,总结这次经验就是:函数的默认返回值是最后一行,用list()返回多个对象(所以为什么这么简单的事情困扰了这么久)

    actionButton()触发画图时,用observeEvent()配合

    observeEvent(input$qcbutton,{
        output$qcdistri <- renderPlot({
          distribution_plot(m6A_anno = qcdatasetinput())
        })
      })
    

    相关文章

      网友评论

          本文标题:把数据整理和画图代码嵌入shiny

          本文链接:https://www.haomeiwen.com/subject/fqzjqqtx.html