是否可以在 dplyr 中进行完全连接并保留连接中使用的所有列?
Is it possible to do a full join in dplyr and keep all the columns used in the join?
我有两个表,我想使用 dplyr 进行完全连接,但我不希望它删除任何列。根据文档和我自己的经验,它只保留左侧的连接列。这是一个问题,当你有一行记录在右侧时,因为连接值消失了。
例如,假设我有两个表a和b,
customerId | revenue customerId | state
-----------|--------- -----------|-------
1 | 2000 1 | CA
2 | 3000 3 | GA
4 | 4000 4 | NY
做类似full_join(a, b, by="customerId")
的事情会产生
customerId | revenue | state
-----------|---------|-------
1 | 2000 | CA
2 | 3000 | <NA>
<NA> | <NA> | GA
4 | 4000 | NY
因此无法判断第三行来自哪个客户。理想的输出是
customerId.a | customerId.b | revenue | state
-------------|--------------|---------|-------
1 | 1 | 2000 | CA
2 | <NA> | 3000 | <NA>
<NA> | 3 | <NA> | GA
4 | 4 | 4000 | NY
请注意,这只是一个玩具示例。我实际上正在使用 sparklyr,所以这一切都在 Spark 中 运行。因此, merge 在这里对我不起作用。有没有办法在 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"))
我无法重现您的问题。所有 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
更新:我可以使用 sparklyr
重现问题。这是一种奇怪的行为,所以你可能想提出一个问题。 (不清楚问题是否出在 sparklyr
或 dplyr
或 DBI
或 Spark SQL。)
使用explain()
,可以看到生成的SQL。
full_join(d1_tbl, d2_tbl, by=c("customerId")) %>% explain()
您可以尝试 运行 自定义 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
您可以在 join:
之前为两个数据帧创建单独的相同 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
已修复
> full_join(d1_tbl, d2_tbl, by="customerId")
# Source: lazy query [?? x 3]
# Database: spark_connection
customerId revenue state
<chr> <dbl> <chr>
1 1 2000 CA
2 3 NaN GA
3 2 3000 <NA>
4 4 4000 NY
只需在dplyr::full_join()
中使用参数keep
即可。
full_join(a, b, by="customerId",keep = TRUE)
我有两个表,我想使用 dplyr 进行完全连接,但我不希望它删除任何列。根据文档和我自己的经验,它只保留左侧的连接列。这是一个问题,当你有一行记录在右侧时,因为连接值消失了。
例如,假设我有两个表a和b,
customerId | revenue customerId | state
-----------|--------- -----------|-------
1 | 2000 1 | CA
2 | 3000 3 | GA
4 | 4000 4 | NY
做类似full_join(a, b, by="customerId")
的事情会产生
customerId | revenue | state
-----------|---------|-------
1 | 2000 | CA
2 | 3000 | <NA>
<NA> | <NA> | GA
4 | 4000 | NY
因此无法判断第三行来自哪个客户。理想的输出是
customerId.a | customerId.b | revenue | state
-------------|--------------|---------|-------
1 | 1 | 2000 | CA
2 | <NA> | 3000 | <NA>
<NA> | 3 | <NA> | GA
4 | 4 | 4000 | NY
请注意,这只是一个玩具示例。我实际上正在使用 sparklyr,所以这一切都在 Spark 中 运行。因此, merge 在这里对我不起作用。有没有办法在 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"))
我无法重现您的问题。所有 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
更新:我可以使用 sparklyr
重现问题。这是一种奇怪的行为,所以你可能想提出一个问题。 (不清楚问题是否出在 sparklyr
或 dplyr
或 DBI
或 Spark SQL。)
使用explain()
,可以看到生成的SQL。
full_join(d1_tbl, d2_tbl, by=c("customerId")) %>% explain()
您可以尝试 运行 自定义 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
您可以在 join:
之前为两个数据帧创建单独的相同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
已修复
> full_join(d1_tbl, d2_tbl, by="customerId")
# Source: lazy query [?? x 3]
# Database: spark_connection
customerId revenue state
<chr> <dbl> <chr>
1 1 2000 CA
2 3 NaN GA
3 2 3000 <NA>
4 4 4000 NY
只需在dplyr::full_join()
中使用参数keep
即可。
full_join(a, b, by="customerId",keep = TRUE)