Problemet er den måde, forespørgslen er opbygget på, når du kun vælger én element og brug IN operatør. dplyr oversættelse til SQL tilføjer ikke den rigtige parentes og fejler derfor. Dette spørgsmål blev diskuteret indgående her
.
En måde at omgå dette på er at sende en anden instruktion til filter() når length af input er lig med 1 (se eksempel nedenfor).
Her er, hvad der sker:
tbl(mydb, "iris") %>%
filter(Species %in% c("setosa", "versicolor")) %>%
.$query
Giver den korrekte SQL forespørgselssyntaks:
<Query> SELECT "Sepal.Length", "Sepal.Width", "Petal.Length", "Petal.Width", "Species"
FROM "iris"
WHERE "Species" IN ('setosa', 'versicolor')
<PostgreSQLConnection>
Og, hvis den udføres, giver den forventede:
#Source: postgres 9.3.13 [example@sqldat.com:5432/csvdump]
#From: iris [100 x 5]
#Filter: Species %in% c("setosa", "versicolor")
#
# Sepal.Length Sepal.Width Petal.Length Petal.Width Species
# (dbl) (dbl) (dbl) (dbl) (chr)
#1 5.1 3.5 1.4 0.2 setosa
#2 4.9 3.0 1.4 0.2 setosa
#3 4.7 3.2 1.3 0.2 setosa
#4 4.6 3.1 1.5 0.2 setosa
#5 5.0 3.6 1.4 0.2 setosa
#6 5.4 3.9 1.7 0.4 setosa
#7 4.6 3.4 1.4 0.3 setosa
#8 5.0 3.4 1.5 0.2 setosa
#9 4.4 2.9 1.4 0.2 setosa
#10 4.9 3.1 1.5 0.1 setosa
#.. ... ... ... ... ...
Lad os se, hvad der sker, hvis du prøver at sende et enkelt element:
tbl(mydb, "iris") %>%
filter(Species %in% "setosa") %>%
.$query
Forespørgslen vil være:
<Query> SELECT "Sepal.Length", "Sepal.Width", "Petal.Length", "Petal.Width", "Species"
FROM "iris"
WHERE "Species" IN 'setosa'
<PostgreSQLConnection>
Hvilket, hvis det udføres, vil resultere i følgende fejl:
Det er fordi for et enkelt element, dplyr oversættelse til SQL forespørgslen tilføjer ikke den rigtige parentes. Læg mærke til, hvordan det er 'setosa' i stedet for ('setosa') .
For at omgå det kan vi gøre:
if(length(input$Species) == 1) {
tbl(mydb, "iris") %>%
filter(Species == input$Species) %>%
}
Hvilket vil bygge en syntaktisk gyldig SQL forespørgsel:
<Query> SELECT "Sepal.Length", "Sepal.Width", "Petal.Length", "Petal.Width", "Species"
FROM "iris"
WHERE "Species" = 'setosa'
<PostgreSQLConnection>
Følgende eksempel løser dette problem. Her instruerer jeg blot appen til at bestå filter(Species == ...) hvis input$Species er af length 1 og filter(Species %in% ...) Ellers.
ShinyApp
server <- function(input, output) {
selectedQuery <- reactive({
if(length(input$Species) == 1) {
tbl(mydb, "iris") %>%
filter(Species == input$Species) %>%
.$query
}
else(
tbl(mydb, "iris") %>%
filter(Species %in% input$Species) %>%
.$query
)
})
selectedData <- reactive({
if(length(input$Species) == 1) {
tbl(mydb, "iris") %>%
filter(Species == input$Species) %>%
data.frame
}
else(
tbl(mydb, "iris") %>%
filter(Species %in% input$Species) %>%
data.frame
)
})
output$plot <- renderPlot({
ggplot2::qplot(Sepal.Length, Petal.Length, data = selectedData(), color = Species)
})
output$query <- renderPrint({
selectedQuery()
})
}
ui <- fluidPage(
sidebarLayout(
sidebarPanel(
selectInput("Species", "Species",
tbl(mydb, "iris") %>%
data.frame %>%
.$Species %>%
unique,
selected = "setosa", multiple = TRUE)
),
mainPanel(
textOutput("query"),
plotOutput("plot")
)
)
)
shinyApp(ui = ui, server = server)
