【问题标题】:Get summary() of mytable from SQL database with R without writing it to my R session使用 R 从 SQL 数据库中获取 mytable 的 summary() 而不将其写入我的 R 会话
【发布时间】:2020-03-09 18:01:37
【问题描述】:

我想用 R 从 SQL 数据库中获取一个表, 我能做到,

df <- sqlQuery(channel, "select * from scheme.mytable1")

然后我想得到一个表格的汇总功能(我想看表格汇总)

summary(df)

我可以通过连接到 SQL db 并将表带到我的 R 会话来做到这一点 (将其视为 R 控制台中的表格作为 df)然后获取摘要(df)

但我想做的是,在不将其写入我的 R 会话的情况下查看其摘要 因为桌子太大了。 (百万列)我无法将其写入我的 R 会话。

但我只想查看其列的摘要。

summary(sqlQuery(channel, "select * from scheme.mytable1"))

我想做类似上面的事情(但代码不起作用,只是为了表明我的目的)

我该怎么做?任何包裹?任何功能?部署者?

谢谢!

【问题讨论】:

  • 我假设你的意思是数百万行?我无法想象你会想在有一百万列的表上调用 summary

标签: sql r database connection summary


【解决方案1】:

您可以做的一件事是利用dplyr::tbl 从数据源创建一个远程表,并编写您自己的summary 方法来完成数据库上的大部分计算。这可能是这样的:

library(dplyr)
library(tidyr)

# create a connection to table using dplyr, use dummy data 
# in memory SQLite here,in practice would do df <- tbl(con,  "mytable1")
con <- DBI::dbConnect(RSQLite::SQLite(), dbname = ":memory:")
copy_to(con, ggplot2::diamonds, "diamonds")
diamonds_db <- tbl(con,  "diamonds")

# create custom summary method for the connection
summary.tbl_SQLiteConnection <- function(object, ...) {
  suppressMessages({
    nums <- object %>% 
      summarise_if(
        is.numeric, 
        # can put whatever functions here
        # these should work for most DBs
        list(Min = min, Max = max, Mean = mean)
      ) %>% 
      collect() %>% 
      pivot_longer(everything()) %>% 
      mutate(name = stringi::stri_reverse(name)) %>% 
      separate(name, into = c("fun", "var"), sep = "_", extra = "merge") %>% 
      mutate_at(vars(var, fun), stringi::stri_reverse) %>% 
      mutate(val = paste0(fun, ": ", round(value, 2))) %>% 
      split(.$var) %>% 
      lapply(`[[`, "val")
    other_nms <- object %>% 
      select_if(~!is.numeric(.x)) %>% 
      head(1) %>% 
      collect() %>% 
      names()
    other <- lapply(other_nms, function(x) {
      x <- ensym(x)
      object %>% 
        group_by(!!x) %>% 
        tally() %>%
        arrange(desc(n)) %>%
        # only show top 10 values
        head(10) %>%
        collect() %>% 
        mutate(tmp = paste0(!!x, ": ", n)) %>% 
        pull(tmp)
    })
  })
  names(other) <- other_nms
  lst <- c(other, nums)
  # format similar to summary.data.frame 
  mat <- matrix(NA_character_, max(sapply(lst, length)), length(lst))
  for (i in seq_along(lst)) {
    for (j in seq_along(mat[, i])) {
      mat[j, i] <- lst[[i]][j]
    }
  }
  colnames(mat) <- names(lst)
  rownames(mat) <- rep("", dim(mat)[1])
  structure(mat, class = "table")
}

summary(diamonds_db)
#> cut              color    clarity    carat     depth       price        table       x          y          z         
#> Fair: 1610       D: 6775  I1: 741    Min: 0.2  Min: 43     Min: 326     Min: 43     Min: 0     Min: 0     Min: 0    
#> Good: 4906       E: 9797  IF: 1790   Max: 5.01 Max: 79     Max: 18823   Max: 95     Max: 10.74 Max: 58.9  Max: 31.8 
#> Ideal: 21551     F: 9542  SI1: 13065 Mean: 0.8 Mean: 61.75 Mean: 3932.8 Mean: 57.46 Mean: 5.73 Mean: 5.73 Mean: 3.54
#> Premium: 13791   G: 11292 SI2: 9194                                                                                 
#> Very Good: 12082 H: 8304  VS1: 8171                                                                                 
#>                  I: 5422  VS2: 12258                                                                                
#>                  J: 2808  VVS1: 3655                                                                                
#>                           VVS2: 5066 

我在一张太大而无法存储在内存中的桌子上试过这个,它奏效了。此函数与summary.data.frame 给出的函数完全不匹配,但应该是一个开始。

【讨论】:

  • 这部分能不能详细写一下? copy_to(con, ggplot2::diamonds, "diamonds") 我会写什么而不是 ggplot2::diamonds, "diamonds" ?
  • 您不需要这样做,因为该表已经存在于您的数据库中。您可以从df &lt;- tbl(con, "mytable1") 开始创建与您的表的远程连接
猜你喜欢
  • 2016-04-17
  • 1970-01-01
  • 2023-03-04
  • 1970-01-01
  • 2020-05-02
  • 2023-04-07
  • 1970-01-01
  • 1970-01-01
  • 2021-12-09
相关资源
最近更新 更多