五位数汇总(含dbplyr)

m0rkklqb  于 2021-06-26  发布在  Impala
关注(0)|答案(1)|浏览(571)

我有4年的经验,使用r,但我是非常新的大数据游戏,因为我总是在csv文件工作。
从远处操纵大量的数据是令人兴奋的,但也不知何故挫败了你过去习惯的简单的事情是要重新设计的。
我现在的任务是对一个变量进行一个5位数的总结:

summary(df$X)

在某些情况下,我与 Impala 有关,这些代码行很好:

library(dbplyr)
localTable <- tbl(con, 'serverTable')
localTable %>% tally()
localTable %>% filter(X > 10) %>% tally()

如果我只是写信

localTable

相反,rstudio会被卡住/占用很多时间,所以我使用任务管理器抑制它。
回到我现在的问题,我试着用以下方式总结出5位数:

summary(localTable$X) #returns Length 0, Class NULL, Mode NULL
localTable %>% fivenum(X) #returns Error in rank(x, ties.method = "min", na.last = "keep") : unimplemented type 'list' in 'greater'

同时使用summary生成自定义summary()

localTable %>% summarize(Min = min(X),
         Q1 = quantile(X, .25),
         Avg = mean(X), 
         Q3 = quantile(X, .75),
         Max = max(X))

返回语法错误。
我的猜测是,我的代码和服务器之间以数据结构的形式缺少一个非常微不足道的链接,但我不知道是什么。
我还尝试将localtable$x保存到内存中的变量

XL <- localTable$X

但我总是得到一个空值
在图形方面,如果我尝试使用dbplot

library(dbplot)
localTable %>% dbplot_histogram(X)

我得到一个空的图形。
我考虑过利用boxplot函数中的5位数摘要,ggplotbuild(object)$data也可以这么说,但是使用dbplot\u boxplot我得到的错误是找不到函数“dbplot\u boxplot”。
我开始使用dbplyr是因为我对dplyr非常熟练,我不想用dbi::dbgetquery在sql中编写查询,但是您可以推荐其他包,如implyr、sparklyr或类似的,以及关于这个主题的教程,因为我发现这些都是非常基本的。
编辑:
根据评论中的要求,我添加了

str(localTable)

哪个是

List of 2 
$ src:List of 2
      ..$ con  :Formal class 'Impala' [package ".GlobalEnv"] with 4 slots
      .. .. ..@ ptr     :<externalptr> 
      .. .. ..@ quote   : chr "`"
      .. .. ..@ info    :List of 15
      .. .. .. ..$ dbname                       : chr "IMPALA"
      .. .. .. ..$ dbms.name                    : chr "Impala"
      .. .. .. ..$ db.version                   : chr "2.9.0-cdh5.12.1"
      .. .. .. ..$ username                     : chr "User"
      .. .. .. ..$ host                         : chr ""
      .. .. .. ..$ port                         : chr ""
      .. .. .. ..$ sourcename                   : chr "impala connector"
      .. .. .. ..$ servername                   : chr "Impala"
      .. .. .. ..$ drivername                   : chr "Cloudera ODBC Driver for Impala"
      .. .. .. ..$ odbc.version                 : chr "03.80.0000"
      .. .. .. ..$ driver.version               : chr "2.6.11.1011"
      .. .. .. ..$ odbcdriver.version           : chr "03.80"
      .. .. .. ..$ supports.transactions        : logi FALSE
      .. .. .. ..$ getdata.extensions.any_column: logi TRUE
      .. .. .. ..$ getdata.extensions.any_order : logi TRUE
      .. .. .. ..- attr(*, "class")= chr [1:3] "Impala" "driver_info" "list"
      .. .. ..@ encoding: chr ""
      ..$ disco: NULL
      ..- attr(*, "class")= chr [1:4] "src_Impala" "src_dbi" "src_sql" "src"
     $ ops:List of 2
      ..$ x   : 'ident' chr "serverTable"
      ..$ vars: chr [1:157] "X" ...
      ..- attr(*, "class")= chr [1:3] "op_base_remote" "op_base" "op"
     - attr(*, "class")= chr [1:5] "tbl_Impala" "tbl_dbi" "tbl_sql" "tbl_lazy" ...

我不确定是否可以输出我的表,因为它是敏感信息

uqdfh47h

uqdfh47h1#

你的帖子有很多方面。我将尝试解决主要问题。
(1) 你在叫什么 localTable 不是本地的。您拥有的是远程表的本地访问点。它是一个远程表,因为数据存储在数据库中,而不是r中。
要将远程表复制到本地r内存中,请使用 localTable = collect(remoteTable) . 小心使用。如果数据库中的表有很多gb,那么传输到r的速度会很慢。如果你 collect 如果数据库表大于r可用的ram,则会收到内存不足错误。
我建议使用 collect 将摘要结果移动到r。在数据库中进行处理和汇总,并将结果放入r。或者,使用 remoteTable %>% head(20) %>% collect() 将前20行复制到r中。
(2) 那个 tableName$colname 不适用于远程表。在r中 $ 表示法允许您访问列表的命名组件。data.frames是一种特殊的列表。如果你尝试 data(iris) 然后 names(iris) 你将得到iris的列名。其中任何一个都可以使用 iris$ .
但是作为你的 str(localTable) 显示, localTable 是长度为2的列表,其中包含第一个命名项 src . 如果你打电话 names(localTable) 然后你会收到两个名字,第一个是 src . 这意味着你可以打电话 localTable$src (以及 localTable$src 也是一个列表,您也可以调用 localTable$src$con ).
使用dbplyr时,r将数据操作命令转换为数据库语言。大多数dplyr命令都定义了翻译,但是没有为所有r命令定义翻译。
因此,建议只访问特定列的方法是 select 来自dplyr:

local_copy_of_just_one_column = remoteTable %>%
  select(required_column) %>%
  collect()

(3) 使用自定义摘要函数的方法是正确的。这是在不将数据拉入本地内存(ram)的情况下生成五位数摘要的最佳方法。
语法错误的一个可能原因是您使用的r命令没有翻译成您的数据库语言。
您可以检查命令是否使用 translate_sql . 我建议你试试

library(dbplyr)
translate_sql(quantile(colname, 0.25))

看看译文是什么样子。
可以使用查看整个表操作的转换 show_query . 这是我调试sql翻译时的常用方法。尝试:

localTable %>%
  summarize(Min = min(X),
            Q1 = quantile(X, .25),
            Avg = mean(X), 
            Q3 = quantile(X, .75),
            Max = max(X)) %>%
  show_query()

如果这不能生成有效的sql,那么执行该命令将出错。
一个可能的原因是 Min 以及 Max 在sql中有特殊的含义,因此在翻译中可能会产生奇怪的行为。
当我尝试 quantile 看起来它可能需要一个 OVER sql中的子句。这是使用 group_by . 所以,也许你想要以下的东西:

localSummary = remoteTable %>%
  # create dummy column
  mutate(ones = 1) %>%
  # group to satisfy over clause
  group_by(ones) %>%
  summarise(var_min = min(var),
            var_lq = quantile(var, 0.25),
            var_mean = mean(var),
            var_uq = quantile(var, 0.75),
            var_max = max(var)) %>%
  # copy results from database into R memory
  collect()

相关问题