我正在尝试从一个表(“positons”)中选择具有特定列(“位置”)的值的行,这些值落在另一个(“my_ranges”)表中定义的范围内,然后添加分组来自“my_ranges”表的标记。
我可以使用tibbles和几个purrr::map2
调用来执行此操作,但相同的方法不适用于dbplyr database-tibbles。这是预期的行为,如果是这样的话,我应该采用不同的方法来使用dbplyr来完成这种任务吗?
这是我的例子:
library("tidyverse")
set.seed(42)
my_ranges <-
tibble(
group_id = c("a", "b", "c", "d"),
start = c(1, 7, 2, 25),
end = c(5, 23, 7, 29)
)
positions <-
tibble(
position = as.integer(runif(n = 100, min = 0, max = 30)),
annotation = stringi::stri_rand_strings(n = 100, length = 10)
)
# note: this works as I expect and returns a tibble with 106 obs of 3 variables:
result <- map2(.x = my_ranges$start, .y = my_ranges$end,
.f = function(x, y) {between(positions$position, x, y)}) %>%
map2(.y = my_ranges$group_id,
.f = function(x, y){
positions %>%
filter(x) %>%
mutate(group_id = y)}
) %>% bind_rows()
# next, make an in-memory db for testing:
con <- DBI::dbConnect(RSQLite::SQLite(), path = ":memory:")
# copy data to db
copy_to(con, my_ranges, "my_ranges", temporary = FALSE)
copy_to(con, positions, "positions", temporary = FALSE)
# get db-backed tibbles:
my_ranges_db <- tbl(con, "my_ranges")
positions_db <- tbl(con, "positions")
# note: this does not work as I expect, and instead returns a tibble with 0 obsevations of 0 variables:
# database range-based query:
db_result <- map2(.x = my_ranges_db$start, .y = my_ranges_db$end,
.f = function(x, y) {
between(positions_db$position, x, y)
}) %>%
map2(.y = my_ranges_db$group_id,
.f = function(x, y){
positions_db %>%
filter(x) %>%
mutate(group_id = y)}
) %>% bind_rows()
答案 0 :(得分:1)
dbplyr
将R
翻译为SQL
。 SQL
中不存在列表。 map
创建列表。因此,无法将map
转换为SQL
。
主要是dplyr
个函数和一些base
函数被翻译,他们正在研究tidyr
函数,正如我所理解的那样。使用dbplyr
尝试在您的方法中使用SQL
逻辑时,或者它很容易破坏。
答案 1 :(得分:0)
只要每次迭代都创建一个尺寸相同的表,那么可能会有一种巧妙的方法将整个操作推送到数据库。这个想法是同时使用import ReactDOM from "react-dom";
import { mock } from "jest";
import { renderToDOM } from "./index";
describe("test ReactDOM.render", () => {
const originalRender = ReactDOM.render;
const originalGetElement = global.document.getElementById;
beforeEach(() => {
global.document.getElementById = () => true;
ReactDOM.render = jest.fn();
});
afterAll(() => {
global.document.getElementById = originalGetElement;
ReactDOM.render = originalRender;
});
it("should call ReactDOM.render", () => {
renderToDOM();
expect(ReactDOM.render).toHaveBeenCalled();
});
});
中的map()
和reduce()
。每个purrr
操作都是惰性的,因此我们可以遍历它们而不必担心发送一堆查询,然后我们可以使用tbl_sql()
,它基本上将每次迭代使用的结果SQL附加到下一个给定数据库中的union()
子句。这是一个示例:
UNION