我一直在遵循这篇文章中提供的解决方案来更新 Shiny 应用程序中数据集的名称和列顺序。原始解决方案使用虚拟数据集,但现在我想将此解决方案扩展到预先具有未知列数的数据集(例如,由用户上传)。我怎样才能做到这一点?
这是我到目前为止尝试过的:
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)
我返回以下错误:
Error in lapply: object 'inputIds' not found
也许你没有把括号放在那里, 在 # 生成用于选择数据集和按钮的 UI:
替换这个
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)
到
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))
要解决此类问题,您应该考虑“调试”, 例如,通过this.
而且你根本不应该使用全局变量,因为它使代码,例如,不可预测.
dplyr
有功能
rename()
,
relocate()
和
tidy select
可用于操作数据框。