0

我想创建一个模块化的 Shiny 应用程序,其中一个模块 ,dataUpload用于导入 CSV,另一个模块 ,chart用于

  1. 根据 CSV 中的列名创建动态 x 和 y 下拉列表
  2. 根据选定的 input$xaxis, input$yaxis 创建一个绘图这会在向量分配中产生错误 invalid type/length (symbol/0)

我认为问题出在我在 chart.R 中的反应式 ggplot 上,我希望得到任何帮助 - 我在这里添加了所有信息,但我也有一个 github 存储库,如果这更容易的话,我认为这可能是一个非常棒的演示交互模块,所以我真的很感激任何帮助!

应用程序

library(shiny)
library(shinyjs)
library(tidyverse)

source("global.R")

ui <- 
  tagList(
    navbarPage(
      "TWO MODULES",
      tabPanel(
        title = "Data",
          dataUploadUI("datafile", "Import CSV")
      ),
      tabPanel(
        title = "Charts",
          chartUI("my_chart")
      )
    )
  )

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

  datafile <- callModule(dataUpload, "datafile", stringsAsFactors = FALSE)
  output$table <- renderTable({ datafile() })

  # PASS datafile WITHOUT () INTO THE MODULE 
  my_chart <- callModule(chart, "my_chart", datafile = datafile)
  output$plot <- renderPlot({ my_chart() })

}

shinyApp(ui, server)

数据上传.R

dataUpload <- function(input, output, session, stringsAsFactors) {
  # The selected file, if any
  userFile <- reactive({
    # If no file is selected, don't do anything
    # input$file == ns("file")
    validate(need(input$file, message = FALSE))
    input$file
  })

  # The user's data, parsed into a data frame
  dataframe <- reactive({
    read.csv(userFile()$datapath,
             stringsAsFactors = stringsAsFactors)
  })

  # We can run observers in here if we want to
  observe({
    msg <- sprintf("File %s was uploaded", userFile()$name)
    cat(msg, "\n")
  })

  # Return the reactive that yields the data frame
  return(dataframe)

}

数据上传UI.R

# The first argument is the id -- the namespace for the module
dataUploadUI <- function(id, label = "CSV file") {
  # Create a namespace function using the provided id
  #ALL UI FUNCTION BODIES MUST BEGIN WITH THIS
  ns <- NS(id)
  # Rather than fluidPage use a taglist
  # If you're just returning a div you can skip the taglist
  tagList(
  sidebarPanel(
    fileInput(ns("file"), label)),

  mainPanel(tableOutput("table"))
  )
}

图表.R

我相信这是需要一些小改动才能正确渲染情节的文件?

chart <- function(input, output, session, datafile = reactive(NULL)) {

  # SINCE DATAFILE IS A REACTIVE WE ADD THE PRERENTHESIS HERE
  # WHERE/HOW CAN I ACCESS input$xaxis?
  # Do I need to use ns? Can you do that in the server side of a module?
  output$XAXIS <- renderUI(selectInput("xaxis", "X Axis", choices = colnames(datafile())))
  output$YAXIS <- renderUI(selectInput("yaxis", "Y Axis", choices = colnames(datafile())))

  # NOT WORKING
  # Use the selectInput x and y to plot
  p <- reactive({
    req(datafile)
    # WORKS: ggplot(datafile(), aes(x = Sepal_Length, y = Sepal_Width))
    # DOES NOT WORK:
    ggplot(datafile(), aes_(x = as.name(input$xaxis), y = as.name(input$yaxis))) +
      geom_point()
  })

  return(p)
}

图表UI.R

chartUI <- function(id, label = "Create Chart") {

  ns <- NS(id)
  tagList(
    sidebarPanel(
      uiOutput(ns("XAXIS")),
      uiOutput(ns("YAXIS"))
    ),
    mainPanel(plotOutput("plot"))
  )
}
4

1 回答 1

0

我们需要在 renderUI 函数中手动指定名称空间,使用session$ns

chart <- function(input, output, session, datafile = reactive(NULL)) {

  # SINCE DATAFILE IS A REACTIVE WE ADD THE PRERENTHESIS HERE
  # WHERE/HOW CAN I ACCESS input$xaxis?
  # Do I need to use ns? Can you do that in the server side of a module?
  output$XAXIS <- renderUI(selectInput(session$ns("xaxis"), "X Axis", choices = colnames(datafile())))
  output$YAXIS <- renderUI(selectInput(session$ns("yaxis"), "Y Axis", choices = colnames(datafile())))

  # NOT WORKING
  # Use the selectInput x and y to plot
  p <- reactive({
    req(datafile)
    # WORKS: ggplot(datafile(), aes(x = Sepal_Length, y = Sepal_Width))
    # DOES NOT WORK:
    ggplot(datafile(), aes_(x = as.name(input$xaxis), y = as.name(input$yaxis))) +
      geom_point()
  })

  return(p)
}
于 2020-01-14T15:50:26.853 回答