提问人:Curious Jorge - user9788072 提问时间:6/6/2023 更新时间:6/6/2023 访问量:38
如何使用单独模块中的代码将自定义标题插入到使用 DT Shiny 渲染的表格中?
How to insert a custom header into a table rendered with DT Shiny with code from a separate module?
问:
我对使用 namespaces 在 R Shiny 中进行模块化完全陌生,我发现它不是很直观。在下面的代码中,分为“核心应用代码”和“模块代码”,反应对象在核心应用代码和模块代码之间传输,以便在模块代码中的多个函数之间使用。该代码在对模块服务器函数(及其定义)的调用中使用参数。它将从一个模块返回的值分配给主服务器函数中的反应式,然后通过调用其服务器函数将该反应式传递给第二个模块。iris1
以下似乎有效,除了跨越几列的客户标头(在模块代码中的函数中以 CSS 呈现的第二个标头,出现在 DT 表标头上方)不起作用。我在下面做错了什么?myContainer
代码 应用代码:
library(shiny)
library(DT)
source("C:/Users/.../my_module.R")
ui <- fluidPage(
numericInput("number", label = "Enter sepal length multiplier:", value = 1),
DTOutput('tbl')
)
server <- function(input, output) {
iris1 <- reactive({
tmp <- iris
tmp$Sepal.Length <- tmp$Sepal.Length * input$number
tmp
})
output$tbl <- renderDT({renderTable(iris1())})
# Pass the reactive object iris1 to the module server function
callModule(my_module_server, "myModule", iris1 = iris1)
}
shinyApp(ui, server)
模块代码(另存为my_module。R):
myContainer <- function() {
htmltools::withTags(table(
class = 'display',
thead(
tr(
th(style = "border-top: none;border-bottom: none;"),
th(colspan = 4, 'Lengths and widths',
class = "dt-center",
style = "border-right: solid 0.5px;border-left: solid 0.5px;border-top: solid 0.5px; background-color:#E6E6E6;"
)
),
tr(
th(),
lapply(names(iris1()), th) # Access iris1 reactive object
)
)
))
}
renderTable <- function(data) {
datatable(
data,
container = myContainer(),
options = list(lengthChange = FALSE)
)
}
my_module_ui <- function(id) {
ns <- NS(id)
DTOutput(ns("tbl"))
}
my_module_server <- function(input, output, session, iris1) {
output$tbl <- renderDT({
renderTable(
iris1() # Access iris1 reactive object
)
})
}
答:
3赞
stefan
6/6/2023
#1
下面是一个模块化代码的工作示例。当您在代码中添加了一个模块时,您实际上并没有使用它,即您的输出是在主服务器中创建的,并且只有此输出包含在主 UI 中。tbl
取而代之的是,我将模块 UI 添加到主 UI 中,并从主服务器中删除了 以及相应的渲染功能。此外,作为一个函数,通过将表的名称作为参数传递,而不是依赖于在应用的不同部分中定义的表,使其自包含。实际上,当我运行您的代码时,因此我收到错误。另外,我认为没有任何理由用自定义函数覆盖。如果需要自定义函数,我建议使用不同的名称来明确这一点。最后,我切换到了新的样式模块,而不是使用 .output$tbl
myContainer
reactive
shiny::renderTable
moduleServer
callModule
library(shiny)
library(DT)
myContainer <- function(x) {
htmltools::withTags(table(
class = "display",
thead(
tr(
th(style = "border-top: none;border-bottom: none;"),
th(
colspan = 4, "Lengths and widths",
class = "dt-center",
style = "border-right: solid 0.5px;border-left: solid 0.5px;border-top: solid 0.5px; background-color:#E6E6E6;"
)
),
tr(
th(),
lapply(x, th)
)
)
))
}
my_module_ui <- function(id) {
ns <- NS(id)
DTOutput(ns("tbl"))
}
my_module_server <- function(id, iris1) {
moduleServer(id, function(input, output, session) {
output$tbl <- renderDT({
datatable(
iris1(),
container = myContainer(names(iris1())),
options = list(lengthChange = FALSE)
)
})
})
}
ui <- fluidPage(
numericInput("number", label = "Enter sepal length multiplier:", value = 1),
my_module_ui("myModule")
)
server <- function(input, output) {
iris1 <- reactive({
tmp <- iris
tmp$Sepal.Length <- tmp$Sepal.Length * input$number
tmp
})
my_module_server("myModule", iris1 = iris1)
}
shinyApp(ui, server)
#>
#> Listening on http://127.0.0.1:3641
评论
1赞
Curious Jorge - user9788072
6/6/2023
是的,这很有效,您的解释非常有帮助。我能够将 、 和 分离到一个单独的文件中,并使用 从主 App 代码中获取它们。我开始通过这个简单的例子来理解模块和命名空间,谢谢。myContainer
my_module_ui
my_module_server
source("C:/Users/.../my_module.R")
评论
my_module_server
my_module_ui
iris1
data.frame
renderTable
data.frame
C: