如何通过单个函数event产生两个不同的输出(文本和数据框)

时间:2018-07-17 15:55:50

标签: r shiny shiny-reactivity

我正在编写我的第一个R / Shiny应用程序(这也是我的第一个R程序,我来自SAS世界)。 我想使用样式选择器(fileInput),对选择的文件进行一些检查:检查文件是否包含变量,输出符合性消息(文件包含此变量)并在屏幕上显示文件。 经过大量的尝试,我设法获得了可以给我期望的功能代码。

    library(shiny)

ui <- shiny::fluidPage(
        shiny::sidebarLayout(
                shiny::sidebarPanel(

    ### permet de selectionner une liste de comptes à partir d un fichier contenant la variable compte 
    shiny::fileInput("fichierDeCompte","Ajouter des comptes \u00e0 partir d'un fichier",multiple=FALSE,accept=c(".csv",".txt",".CSV",".TXT")),
    shiny::verbatimTextOutput("msgTxt2")

    )
    ,           shiny::mainPanel(
                    shiny::tableOutput("laTable")
                                )
    )

)


server <- function(input,output,session) {
        donneesApp <- shiny::reactiveValues(fichier=c())
        donneesApp <- shiny::reactiveValues(nbVar=0)
        donneesApp <- shiny::reactiveValues(classeVar=c(0))
        donneesApp <- shiny::reactiveValues(nomVar=c(0))    

            ## FIRST
        valeurr1 <- shiny::eventReactive(input$fichierDeCompte,{
        req(input$fichierDeCompte$datapath)
        donneesApp$fichier <- gsub("/","\\\\",input$fichierDeCompte$datapath)
        donneesApp$nomVar=scan(donneesApp$fichier,sep=",",what="character",nlines=1)
        donneesApp$nbVar=length(donneesApp$nomVar)
        donneesApp$classeVar=rep("character",donneesApp$nbVar)
        names(donneesApp$classeVar)=donneesApp$nomVar
        if ("compte" %in% tolower(donneesApp$nomVar)) {
                                                return(  paste("Le fichier ", input$fichierDeCompte$name,  " contient une variable d\u00e9nomm\u00e9e 'compte'")    )                               
                                                    } else {
                                                return( paste("Le fichier ",  input$fichierDeCompte$name, " ne contient pas de variable d\u00e9nomm\u00e9e 'compte'") )
                                                    }                                                   
                                            })      

            ## SECOND 
        valeurr2 <- shiny::eventReactive(input$fichierDeCompte,{
        req(input$fichierDeCompte$datapath)
        donneesApp$fichier <- gsub("/","\\\\",input$fichierDeCompte$datapath)
        donneesApp$nomVar=scan(donneesApp$fichier,sep=",",what="character",nlines=1)
        donneesApp$nbVar=length(donneesApp$nomVar)
        donneesApp$classeVar=rep("character",donneesApp$nbVar)
        names(donneesApp$classeVar)=donneesApp$nomVar
        if ("compte" %in% tolower(donneesApp$nomVar)) {
                                                return (  read.table(donneesApp$fichier,header=TRUE,sep=",",colClasses=donneesApp$classeVar) )
                                                    } else {
                                                return ( NULL )
                                                    }                                                   
                                            })  

        output$laTable <- shiny::renderTable({ valeurr2() })                                    
        output$msgTxt2 <- shiny::renderText({valeurr1() })      
}
app <- shiny::shinyApp(ui,server)
shiny::runApp(app)

test OK

但是,此成功是以将遵从性消息的处理与读取文件分开的代价为代价的。 我通过一个双块eventReactive(参见valuer1和value22)实现了它。 我尝试将其合而为一,但我做不到。

library(shiny)

ui <- shiny::fluidPage(
        shiny::sidebarLayout(
                shiny::sidebarPanel(

    ### permet de selectionner une liste de comptes à partir d un fichier contenant la variable compte 
    shiny::fileInput("fichierDeCompte","Ajouter des comptes \u00e0 partir d'un fichier",multiple=FALSE,accept=c(".csv",".txt",".CSV",".TXT")),
    shiny::verbatimTextOutput("msgTxt2")

    )
    ,           shiny::mainPanel(
                    shiny::tableOutput("laTable")
                                )
    )

)


