按 id 合并,但在某些列中用新数据替换旧数据

merge by id but replace old data with new data in some columns

基本上,我有一个数据框,其中有一些数据需要替换为不同数据框中的数据。仅需要更改许多列中的少数几个观察结果。

为了说明,假设我有一个数据框:

df1 <- data.frame(index = c('a', 'b', 'c', 'd', 'e'), 
                  var1 = c(40, 22, 12, 4, 0),
                  var2 = c(75, 55, 65, 15, 0),
                  var3 = c(9, 18, 81, 3, 0),
                  var4 = c(1, 11, 21, 61, 0),
                  var5 = c(-1, -2, -3, -4, 0),
                  var6 = c(0, 1, 0, 1, 0))

    index   var1   var2   var3   var4   var5   var6
1     a     40     75      9      1     -1      0
2     b     22     55     18     11     -2      1
3     c     12     65     81     21     -3      0
4     d      4     15      3     61     -4      1
5.    e      0      0      0     0       0      0

然后,一些更好的观察“b”和“c”的数据出现了,但仅限于变量“var2”和“var3”:

df2 <- data.frame(index = c('a', 'b', 'c', 'd'), 
                  var1 = c(40, 22, 12, 4),
                  var2 = c(75, 550, 650, 15),
                  var3 = c(9, 180, 810, 3),
                  var4 = c(1, 11, 21, 61))

  index var1 var2 var3 var4
1     a   40   75    9    1
2     b   22  550  180   11
3     c   12  650  810   21
4     d    4   15    3   61

我想要结果数据框:


   index var1 var2 var3 var4 var5 var6
1     a   40   75    9    1   -1    0
2     b   22  550  180   11   -2    1
3     c   12  650  810   21   -3    0
4     d    4   15    3   61   -4    1
5     e    0    0    0    0    0    0

任何提示(特别是任何可提供的 tidyverse 解决方案?)我玩过 mutateacrossreplace,但似乎无法理解。

澄清:我希望将 var2 和 var3 的新值替换为 df2 中的值,只要在 df1 中找到索引值。其他一切都应该保持不变。我正在处理的数据集的索引值出现了很多次。我尝试了以下,但语法有问题:

df1 %>%
    mutate(across(c(var2, var3),
           ~if_else(index %in% df2$index),
                     .[df2$index],
                     .))

更新二:新说明后:删除之前的回答:

library(dplyr)

bind_rows(df1, df2) %>% 
  arrange(index) %>% 
  mutate(across(var1:var4, ~ifelse(index=="b" |
                                     index == "c", lead(.), .))) %>% 
  na.omit()
  index var1 var2 var3 var4 var5 var6
1     a   40   75    9    1   -1    0
3     b   22  550  180   11   -2    1
5     c   12  650  810   21   -3    0
7     d    4   15    3   61   -4    1
9     e    0    0    0    0    0    0

根据您在 OP 中提供的数据,以及 'better' 观察值较大的事实,以下似乎给出了预期的结果:

library(dplyr)

df1 <- data.frame(index = c('a', 'b', 'c', 'd', 'e'), 
                  var1 = c(40, 22, 12, 4, 0),
                  var2 = c(75, 55, 65, 15, 0),
                  var3 = c(9, 18, 81, 3, 0),
                  var4 = c(1, 11, 21, 61, 0),
                  var5 = c(-1, -2, -3, -4, 0),
                  var6 = c(0, 1, 0, 1, 0))


df2 <- data.frame(index = c('a', 'b', 'c', 'd'), 
                  var1 = c(40, 22, 12, 4),
                  var2 = c(75, 550, 650, 15),
                  var3 = c(9, 180, 810, 3),
                  var4 = c(1, 11, 21, 61))


get_best <- function(col){
  value <- max(unlist(col), na.rm=TRUE)
  return(value)
}

a <- bind_rows(df1,df2) %>% 
  group_by(index) %>% 
  mutate(across(.cols=everything(),
                .fns=get_best)) %>% 
  unique()

输出:

# A tibble: 5 × 7
# Groups:   index [5]
  index  var1  var2  var3  var4  var5  var6
  <chr> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl>
1 a        40    75     9     1    -1     0
2 b        22   550   180    11    -2     1
3 c        12   650   810    21    -3     0
4 d         4    15     3    61    -4     1
5 e         0     0     0     0     0     0