是否可以在dplyr中进行完全连接并保留连接中使用的所有列?

Dav*_*aid 2 r dplyr sparklyr

我有两个表,我想使用dplyr进行完全连接,但我不希望它删除任何列.根据文档和我自己的经验,它只保留左侧的连接列.由于连接值消失,当您有一个右侧记录的行时,这是一个问题.

例如,假设我有两个表a和b,

customerId | revenue               customerId | state
-----------|---------              -----------|-------
    1      | 2000                       1     |  CA
    2      | 3000                       3     |  GA
    4      | 4000                       4     |  NY
Run Code Online (Sandbox Code Playgroud)

做一些full_join(a, b, by="customerId")会产生的东西

customerId | revenue | state
-----------|---------|-------
    1      |   2000  |  CA
    2      |   3000  | <NA>
   <NA>    |   <NA>  |  GA
    4      |   4000  |  NY
Run Code Online (Sandbox Code Playgroud)

所以没有办法告诉第三行来自哪个客户.理想的输出是

customerId.a | customerId.b | revenue | state
-------------|--------------|---------|-------
      1      |      1       |   2000  |  CA
      2      |     <NA>     |   3000  | <NA>
    <NA>     |      3       |   <NA>  |  GA
      4      |      4       |   4000  |  NY
Run Code Online (Sandbox Code Playgroud)

请注意,这只是一个玩具示例.我实际上正在使用sparklyr所以这一切都在Spark中运行.因此,合并对我来说不起作用.有没有办法在dplyr中做我正在寻找的东西?

编辑:正如有人指出,这实际上是在本地dplyr本身的工作.但是,我确实使用sparklyr(使用dplyr)看到了这个问题.以下代码可以看到:

library(sparklyr)
sc <- spark_connect("local[4]")
d1 <- data_frame(customerId = c("1","2","4"), revenue=c(2000,3000,4000))
d2 <- data_frame(customerId = c("1","3","4"), state=c("CA", "GA", "NY"))
d1_tbl <- copy_to(sc, d1)
d2_tbl <- copy_to(sc, d2)
full_join(d1_tbl, d2_tbl, by=c("customerId"))
Run Code Online (Sandbox Code Playgroud)

Psi*_*dom 9

您可以customerId加入之前为两个数据框创建单独的相同内容:

full_join(
    mutate(a, customerId.a = customerId), 
    mutate(b, customerId.b = customerId), 
    by="customerId"
) %>% select(-customerId)

#  revenue customerId.a state customerId.b
#1    2000            1    CA            1
#2    3000            2  <NA>           NA
#3    4000            4    NY            4
#4      NA           NA    GA            3
Run Code Online (Sandbox Code Playgroud)

  • 这应该是公认的答案 - 问题要求保留两个表中的所有 _columns_,如果您想检查哪些行没有连接,您需要这样做,而不仅仅是包含连接键的所有值的一列. 这个答案是迄今为止最简单的方法。 (2认同)

Ric*_*ton 5

我无法重现你的问题。所有 ID 都应该(并且已经)包含在完整连接中。

library(data_frame)
d1 <- data_frame(
  customerId = c(1, 2, 4),
  revenue = c(2000, 3000, 4000)
)
d2 <- data_frame(
  customerId = c(1, 3, 4),
  state = c("CA", "GA", "NY")
)

full_join(d1, d2, by = "customerId")
## # A tibble: 4 × 3
##   customerId revenue state
##        <dbl>   <dbl> <chr>
## 1          1    2000    CA
## 2          2    3000  <NA>
## 3          4    4000    NY
## 4          3      NA    GA
Run Code Online (Sandbox Code Playgroud)

更新:我可以使用sparklyr. 这是奇怪的行为,所以你可能想提出一个问题。(不清楚是否该问题是否与sparklyrdplyrDBI或火花SQL虽然)。

使用explain(),您可以查看生成的 SQL。

full_join(d1_tbl, d2_tbl, by=c("customerId")) %>% explain()
Run Code Online (Sandbox Code Playgroud)

您可以尝试运行自定义 SQL 查询来获取您想要的内容,尽管它有点麻烦。

library(DBI)
qry <- "SELECT 
    d1.customerID AS customerID1, 
    d2.customerID AS customerID2, 
    d1.revenue, 
    d2.state 
  FROM d1 
  FULL JOIN d2 
    ON d1.customerId = d2.customerId"
dbGetQuery(sc, qry)  
##   customerID1 customerID2 revenue state
## 1           1           1    2000    CA
## 2           2        <NA>    3000  <NA>
## 3        <NA>           3     NaN    GA
## 4           4           4    4000    NY
Run Code Online (Sandbox Code Playgroud)