您如何计算从 Shiny 中的 textInput 框中获取的数据?

Posted

技术标签:

【中文标题】您如何计算从 Shiny 中的 textInput 框中获取的数据?【英文标题】:How do you calculate data taken from textInput boxes in Shiny? 【发布时间】:2016-07-11 01:02:42 【问题描述】:

用户界面代码:

===

library(shiny)

  shinyUI(

    # Use a fluid Bootstrap layout
    fluidPage(    


      # Generate a row with a sidebar
      sidebarLayout(      


        # Define the sidebar with one input
        sidebarPanel(
          sliderInput("capacity", "Current Capacity:", 
                      min=0, max=100, value=10),
          c(list(
            textInput("service", "Service Component Name", ""),
            actionButton("addbtn", "Add Component"))),
            #lapply(seq(10), function(i) uiOutput(paste0("ui", i)))

            br(),
            br(), 
            br(),
            br(),
            br(),
          actionButton("calcbtn", "Calculate Projection")




        ),



        # Create a spot for the barplot
        mainPanel(
          textInput("inputWork","Volume", ),
          textInput("inputGrowth","Growth Rate", ),
          lapply(seq(10), function(i) uiOutput(paste0("ui", i)))
          #tags$p("Web"),
          #verbatimTextOutput("input_type_text")

        )

      )
    )
  )

服务器代码:

   server <- function(input, output) 

  observeEvent(input$addbtn, 
    n <- isolate(input$addbtn)
    if (n == 0) return()

    # create n-th pair of text input and output
    output[[paste0("ui", n)]] <- renderUI(
      list(textInput(paste0("textin", n), isolate(input$service)),
           textOutput(paste0("textout", n))))

    # display something in the output
    output[[paste0("textout", n)]] <- renderText(
      work<-as.numeric(input$inputWork)
      growth<-as.numeric(input$inputGrowth)
      print(growth)


     #paste("projection", (100+growth)*as.numeric(input[[paste0("textin", n)]]))
    )
  )
  observeEvent(input$calcbtn, 
    n <- isolate(input$calcbtn)
    if (n == 0) return()

    output[[paste0("textout", n)]] <- renderText(
      work<-as.numeric(input$inputWork)
      growth<-as.numeric(input$inputGrowth)
      project<-growth+as.numeric(input$service)

      print(growth)
      print(project)

      paste("projection", ((1+growth/100)*as.numeric(input[[paste0("textin", n)]])))
    )
  )

这就是我想要做的。此代码将有一个初始文本框和提交按钮。用户在第一个输入文本中放置一个文本,单击提交按钮,在主面板中生成一个新文本。用户可以多次执行此操作以在主面板中创建多个文本输入框。

我在主面板顶部还有一个静态的另一个 inputText 框,标记为 Workload。

所以,这就是我想要做的:

    用户将在工作负载 textIntut 中插入数据(它需要数字)。 用户将数据插入到其他动态生成的文本输入框中(都必须是数字)。 我将从工作负载和所有其他文本框获取值,进行一些计算和预测,并在每个动态生成的文本输入框旁边显示数据,如果我可以在生成的文本框旁边插入文本框以显示我的输出,那就太好了.

例如,我的工作负载中有数据,我生成了 Web_server、App_server 文本输入框。我将从工作负载中获取数据并除以 web_server 中的数据,并将其显示在 web_server 文本输入框旁边(在文本框中显示数据),对 app_server 文本输入框执行相同操作。

任何想法我可以如何在闪亮的情况下做到这一点?这就是我想要完成的图像。鉴于来自用户的工作负载增长率和来自用户输入部分的其他输入,我将不得不计算并填充相应的文本框。

【问题讨论】:

假设calcbtn 是在 UI 中的某处定义的,那么单击它时的预期行为是什么?这会更新所有动态创建的 textOutput,还是只更新其中一个? 您的代码会出现这种行为。它会一一更新textOutput。另外,我从代码中猜想,即使您更改textInput 并再次单击calcbtntextOutput 也不会再更新。现在,单击calcbtn 时,您的预期行为是什么? 提问时,不要分别复制粘贴ui.Rserver.R。人们必须使用它们创建一个文件夹,并创建两个文件只是为了尝试您的代码。相反,准备一组代码,人们可以简单地将其复制到他或她的编辑器中并运行它。 不幸的是,没有。收到答案后,您似乎正在更新您的问题。你不应该那样做,因为如果你改变问题,这个帖子对以后看到这个的其他人来说毫无用处。如果您的原始问题得到解决,请接受并在必要时创建一个新线程。 另外,在提问的时候,尽量做一个最小的可复现的例子。您当前的问题听起来像是在要求人们识别代码中的错误。相反,只需描述你想做什么,以及你是如何陷入困境的。然后人们可以为您提供更多帮助。 【参考方案1】:

