【问题标题】:(Shiny) "ERROR: [on_request_read] parse error"(闪亮)“错误:[on_request_read] 解析错误”
【发布时间】:2016-12-25 18:36:50
【问题描述】:

目标:我希望用户上传自己的数据框,在他们的数据框中指定提供“名称”、“经度”和“纬度”数据的列,然后创建使用 DataTable 的表(DT 包)。

问题:用户做出选择后,数据框出现在渲染表上,但当他们尝试对每一列进行排序或与数据交互,甚至更改“名称”的选择时、“经度”或“纬度”,控制台上会出现以下错误消息:

ERROR: [on_request_read] parse error

这是我的 ui 和服务器页面的代码(注意:我使用 dashboardPage 进行布局):

可重现的例子

ui <- dashboardPage(

  dashboardHeader(title = "Test") , 

  dashboardSidebar(
    sidebarMenu(
      menuItem("Selections", tabName = "selections"),
      menuItem("Data Table", tabName = "dataTable")
    )
  ),

  dashboardBody(
    tabItems(
      tabItem(
        tabName = "selections",
        selectInput("mapChoice", 
                    label = "Choose a map:", 
                    choices = c("", 
                                "New Map from Data Table"),
                    selected = ""),

        conditionalPanel("input.mapChoice == 'New Map from Data Table'",
          fileInput("userData",
                    label = "Choose CSV File", 
                    accept=c('text/csv', 
                             'text/comma-separated-values,text/plain', 
                             '.csv')),               

          uiOutput("newMapUI")
        ), 
        ###############################################
        # Bookmark widget
        shinyURL.ui(width = "400px")
        ###############################################
      ), 

      tabItem(
        tabName = "dataTable",
        DT::dataTableOutput("table")
      )
    )
  )


  )


server <- function(input, output, session) {
  ############################################################
  # Add in function for saving and recording urls as bookmarks
  shinyURL.server(session)
  ############################################################

  userData <- reactive({

    path <- input$userData

    if (is.null(path))
      return (NULL)

    results <- read.csv(file = path$datapath, 
                        header = TRUE, 
                        stringsAsFactors = FALSE)
    results

  })

  output$newMapUI <- renderUI({


    list(

      # Specify the column for labeling
      if (!is.null(userData())) {
        selectizeInput("nameCol", 
                       label = "Choose the column to be used for
                       point labels: ", 
                       choices = c(names(userData())),
                       multiple = TRUE,
                       options = list(placeholder = 'Name', 
                                      maxItems = 1))
      }, 

      # Specify longitude column
      if (!is.null(userData())) {
        selectizeInput("lonCol", 
                       label = "Choose the column containing longitude
                       values: ", 
                       choices = c(names(userData())),
                       multiple = TRUE,
                       options = list(placeholder = 'Longitude', 
                                      maxItems = 1))
      }, 
      # Specify latitude column
      if (!is.null(userData())) {
        selectizeInput("latCol", 
                       label = "Choose the column conatining latitude
                       values: ", 
                       choices = c(names(userData())),
                       multiple = TRUE,
                       options = list(placeholder = 'Latitude', 
                                      maxItems = 1))
      }

    )



  })

  nameCol <- reactive({
    as.character(input$nameCol)
  })

  lonCol <- reactive({
    as.character(input$lonCol)
  })

  latCol <- reactive({
    as.character(input$latCol)
  })



  newUserData <- reactive({

    if (is.null(userData())) 
      return (NULL)

    # Create the new data frame:
    if (length(nameCol()) != 0 &&
        length(lonCol()) != 0 &&
        length(latCol()) != 0) {

      userData <- userData()

      name <- nameCol()
      lonCol <- lonCol()
      latCol <- latCol()

      results <- data.frame(Name = userData[, name], 
                            Longitude = userData[, lonCol], 
                            Latitude = userData[, latCol])

      results$Name <- as.character(results$Name)
      results$Longitude <- as.numeric(results$Longitude)
      results$Latitude <- as.numeric(results$Latitude)

    }

    results

  })

  mapData <- reactive({

    data <- data.frame()

    if (input$mapChoice == "New Map from Data Table") {

      if (length(nameCol()) != 0 &&
          length(lonCol()) != 0 &&
          length(latCol() != 0)) {
        data <- newUserData()
      }
    }
      data
    })

  output$table <- DT::renderDataTable({

    datatable(mapData(), 
              extensions = c('Buttons', 'FixedHeader', 'Scroller'), 
              options = list(dom = 'Bfrtip', 
                             buttons = list('copy', 'print', 
                                            list(extend = 'csv', 
                                                 filename = 'map data', 
                                                 text = 'Download') 
                             ), 
                             scrollX = TRUE, 
                             pageLength = nrow(mapData()), 
                             fixedHeader = TRUE, 
                             deferRender = FALSE, 
                             scrollY = 400, 
                             scroller = FALSE, 
                             autowidth = TRUE
              )
    )

  }
  ) # End of table render

  }

