sql >> Databasteknik >  >> RDS >> PostgreSQL

multipla selectInput-värden skapar oväntat dplyr (postgres) beteende

Problemet är hur frågan är konstruerad när du bara väljer en element och använd IN operatör. dplyr översättning till SQL lägger inte till rätt parentes och misslyckas därmed. Den här frågan diskuterades utförligt här .

Ett sätt att kringgå detta är att skicka en annan instruktion till filter() när length av input är lika med 1 (se exempel nedan).

Det här är vad som händer:

tbl(mydb, "iris") %>%
  filter(Species %in% c("setosa", "versicolor")) %>%
  .$query

Ger rätt SQL frågesyntax:

<Query> SELECT "Sepal.Length", "Sepal.Width", "Petal.Length", "Petal.Width", "Species"
FROM "iris"
WHERE "Species" IN ('setosa', 'versicolor')
<PostgreSQLConnection>

Och, om den körs, ger den förväntade:

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

Låt se vad som händer om du försöker skicka ett enda element:

tbl(mydb, "iris") %>%
  filter(Species %in% "setosa") %>%
  .$query

Frågan blir:

<Query> SELECT "Sepal.Length", "Sepal.Width", "Petal.Length", "Petal.Width", "Species"
FROM "iris"
WHERE "Species" IN 'setosa'
<PostgreSQLConnection>

Vilket, om det körs, kommer att resultera i följande fel:

Det beror på att för ett enskilt element, dplyr översättning till SQL query lägger inte till rätt parentes. Lägg märke till hur det är 'setosa' istället för ('setosa') .

För att kringgå det kan vi göra:

if(length(input$Species) == 1) { 
  tbl(mydb, "iris") %>% 
    filter(Species == input$Species) %>% 
}

Vilket kommer att bygga en syntaktisk giltig SQL fråga:

<Query> SELECT "Sepal.Length", "Sepal.Width", "Petal.Length", "Petal.Width", "Species" 
FROM "iris" 
WHERE "Species" = 'setosa' 
<PostgreSQLConnection>

Följande exempel löser problemet. Här instruerar jag helt enkelt appen att passera filter(Species == ...) om input$Species är av length 1 och filter(Species %in% ...) annat.

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. Flera maxvärden i en fråga

  2. konvertera sql-tabellen i matrisform

  3. Java MySQL-integration med ArrayLists

  4. MySQL-replikering med ProxySQL på WHM/cPanel-servrar:del två