将动态生成的TextInput捕获到数据框中

时间:2018-01-18 16:04:58

标签: r dataframe shiny

我是R的新手(我不是程序员)并尝试创建一个交互式仪表板,用户可以在其中输入动态生成的文本输入框中的数字。我无法将这些输入捕获到一个合适的数据框中,我可以将其连接到其他数据并运行计算。

我按照这个example帮助我生成动态输入框并将它们捕获到数据框中,尽管我的情况有点不同。我的问题是关于接下来的步骤。创建输入后,我能够将它们放入我认为的数据框架中。我在数据中添加了行名称,以便在转置数据时它们可以成为列名。转置后,我从转置数据中删除了新的行名。我创建了新列,它们接受用户的输入,将它们转换为数字,然后执行一两个计算。我在下面包含了捕获问题的简化代码,可以在显示的数据表中看到。

 library(shiny)
library(dplyr)

ui <- fluidPage(
    selectInput("SelectControl", "Selector:", c("Method A", "Method B"), multiple=FALSE),
    uiOutput("manualInputs"),
    tableOutput("ListTable"),
    DT::dataTableOutput("mytable1"),
    DT::dataTableOutput("mytable2")
)
#End UI, Start Server----------------------------------------------------
server <- function(input, output) {

  #In my full version, the months are dynamic, i.e. Jan2017, etc
  uniqueMo <- data.frame(FISCAL_MONTH=c("Jan", "Feb", "Mar", "Apr"))

  #Create the text input boxes dynamically
  output$manualInputs <- renderUI({
    NumberBoxes <- nrow(uniqueMo)
    lapply(1:NumberBoxes, function(i){ 
      monthout <- uniqueMo
      textInput(paste(monthout[i,]), label=monthout[i,], value=0 ) })
  })

  #Try to place the results of the text inputs into a data frame
  Llist <- reactive({
    NumberB <- nrow(uniqueMo) 
    monthout <-uniqueMo
    data.frame(lapply(1:NumberB, function(i) {input[[paste(monthout[i,]) ]] }  ))
  })

  #Add row names so that they will become column names when I transpose
  lister3 <- reactive({
    lister4 <- Llist()
    rownames(lister4) <- "inputs2"
    lister4})
  #Transpose the data and bind back to the list of months
  lister5 <- reactive({t(lister3() ) })
  lister6 <- reactive({cbind(uniqueMo, lister5() )})

  #create a new column that equals the user inputs but which is numeric
  lister7 <- reactive({mutate(lister6(), input=if(inputs2=="0") {0} else {as.numeric(levels(inputs2))[inputs2] }  ) })

  #And finally, two examples of calculations that behave strangely
  lister8 <- reactive({mutate(lister7(), newcolumn=if(input==1) {input*100} else {input*2}  ) })
  lister9 <- reactive({mutate(lister7(), newcolumn2=if(input$SelectControl=="Method A") {input*100} else {input*2}  ) })

  #Display the results of the calculations for easy viewing
  output$mytable1 <- DT::renderDataTable({lister8() })
  output$mytable2 <- DT::renderDataTable({lister9() })

}

shinyApp(ui, server)

值得指出的两件事。在第一个数据表输出中,我希望如果我输入1,则“newcolumn”的相应行中的值为100.实际上,所有行都乘以100,具体取决于第一个输入框是否为1,而不是而不是“输入”列中的相应值是否为1.要查看我的意思,请在第一个框中键入1,然后在第二个框中键入2。然后尝试在第一个中键入2,在第二个中键入1。

其次,第二个图表显示错误:

评估错误:$运算符对原子向量无效。

很明显,我的结果并没有像我想象的那样处于正确的数据框架中。我知道lapply会创建列表,但我没有成功尝试转换为正确的数据框。我搜索并尝试了我能想到的一切。有人可以帮助我吗?

1 个答案:

答案 0 :(得分:0)

我想这个问题源于if(input$SelectControl=="Method A")语句,因为dataframe有一个名为input的列。只需将input$SelectControl的值保存在变量中并与该变量进行比较就可以使代码正常工作。

您需要替换

lister9 <- reactive({mutate(lister7(), newcolumn2=if(input$SelectControl=="Method A") {input*100} else {input*2}  ) })

在您的服务器中使用类似的内容

lister9 <- reactive({
    selectControl <- input$SelectControl
    mutate(lister7(), newcolumn2=if(selectControl=="Method A") {input*100} else {input*2}  ) 
    })

我想应该让你的代码有效。

希望它有所帮助!