left_join两个数据帧并覆盖

时间:2016-02-25 20:00:20

标签: r dplyr

我希望合并两个数据框,其中df2会覆盖NAdf1中存在的任何值。 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

2 个答案:

答案 0 :(得分:4)

我认为你想要的是保留df2的值,只添加df1df2中不存在anti_join的内容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

“anti_join返回x中所有行,其中y中没有匹配的值,只保留x中的列。”

我的解决方案:

y

此行提供所需的输出(以不同的顺序)但是,您应该注意警告消息,在使用数据集时,请务必将$formulaParser = new \PHPExcel_Calculation_FormulaParser('=IF(T1<X2,"foo", T1+X2)'); dump($formulaParser->getTokens()); 读作字符变量。

答案 1 :(得分:0)

这是我现在使用的习惯用法,此外,它还处理保留不属于更新表的列。我使用的名称与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创建