server <- function(input,output,session) {
        donneesApp <- shiny::reactiveValues(fichier=c())
        donneesApp <- shiny::reactiveValues(nbVar=0)
        donneesApp <- shiny::reactiveValues(classeVar=c(0))
        donneesApp <- shiny::reactiveValues(nomVar=c(0))    


        valeur <- shiny::eventReactive(input$fichierDeCompte,{
        req(input$fichierDeCompte$datapath)
        donneesApp$fichier <- gsub("/","\\\\",input$fichierDeCompte$datapath)
        donneesApp$nomVar=scan(donneesApp$fichier,sep=",",what="character",nlines=1)
        donneesApp$nbVar=length(donneesApp$nomVar)
        donneesApp$classeVar=rep("character",donneesApp$nbVar)
        names(donneesApp$classeVar)=donneesApp$nomVar
        if ("compte" %in% tolower(donneesApp$nomVar)) {
                                                dfres <- read.table(donneesApp$fichier,header=TRUE,sep=",",colClasses=donneesApp$classeVar)
                                                texteres <-  paste("Le fichier ", input$fichierDeCompte$name,  " contient une variable d\u00e9nomm\u00e9e 'compte'")                                
                                                    } else {
                                                dfres <- NULL 
                                                texteres <- paste("Le fichier ",  input$fichierDeCompte$name, " ne contient pas de variable d\u00e9nomm\u00e9e 'compte'") 
                                                    }                                                   
                                            })      


        output$laTable <- shiny::renderTable({ valeur()$dfres })                                    
        output$msgTxt2 <- shiny::renderText({ valeur()$texteres })      
}
app <- shiny::shinyApp(ui,server)
shiny::runApp(app)

test KO log test KO 我想知道错误的出处,使用单个eventReactive块的正确编码是什么,或者如果eventReactive不是要使用的正确函数,我应该如何编写此代码以使其更清晰?

感谢您关注我的问题。 亲切地

编辑:使用observeEvent和一个代码块测试OK

有一种方法可以使用eventReactive而不是watchReactive来做类似的事情?

library(shiny)
ui <- shiny::fluidPage(
    shiny::sidebarLayout(
            shiny::sidebarPanel(
### permet de selectionner une liste de comptes à partir d un fichier contenant la variable compte 
shiny::fileInput("fichierDeCompte","Ajouter des comptes \u00e0 partir d'un fichier",multiple=FALSE,accept=c(".csv",".txt",".CSV",".TXT")),
shiny::verbatimTextOutput("msgTxt2")
)
,           shiny::mainPanel(
                shiny::tableOutput("laTable")
                            )
)
)
server <- function(input,output,session) {
    donneesApp <- shiny::reactiveValues(fichier=c())
    donneesApp <- shiny::reactiveValues(nbVar=0)
    donneesApp <- shiny::reactiveValues(classeVar=c(0))
    donneesApp <- shiny::reactiveValues(nomVar=c(0))    
    observeEvent(input$fichierDeCompte,{
    req(input$fichierDeCompte$datapath)
    donneesApp$fichier <- gsub("/","\\\\",input$fichierDeCompte$datapath)
    donneesApp$nomVar=scan(donneesApp$fichier,sep=",",what="character",nlines=1)
    donneesApp$nbVar=length(donneesApp$nomVar)
    donneesApp$classeVar=rep("character",donneesApp$nbVar)
    names(donneesApp$classeVar)=donneesApp$nomVar
    if ("compte" %in% tolower(donneesApp$nomVar)) {
    output$laTable <- shiny::renderTable({read.table(donneesApp$fichier,header=TRUE,sep=",",colClasses=donneesApp$classeVar) })
    output$msgTxt2 <- shiny::renderText({  paste("Le fichier ", input$fichierDeCompte$name,  " contient une variable d\u00e9nomm\u00e9e 'compte'")    })                            
                                                } else {
    output$laTable <- shiny::renderTable({  NULL })
    output$msgTxt2 <- shiny::renderText({ paste("Le fichier ",  input$fichierDeCompte$name, " ne contient pas de variable d\u00e9nomm\u00e9e 'compte'")    })
                                                }
                                        })      
}
app <- shiny::shinyApp(ui,server)
shiny::runApp(app)

0 个答案:

没有答案