当您使用数据库时,如何在 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)
Error:
by
must be a (named) character vector, list, or NULL for natural joins (not recommended in production code), not logical
当尝试使用 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)
Error: in UseMethod("expand_") : no applicable method for 'expand_' applied to an object of class "c('tbl_dbi', 'tbl_sql', 'tbl_lazy', 'tbl')"
有谁知道在使用数据库时如何在 dplyr 代码中编写此连接?非常感谢。
最佳答案
我认为您没有正确理解 by
参数。
在by = c("col1"= "col2")
中,=
不是和相等运算符,而是一个赋值运算符( R 中的相等运算符是 ==
)。 c(...)
中的表达式创建一个命名的字符向量(名称:col1
值:col2
),dplyr 将其用于连接。您没有在任何地方定义连接期间进行的比较类型,比较是在 dplyr 中硬编码的。我不认为 dplyr 支持非 equi 连接(还)。
在by = c("col1"!= "col2")
中,!=
是不等式运算符。因此,您的陈述与编写 by = TRUE
相同(这是荒谬的)。
另请查看 this question有关 dplyr 中非 equi 连接主题的更多讨论。
关于r - 使用数据库时 dplyr 加入 : How do you do a non standard join `col1` ! = `col2`?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47485779/