选择性左加入 r
Selective left join in r
我想根据联合列和行的条件有选择地左连接两个数据框。
我看到一些类似的帖子使用 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"))
基本上,我想通过邮政编码将 df2 中的“pct”列加入到 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
提前致谢。
加入数据并将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)
1) 这左连接 df1
和 zipcode
上的 df2
但仅连接 exp.id
为 0 的行. 对于其他行 pct
是 NA,如问题中所示的预期结果。请注意,点是一个 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),但 returns 只有 exp.id
行为零。这与问题中要求的不同,但评论表明它很有趣。
这里的代码和 (1) 之间的区别说明了在 on
和 where
中包含条件之间的细微差别。因为在这种情况下我们有一个简单的条件,所以我们可以使用 using
子句而不是 on
。 using
结果是一个 zipcode
所以我们不需要区分 a.zipcode
和 b.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=?)
我想根据联合列和行的条件有选择地左连接两个数据框。
我看到一些类似的帖子使用 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"))
基本上,我想通过邮政编码将 df2 中的“pct”列加入到 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
提前致谢。
加入数据并将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)
1) 这左连接 df1
和 zipcode
上的 df2
但仅连接 exp.id
为 0 的行. 对于其他行 pct
是 NA,如问题中所示的预期结果。请注意,点是一个 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),但 returns 只有 exp.id
行为零。这与问题中要求的不同,但评论表明它很有趣。
这里的代码和 (1) 之间的区别说明了在 on
和 where
中包含条件之间的细微差别。因为在这种情况下我们有一个简单的条件,所以我们可以使用 using
子句而不是 on
。 using
结果是一个 zipcode
所以我们不需要区分 a.zipcode
和 b.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=?)