Как импортировать данные, выбирать переменные и создавать графики с блестящими модулями?

#r #shiny

#r #блестящий

Вопрос:

Я пытаюсь загрузить данные, а затем выбрать переменные из загруженных данных для создания точечной диаграммы.

  1. Модуль импорта: импорт данных из файла csv и отображение таблицы предварительного просмотра
  2. Выберите модуль: выберите переменные из импортированного набора данных
  3. Модуль диаграммы рассеяния: создайте диаграмму рассеяния на основе выбранных переменных.

Проблемы, с которыми я сталкиваюсь, включают

  1. Размещение импортированных данных в нужном модуле.
  2. Обновление параметров selectInput с помощью переменных из файла csv
  3. Правильное подключение модулей

Чтобы решить эту проблему, я чувствую, что должен добавить observe где-нибудь и подключить его к другим модулям. Что-то вроде этого observe({updateSelectInput(session, "var1", choices = names(dtreact()))})

Прямо сейчас приложение не запускается и выдает эту ошибку: Error in varselect_ui("select") : object 'dtreact' not found

Вот ссылка на пример файла .csv

 library(shiny)
library(dplyr)
library(rlang)
library(ggplot2)



scatter_plot <- function(dataset, xvar, yvar) {
  
  x <- rlang::sym(xvar)
  y <- rlang::sym(yvar)
  
  p <- ggplot(dataset, aes(x = !!x, y = !!y))  
    geom_point()  
    theme(axis.title = element_text(size = rel(1.2)),
          axis.text = element_text(size = rel(1.1)))
  
  return(p)
  
}

importUI <- function(id) {
  ns <- NS(id)
  
  tagList(
    fileInput(ns("file1"), "Choose CSV File", accept = ".csv"),
    checkboxInput(ns("header"), "Header", TRUE),
    tableOutput(ns("contents"))
  )
  
}

importSE <- function(id) {
  moduleServer(id, 
               function(input, output, session) {
                 
                 dtreact <- reactive({
                   file <- input$file1
                   if (is.null(file))
                     return(NULL)
                   read.csv(file$datapath, header = input$header)
                 })
                 
                 
                 output$contents <- renderTable({
                   dtreact()
                 })
          }
  )
  
}

varselect_ui <- function(id) {
  ns <- NS(id)
  var_choices <- names(dtreact)
  tagList(selectInput(ns("xvar"), "Select X variable", choices = var_choices, selected = NULL),
          selectInput(ns("yvar"), "Select Y variable", choices = var_choices, selected = NULL))
}

varselect_server <- function(id) {
  moduleServer(id,
               function(input, output, session) {
  return(
    list(
      xvar = reactive({input$xvar}),
      yvar = reactive({input$yvar})
    )
  )
                 }
  )
}

scatterplot_ui <- function(id) {
  ns <- NS(id)
  plotOutput(ns("plot1"))
  
}

scatterplot_server <- function(id) {
  moduleServer(id, 
               function(input, output, session, dataset, plot1vars, plot2vars) {
  
  plot1_obj <- reactive({
    p <- scatter_plot(dataset, xvar = plot1vars$xvar(), yvar = plot1vars$yvar())
    return(p)
  })
  
  output$plot1 <- renderPlot({
    plot1_obj()
  })
  }
  )
}






ui <- fluidPage(
  importUI("import"),
  varselect_ui("select"),
  scatterplot_ui("scatter")
)



server <- function(input, output, session) {
  importSE("import")
  varselect_server("select")
  scatterplot_server("scatter")
  
}

shinyApp(ui, server)
  

Код был адаптирован из этого примера

Ответ №1:

Вам не нужен observe , но есть разумный способ связать выходные данные модулей со входными данными модулей. Поэтому используйте return в модулях, которые генерируют данные, которые должны использоваться другими модулями, и храните эти значения в функции main server в переменных. Эти переменные вы можете затем использовать в качестве входных данных для других модулей. Также важно, что если вы передаете реактивы в качестве входных данных в модули, они должны быть не оценены (поэтому передайте dataset вместо dataset() ):

 library(shiny)
library(dplyr)
library(rlang)
library(ggplot2)



scatter_plot <- function(dataset, xvar, yvar) {
  
  x <- rlang::sym(xvar)
  y <- rlang::sym(yvar)
  
  p <- ggplot(dataset, aes(x = !!x, y = !!y))  
    geom_point()  
    theme(axis.title = element_text(size = rel(1.2)),
          axis.text = element_text(size = rel(1.1)))
  
  return(p)
  
}

importUI <- function(id) {
  ns <- NS(id)
  
  tagList(
    fileInput(ns("file1"), "Choose CSV File", accept = ".csv"),
    checkboxInput(ns("header"), "Header", TRUE),
    tableOutput(ns("contents"))
  )
  
}

importSE <- function(id) {
  moduleServer(id, 
               function(input, output, session) {
                 
                 dtreact <- reactive({
                   file <- input$file1
                   if (is.null(file))
                     return(NULL)
                   read.csv(file$datapath, header = input$header)
                 })
                 
                 
                 output$contents <- renderTable({
                   dtreact()
                 })
                 
                 return(dtreact)
               }
  )
  
}

varselect_ui <- function(id) {
  ns <- NS(id)
  var_choices <- ""
  tagList(selectInput(ns("xvar"), "Select X variable", choices = var_choices, selected = NULL),
          selectInput(ns("yvar"), "Select Y variable", choices = var_choices, selected = NULL))
}

varselect_server <- function(id, dataset) {
  moduleServer(id,
               function(input, output, session) {
                 observeEvent(dataset(), {
                   updateSelectInput(session,
                                     "xvar",
                                     choices = names(dataset()))
                   updateSelectInput(session,
                                     "yvar",
                                     choices = names(dataset()))
                 })
                 
                 return(
                   list(
                     xvar = reactive({input$xvar}),
                     yvar = reactive({input$yvar})
                   )
                 )
               }
  )
}

scatterplot_ui <- function(id) {
  ns <- NS(id)
  plotOutput(ns("plot1"))
  
}

scatterplot_server <- function(id, dataset, plot1vars, plot2vars) {
  moduleServer(id, 
               function(input, output, session) {
                 
                 plot1_obj <- reactive({
                   req(dataset())
                   p <- scatter_plot(dataset(), xvar = plot1vars(), yvar = plot2vars())
                   return(p)
                 })
                 
                 output$plot1 <- renderPlot({
                   plot1_obj()
                 })
               }
  )
}






ui <- fluidPage(
  importUI("import"),
  varselect_ui("select"),
  scatterplot_ui("scatter")
)



server <- function(input, output, session) {
  dataset <- importSE("import")
  plotvars <- varselect_server("select", dataset = dataset)
  scatterplot_server("scatter", dataset = dataset, plot1vars = plotvars$xvar,
                     plot2vars = plotvars$yvar)
  
}

shinyApp(ui, server)
  

Комментарии:

1. хороший вариант……….