shinyApp(ui = ui, server = server)

注意:如果我尝试将此数据用于绘图,那也将不起作用。 (在地图上绘制点是我的最终目标)。

Update1:出于某种愚蠢的原因,这个 sn-p 应用程序运行得非常好,但这些代码行直接来自我的应用程序。随着更多事情的发生,我将继续更新。

Update2:经过大量的搜索和调试,我终于在运行应用时通过浏览器提供的js帮助找到了错误消息的来源。错误是尝试将 shinyURL 与 DT 和 fileInput 结合使用。我的猜测是 shinyURL 正在尝试保存一个 url,这对于浏览器来说太长了,并且它提供了用户提供的信息。换句话说,它可能正在尝试使用 url 信息保存 fileInput 数据..?我将 shinyURL 函数添加到上面的示例中,以便它提供与我卡住的完全相同的错误消息。我不需要立即解决,但我很好奇到底发生了什么。 (产生错误的行在上面和下面用### 突出显示。

【问题讨论】:

  • 你能把reproducible example弄小一点吗?例如,fileInput 是否与本次讨论相关,或者任何数据集都可用于测试(请选择一个)?如果这是我可以复制/粘贴到单个文件中的内容(例如使用shinyApp),那将会很有帮助。最后,请包含显式代码以包含您正在使用的非基础包(即library(shiny)library(shinydashboard))。
  • 是的。我很抱歉。我一直在努力提供正确级别的细节,因为这是一个涉及超过 4000 行代码的应用程序的一个小 sn-p。文件输入似乎是问题的根源。 (我将在上面发布可重现的示例)显示“Shiny App/data”中给出的数据框不会出现错误。
  • 很高兴知道,谢谢。您是否尝试将browser() 放入您的每个(大)reactive 块中以查看问题到底出在哪里? (顺便说一句:您可能可以使用validate(need(! is.null(userData()), FALSE)) 并多次排除您对is.null(...) 的测试。有关更多信息,请参阅?validate。)
  • 我实际上并不熟悉browser(),所以我将不得不花一些时间来调查它。另外,感谢您的提示!
  • 哦哦哦哦,这并不难,而且(在我看来)它是一个基本调试工具。 “R Gurus”知道如何使用其他功能——通常是较低级别的——但是一旦你掌握了它,这将很快而且相对容易。也许查看最近的article at RStudio,即使您不使用 RStudio,它也可能会有所帮助。

标签: r datatable shiny reactive-programming dt


【解决方案1】:

解决方案

这个问题在我最近的更新中是预料到的,用户上传的文件和DT中数据框的交互导致shinyURL生成的URL完全太长。

为了找到一个允许 shinyURL 仍然存在于应用程序中的解决方法,我进行了一些调查并发现 DT 输出创建了自己的输入对象,例如 input$tableId_rows_current,它试图保存表的所有索引用户与之交互的时间。因此,一旦数据框太大,与之进行的任何交互都会传递一个 url 查询错误,该错误在 R Studio 的控制台上显示为ERROR [on_request_read] parse error

幸运的是,shinyURL 还有一种忽略用户选择输入的固有方式。如何?只需简单地放置一个“。”创建新小部件时在输入 ID 的开头。或者,在 DT 表输出的情况下,在数据表输出 ID 的开头放置一个句点,以便忽略所有固有的 DT 输入。

代码解决方案:

ui <- dashboardPage(

  dashboardHeader(title = "Test") , 

  dashboardSidebar(
    sidebarMenu(
      menuItem("Selections", tabName = "selections"),
      menuItem("Data Table", tabName = "dataTable")
    )
  ),

  dashboardBody(
    tabItems(
      tabItem(
        tabName = "selections",
        selectInput("mapChoice", 
                    label = "Choose a map:", 
                    choices = c("", 
                                "New Map from Data Table"),
                    selected = ""),

        conditionalPanel("input.mapChoice == 'New Map from Data Table'",
#########################################################
# Add in a period before file input ID
#########################################################
          fileInput(".userData",
                    label = "Choose CSV File", 
                    accept=c('text/csv', 
                             'text/comma-separated-values,text/plain', 
                             '.csv')),               

          uiOutput("newMapUI")
        ), 
        # # Bookmark widget
        shinyURL.ui(width = "400px")
      ), 

      tabItem(
        tabName = "dataTable",
########################################################
# Add in a period before data table output ID
########################################################
        DT::dataTableOutput(".table")
      )
    )
  )


  )


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

  # # Add in function for saving and recording urls as bookmarks
  shinyURL.server(session)

  userData <- reactive({

    path <- input$.userData

    if (is.null(path))
      return (NULL)

    results <- read.csv(file = path$datapath, 
                        header = TRUE, 
                        stringsAsFactors = FALSE)
    results

  })

  output$newMapUI <- renderUI({


    list(

      # Specify the column for labeling
      if (!is.null(userData())) {
        selectizeInput("nameCol", 
                       label = "Choose the column to be used for
                       point labels: ", 
                       choices = c(names(userData())),
                       multiple = TRUE,
                       options = list(placeholder = 'Name', 
                                      maxItems = 1))
      }, 

      # Specify longitude column
      if (!is.null(userData())) {
        selectizeInput("lonCol", 
                       label = "Choose the column containing longitude
                       values: ", 
                       choices = c(names(userData())),
                       multiple = TRUE,
                       options = list(placeholder = 'Longitude', 
                                      maxItems = 1))
      }, 
      # Specify latitude column
      if (!is.null(userData())) {
        selectizeInput("latCol", 
                       label = "Choose the column conatining latitude
                       values: ", 
                       choices = c(names(userData())),
                       multiple = TRUE,
                       options = list(placeholder = 'Latitude', 
                                      maxItems = 1))
      }

    )



  })

  nameCol <- reactive({
    as.character(input$nameCol)
  })

  lonCol <- reactive({
    as.character(input$lonCol)
  })

  latCol <- reactive({
    as.character(input$latCol)
  })



  newUserData <- reactive({

    if (is.null(userData())) 
      return (NULL)

    # Create the new data frame:
    if (length(nameCol()) != 0 &&
        length(lonCol()) != 0 &&
        length(latCol()) != 0) {

      userData <- userData()

      name <- nameCol()
      lonCol <- lonCol()
      latCol <- latCol()

      results <- data.frame(Name = userData[, name], 
                            Longitude = userData[, lonCol], 
                            Latitude = userData[, latCol])

      results$Name <- as.character(results$Name)
      results$Longitude <- as.numeric(results$Longitude)
      results$Latitude <- as.numeric(results$Latitude)

    }

    results

  })

  mapData <- reactive({

    data <- data.frame()

    if (input$mapChoice == "New Map from Data Table") {

      if (length(nameCol()) != 0 &&
          length(lonCol()) != 0 &&
          length(latCol() != 0)) {
        data <- newUserData()
      }
    }
      data
    })

  output$.table <- DT::renderDataTable({

    datatable(mapData(), 
              extensions = c('Buttons', 'FixedHeader', 'Scroller'), 
              options = list(dom = 'Bfrtip', 
                             buttons = list('copy', 'print', 
                                            list(extend = 'csv', 
                                                 filename = 'map data', 
                                                 text = 'Download') 
                             ), 
                             scrollX = TRUE, 
                             pageLength = nrow(mapData()), 
                             fixedHeader = TRUE, 
                             deferRender = FALSE, 
                             scrollY = 400, 
                             scroller = FALSE, 
                             autowidth = TRUE
              )
    )

  }
  ) # End of table render

  }

shinyApp(ui = ui, server = server)

【讨论】:

    猜你喜欢
    • 2017-11-27
    • 1970-01-01
    • 2015-06-11
    • 1970-01-01
    • 1970-01-01
    • 2020-04-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多