I have been following the solution provided in this post to update the names and column order of a dataset in a Shiny app. The original solution used a dummy dataset, but now I want to extend this solution to for a dataset (e.g., uploaded by the user) with an unknown number of columns in advance. How can I achieve this?
This is what I have tried so far:
library(shiny)
library(data.table)
library(sortable)
ui <- fluidPage(
fluidRow(column(width = 3, uiOutput('ui_rank_list')),
column(width = 9,
actionButton('gen_test_data', label = 'Generate test data'),
tableOutput('preview_table')))
)
server <- function(input, output, session) {
rv_data <- reactiveVal()
# Generate some test data
observeEvent(input$gen_test_data, {
nrows <- 5
ncols <- sample(2:10, 1) # This number is in fact unknown
col_names <- replicate(ncols,
paste0(c(sample(letters, 4, replace = TRUE),
sample(10:100, 2, replace = TRUE)), collapse = ''))
DT <- data.table(matrix(1:(5*ncols), ncol = ncols))
setnames(DT, col_names)
rv_data(DT)
})
# Generate UI for selecting data set as well as buttons
output$ui_rank_list <- renderUI({
req(rv_data(), rv_labels())
DT <- copy(rv_data())
inputIds <<- paste0("textInput", seq_along(names(DT)))
labels <- setNames(lapply(seq_along(initial_column_names), function(i){textInput(inputId = inputIds[i], label = "", value = initial_column_names[i], width = NULL, placeholder = NULL)}), inputIds)
column_rank_list <- rank_list(
text = "Reorder / rename columns",
labels = labels,
input_id = "column_rank_list"
)
column_rank_list
})
# Change columns' order
observeEvent(input$column_rank_list, {
req(input$column_rank_list)
tmpDT <- copy(rv_data())
column_order <- sapply(input$column_rank_list, function(x){ input[[x]] })
setcolorder(tmpDT, column_order)
rv_data(tmpDT)
})
# Change column names
observeEvent(sapply(inputIds, function(x){input[[x]]}), {
req(input$column_rank_list)
tmpDT <- copy(rv_data())
column_order <- sapply(input$column_rank_list, function(x){ input[[x]] })
setnames(tmpDT, column_order)
rv_data(tmpDT)
})
# Preview table
output$preview_table <- renderTable({
req(rv_data())
rv_data()
})
}
shinyApp(ui, server)
I return the following error: Error in lapply: object 'inputIds' not found