dplyr:翻译R到SQL
基本数学运算: +, -, *, /, %%, ^
数学函数: abs, acos, acosh, asin, asinh, atan, atan2, atanh, ceiling, cos, cosh, cot, coth, exp, floor, log, log10, round, sign, sin, sinh, sqrt, tan, tanh
逻辑判断: <, <=, !=, >=, >, ==, %in%
异或判断: &, &&, |, ||, !, xor
聚合函数: mean, sum, min, max, sd, var
使用 explain
函数可以查看到对应的SQL翻译:
explain(your_dplyr_manipulation_chain)
pool:连接池管理
为什么在操作数据库上不是直接使用DBI
,而是要多加一层pool
呢?答案很简单,因为使用pool
可以做连接池的管理,复用链接提升性能。pool
为使用者提供了一个伪链接,如果是一条之前请求过的SQL,那么pool
会将之前请求过的数据直接返回而无需等待。
在Shiny
中,pool
会在所有session都结束的时候自动地回收资源而不需要其他操作。
这里是shiny官方blog上的一个例子:
library(shiny)
library(DBI)
library(pool)
pool <- dbPool(
drv = RMySQL::MySQL(),
dbname = "shinydemo",
host = "shiny-demo.csa7qlmguqrf.us-east-1.rds.amazonaws.com",
username = "guest",
password = "guest"
)
ui <- fluidPage(
textInput("ID", "Enter your ID:", "5"),
tableOutput("tbl"),
numericInput("nrows", "How many cities to show?", 10),
plotOutput("popPlot")
)
server <- function(input, output, session) {
output$tbl <- renderTable({
sql <- "SELECT * FROM City WHERE ID = ?id;"
query <- sqlInterpolate(pool, sql, id = input$ID)
dbGetQuery(pool, query)
})
output$popPlot <- renderPlot({
query <- paste0("SELECT * FROM City LIMIT ",
as.integer(input$nrows)[1], ";")
df <- dbGetQuery(pool, query)
pop <- df$Population
names(pop) <- df$Name
barplot(pop)
})
}
shinyApp(ui, server)
数据库操作之事务
原来的显示事务操作
conn <- poolCheckout(pool)
dbWithTransaction(conn, {
dbGetQuery(conn, A)
dbGetQuery(conn, B)
})
poolReturn(conn)
现在的隐式事务操作
dbWithTransaction(pool, {
dbGetQuery(pool, A)
dbGetQuery(pool, B)
})
输入异常处理
因为有了req
函数,我们可以在响应式代码块中轻松应对下面几类相似地空值判断:
FALSE
NULL
""
空的原子向量
仅仅包含缺失值的原子向量
try-error 类的对象中出现包含的 FALSE 的逻辑向量 (可见于 ?base::try)
是否点击了 actionButton
下面是shiny 官方博客中的一个例子:
library(shiny)
ui <- fluidPage(
selectInput("datasetName", "Dataset", c("", "pressure", "cars")),
plotOutput("plot"),
tableOutput("table")
)
server <- function(input, output, session) {
dataset <- reactive({
# Make sure requirements are met
req(input$datasetName)
get(input$datasetName, "package:datasets", inherits = FALSE)
})
output$plot <- renderPlot({
plot(dataset())
})
output$table <- renderTable({
head(dataset(), 10)
})
}
shinyApp(ui, server)