3

('col1' != 'col2')当您使用数据库时,如何在 dplyr 中进行非标准连接。

例子:

设置数据库:

library(dplyr)

con <- DBI::dbConnect(RSQLite::SQLite(), ":memory:")

tableA <- data.frame(col1= c("a","b","c","d"),
                     col2 = c(1,2,3,4))

copy_to(con, tableA)

这是在使用数据库时我想使用 dplyr 代码执行的 sql 连接:

SQL 代码:

tbl(con, sql("select a.col1, b.col2
              from 
              tableA as a
              inner join 
              tableA as b
              on a.col1 <> b.col1")) %>% 
 arrange(col1, col2)

结果:

# Source:     SQL [?? x 2]
# Database:   sqlite 3.19.3 [:memory:]
# Ordered by: col1, col2
     col1  col2
    <chr> <dbl
1     a     2
2     a     3
3     a     4
4     b     1
5     b     3
6     b     4
7     c     1
8     c     2
9     c     4
10     d     1
# ... with more rows

dplyr 代码:

这是我在重新创建上面的 sql 代码时尝试的初始 dplyr 代码:

tbl(con,"tableA")->dbtableA

dbtableA %>% 
  inner_join(dbtableA, by = c('col1' != 'col1')) %>% 
  select(col1, col2=col2.x) %>% 
  arrange(col1, col2)

错误:by对于自然连接,必须是(命名的)字符向量、列表或 NULL(不推荐在生产代码中使用),不符合逻辑

尝试使用 tidyr 包(下面的代码)解决此问题时,我收到一条错误消息:

library(tidyr)

dbtableA %>% 
  expand(col1,col2) %>% 
  left_join(dbtableA, by = 'col1') %>%
  filter(col2.x != col2.y) %>% 
  select(col1, col2 = col2.x) %>% 
  arrange(col1, col2)

错误:在 UseMethod("expand_") 中:没有适用于 'expand_' 的方法应用于类“c('tbl_dbi', 'tbl_sql', 'tbl_lazy', 'tbl')”的对象

有谁知道在使用数据库时如何在 dplyr 代码中编写这个连接?提前谢谢了。

4

1 回答 1

4

我认为你没有by正确理解这个论点。

by = c("col1" = "col2"), =is不是和相等运算符,而是一个赋值运算符(R 中的相等运算符是==)。里面的表达式c(...)创建了一个命名的字符向量(名称:col1col2:),dplyr 将其用于连接。您没有定义在连接期间进行的比较类型,比较在 dplyr 中是硬编码的。我不认为 dplyr 支持非 equi 连接(还)。

by = c("col1" != "col2")!=是不等式运算符。所以你的陈述与写作相同by = TRUE(这是荒谬的)。

另请查看此问题,以获取有关 dplyr 中非 equi 连接主题的更多讨论。

于 2017-11-25T12:20:22.793 回答