以下代码实现:

    单击按钮时添加文本输入(和输出)(最多 10 个)。 每个文本输出都使用输入信息显示一些消息。

注意:

文本输出显示在输入下方而不是旁边。这更多是关于设计问题。我对 html 或 CSS 不是很熟悉,抱歉。 这根本不进行计算。您的任务是添加更多组件并根据需要更改renderText 的内容。 我使用textOutput 来显示计算结果,但您的意图可能是使用textInput。通常,您应该使用textOutput 来显示某些内容,尽管可以将输入对象用作输出对象。 我使用了textInput,但如果输入应始终为数字,您可以改用numericInput,正如其中一位cmets 所建议的那样。

玩得开心。

library(shiny)

ui <- c(list(
  textInput("service", "Service Component Name", ""),
  actionButton("addbtn", "add")),
  lapply(seq(10), function(i) uiOutput(paste0("ui", i)))
)


server <- function(input, output) 

  observeEvent(input$addbtn, 
    n <- input$addbtn
    if (n == 0) return()
    if (n > 10) return()

    # create n-th pair of text input and output
    output[[paste0("ui", n)]] <- renderUI(
      list(textInput(paste0("textin", n), isolate(input$service)),
           textOutput(paste0("textout", n))))

    # display something in the output
    output[[paste0("textout", n)]] <- renderText(
      paste("you wrote", input[[paste0("textin", n)]])
    )
  )


runApp(list(ui = ui, server = server))

【讨论】:

对不起,我忘了提。输出需要由命令按钮生成。一旦所有输入到位,用户需要能够按下提交按钮,输出框将被填充。你能修改这个吗,我从那里拿来。再次感谢!!! 还有一个按钮可以清除所有字段而不刷新页面? Here 是一种清除所有字段的方法 你也可以这样做。添加一个按钮并重写renderText 部分。这是你的任务!提示:isolateobserveEvent @user1471980 您可以使用reset() 包中的reset() 函数来清除输入。【参考方案2】:

实现您的愿望的一些技巧是:

renderText 正在检查其组件中的更改,并在修改组件的值时执行。这就是为什么对于 input$textin1,在文本输入中输入内容后会立即进行更新。 isolate 阻止组件触发执行。使用isolate(input$textin1),修改文本输入不会更新textOutput。 对于触发renderText 执行的按钮,您只需在renderText 中添加按钮即可。在内部,当单击按钮时,其值会增加。因此,它是函数正在检查的组件的值修订,执行发生。 最后,您需要对所有textin1textin2、...进行此操作

以下代码实现了这一点。检查与上一个答案的区别。

library(shiny)

ui <- c(list(
  textInput("service", "Service Component Name", ""),
  actionButton("addbtn", "add"), 
  actionButton("calcbtn", "calc")),
  lapply(seq(10), function(i) uiOutput(paste0("ui", i)))
)


server <- function(input, output) 

  observeEvent(input$addbtn, 
    n <- input$addbtn
    if (n == 0) return()
    if (n > 10) return()

    # create n-th pair of text input and output
    output[[paste0("ui", n)]] <- renderUI(
      list(textInput(paste0("textin", n), isolate(input$service)),
           textOutput(paste0("textout", n))))

    # display something in the output
    output[[paste0("textout", n)]] <- renderText(
      input$calcbtn
      paste("you wrote", isolate(input[[paste0("textin", n)]]))
    )
  )


runApp(list(ui = ui, server = server))

【讨论】:

以上是关于您如何计算从 Shiny 中的 textInput 框中获取的数据?的主要内容,如果未能解决你的问题,请参考以下文章

闪亮:从具有多个值的 textInput 中子集表

如何将更新的列名从 HandsOnTable 传递到 Shiny 中的绘图?

在 Shiny 中使用部分 textInput 作为 R 中的变量

如何在 Shiny 应用程序中验证 textInput?

如何在 Shiny 中使用 textInput 来命名上传数据框的列

如何使用 insertUI 在 Shiny 应用程序中将 textInput 转换为输出