How to modify values in a datable based on a numeric input column with Shiny

I am a beginner in Shiny, and I would like to use values from numeric inputs included in a data table, to update other fields from the same data table.

At this step, it works when the numeric inputs are outside the table, but not when they are included in it. Here is a very simplified version of what I tried, which doesn't work:

Server.R
library(DT)
server.fun <- function(input, output) {
        vect_res<- reactive({
        value<-NULL
        sapply(1:10, FUN = function(i) {
        value[i] <<- eval(parse(text=(paste("input$Item",i, sep = "."))))
        })
        return(value)
        }
    )
output$results <- renderDataTable({
        results <- data.frame(ID=1:10, contents=letters[1:10])
        test=NULL
        sapply(1:10, FUN = function(i) {
        test[i] <<-as.character(numericInput(paste("Item",i, sep = "."),"", value = 1,step=0.1)
        )          
        })
        results$test<-test
        results$value<-vect_res()
        datatable(results, escape=FALSE)
    })
}

ui.R
library(DT)
shinyUI({
basicPage(
    dataTableOutput( "results" )
    )
})

This results in only 3 columns. The numeric inputs are indeed included in the table, but I would expect a 4th column, which would contain the values entered in the numeric inputs.

1 Like

The key here is to use renderUI and uiOutput for dynamic outputs.

I modified this example from here, which also allows you to create any number of rows instead of just the fixed 10. https://stackoverflow.com/questions/36141451/ammending-dynamic-input-code-in-r-shiny

Server.R

server.fun <- function(input, output) {
 
  observeEvent(input$numInputs, {
    output$inputGroup = renderUI({
      input_list <- lapply(1:input$numInputs, function(i) {
        # for each dynamically generated input, give a different name
        inputName <- paste("input", i, sep = "")
        numericInput(inputName, inputName,1)
      })
      do.call(tagList, input_list)
    })
  })
  
  # this is just a demo to display all the input values
  output$inputValues <- DT::renderDataTable({
    all <- paste(lapply(1:input$numInputs, function(i) {
      inputName <- paste("input", i, sep = "")
      input[[inputName]]
    }))
    matrix = as.matrix(read.table(text=all))
    df <- data.frame(matrix)
    df$example_vals <- 1:input$numInputs
    df$another_col <- rep("A", times = input$numInputs)
    df
  })
  
}

ui.R

library(DT)
shinyUI({
  sidebarLayout(
    sidebarPanel(
      numericInput("numInputs", "How many inputs do you want", 4),
      # place to hold dynamic inputs
      uiOutput("inputGroup")
    ),
    # this is just a demo to show the input values
    mainPanel(DT::dataTableOutput("inputValues"))
  )
})
1 Like

Thank you for your answer.
However, maybe I was not clear enough, sorry, but my problem is that I could not manage to incorporate the inputs into the datatable.

Do you know if this is possible?

Oh I see, I believe this will accomplish what you need?

library(shiny)
library(rhandsontable)

ui <- fluidPage(
  rHandsontableOutput('hot')
)

server <- function(input,output,session)({
  df<- data.frame(numeric_input = c(0,0,0), result = c(0,0,0), diff=c(0,0,0), select= as.logical( c(FALSE,FALSE,FALSE)))
  values <- reactiveValues(data = df)
  
  
  observe({
    if(!is.null(input$hot)){
      values$data <- as.data.frame(hot_to_r(input$hot))
      isolate(values$data[,'result'] <- values$data[,'numeric_input'])
      output$hot <- renderRHandsontable({
        rhandsontable(values$data)
      })
    }
  })    
  
  output$hot <- renderRHandsontable({
    rhandsontable(values$data)
  })
  
})

shinyApp(ui = ui, server = server)
2 Likes

Thank you, you helped me a lot!!

1 Like