我有一个模块,它的参数传递给模块内的另一个函数(fun1)。此功能允许默认为 NULL 以跳过过滤。 是否有推荐的方法允许模块参数为 NULL 或响应式?
我尝试过的三种方法是(似乎都有效):
- 将默认模块参数设置为:reactive({NULL}) 而不是 NULL。
这似乎最简单并且确实有效。有什么理由不这样做? - 创建函数来检查 !is.reactive(x) & is.null(x) - 并直接在 fun1 参数中使用此函数。它将根据模块参数传递 NULL 或 arg1()。
- 在传递给 fun1 之前,在模块内部创建另一个反应式以将 NULL 转换为反应式({NULL})。
请注意,我已将该功能简化为单个过滤输入。实际功能有多个。
下面有以下代码:
- 模块内部使用的函数(这是我希望允许将参数设置为 null in)
- 3 个不同方法的示例模块。我认为一切似乎都有效。
- 具有所有三个模块输出的闪亮应用程序
#internal function
fun1 <- function(x, arg1=NULL){
x %>%
if (!is.null(arg1))
dplyr::filter(., .data$gear %in% arg1)
else .
}
#Module Options
#--------------------
#1. Set default to reactive({NULL}) instead of NULL
server1 <- function(id, dataset, arg1in=reactive({NULL})){
moduleServer(
id,
function(input, output, session) {
stopifnot(is.reactive(dataset))
out <- reactive({
fun1(dataset(), arg1 = arg1in())
})
#print(arg1in)
return(out)
})
}
#2. create function to check is reactive and NULL --> and use directly in fun1
server2 <- function(id, dataset, arg1in=NULL){
moduleServer(
id,
function(input, output, session) {
stopifnot(is.reactive(dataset))
check_null_arg <- function(x){
if(!is.reactive(x) & is.null(x)){
NULL
}else{
x()
}
}
out <- reactive({
fun1(dataset(), arg1 = check_null_arg(arg1in))
#check_null_arg(arg1in)
#!is.reactive(arg1in) & is.null(arg1in)
})
#print(arg1in)
#print(check_null_arg(arg1in))
return(out)
})
}
#3. make a second reactive inside module based on input
server3 <- function(id, dataset, arg1in=NULL){
moduleServer(
id,
function(input, output, session) {
stopifnot(is.reactive(dataset))
argR <- reactive({
if(is.null(x)){NULL}else{arg()}
})
out <- reactive({
fun1(dataset(), arg1 = argR())
})
#print(argR())
#print(arg1in)
return(out)
})
}
测试应用 显示 3 种方法的输出。
library(dplyr)
library(shiny)
ui <- fluidPage(
titlePanel("Testing Application"),
#sidebarLayout(),
mainPanel(
h3("1. Use reactive({NULL}) as argument default"),
h4("using default arg1in = reactive({NULL})"),
verbatimTextOutput("out1"),
h4("using arg1in = reactive({ARG})"),
verbatimTextOutput("out1b"),
br(),
h3("2. Create function to check if !reactive and NULL"),
h4("using default arg1in = NULL"),
verbatimTextOutput("out2"),
h4("using arg1in = reactive({ARG})"),
verbatimTextOutput("out2b"),
br(),
h3("3. Create second internal reactive"),
h4("using default arg1in = NULL"),
verbatimTextOutput("out3"),
h4("using arg1in = reactive({ARG})"),
verbatimTextOutput("out3b")
)
)
server <- function(input, output, session) {
dat <- mtcars
ARG <-reactive({ 4})
mod1 <- server1("mod1", dataset = reactive({dat})) #use default arg1in = reactive({NULL})
mod1b <- server1("mod1b", dataset = reactive({dat}), arg1in=ARG) #use default arg1in = reactive({NULL})
mod2 <- server1("mod2", dataset = reactive({dat})) #use default arg1in=NULL)
mod2b <- server1("mod2b", dataset = reactive({dat}), arg1in=ARG) #use default arg1in=NULL)
mod3 <- server1("mod3" , dataset = reactive({dat})) #use default arg1in=NULL)
mod3b <- server1("mod3b" , dataset = reactive({dat}), arg1in=ARG) #use default arg1in=NULL)
output$out1 <- renderPrint({
str(mod1())
})
output$out1b <- renderPrint({
str(mod1b())
})
output$out2 <- renderPrint({
str(mod2())
})
output$out2b <- renderPrint({
str(mod2b())
})
output$out3 <- renderPrint({
str(mod3())
})
output$out3b <- renderPrint({
str(mod3b())
})
}
shinyApp(ui = ui, server = server)