首页 > 解决方案 > 将两个数据帧合并到一个匹配变量上,只为其他不相交的变量保留一个值

问题描述

我有两个需要合并的数据框。数据框共享所有相同的列。我基于一个共享变量 worker_ID 进行合并。但是,其他变量通常是不相交的:一个数据框将具有“NA”,而另一个数据框将具有给定变量的另一个值。如何以输出仅保留非 NA 值的方式合并?

x = worker_ID Var_1 Var_2 Var_3
    1         33    NA    NA
    2         NA    46    NA

y = worker_ID Var_1 Var_2 Var_3
    1         NA    75    NA
    2         NA    NA    66

z <- merge(x,y,by="worker_ID", all = TRUE)

这种方法不起作用,因为我得到的不是我想要的输出 z,而是一个数据框,每个变量都有两列(一列用于 x 中的变量值,另一列用于 y)。我想要的输出是 z。

z = worker_ID Var_1 Var_2 Var_3
    1         33    75    NA
    2         NA    46    66

我如何告诉 R 让任何非 NA 条目取代 NA 条目?

标签: rmerge

解决方案


正如本建议的那样,您可以使用coalesce(). 根据您目前的样本数据,我做了以下事情。x对于和中相同位置的每一对列y,我使用coalesce()并创建了一个向量。我将结果转换为sapply()数据框并worker_ID在最后添加。请注意,我as.numeric()用于Var_3. 我不确定您的数据是什么样的,但 Var_3 inx可以是逻辑的而不是数字的。我确保x'y` 中的 Var_3 和 Var_3 都是数字。

library(tidyverse)

sapply(2:ncol(x), function(whatever){
  coalesce(as.numeric(pull(x, whatever)),
           as.numeric(pull(y, whatever))) -> foo
  return(foo)
}) %>% 
as_tibble %>% 
bind_cols(work_ID = pull(x, 1), .)

#  A tibble: 2 x 4
#  work_ID    V1    V2    V3
#    <int> <dbl> <dbl> <dbl>
#1       1    33    75    NA
#2       2    NA    46    66

更新

接受 akrun 的建议,我认为以下代码效果很好。map_dfc()就像sapply()这样循环遍历每一列对。好处是map_dfc()创建了一个数据框;无需使用as_tibble().

map_dfc(2:ncol(x), ~ coalesce(as.numeric(pull(x, .x)),
                              as.numeric(pull(y, .x)))) %>% 
bind_cols(work_ID = pull(x, 1), .)

推荐阅读