如何将数据框架对象从renderUI传递到eventReactive? [英] How to pass data frame object from renderUI to eventReactive?

查看:56
本文介绍了如何将数据框架对象从renderUI传递到eventReactive?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我希望我清楚。我想知道如何在服务器功能中将用户输入的数据帧从renderUI传递到evenReactive。问题是在eventReactive中找不到ct。

I hope I am clear. I want to know how to pass user input data frame from renderUI to evenReactive in the server function. The problem is that in the eventReactive, ct is not found. Please advise !

我的代码如下:

ui <-
  fluidPage(
    sidebarPanel(
      fileInput("file1", "Import",
                accept = c(".xlsx")),
      uiOutput("selectCAT"),
      actionButton("goBu", "Click!")),

    mainPanel("Display Results"
              tableOutput("acBTTON")
    ))



server <- function(input, output, session)
{
  output$selectCAT <- renderUI({
    req(input$file1)
    ct <- read_excel(input$file1$datapath, sheet = "abc")
    empl <- read_excel(input$file2$datapath, sheet = "emp")

    selectInput(inputId = "showp",
                label = "Selection",
                empl)})
}


 pf <- eventReactive(input$goBu,{
    s1 <- sqldf("SELECT * FROM ct")
  })
  output$acBTTON <- renderTable({
    pf()})


解决方案

关于此详细/增强示例应用程序的一些信息。

A few things about this verbose/augmented sample app.


  • 我不认为您确实需要 uiOutput renderUI ,因为您要尝试的是更改<$ c中的可用选项$ c> selectInput 。

  • 我包括一些详细信息,因此您可以(例如)查看 req 工作,容易被禁用或删除(我经常在我自己的闪亮应用中拥有此代码,默认情况下处于禁用状态,以便在需要解决可能涉及反应性的任何问题时)。 (如果看到 In:而没有相应的 Out:,则表示 req 行由于需求不足而中断了流量。)

  • 您在示例中引用了 file2 ,但从未设置。 ..我忽略了它,但是我认为您可以扩展您的 ui 来容纳它,并扩展 server 逻辑来处理它

  • 使用 sqldf 通常是足够安全的,但是它建议使用的SQL不能(直接)防止SQL注入。如果您使用用户定义的自由文本进行这些查询,则应采取更多的保护措施。

  • 我添加了 defcat ,选择一个类别中的消息。因为显然不是您要过滤的东西,所以在过滤(并因此渲染)之前,我明确确保它不是选定的类别。

  • I don't think you really need uiOutput and renderUI, since what you are trying to do is change the available options in a selectInput.
  • I included some verbosity, so you can (for example) see req working, easily disabled or removed (I often have this code in my own shiny apps, disabled by default, for when I need to troubleshoot anything that might involve reactivity). (If you see In: and no corresponding Out:, this means the req line interrupted flow due to insufficient requirements.)
  • You referenced file2 in your example but never set it up ... I ignored it, but I think you could extend your ui to accommodate it, and server logic to handle it.
  • The use of sqldf is generally safe enough, but the SQL it suggests does not guard (directly) against SQL injection. If you take these queries with user-defined free text, more safeguards should be taken.
  • I added defcat, a "select a category" type message in the pull-down. Because it's obviously not something you want to filter on, I explicitly ensure it is not the selected category before filtering (and therefore rendering).

鉴于此,我将给出两个结果:一个不带 renderUI 的结果,另一个带它的结果。

Given that, I'll present two results: one without renderUI, and one with it.

第一个,不带:

library(shiny)
library(sqldf)

defcat <- "Select a category ..."
ui <- fluidPage(
  sidebarPanel(
    fileInput("file1", "Import", accept = ".xlsx"),
    selectInput("selectCAT", "Category", choices = defcat),
    actionButton("goBu", "Click!")
  ),
  mainPanel(
    "Display Results",
    tableOutput("acBTTON")
  )
)

verbose <- TRUE
msg <- if (verbose) message else c

