通过同一数据库中另一个 table 的 ID 过滤一个 SQLite 数据库 table 中的数据
Filter data in one SQLite database table by ids from another table in the same database
我有一个包含两个 table 的本地 SQLite 数据库。我想使用 dbplyr 从一个 table 根据来自另一个 table 的 id 过滤行进行查询。
例如,如果不涉及数据库,我会这样做:
# install.packages("tidyverse")
library(tidyverse)
data <-
tibble(id = seq(1, 8),
data = LETTERS[seq(1, 8)])
condition <-
tibble(id = seq(1, 8),
group = c(rep("low", 4), rep("high", 4)))
data %>%
filter(id %in% pull(condition %>%
filter(group == "high") %>%
select(id)))
这给了我
# A tibble: 4 × 2
id data
<int> <chr>
1 5 E
2 6 F
3 7 G
4 8 H
在数据库中使用与 tables 相同的代码,而不是在内存中使用 tibbles
# install.packages("RSQLite")
library(RSQLite)
test_db <-
dbConnect(RSQLite::SQLite(), "test_db.sqlite")
dbWriteTable(test_db, "data_tbl", data)
dbWriteTable(test_db, "condition_tbl", condition)
dbListTables(test_db)
data_db <-
tbl(test_db, "data_tbl")
condition_db <-
tbl(test_db, "condition_tbl")
data_db %>%
filter(id %in%
pull(condition_db %>%
filter(group == "high") %>%
select(id)))
产生以下错误:
Error in UseMethod("escape") :
not applicable method for 'escape' applied on object of class "c('tbl_SQLiteConnection', 'tbl_dbi', 'tbl_sql', 'tbl_lazy', 'tbl')"
当我首先在内存中加载 ID 时,查询工作没有问题。
detour <-
pull(condition_db %>%
filter(group == "high") %>%
select(id) %>%
collect())
data_db %>%
filter(id %in% detour)
# A tibble: 4 × 2
id data
<int> <chr>
1 5 E
2 6 F
3 7 G
4 8 H
因为 pull()
似乎是这里的问题 - 我如何在没有上面提供的“绕行”的情况下进行此类查询?
我在使用 dbplyr 时使用 semi-join 来解决这个问题。两个 table 之间的 semi-join returns 来自第一个 table 的每个记录,其中至少有一个与第二个 table 中的记录匹配。 (一个anti-join类似,返回第二个table中没有匹配的地方。)
这看起来像:
prepared_condition = condition %>%
filter(group == "high")
output = data %>%
semi_join(prepared_condition, by = "id")
我有一个包含两个 table 的本地 SQLite 数据库。我想使用 dbplyr 从一个 table 根据来自另一个 table 的 id 过滤行进行查询。
例如,如果不涉及数据库,我会这样做:
# install.packages("tidyverse")
library(tidyverse)
data <-
tibble(id = seq(1, 8),
data = LETTERS[seq(1, 8)])
condition <-
tibble(id = seq(1, 8),
group = c(rep("low", 4), rep("high", 4)))
data %>%
filter(id %in% pull(condition %>%
filter(group == "high") %>%
select(id)))
这给了我
# A tibble: 4 × 2
id data
<int> <chr>
1 5 E
2 6 F
3 7 G
4 8 H
在数据库中使用与 tables 相同的代码,而不是在内存中使用 tibbles
# install.packages("RSQLite")
library(RSQLite)
test_db <-
dbConnect(RSQLite::SQLite(), "test_db.sqlite")
dbWriteTable(test_db, "data_tbl", data)
dbWriteTable(test_db, "condition_tbl", condition)
dbListTables(test_db)
data_db <-
tbl(test_db, "data_tbl")
condition_db <-
tbl(test_db, "condition_tbl")
data_db %>%
filter(id %in%
pull(condition_db %>%
filter(group == "high") %>%
select(id)))
产生以下错误:
Error in UseMethod("escape") :
not applicable method for 'escape' applied on object of class "c('tbl_SQLiteConnection', 'tbl_dbi', 'tbl_sql', 'tbl_lazy', 'tbl')"
当我首先在内存中加载 ID 时,查询工作没有问题。
detour <-
pull(condition_db %>%
filter(group == "high") %>%
select(id) %>%
collect())
data_db %>%
filter(id %in% detour)
# A tibble: 4 × 2
id data
<int> <chr>
1 5 E
2 6 F
3 7 G
4 8 H
因为 pull()
似乎是这里的问题 - 我如何在没有上面提供的“绕行”的情况下进行此类查询?
我在使用 dbplyr 时使用 semi-join 来解决这个问题。两个 table 之间的 semi-join returns 来自第一个 table 的每个记录,其中至少有一个与第二个 table 中的记录匹配。 (一个anti-join类似,返回第二个table中没有匹配的地方。)
这看起来像:
prepared_condition = condition %>%
filter(group == "high")
output = data %>%
semi_join(prepared_condition, by = "id")