sql >> Database teknologi >  >> RDS >> PostgreSQL

multiple selectInput værdier skaber uventet dplyr (postgres) adfærd

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 [[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
#..          ...         ...          ...         ...     ...
 

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)
 


  1. Få en liste over datoer mellem to datoer ved hjælp af en funktion

  2. FEJL 1044 (42000):Adgang nægtet for 'root' med alle privilegier

  3. Opgradering fra PostGIS 2.1:Fejl:forsøg på at omdefinere parameteren postgis.backend

  4. Hvor indsætter jeg ORDER BY i min MYSQL-forespørgsel