如何用另一个数据框的数据填充一个数据框,同时保留第一个数据框的 NA

Chr*_*ris 10 r dataframe na dplyr

我有 2 个数据框,它们具有相同的列名,但行数不同。第一个数据框 (a) 看起来与此类似:

a = data.frame("Site"=c(1,2,3,4,7,9,10,11,13,14), 
               "v1"=c(0,0,0,0,0,0,0,0,0,0), 
               "v2"=c(0,0,0,0,NA,NA,NA,0,0,0), 
               "v3"=c(0,0,0,NA,0,NA,0,0,0,0), 
               "v4"=c(0,0,0,0,0,0,0,0,NA,NA), 
               "v5"=c(0,0,0,0,0,NA,0,NA,0,0)) 
Run Code Online (Sandbox Code Playgroud)

注意:站点 5、6、8 和 12 故意缺失。

第二个数据框 (b) 看起来像这样:

b = data.frame("Site"=c(2,3,4,7,10,14),
               "v1"=c(1,NA,2,1,NA,NA),
               "v2"=c(1,1,NA,NA,NA,NA),
               "v3"=c(NA,1,NA,NA,NA,1),
               "v4"=c(1,NA,4,1,NA,NA),
               "v5"=c(1,NA,2,1,1,3))
Run Code Online (Sandbox Code Playgroud)

我想要实现的是:

desired = data.frame("Site"=c(1,2,3,4,7,9,10,11,13,14), 
                     "v1"=c(0,1,0,2,1,0,0,0,0,0), 
                     "v2"=c(0,1,1,0,NA,NA,NA,0,0,0), 
                     "v3"=c(0,0,1,NA,0,NA,0,0,0,1), 
                     "v4"=c(0,1,0,4,1,0,0,0,NA,NA), 
                     "v5"=c(0,1,0,2,1,NA,1,NA,0,3))
Run Code Online (Sandbox Code Playgroud)

我将数据帧 b 中的数据“注入”(我确信有更好的术语)到数据帧 a 中,但是我想用零替换 b 中的任何 NA,并保持 a 中的 NA 原样。

我发现并尝试过这段代码:

cols <- colnames(a)[colnames(a) %in% colnames(b)]
rows <- rownames(a)[rownames(a) %in% rownames(b)]

a[rows, cols] <- b[rows, cols]
Run Code Online (Sandbox Code Playgroud)

但它也带来了 NA。我考虑先用零替换 NA,但即便如此,它也会删除我当前在数据帧 a 中想要保留的 NA。

也许 for 循环或 tidyverse 中的某些东西是可行的方法,但我什至不知道从哪里开始。任何帮助将非常感激!

Ony*_*mbu 0

merge(b, a, by = 'Site', all = TRUE) %>%
  split.default(sub('.x|.y', '', names(.))) %>%
  map_df(~coalesce(!!!.x))

# A tibble: 10 x 6
    Site    v1    v2    v3    v4    v5
   <dbl> <dbl> <dbl> <dbl> <dbl> <dbl>
 1     1     0     0     0     0     0
 2     2     1     1     0     1     1
 3     3     0     1     1     0     0
 4     4     2     0    NA     4     2
 5     7     1    NA     0     1     1
 6     9     0    NA    NA     0    NA
 7    10     0    NA     0     0     1
 8    11     0     0     0     0    NA
 9    13     0     0     0    NA     0
10    14     0     0     1    NA     3
Run Code Online (Sandbox Code Playgroud)

  • @AnoushiravanR `rbind(a, b)%&gt;% group_by(Site)%&gt;% summarise(across(everything(), ~if(any(!is.na(.x))) max(.x, na.rm = TRUE) else NA))` 是合并两者的另一种方法。 (2认同)