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?