r - 空 textInput() 导致传单闪亮应用程序出错
r - Empty textInput() causing error in leaflet shiny app
我有一个闪亮的应用程序,可以在传单地图上绘制来自 API 的数据。它还需要来自用户的 2 个输入,这些输入被传递到 API call
。
其中一个是文本输入,用于设置 API
应为其提取数据的区域。如果用户输入了不正确的区域代码或简单地删除了代码,闪亮的应用程序会给出错误,然后您必须输入正确的代码并等待应用程序回到正轨。它很笨拙,看起来很糟糕。
我试图通过使用 if(is.null(APIdata()))
和 if{}else{}
来绕过它(见下面的代码),但这实际上并没有改变任何东西。我认为它会起作用,而且我对它只是跳回到一张空的传单的想法很好。还有什么我可以做的吗?
错误:
Error: parse error: premature EOF
(right here) ------^
和
Warning: Error in : parse error: premature EOF
(right here) ------^
Stack trace (innermost first):
96: parse_string
95: parseJSON
94: fromJSON_string
93: jsonlite::fromJSON
92: ebird_GET
91: ebirdnotable
90: <reactive:APIdata> [/Users/Guest/Desktop/eBirdRarity/app.R#41]
79: APIdata
78: func [/Users/Guest/Desktop/eBirdRarity/app.R#68]
77: origRenderFunc
76: output$myMap
1: runApp
代码:
library(shiny)
library(shinydashboard)
library(shinythemes)
library(leaflet)
library(leaflet.extras)
library(rebird)
ui <- bootstrapPage(
theme = shinytheme("superhero"),
# Setting map to full-screen
tags$style(type="text/css", "html, body {width:100%;height:100%}"),
# Initializing leaflet output
leafletOutput("myMap", width="100%", height="100%"),
# Adding title overlayed on leaflet map
absolutePanel(top = 1, left = 50, draggable = T,
titlePanel("eBird Recent Rarities Viewer")),
# Adding slider input overlayed on leaflet map
absolutePanel(bottom = 1, left = 45, draggable = T,
sliderInput("slider_in", "Days Back", min = 1, max = 30, value = 14, round = T)),
# Adding text input overlayed on leaflet map
absolutePanel(top = 1, right = 45, draggable = T,
textInput("region_in", "Region Code", value = "US-MA", placeholder = "US-MA"))
)
server <- function(input, output) {
# Rendering data frame from API with slider input
APIdata <- reactive({
# Initial fetch of data from eBird API
a <- ebirdnotable(region = as.character(input$region_in), back = as.numeric(input$slider_in))
# Changing review status from logical to numeric
cols <- sapply(a, is.logical)
a[,cols] <- lapply(a[,cols], as.numeric)
# Initializing new date column
a["date"] <- format(strptime(a$obsDt, format = "%Y-%m-%d"), "%b %d")
# Initializing new color grouping column
a["group"] <- NA
# Assigning colors by review status
idx<- (a$obsReviewed == 0) # Not reviewed
a$group[idx] <- "white"
idx<- (a$obsReviewed == 1) & (a$obsValid == 1) # Reviewed and accepted
a$group[idx] <- "green"
# Jittering lat/lon points to fix point overlap
a$lat = jitter(a$lat, factor = 3)
# print(a)
return(a)
})
# Leaflet map
output$myMap = renderLeaflet({
if(is.null(APIdata()))
{
# Rendering leaflet map
return(leaflet() %>% addTiles()) %>%
addSearchOSM(options = searchOSMOptions(zoom = 8))
}
else
{
# Splitting up by review status in order to show reviewed on top
notReviewed = APIdata()[APIdata()$group == "white",]
accepted = APIdata()[APIdata()$group == "green",]
# Rendering leaflet map
leaflet() %>% addTiles() %>%
addCircleMarkers(data = notReviewed, color = "white", opacity = 0.7, label = paste(notReviewed$comName,", ",notReviewed$date, ", ", notReviewed$locName,sep = "")) %>% # , labelOptions = labelOptions(noHide = F, direction = 'auto')) %>%
addCircleMarkers(data = accepted, color = "green", opacity = 0.7, label = paste(accepted$comName,", ",accepted$date, ", ", accepted$locName, sep = "")) %>% # , labelOptions = labelOptions(noHide = F, direction = 'auto')) %>%
addLegend(position = "bottomright",
colors = c("#FFFFFF", "#008000"),
labels = c("Not reviewed", "Accepted"),
title = "Legend: review status", opacity = 1) %>%
addSearchOSM(options = searchOSMOptions(zoom = 8))
}
})
}
# Run the application
shinyApp(ui = ui, server = server)
您可以只验证您得到的是带值的 tibble
还是空的 tibble
。如果 tibble
为空,您可以 return NULL
。这样,您添加的用于检查 APIdata()
是否为 NULL
的验证就可以工作了。
您可以在反应式中的 a <- ebirdnotable(region = as.character(input$region_in), back = as.numeric(input$slider_in))
之后添加 if(length(a) == 0){return(NULL)}
以使其起作用。
编辑:
正如您在评论中提到的,您实际上可以在此处使用 try
。这意味着除了上述条件之外还要添加一个条件,代码将如下所示:
a <- try(ebirdnotable(region = as.character(input$region_in), back = as.numeric(input$slider_in)))
if(class(a) == "try-error" ||length(a) == 0){return(NULL)}
希望对您有所帮助!
我有一个闪亮的应用程序,可以在传单地图上绘制来自 API 的数据。它还需要来自用户的 2 个输入,这些输入被传递到 API call
。
其中一个是文本输入,用于设置 API
应为其提取数据的区域。如果用户输入了不正确的区域代码或简单地删除了代码,闪亮的应用程序会给出错误,然后您必须输入正确的代码并等待应用程序回到正轨。它很笨拙,看起来很糟糕。
我试图通过使用 if(is.null(APIdata()))
和 if{}else{}
来绕过它(见下面的代码),但这实际上并没有改变任何东西。我认为它会起作用,而且我对它只是跳回到一张空的传单的想法很好。还有什么我可以做的吗?
错误:
Error: parse error: premature EOF
(right here) ------^
和
Warning: Error in : parse error: premature EOF
(right here) ------^
Stack trace (innermost first):
96: parse_string
95: parseJSON
94: fromJSON_string
93: jsonlite::fromJSON
92: ebird_GET
91: ebirdnotable
90: <reactive:APIdata> [/Users/Guest/Desktop/eBirdRarity/app.R#41]
79: APIdata
78: func [/Users/Guest/Desktop/eBirdRarity/app.R#68]
77: origRenderFunc
76: output$myMap
1: runApp
代码:
library(shiny)
library(shinydashboard)
library(shinythemes)
library(leaflet)
library(leaflet.extras)
library(rebird)
ui <- bootstrapPage(
theme = shinytheme("superhero"),
# Setting map to full-screen
tags$style(type="text/css", "html, body {width:100%;height:100%}"),
# Initializing leaflet output
leafletOutput("myMap", width="100%", height="100%"),
# Adding title overlayed on leaflet map
absolutePanel(top = 1, left = 50, draggable = T,
titlePanel("eBird Recent Rarities Viewer")),
# Adding slider input overlayed on leaflet map
absolutePanel(bottom = 1, left = 45, draggable = T,
sliderInput("slider_in", "Days Back", min = 1, max = 30, value = 14, round = T)),
# Adding text input overlayed on leaflet map
absolutePanel(top = 1, right = 45, draggable = T,
textInput("region_in", "Region Code", value = "US-MA", placeholder = "US-MA"))
)
server <- function(input, output) {
# Rendering data frame from API with slider input
APIdata <- reactive({
# Initial fetch of data from eBird API
a <- ebirdnotable(region = as.character(input$region_in), back = as.numeric(input$slider_in))
# Changing review status from logical to numeric
cols <- sapply(a, is.logical)
a[,cols] <- lapply(a[,cols], as.numeric)
# Initializing new date column
a["date"] <- format(strptime(a$obsDt, format = "%Y-%m-%d"), "%b %d")
# Initializing new color grouping column
a["group"] <- NA
# Assigning colors by review status
idx<- (a$obsReviewed == 0) # Not reviewed
a$group[idx] <- "white"
idx<- (a$obsReviewed == 1) & (a$obsValid == 1) # Reviewed and accepted
a$group[idx] <- "green"
# Jittering lat/lon points to fix point overlap
a$lat = jitter(a$lat, factor = 3)
# print(a)
return(a)
})
# Leaflet map
output$myMap = renderLeaflet({
if(is.null(APIdata()))
{
# Rendering leaflet map
return(leaflet() %>% addTiles()) %>%
addSearchOSM(options = searchOSMOptions(zoom = 8))
}
else
{
# Splitting up by review status in order to show reviewed on top
notReviewed = APIdata()[APIdata()$group == "white",]
accepted = APIdata()[APIdata()$group == "green",]
# Rendering leaflet map
leaflet() %>% addTiles() %>%
addCircleMarkers(data = notReviewed, color = "white", opacity = 0.7, label = paste(notReviewed$comName,", ",notReviewed$date, ", ", notReviewed$locName,sep = "")) %>% # , labelOptions = labelOptions(noHide = F, direction = 'auto')) %>%
addCircleMarkers(data = accepted, color = "green", opacity = 0.7, label = paste(accepted$comName,", ",accepted$date, ", ", accepted$locName, sep = "")) %>% # , labelOptions = labelOptions(noHide = F, direction = 'auto')) %>%
addLegend(position = "bottomright",
colors = c("#FFFFFF", "#008000"),
labels = c("Not reviewed", "Accepted"),
title = "Legend: review status", opacity = 1) %>%
addSearchOSM(options = searchOSMOptions(zoom = 8))
}
})
}
# Run the application
shinyApp(ui = ui, server = server)
您可以只验证您得到的是带值的 tibble
还是空的 tibble
。如果 tibble
为空,您可以 return NULL
。这样,您添加的用于检查 APIdata()
是否为 NULL
的验证就可以工作了。
您可以在反应式中的 a <- ebirdnotable(region = as.character(input$region_in), back = as.numeric(input$slider_in))
之后添加 if(length(a) == 0){return(NULL)}
以使其起作用。
编辑:
正如您在评论中提到的,您实际上可以在此处使用 try
。这意味着除了上述条件之外还要添加一个条件,代码将如下所示:
a <- try(ebirdnotable(region = as.character(input$region_in), back = as.numeric(input$slider_in)))
if(class(a) == "try-error" ||length(a) == 0){return(NULL)}
希望对您有所帮助!