当表的数量逐个变化时,有什么方法可以在Rshiny中显示多个表吗? 我想创建一个 Rshiny 应用程序,它可以读取多个 csv 文件并显示与每个 csv 文件对应的多个表。不过,提供的文件数量会因情况而异。
到目前为止我编写的代码可以读取多个文件并将它们存储在反应值列表中,但我不知道应用程序应该在输出方面做什么。 这是我的代码:
ui <- fluidPage(
sidebarLayout(
sidebarPanel(
fileInput("upload", "Upload a file", multiple=TRUE)
),
mainPanel(
tableOutput("table")
)
)
)
server <- function(input, output, session) {
data <- reactive({
req(input$upload)
files <- reactiveValues()
browser()
for (i in 1:length(input$upload$datapath)){
files[[paste0(i)]] <- read.csv(input$upload$datapath[i])
}
return(files)
})
output$table <- renderTable({
data()
})
}
shinyApp(ui, server)
评论模块中建议的是解决方案:
library(shiny)
library(DT)
library(uuid)
tmpdir <- tempdir()
cat(tmpdir)
write.csv(mtcars, file.path(tmpdir, "mtcars.csv"))
write.csv(iris, file.path(tmpdir, "iris.csv"))
csv_ui <- function(id) {
ns <- NS(id)
fluidRow(
DTOutput(ns("tab"))
)
}
csv_server <- function(id, the_data) {
moduleServer(
id,
function(input, output, session) {
output$tab <- renderDataTable({
datatable(the_data)
})
}
)
}
ui <- fluidPage(
titlePanel("Modules to the Rescue"),
sidebarLayout(
sidebarPanel(
fileInput("upload", "Upload a file", multiple = TRUE)
),
mainPanel(
uiOutput("tables")
)
)
)
server <- function(input, output, session) {
obs <- list()
output$tables <- renderUI({
paths <- req(input$upload$datapath)
tabs <- vector("list", length(input$upload$datapath))
for (idx in seq_along(paths)) {
local({
jdx <- idx
uid <- UUIDgenerate() ## or create any other unique name
tabs[[jdx]] <<- csv_ui(uid)
obs[[jdx]] <<- csv_server(uid, read.csv(input$upload$datapath[jdx]))
})
}
do.call(tagList, tabs)
})
}
shinyApp(ui, server)
您需要
local
构造,否则最后一个表格将被打印两次。这与惰性评估有关,可以在这个gist中找到一个很好的比较