首页 > 解决方案 > 用 R 中匹配的 ID 和日期替换两个数据帧的 NA 值

问题描述

我有两个行和列长度不同的数据框

data.frame(
  stringsAsFactors = FALSE,
              Date = c("01/01/2000", "01/01/2010", "01/01/2020"),
           Germany = c(5, 8, 9),
            France = c(4, NA, 7),
        Luxembourg = c(10, 6, 3)
) -> df1
data.frame(
  stringsAsFactors = FALSE,
              Date = c("01/01/1990", "01/01/2000", "01/01/2010", "01/01/2020"),
           Germany = c(1, 9, 7, NA),
            France = c(10, 3, 9, 6),
        Luxembourg = c(10, NA, NA, 7),
           Belgium = c(NA, 8, 1, 9)
) -> df2

dfs

我必须创建第三个 df (df3),其中,

  1. df1的NA 值通过匹配ID日期替换为df2的值,反之亦然(df2 的 NA 替换为 df1)
  2. df1 的值是优先级 (=TRUE)
  3. 所有不在一个数据框中的列(如本例中的比利时)也应包含在 df3 中

df3应如下所示:

结果

任何帮助将不胜感激

标签: r

解决方案


我们可以加入on“日期”并使用fcoalesce相应的非 NA 替换 NA

library(data.table)
nm2 <- intersect(names(df2)[-1], names(df1)[-1])
df3 <- copy(df2)
setDT(df3)[df1, (nm2) := Map(fcoalesce, mget(nm2),
       mget(paste0('i.', nm2))), on = .(Date)]

-输出

df3
#         Date Germany France Luxembourg Belgium
#1: 01/01/1990       1     10         10      NA
#2: 01/01/2000       9      3         10       8
#3: 01/01/2010       7      9          6       1
#4: 01/01/2020       9      6          7       9

或者这可以用tidyverse

library(dplyr)
library(stringr)
left_join(df2, df1, by = 'Date') %>% 
   mutate(Date, across(ends_with(".x"), 
    ~ coalesce(., get(str_replace(cur_column(), "\\.x$", ".y"))))) %>% 
   select(-ends_with('.y')) %>% 
   rename_with(~ str_remove(., "\\.x$"), ends_with('.x'))

推荐阅读