0

I am very new to R (I'm not a programmer) and trying to create an interactive dashboard where a user can enter numbers into dynamically generated text input boxes. I am having trouble capturing those inputs into a proper data frame that I can join to other data and run calcs on.

I followed this example which helped me to generate the dynamic input boxes and capture them into a data frame, though my situation is a bit different. My question is about the next steps. After creating the inputs, I was able to place those into what I thought is a data frame. I added row names to the data so that they could become column names when I transpose the data. After transposing, I removed the new row names from the transposed data. I created new columns that take the user's inputs, convert them to numbers, and then perform a calc or two. I've included simplified code below that captures the issue, which can be seen in the displayed data tables.

 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)

Two things worth pointing out. In the first data table output, I expect that if I type a 1, the value in the corresponding row of "newcolumn" is 100. In reality, all rows are multiplied by 100 depending on if the first input box is a 1, rather than whether the corresponding value in the "input" column is 1. To see what I mean, type a 1 in the first box, then a 2 in the second. Then try typing 2 in the first, 1 in the second.

Secondly, the second chart show the error:

Evaluation error: $ operator is invalid for atomic vectors.

So clearly my results are not in a proper data frame as I thought. I know lapply creates lists, and I've unsuccessfully tried to convert to a proper data frame. I've searched and tried everything I can think of. Can someone please help me?

epiphius
  • 33
  • 4

1 Answers1

0

I guess the problem stems from the statement if(input$SelectControl=="Method A") as your dataframe has a column called input. Just saving the value of input$SelectControl in a variable and comparing with that variable should make your code work.

You need to replace

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

in your server with something like this

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

which I guess should make your code work.

Hope it helps!

SBista
  • 7,479
  • 1
  • 27
  • 58