你如何使用数据框、列表、向量等过滤到 R 数据库中的 table?

How do you filter with a Dataframe, list, vector etc. to a table in a database in R?

我有一大组 id-s 在 csv 文件中。如何仅使用 csv 文件中的单列 table 过滤数据库 table?

例如在 ODBC 数据库中我们有:

TABLE 1

+---------+------+
|   ID    | TYPE |
+---------+------+
| 43PRJIF | A    |
| 35IRPFJ | A    |
| 452JSU  | B    |
| 78JFIER | B    |
| 48IRUW  | C    |
| 89UEJDU | C    |
| 784NFJR | D    |
| 326NFR  | D    |
| 733ZREW | E    |
+---------+------+

在 CSV 文件中我们有:

+---------+
|   ID    |
+---------+
| 89UEJDU |
| 784NFJR |
| 326NFR  |
| 733ZREW |
+---------+

基本上,如果可能的话,我想使用 dbplyr 包中的东西。例如,将 csv table 导入数据框,然后在 dbplyr 中使用如下语法:

new_table <- TABLE1 %>%
filter(id == "ROWS IN THE CSV") 

要获得这样的输出:

+---------+------+
|   ID    | TYPE |
+---------+------+
| 89UEJDU | C    |
| 784NFJR | D    |
| 326NFR  | D    |
| 733ZREW | E    |
+---------+------+

提前感谢您的帮助!

快速解决方案是使用 merge 函数

示例:

table1 <- data.frame(
     ID = c("4322", "2245", "3356"),
    TYPE = c("B", "A", "A")
)

table2 <- data.frame(
    ID = c("2245")
)
table3 <- merge(table2, table1, all.x = TRUE, by = "ID")

ID    TYPE
2245    A

table3 是通过使用 table2

过滤 table1 创建的

一般来说,加入或合并 table 需要他们共享相同的环境。因此,这里有三个通用选项:

  1. 将远程 table 加载到 R 的本地工作区
  2. 将 CSV table 加载到数据库中并使用半连接。
  3. 'Smuggle' 将 CSV 中的 ID 列表导入数据库

让我们依次考虑:

选项 1

这可能是最简单的选项,但它要求 remote/ODBC table 足够小以适合 R 的工作内存。如果是,可以调用local_table = collect(remote_table)加载数据库table.

选项 2

dbplyr 包含一个命令 copy_to (ref),它允许您通过 odbc 将本地 tables 复制到 database/remote 连接。您需要具有在远程环境中创建 table 的权限。

这种方法使用了 DBI 包。在编写 CRAN 上的 DBI v1.0.0 时,在写入非默认模式时有一些限制。所以你可能需要在GitHub(here).

上升级到开发版

您的代码将类似于:

DBI::dbWriteTable(db_connection,
                  DBI::Id(schema = "schema", table = "name")),
                  r_table_name)

选项 3

通过 table 定义将 ID 列表走私到数据库中。这与 here 的想法相同,如果 ID 列表很短,效果最好。

远程 table 基本上由获取其结果的 code/query 定义。因此,ID 列表可以出现在定义遥控器的代码中 table。考虑以下示例:

library(dplyr)
library(dbplyr)
data(mtcars)

list_of_ids = c(1,2,3,4)
df = tbl_lazy(mtcars, con = simulate_mssql())
df %>% filter(ID %in% list_of_ids ) %>% show_query()

show_query() 呈现定义遥控器当前版本的代码 table。在上面的示例中,returns 以下 - 请注意 ID 列表现在出现在代码中。

<SQL>
SELECT *
FROM `df`
WHERE (`ID` IN (1.0, 2.0, 3.0, 4.0))

如果ID列表很长,这个查询的大小就会成为一个问题。因此,使用这种方法可以过滤的 ID 数量是有限制的(我没有测试这种方法来找到限制 - 我很少对超过 10 个的列表使用 IN 子句)。