Vấn đề là cách truy vấn được tạo khi bạn chỉ chọn một và sử dụng IN
nhà điều hành. dplyr
dịch sang SQL
không thêm dấu ngoặc thích hợp và do đó, không thành công. Vấn đề này đã được thảo luận ở độ dài tại đây
.
Một cách để giải quyết vấn đề này là chuyển một hướng dẫn khác tới filter()
khi length
của đầu vào bằng 1 (xem ví dụ bên dưới).
Đây là những gì đang xảy ra:
tbl(mydb, "iris") %>%
filter(Species %in% c("setosa", "versicolor")) %>%
.$query
Cung cấp SQL
thích hợp cú pháp truy vấn:
<Query> SELECT "Sepal.Length", "Sepal.Width", "Petal.Length", "Petal.Width", "Species"
FROM "iris"
WHERE "Species" IN ('setosa', 'versicolor')
<PostgreSQLConnection>
Và, nếu được thực thi, sẽ cho kết quả như mong đợi:
#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
#.. ... ... ... ... ...
Hãy xem điều gì sẽ xảy ra nếu bạn cố gắng chuyển một phần tử duy nhất:
tbl(mydb, "iris") %>%
filter(Species %in% "setosa") %>%
.$query
Truy vấn sẽ là:
<Query> SELECT "Sepal.Length", "Sepal.Width", "Petal.Length", "Petal.Width", "Species"
FROM "iris"
WHERE "Species" IN 'setosa'
<PostgreSQLConnection>
Nếu được thực thi, sẽ dẫn đến lỗi sau:
Đó là bởi vì đối với một phần tử duy nhất, dplyr
dịch sang SQL
truy vấn không thêm dấu ngoặc đơn thích hợp. Lưu ý cách nó 'setosa'
thay vì ('setosa')
.
Để tránh điều đó, chúng ta có thể làm:
if(length(input$Species) == 1) {
tbl(mydb, "iris") %>%
filter(Species == input$Species) %>%
}
Điều này sẽ tạo ra một SQL
hợp lệ về mặt cú pháp truy vấn:
<Query> SELECT "Sepal.Length", "Sepal.Width", "Petal.Length", "Petal.Width", "Species"
FROM "iris"
WHERE "Species" = 'setosa'
<PostgreSQLConnection>
Ví dụ sau đây hoạt động xung quanh vấn đề này. Ở đây tôi chỉ hướng dẫn ứng dụng vượt qua bộ lọc filter(Species == ...)
if input$Species
có độ dài length
1 và bộ lọc filter(Species %in% ...)
nếu không thì.
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)