left_join 两个数据帧并覆盖
Posted
技术标签:
【中文标题】left_join 两个数据帧并覆盖【英文标题】:left_join two data frames and overwrite 【发布时间】:2016-02-25 20:00:20 【问题描述】:我想合并两个数据帧,其中df2
覆盖NA
或df1
中的任何值。 Merge data frames and overwrite values 提供了一个data.table
选项,但我想知道是否有办法使用dplyr
来做到这一点。我已经尝试了所有_join
选项,但似乎都没有这样做。有没有办法用dplyr
做到这一点?
这是一个例子:
df1 <- data.frame(y = c("A", "B", "C", "D"), x1 = c(1,2,NA, 4))
df2 <- data.frame(y = c("A", "B", "C"), x1 = c(5, 6, 7))
期望的输出:
y x1
1 A 5
2 B 6
3 C 7
4 D 4
【问题讨论】:
left_join(df1, df2, by="y") %>% transmute(y, x1 = ifelse(is.na(x1.y), x1.x, x1.y))
?也许这可以添加到另一个答案中,而这个答案被骗了? (另一个不是data.table的具体问题)
【参考方案1】:
我认为您想要的是保留 df2
的值,并且只添加 df1
中不存在于 df2
中的值,这就是 anti_join
所做的:
“anti_join 从 x 中返回所有在 y 中没有匹配值的行,只保留来自 x 的列。”
我的解决方案:
df3 <- anti_join(df1, df2, by = "y") %>% bind_rows(df2)
Warning messages:
1: In anti_join_impl(x, y, by$x, by$y) :
joining factors with different levels, coercing to character vector
2: In rbind_all(x, .id) : Unequal factor levels: coercing to character
> df3
Source: local data frame [4 x 2]
y x1
(chr) (dbl)
1 D 4
2 A 5
3 B 6
4 C 7
这一行给出了所需的输出(以不同的顺序),但是,您应该注意警告消息,在使用数据集时,请务必将 y
作为字符变量读取。
【讨论】:
谢谢!最后!我的背景不是计算机科学,奇怪的是我很难找到这个答案。我应该一直在寻找什么?R merge dataframes with priority
或 R complete dataframe from other dataframe if values not present
或 R merge without overwrite
或 R add rows if not present
等等……都失败了……【参考方案2】:
这是我现在使用的习惯用法,此外,它还处理保留不属于更新表的列。我使用了一些与 OP 不同的名称,但味道相似。
我要做的一件事是为连接中使用的键创建一个变量,因为我在几个地方使用它。但除此之外,它会执行所需的操作。
它本身不处理例如“如果值为 NA 则更新此行”的操作,但您应该在创建连接表时执行该条件。
library(dplyr)
#>
#> Attaching package: 'dplyr'
#> The following objects are masked from 'package:stats':
#>
#> filter, lag
#> The following objects are masked from 'package:base':
#>
#> intersect, setdiff, setequal, union
.keys <- c("key1", "key2")
.base_table <- tribble(
~key1, ~key2, ~val1, ~val2,
"A", "a", 0, 0,
"A", "b", 0, 1,
"B", "a", 1, 0,
"B", "b", 1, 1)
.join_table <- tribble(
~key1, ~key2, ~val2,
"A", "b", 100,
"B", "a", 111)
# This works
df_result <- .base_table %>%
# Pull off rows from base table that match the join table
semi_join(.join_table, .keys) %>%
# Drop cols from base table that are in join table, except for the key columns
select(-matches(setdiff(names(.join_table), .keys))) %>%
# Left join on the join table columns
left_join(.join_table, .keys) %>%
# Remove the matching rows from the base table, and bind on the newly joined result from above.
bind_rows(.base_table %>% anti_join(.join_table, .keys))
df_result %>%
print()
#> # A tibble: 4 x 4
#> key1 key2 val1 val2
#> <chr> <chr> <dbl> <dbl>
#> 1 A b 0 100
#> 2 B a 1 111
#> 3 A a 0 0
#> 4 B b 1 1
由reprex package (v0.3.0) 于 2019 年 12 月 12 日创建
【讨论】:
以上是关于left_join 两个数据帧并覆盖的主要内容,如果未能解决你的问题,请参考以下文章
如何在 Scala 中连接两个数据帧并通过索引从数据帧中选择几列?
我应该如何在 Pandas 中减去两个数据帧并显示所需的输出?