当我在遥远的Postgres
数据库上尝试一些代码时,收到以下错误消息。
以下的Peusdo再现代码在数据帧位于本地但远处时效果很好。
library(tidyverse)
library(dbplyr)
library(RPostgres)
event <- tibble(id = c("00_1", "00_2", "00_3", "00_4", "00_5", "00_6", "00_7"),
type_id = c("A", "B", "C", "B", "A", "B", "C"))
detail <- tibble(id = c(1L, 2L, 3L, 4L, 5L, 6L, 7L, 8L, 9L, 10L, 11L, 12L),
event_id = c("00_1", "00_1", "00_2", "00_2", "00_3", "00_4", "00_4", "00_5", "00_6", "00_6", "00_7", "00_8"),
type_id = c(3L, 4L, 6L, 7L, 2L, 6L, 3L, 2L, 6L, 5L, 2L, 1L))
event_f <- event %>%
mutate(new_variable = id %in% (detail %>%
filter(type_id == 6) %>%
pull(event_id))) %>%
collect()
Error in UseMethod("escape") : no applicable method for 'escape' applied to an object of class "c('tbl_PqConnection', 'tbl_dbi', 'tbl_sql', 'tbl_lazy', 'tbl')"
答案 0 :(得分:1)
该问题很可能是由嵌套dplyr查询引起的。这里有两种可能性:
dbplyr无法将查询转换为SQL,
dbplyr会翻译您的查询,但它不是有效的SQL。
dbplyr尝试将每组命令转换为SQL。一种验证方法是使用函数show_query()
。
例如R命令:
my_table %>% mutate(new_col = 2 * old_col + id) %>% select(new_col, id) %>% show_query()
将返回类似以下SQL命令的内容:
SELECT 2 * old_col + id AS new_col, id
FROM database.my_table
这仅在将R转换为SQL的情况下才会发生。因此:
如果show_query
返回SQL,则应查看该SQL以确定错误之处,并使用R命令更正此问题
如果show_query
没有返回或给出错误,则dbplyr无法转换您的查询,因此需要对其进行重组。
由于预计该问题是由嵌套的dplyr命令(detail %>% filter %>% pull)
引起的,因此我建议将其替换为semi_join,如下所示:
detail_f <- detail %>%
filter(type_id == 6)
event_f <- event %>%
semi_join(detail_f, by = c("id" = "type_id")) %>%
collect()
如果您不熟悉半联接,您可能会发现this帖子很有帮助。 R还支持使用反联接。
修改:误读了您的初始查询。
由于要在输出表中添加event_id
存在/不存在的指示符,因此可以避免半联接或反联接。也许像下面这样:
detail_f <- detail %>%
filter(type_id == 6) %>%
select(id_to_compare = event_id) %>%
mutate(new_variable = 1)
event_f <- event %>%
left_join(detail_f, by = c("id" = "id_to_compare")) %>%
mutate(new_variable = ifelse(is.na(new_variable), 0, new_variable) %>%
collect()
请注意,我在这里使用0和1代替了FALSE
和TRUE
,因为某些版本的SQL无法像R那样容易地处理它们。