【发布时间】: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