Доступ к входным значениям из пользовательского интерфейса одного модуля R Shiny с помощью функции сервера второго модуля - PullRequest
0 голосов
/ 02 мая 2020

1. Моя цель

Я хочу использовать модули Shiny для создания приложения, в котором:

  1. категория A, B или C выбрана с помощью radioButtons
  2. dateRangeInput, чьи min и max аргументы определяются выбранной категорией с использованием updateDateRangeInput
  3. подмножества вектора дат, так что он содержит элементы только между start и end из dateRangeInput

Пока у меня есть шаги 1. и 2. для работы с использованием модуля Shiny. Я предпочитаю выполнять шаг 3. в отдельном модуле или, по крайней мере, в отдельной модульной серверной функции (см. Часть 4).

Мой реальный вариант использования заключается в считывании нескольких файлов из каталога в приложение Shiny. Все файлы имеют строку даты и строку категории как часть их имени. Только файлы выбранной категории и даты в диапазоне дат должны быть прочитаны в моем приложении Shiny. В этом минимальном примере предположим, что файлы представлены all_dates. Обратите внимание, что в моем реальном приложении я использую flexdashboard R вместо приложения Shiny в скрипте.

2. Мой код

Вот первая функция интерфейса модуля:

library(shiny)

# date range depends on the selected category A, B or C
dateRangeCategoryUI <- function(id) {
  ns <- NS(id)
  tagList(
    dateRangeInput(ns("date_range"), label = "select dates"),
    radioButtons(
      ns("category"), 
      label = "select category",
      choices = list("A", "B", "C"), 
      selected = "A"
    )
  )
}

Вот первая функция сервера модуля:

# Server function to find min and max date for a selected category
dateRangeCategory <- function(input, output, session) {
  observe({
    category_min <- switch(
      input$category,
      "A" = Sys.Date() - lubridate::days(1),
      "B" = Sys.Date() - lubridate::days(2),
      "C" = Sys.Date() - lubridate::days(3)
    )
  category_max <- switch(
      input$category,
      "A" = Sys.Date() + lubridate::days(1),
      "B" = Sys.Date() + lubridate::days(2),
      "C" = Sys.Date() + lubridate::days(3)
    )
    updateDateRangeInput(
      session, 
      "date_range",
      start = Sys.Date(),
      end = Sys.Date(),
      min = category_min,
      max = category_max 
    )
  })
}

Вот приложение Shiny, использующее приведенное выше модуль, который работает должным образом:

ui <- fluidPage(
  sidebarLayout(
    sidebarPanel(
      dateRangeCategoryUI("range_and_category")
    ),
    mainPanel()
  )
)

server <- function(input, output, session) {
  callModule(dateRangeCategory, "range_and_category")
}

shinyApp(ui, server)

Для шага 3. выше я хочу создать второй модуль (в другом скрипте .R), который:

  1. обращается к start и end значения dateRangeInput, созданные dateRangeCategoryUI
  2. , загружают вектор дат (в этом минимальном примере я просто создаю объект all_dates)
  3. возвращает подмножество этот объект называется selected_dates, сохраняя даты только в пределах start и end

Функция сервера второго модуля может выглядеть примерно так:

selectDates <- function(input, output, session) {
  all_dates <- seq.Date(
    from = Sys.Date() - lubridate::days(3),
    to = Sys.Date() + lubridate::days(3),
    by = "days"
  )

  selected_dates <- reactive({
    # input$date_range should refer to `dateRangeInput` from `dateRangeCategoryUI`
    range_start <- input$date_range[1]
    range_end <- input$date_range[2]
    all_dates[all_dates >= range_start & all_dates <= range_start]
  })
  return(selected_dates)
}

Я бы тогда хотелось бы иметь эти selected_dates в функции сервера моего приложения Shiny:

ui <- fluidPage(
  sidebarLayout(
    sidebarPanel(
      dateRangeCategoryUI("range_and_category")
    ),
    mainPanel()
  )
)

server <- function(input, output, session) {
  callModule(dateRangeCategory, "range_and_category")  # first module
  selected_dates <- callModule(selectDates, "range_and_category")  # second module
}

shinyApp(ui, server)

3. Мой главный вопрос

Как selectDates получить доступ к значениям start и end из dateRangeInput, созданным dateRangeCategoryUI?

4. Вопросы по организации модулей

  1. Если я выберу работу с двумя модулями, второй модуль будет иметь только серверную функцию и функцию пользовательского интерфейса. Это разрешено?
  2. Было бы проще получить доступ к start и end, если бы я поместил функции selectDates и dateRangeCategory в один файл? В этом случае у меня будет один модуль с двумя функциями сервера. Это разрешено?
  3. Имеет ли смысл обрабатывать обе операции (установка диапазона дат по категориям и создание selected_dates) с помощью одной и той же функции сервера модуля? результат будет выглядеть так: selected_dates <- callModule(dateRangeCategory, "range_and_category")
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...