dplyr加入:在使用数据库时,如何进行非标准连接`col1`!=`col2`?

时间:2017-11-25 12:06:10

标签: r database dplyr dbplyr

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

实施例

设置数据库:

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中(&#34;展开_&#34;):     没有适用的方法来扩展_&#39;应用于课程&#34; c的对象(&#39; tbl_dbi&#39;,&#39; tbl_sql&#39;,&#39; tbl_lazy&#39;,&#39; tbl&#39;)&# 34;

有没有人知道在使用数据库时如何在dplyr代码中编码此连接?非常感谢提前。

1 个答案:

答案 0 :(得分:4)

我认为您无法正确理解by参数。

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

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

另请查看this question,了解有关dplyr中非equi连接主题的更多讨论。