Masalahnya adalah cara kueri dibuat ketika Anda hanya memilih satu elemen dan gunakan IN operator. dplyr terjemahan ke SQL tidak menambahkan tanda kurung yang tepat dan dengan demikian, gagal. Masalah ini telah dibahas panjang lebar di sini
.
Salah satu cara untuk mengatasinya adalah dengan meneruskan instruksi yang berbeda ke filter() ketika length input sama dengan 1 (lihat contoh di bawah).
Inilah yang terjadi:
tbl(mydb, "iris") %>%
filter(Species %in% c("setosa", "versicolor")) %>%
.$query
Memberikan SQL yang tepat sintaks kueri:
<Query> SELECT "Sepal.Length", "Sepal.Width", "Petal.Length", "Petal.Width", "Species"
FROM "iris"
WHERE "Species" IN ('setosa', 'versicolor')
<PostgreSQLConnection>
Dan, jika dieksekusi, memberikan yang diharapkan:
#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
#.. ... ... ... ... ...
Mari lihat apa yang terjadi jika Anda mencoba melewati satu elemen:
tbl(mydb, "iris") %>%
filter(Species %in% "setosa") %>%
.$query
Kuerinya adalah:
<Query> SELECT "Sepal.Length", "Sepal.Width", "Petal.Length", "Petal.Width", "Species"
FROM "iris"
WHERE "Species" IN 'setosa'
<PostgreSQLConnection>
Yang, jika dijalankan, akan menghasilkan kesalahan berikut:
Itu karena untuk satu elemen, dplyr terjemahan ke SQL kueri tidak menambahkan tanda kurung yang tepat. Perhatikan bagaimana 'setosa' bukannya ('setosa') .
Untuk menghindarinya, kita dapat melakukan:
if(length(input$Species) == 1) {
tbl(mydb, "iris") %>%
filter(Species == input$Species) %>%
}
Yang akan membangun SQL yang valid secara sintaksis permintaan:
<Query> SELECT "Sepal.Length", "Sepal.Width", "Petal.Length", "Petal.Width", "Species"
FROM "iris"
WHERE "Species" = 'setosa'
<PostgreSQLConnection>
Contoh berikut mengatasi masalah ini. Di sini saya hanya menginstruksikan aplikasi untuk melewati filter(Species == ...) jika input$Species adalah length 1 dan filter(Species %in% ...) jika tidak.
Aplikasi Shiny
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)
