首页 > 解决方案 > 允许闪亮模块参数为 NULL 或反应性的推荐方法?

问题描述

我有一个模块,它的参数传递给模块内的另一个函数(fun1)。此功能允许默认为 NULL 以跳过过滤。 是否有推荐的方法允许模块参数为 NULL 或响应式?

我尝试过的三种方法是(似乎都有效):

  1. 将默认模块参数设置为:reactive({NULL}) 而不是 NULL。
    这似乎最简单并且确实有效。有什么理由不这样做?
  2. 创建函数来检查 !is.reactive(x) & is.null(x) - 并直接在 fun1 参数中使用此函数。它将根据模块参数传递 NULL 或 arg1()。
  3. 在传递给 fun1 之前,在模块内部创建另一个反应式以将 NULL 转换为反应式({NULL})。

请注意,我已将该功能简化为单个过滤输入。实际功能有多个。

下面有以下代码:

#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)

标签: shinymodules

解决方案


推荐阅读