你如何使用数据框、列表、向量等过滤到 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 需要他们共享相同的环境。因此,这里有三个通用选项:
- 将远程 table 加载到 R 的本地工作区
- 将 CSV table 加载到数据库中并使用半连接。
- '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
子句)。
我有一大组 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 需要他们共享相同的环境。因此,这里有三个通用选项:
- 将远程 table 加载到 R 的本地工作区
- 将 CSV table 加载到数据库中并使用半连接。
- '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
子句)。