如何使用 dplyr 包在 R 中使用连接的数据库?

Dav*_*íaz 1 r pool dplyr

我正在寻找一种使用 R 处理连接数据库的方法,这样我就不必将数据库上传到我的内存中。我一直在使用poolDBI包连接到数据库并dplyr进行数据操作,但我发现了一些我无法解决的问题:

加载数据:

library(pool)
library(dplyr)
library(RMariaDB)

my_db <- dbPool(
  MariaDB(),
  donate = "aaa",
  host = "localhost",
  username = "root"
)
Run Code Online (Sandbox Code Playgroud)

- 第一个问题:无法使用切片功能

my_db %>% tbl("bbb") %>%
  slice(2:10)
#Error: slice() is not supported on database backends
Run Code Online (Sandbox Code Playgroud)

对于这个问题我想出了这个解决方法:

my_db %>% tbl("bbb") %>%
  mutate(Rowindx = row_number()) %>%
  filter(Rowindx >= 2 && Rowindx <= 10) 
Run Code Online (Sandbox Code Playgroud)

这对我有用,但我想知道是否有更好的解决方案来解决这个问题

- 第二个问题:无法使用以下命令更改列的类或类型 transmute()

我有一个列类字符,我想将其更改为因子。我尝试过以下代码,它可以在没有连接的数据库的情况下工作。

my_db %>% tbl("bbb") %>%
  transmute (colname = factor(colname))
#Error: FUNCTION aaa.factor does not exist [1305]
Run Code Online (Sandbox Code Playgroud)

对于这个问题,我还没有想出任何解决方案,任何有关如何解决它的想法将不胜感激。

r2e*_*ans 5

  1. head作品:

    tbl(con, "mtcars") %>%
      filter(between(disp, 50, 200)) %>%
      head(3) %>%
      show_query()
    # <SQL>
    # SELECT TOP 3 *
    # FROM "mtcars"
    # WHERE ("disp" BETWEEN 50.0 AND 200.0)
    
    Run Code Online (Sandbox Code Playgroud)

    (我正在针对 SQL Server 进行演示,它使用的SELECT TOP 3不是所有其他 DBMS 的标准SELECT ... LIMIT 3。)

    当然,这并不能立即提供执行诸如 之类的子集的能力2:10,但如果您希望做的只是删除第一行,那么我建议您可以slice(-1)(在本例中)在collect将数据完全导入 R 后(其中应在完成其他过滤后进行,以减少下载的数据)。

    请注意,这是一个通用切片/ head,而不是每组切片,以防您考虑这样做。在 R/ 中dplyr,每个组通常更愿意成为%>% do(head(10))(返回每个组的前 10 行)副%>% head(10)(返回所有数据的前 10 行,无论组如何)。我还没发现do(head(3))可以在 SQL 中工作(尽管我的测试受到限制)。

    作为附带评论,您没有提到对数据进行排序,并且通常无法保证查询中数据的顺序;如果您有特定的订单要求,则应该具体。如果您不这样做,那么可能无法保证您始终获得所需的行。当然,我并不是说它是随机的,但 DBMS 中存储的数据顺序是有意的,由许多因素决定,包括表上构建的索引。如果您不了解所有这些内容并且了解 DBMS 的详细情况,那么最好在考虑切片之前确保顺序。

  2. 一般来说(dplyr,不是dbplyr),filter(Rowindx >= 2 && Rowindx <= 10)是错误/损坏的。使用filter(Rowindx >= 2 & Rowindx <= 10)(单个&,而不是双重)或filter(between(Rowindex, 2, 10)). 虽然它仍然可以工作dbplyr(两者&&&映射到 SQL's AND),但当建议使用向量时,在 R 中使用它有点懒惰/草率。(dplyr::between也映射到 SQL BETWEEN,所以无论如何,这里可能会更好。)

  3. 的概念factor在 SQL 中没有通用的等价物,至少不是以我相信您想要的方式使用它。这是一个R的事情。因此,我建议您mutatefilter您需要的内容,当您确信您只需要所需的行/列时,然后是collect()您的数据(将所有行检索到 R 中),然后 transmutefactor.