选择性左接右



我想根据一个联合列和行的条件选择性地左联接两个数据帧。

我看到了一些使用fuzzyjoin和sqldf的类似帖子,但我发现之前的例子与我的不完全一样。

示例dfs:

df1 <- data.frame(id = c("1", "2", "3"),
zipcode = c("11111", "44444", "33333"),
exp.id = c("0", "0", "1"))
df2 <- data_frame(zipcode = c("11111", "22222", "33333", "44444", "55555"),
pct = c("0.1", "0.5", "0.9", "0.7", "0.8"))

基本上,我想加入";pct";列通过邮政编码从df2到df1,但仅在"处连接;exp.id"="0";

我期望的结果应该是这样的:

id    zipcode exp.id pct  
<chr> <chr>   <chr>  <chr>
1 1     11111   0      0.1  
2 2     44444   0      0.7  
3 3     33333   1      NA  

提前谢谢。

1(此左键将df1zipcode上的df2连接,但仅连接exp.id为0的行。对于其他行,pct是NA,如问题中所示的预期结果。请注意,dot是一个SQL运算符,因此我们用方括号将exp.id括起来以转义名称。

library(sqldf)
sqldf("select a.id, a.zipcode, b.pct
from df1 a 
left join df2 b on a.zipcode = b.zipcode and [exp.id] = 0")
##   id zipcode  pct
## 1  1   11111  0.1
## 2  2   44444  0.7
## 3  3   33333 <NA>

2(这与(1(类似,但只返回零的exp.id行。这与问题中的要求不同,但一条评论表明这很有意思。

这里的代码和(1(之间的差异说明了在onwhere中包括条件之间的细微差异。因为在这种情况下我们有一个简单的条件,所以我们可以使用using子句而不是onusing产生单个zipcode,因此我们不需要区分a.zipcodeb.zipcode

sqldf("select a.id, zipcode, b.pct
from df1 a left join df2 b using(zipcode)
where [exp.id] = 0")
##   id zipcode pct
## 1  1   11111 0.1
## 2  2   44444 0.7

请注意,SQL引擎在内部创建一个查询计划,以优化计算,同时保持相同的输出。它不一定按写入的顺序执行操作,也就是说,它不一定执行联接然后减少结果,但可以首先减少df1以提高性能,因为这会产生相同的结果。我们在下面显示了查询计划的信息,我们看到,实际上,它首先扫描df1

sqldf("explain query plan select a.id, zipcode, b.pct
from df1 a left join df2 b using(zipcode)
where [exp.id] = 0")
##   id parent notused                                                           detail
## 1  3      0       0                                              SCAN TABLE df1 AS a
## 2 16      0       0 SEARCH TABLE df2 AS b USING AUTOMATIC COVERING INDEX (zipcode=?)

连接数据并将pct值转换为NA,其中exp.id != 0

library(dplyr)
res <- df1 %>%
left_join(df2, by = 'zipcode') %>%
mutate(pct = replace(pct, exp.id != 0, NA))
res
#  id zipcode exp.id  pct
#1  1   11111      0  0.1
#2  2   44444      0  0.7
#3  3   33333      1 <NA>

在基地R-

res <- transform(merge(df1, df2, by = 'zipcode', all.x = TRUE), 
pct = replace(pct, exp.id != 0, NA))

此外,您只能在exp.id = 0处加入那些值。

df1 %>%
filter(exp.id == 0) %>%
left_join(df2, by = 'zipcode') %>%
right_join(df1)

相关内容

  • 没有找到相关文章

最新更新