server <- function(input, output, session) {
  dat_mt <- eventReactive(input$file1, {
    msg("In: dat_mt ...")
    req(input$file1)
    out <- readxl::read_excel(input$file1$datapath, "mt")
    msg("Out: dat_mt ...")
    out
  })
  dat_ir <- eventReactive(input$file1, {
    msg("In: dat_ir ...")
    req(input$file1)
    out <- readxl::read_excel(input$file1$datapath, "ir")
    msg("Out: dat_ir ...")
    out
  })

  observeEvent(dat_mt(), {
    msg("In: observe dat_mt() ...")
    req(dat_mt())
    sel <- if (input$selectCAT %in% dat_mt()$cyl) input$selectCAT else defcat
    updateSelectInput(session, "selectCAT",
                      choices = c(defcat, sort(unique(dat_mt()$cyl))),
                      selected = sel)
    msg("Out: observe dat_mt() ...")
  })

  pf <- eventReactive(input$goBu, {
    msg("In: event input$goBu ...")
    req(defcat != input$selectCAT, dat_mt(), dat_ir())
    mt <- dat_mt()
    ir <- dat_ir()
    # WARNING: potential for SQL injection, proof-of-concept only
    out <- sqldf(paste("select * from mt where cyl =", input$selectCAT))
    msg("Out: event input$goBu ...")
    out
  })

  output$acBTTON <- renderTable({
    msg("In: acBTTN ...")
    req(pf())
    out <- pf()
    msg("Out: acBTTN ...")
    out
  })
}
shinyApp(ui, server)






第二个具有动态UI。注意只有两个区别:


The second, with dynamic UI. The only two differences are noted:

ui <- fluidPage(
  sidebarPanel(
    fileInput("file1", "Import", accept = ".xlsx"),
    ## replace selectInput with this:
    uiOutput("selectCATdyn"),
    ## end dif
    actionButton("goBu", "Click!")
  ),
  mainPanel(
    "Display Results",
    tableOutput("acBTTON")
  )
)

server <- function(input, output, session) {
  dat_mt <- eventReactive(input$file1, {
    msg("In: dat_mt ...")
    req(input$file1)
    out <- readxl::read_excel(input$file1$datapath, "mt")
    msg("Out: dat_mt ...")
    out
  })
  dat_ir <- eventReactive(input$file1, {
    msg("In: dat_ir ...")
    req(input$file1)
    out <- readxl::read_excel(input$file1$datapath, "ir")
    msg("Out: dat_ir ...")
    out
  })

  ## replace observeEvent(dat_mt(),... with      
  output$selectCATdyn <- renderUI({
    req(dat_mt(), dat_ir())
    selectInput(inputId = "selectCAT", label = "Selection",
                choices = c(defcat, sort(unique(dat_mt()$cyl))),
                selected = defcat)
  })
  ## end diff

  pf <- eventReactive(input$goBu, {
    msg("In: event input$goBu ...")
    on.exit( msg("Out: event input$goBu ...") )
    req(defcat != input$selectCAT, dat_mt(), dat_ir())
    mt <- dat_mt()
    ir <- dat_ir()
    # WARNING: potential for SQL injection, proof-of-concept only
    out <- sqldf(paste("select * from mt where cyl =", input$selectCAT))
    out
  })

  output$acBTTON <- renderTable({
    msg("In: acBTTN ...")
    req(pf())
    out <- pf()
    msg("Out: acBTTN ...")
    out
  })
}

在我玩这个游戏的过程中,我意识到为什么要使用动态UI,所以它现在更有意义:-)

As I play with this, I realize why you wanted dynamic UI, so it now "makes more sense" :-)

但请注意:您可以通过静态定义它(如我的第一个解决方案)并使用 shinyjs :: hide shinyjs :: disable 在另一个 observe 块中。

Side note, though: you can have a similar effect by defining it statically (as in my first solution) and use shinyjs::hide or shinyjs::disable inside another observe block.

设置:

wb <- openxlsx::createWorkbook()
openxlsx::addWorksheet(wb, "mt")
openxlsx::writeDataTable(wb, "mt", x = mtcars)
openxlsx::addWorksheet(wb, "ir")
openxlsx::writeDataTable(wb, "ir", x = iris)
openxlsx::saveWorkbook(wb, "Johnseito.xlsx")

这篇关于如何将数据框架对象从renderUI传递到eventReactive?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