R join或merge不重复非连接列(可重现)

时间:2018-03-09 01:01:35

标签: r join merge

这与标记的副本不同,因为我必须动态合并删除NA的列值,同时合并

我不能使用datatxt1或datatxt2作为合并列,因为(如下所示)df1和df2来自可能包含或不包含这些列的函数。下面的数据样本是数据可能的样本,而不是最终结果。这是以下答案的问题

原始问题

如何获取任何连接或合并命令(如果列存在于两个集合中:如果任一向量中存在值但在每个向量中合并相等的值,则组合覆盖NA的列,b(存在于一个集合中:keep)输出中包含NA的列,或者c(在任何一个集合中都不存在:不包括在输出中。每次在两个集合中都有一个一致的列来索引和合并(数据示例中的ID_2)。

基本上我需要在ID_2上合并两个集合,考虑组合列的可能性,以及那些需要在合并之前组合的集合。

说我有这样的数据:

 df1 <- data.frame(
        ID_2=c("5", "9", "20", "6", "8"),
        datatxt1=c("data1","data2","data3","data4","data5"),
        datatxt2=c("text1","text2","text3","text4","text5"),
        datan= c(1,2,3,4,5),
        stringsAsFactors = FALSE
                       )

df2 <- data.frame(
        ID_2=c(rep("5",20),rep( "9",20), rep("6",20)),
        datatxt1=c(rep("NA",20), rep("data2",20), rep("data4",20)),
        datatxt2=c(rep("text1",20), rep("text2",20), rep("text4",20)),
        adddatan= c(rep(500,20),rep(400,20),rep(300,20)),
        stringsAsFactors = FALSE
                       )         

什么是JOIN或MERGE命令会为我提供这样的数据?

df.desired <- data.frame(
                ID_2=c(rep("5",20),rep( "9",20), rep("6",20)),
                datatxt1=c(rep("data1",20), rep("data2",20), rep("data4",20)),
                datatxt2=c(rep("text1",20), rep("text2",20), rep("text4",20)),
                datan=c(rep(1,20), rep(2,20), rep(4,20)),
                adddatan= c(rep(500,20),rep(400,20),rep(300,20)),
                stringsAsFactors = FALSE
                   )  

推理:

1.在一个更大的函数中,我在函数中加载了一个数据框。我不会总是在公共列中有数据点(所以我不能在它们上合并),但我想保留它们,如果我在两者中都有它们但是根据查找纠正它们,并保留一个列名称与将数据合并在一个单独的公共列上。

更新

其他数据示例,我还需要它在澄清请求下工作。我还需要它在datatxt1是完整列的情况下工作,两者都不完整,缺少一列,或两者都缺失

##Supplemental Example 1

df3 <- data.frame(
  ID_2=c("5", "9", "20", "6", "8"),
  datatxt1=c("data1","data2","data3","data4","data5"),
  datatxt2=c("text1","text2","text3","text4","text5"),
  datan= c(1,2,3,4,5),
  adddatan= c(NA,200,100,300,500),
  stringsAsFactors = FALSE
)


df4 <- data.frame(
  ID_2=c(rep("5",20),rep( "9",20), rep("6",20)),
  datatxt1=c(rep("data1",20), rep("data2",20), rep("data4",20)),
  datatxt2=c(rep("text1",20), rep(NA,20), rep("text4",20)),
  adddatan= c(rep(500,20),rep(NA,20),rep(300,20)),
  stringsAsFactors = FALSE
)         



df.desired34 <- data.frame(
  ID_2=c(rep("5",20),rep( "9",20), rep("6",20)),
  datatxt1=c(rep("data1",20), rep("data2",20), rep("data4",20)),
  datatxt2=c(rep("text1",20), rep("text2",20), rep("text4",20)),
  datan=c(rep(1,20), rep(2,20), rep(4,20)),
  adddatan= c(rep(500,20),rep(200,20),rep(300,20)),
  stringsAsFactors = FALSE
)  

###Supplemental Example 2


df5 <- data.frame(
  ID_2=c("5", "9", "20", "6", "8"),
  datatxt1=c("data1","data2","data3","data4","data5"),
  datan= c(1,2,3,4,5),
  adddatan= c(100,200,300,NA,500),
  stringsAsFactors = FALSE
)


df6 <- data.frame(
  ID_2=c(rep("20",20),rep( "6",20), rep("8",20)),
  datatxt2=c(rep("text3",20), rep(NA,20), rep("text5",20)),
  adddatan= c(rep(300,20),rep(NA,20),rep(500,20)),
  stringsAsFactors = FALSE
)         



df.desired56 <- data.frame(
  ID_2=c(rep("20",20),rep( "6",20), rep("8",20)),
  datatxt1=c(rep("data3",20), rep("data4",20), rep("data5",20)),
  datatxt2=c(rep("text3",20), rep(NA,20), rep("text5",20)),
  datan=c(rep(3,20), rep(4,20), rep(5,20)),
  adddatan= c(rep(300,20),rep(NA,20),rep(500,20)),
  stringsAsFactors = FALSE
) 

##Supplemental Example 3

df7 <- data.frame(
  ID_2=c("5", "9", "20", "6", "8"),
  datatxt1=c("data1","data2","data3",NA,"data5"),
  datan= c(1,2,3,4,5),
  adddatan= c(100,200,300,400,500),
  stringsAsFactors = FALSE
)


df8 <- data.frame(
  ID_2=c(rep("5",20),rep( "9",20), rep("6",20)),
  datatxt1=c(rep("data1",20), rep("data2",20), rep(NA,20)),
  adddatan= c(rep(100,20),rep(200,20),rep(400,20)),
  stringsAsFactors = FALSE
)         



df.desired78 <- data.frame(
  ID_2=c(rep("5",20),rep( "9",20), rep("6",20)),
  datatxt1=c(rep("data1",20), rep("data2",20), rep(NA,20)),
  datan=c(rep(1,20), rep(2,20), rep(4,20)),
  adddatan= c(rep(100,20),rep(200,20),rep(400,20)),
  stringsAsFactors = FALSE
)  

2 个答案:

答案 0 :(得分:0)

我不太了解您的预期输出。例如,ID_2 == 20df.desired行背后的逻辑是什么?其他列值似乎与df1中的任何条目都不匹配。你能否仔细检查一下你的预期输出是否正确。

除此之外,这几乎可以再现您的预期结果:

library(tidyverse);
df <- df2 %>%
    left_join(df1, by = c("ID_2", "datatxt2")) %>%
    select(ID_2, datatxt1.y, datatxt2, datan, adddatan) %>%
    rename(datatxt1 = datatxt1.y)

说明:执行left_join df2df1,然后选择并重命名列以与预期结果保持一致。请注意,datatxt1 = datatxt1.y会将来自datatxt1的{​​{1}}条目替换为来自df2的条目。

更新

仅在df1上合并,然后根据ID_2datatxt2datatxt2是否NA来填写df1

df2

df <- df2 %>% left_join(df1, by = c("ID_2")) %>% mutate(datatxt2 = ifelse(is.na(datatxt2.x), datatxt2.y, datatxt2.x)) %>% select(ID_2, datatxt1.y, datatxt2, datan, adddatan) %>% rename(datatxt1 = datatxt1.y); df相同。

答案 1 :(得分:0)

看起来你正在寻找动态连接,如果你想确定是否要加入datatxt1或datatxt2,下面应该是我能想到的最小例子。

library(sqldf)

if (sum(is.na(df2$datatxt1)) > sum(is.na(df2$datatxt2))) {
  desire <- sqldf("select a.*,b.adddatan from df1 a join df2 b on a.id_2=b.id_2 and a.datatxt2=b.datatxt2")
} else {
  desire <- sqldf("select a.*,b.adddatan from df1 a join df2 b on 
a.id_2=b.id_2 and a.datatxt1=b.datatxt1")
}