【问题标题】:renderIUI not working in Shiny Modules in RrenderIUI 在 R 中的 Shiny Modules 中不起作用
【发布时间】:2018-08-20 08:54:59
【问题描述】:

我在 Shiny 中使用 shinydashboard 和来自 gapminder 的数据制作了一个简单的应用程序。基本版本可以工作,但我不能把它分成模块。

该应用正在根据用户选择绘制直方图:

  • 列表中的大陆(数据中可用的所有大陆) 和
  • 国家/地区(根据所选大陆过滤国家/地区)

代码和屏幕如下。 应用:

    library(gapminder)
    library(shiny)
    library(shinydashboard)
    library(dplyr)

    ui <- dashboardPage(

    skin = "yellow",
    dashboardHeader(
    title = "gapminder - data",
    titleWidth = 300
  ),

  dashboardSidebar(
    width = 300,
    sidebarMenu(
      id="menu",

      uiOutput("continent"),
      uiOutput("country")

    )
  ),


  dashboardBody(

    fluidRow(
      plotOutput("plot")
    ))
  )

server <- function(input, output, session) {

  data <- reactive({
    all_data <- filter(gapminder, country != "Kuwait")
    all_data
  })

  output$continent <- renderUI({

    data <- data()
    selectInput("continent",
                "CONTINENT:",
                multiple = FALSE,
                choices = sort(unique(data$continent)))
  })


  output$country <- renderUI({

    data <- data()
    ct <- input$continent

    data %>%
      filter(continent == ct) %>%
      .$country %>%
      unique() %>%
      as.character() -> names

    selectInput("country",
                "COUNTRY:",
                multiple = FALSE,
                choices = names)
  })


  output$plot <- renderPlot({

    data <- data()
    ct <- input$continent
    co <- input$country

    data %>%
    filter(continent == ct,
           country == co) %>%
      .$lifeExp ->selected_data


  histogram <- hist(selected_data)
  histogram

})

}
# Run the application 
shinyApp(ui = ui, server = server)

我想使用 Shiny Modules 重写它 - 将下拉字段放在单独的模块中。我收到了这样的错误:

修改后的应用程序(带模块)的代码是:

library(gapminder)
library(shiny)
library(shinydashboard)
library(dplyr)

source("global.R")

ui <- dashboardPage(

  skin = "yellow",

  dashboardHeader(
    title = "gapminder - data",
    titleWidth = 300
  ),

  dashboardSidebar(
    width = 300,

    sidebarMenu(
      id="menu",

      gapModuleUI("all")

    ) ),


  dashboardBody(

    fluidRow(
      plotOutput("plot")
    )
  )
)

server <- function(input, output, session) {

  callModule(gapModule, "all")

  data <- reactive({
    all_data <- filter(gapminder, country != "Kuwait")
    all_data
  })

  output$plot <- renderPlot({

    data <- data()
    ct <- input$continent
    co <- input$country

    data %>%
      filter(continent == ct,
             country == co) %>%
      .$lifeExp ->selected_data


    histogram <- hist(selected_data)
    histogram

  })

}
# Run the application 
shinyApp(ui = ui, server = server)

并且模块在 global.R 中:

gapModuleUI <- function(id) {
  ns <- NS(id)

  tagList(

    uiOutput(ns("continent")),

    uiOutput(ns("country"))
  )
}

gapModule <- function(input, output, session) {

  ns <- session$ns

  data <- reactive({
    all_data <- filter(gapminder, country != "Kuwait")
    all_data
  })

  output$continent <- renderUI({

    data <- data()

    selectInput(ns("continent"),
                "CONTINENT:",
                multiple = FALSE,
                choices = sort(unique(data$continent)))

    })


  output$country <- renderUI({

    data <- data()
    ct <- reactive({input$continent})

    data %>%
      filter(continent == ct) %>%
      .$country %>%
      unique() %>%
      as.character() -> names

    selectInputns(ns("country"),
                "COUNTRY:",
                multiple = FALSE,
                choices = names)
  })

}

我应该对我的模块进行哪些更改?

【问题讨论】:

  • ui 部分尝试使用ns &lt;- NS(id) 然后gapModuleUI(ns("all")) 而不是gapModuleUI("all")
  • @potockan,在 ui 中,您的意思是 ui &lt;- dashboardPage(...?不幸的是,它不起作用。

标签: r module shiny shinydashboard


【解决方案1】:

在渲染 UI 时,在模块的服务器部分,您还必须将 ID 包装在 ns 中。要从session 获取它,请使用ns &lt;- session$ns。那么:

  output$continent <- renderUI({

    data <- data()

    selectInput(ns("continent"),
                "CONTINENT:",
                multiple = FALSE,
                choices = sort(unique(data$continent)))

    })

output$country相同

编辑: 所以三件事:

  1. global.R 中将filter(continent == ct) %&gt;% 更改为filter(continent == ct()) %&gt;%ct 是反应函数。
  2. global.R 中,您还有一个错字:将selectInputns(ns("country"), 更改为selectInput(ns("country"),
  3. 在主文件中有重要的东西。您尝试使用来自此模块外部模块的输入:ct &lt;- input$continentco &lt;- input$country。模块应该是自包含的,但有办法找到它们。 NS(id) 只是将"id-" 附加到它所应用的所有内容,即:NS("MyId")("input") == "MyId-input"。因此,如果您想使用模块输入,可以通过以下几种方式进行:

    nsall <- NS("all")
    ct <- input[[nsall('continent')]]
    co <- input[[nsall('country')]]
    

    ct <- input$`all-continent`
    co <- input$`all-country`
    

    或者你也可以让你的gapModule返回一些东西:

    return(reactive(c(ct = input$continent, co = input$country)))
    

    然后:

    params <- callModule(gapModule, "all")
    ct <- params()['ct']
    co <- params()['co']
    

【讨论】:

  • 我已经改了,但是现在又出了一个新的bug……你看,我已经编辑了代码。
猜你喜欢
  • 2020-04-26
  • 1970-01-01
  • 1970-01-01
  • 2020-07-08
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-09-29
  • 1970-01-01
相关资源
最近更新 更多