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 [[email protected]: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)