2016-07-19 35 views
0

我有2个数据帧。 如果df2中的SysId为0,那么我必须通过AppId合并到df1,否则我必须在SysId和AppId上合并并获得标志。根据不同的连接条件在R中合并数据框?

我已经在两个步骤中用两个步骤完成了它,附加功能是在合并之后基于两个标志列创建一个新列。我需要根据不同的连接条件进行合并,并将其放在同一列中。另外我创建的方式看起来很圆,有更好的方法吗?在此先感谢

df1 = data.frame(
SysId=rep(1001:1003,3), 
AppId=c(rep("A",3),rep("B",3),rep("C",3)) 
       ) 

df2 = data.frame(
SysId=c(1002,1003,0), 
AppId=c("A","B","C"), 
Flag="Y" 
) 

df1 

    SysId AppId 
    1 1001  A 
    2 1002  A 
    3 1003  A 
    4 1001  B 
    5 1002  B 
    6 1003  B 
    7 1001  C 
    8 1002  C 
    9 1003  C 

df2 

     SysId AppId Flag 
    1 1002  A Y 
    2 1003  B Y 
    3  0  C Y 

    Final Expected Result 
    SysId AppId  Flag 
    1 1001  A   
    2 1002  A   Y 
    3 1003  A 
    4 1001  B 
    5 1002  B 
    6 1003  B   Y 
    7 1001  C   Y 
    8 1002  C   Y 
    9 1003  C   Y 

df1 <- merge(x=df1,y=df2[df2$SysId == 0, c("AppId","Flag")],by=c("AppId"), all.x=TRUE) 
df1 <- merge(x=df1,y=df2,by=c("SysId","AppId"), all.x=TRUE) 

    After Merging two times 
     SysId AppId Flag.x Flag.y 
    1 1001  A <NA> <NA> 
    2 1001  B <NA> <NA> 
    3 1001  C  Y <NA> 
    4 1002  A <NA>  Y 
    5 1002  B <NA> <NA> 
    6 1002  C  Y <NA> 
    7 1003  A <NA> <NA> 
    8 1003  B <NA>  Y 
    9 1003  C  Y <NA> 
+0

这是一种复杂的规则。我不知道合并逻辑中的条件通配符规范。也许SQL会有这样的? –

+0

我认为你的解决方案很好。现在只需执行'df1 $ Flag < - ifelse(is.na(df1 $ Flag.x),df1 $ Flag.y,df1 $ Flag.x)'。如果你在Flag.x和Flag.y中得到不同的标志,会发生什么...... – dash2

+0

感谢42和dash2为你的快速答案。 – user3254389

回答

1

你可以从你的“合并”移动逻辑为“关键”一栏,然后在这个新列常合并,像这样:

df1 <- data.frame(SysId=rep(1001:1003,3),AppId=c(rep("A",3),rep("B",3),rep("C",3)),stringsAsFactors=FALSE) 
df2 <- data.frame(SysId=c(1002,1003,0),AppId=c("A","B","C"),Flag="Y",stringsAsFactors=FALSE) 

# move the condition to the key 
df2$key <- ifelse(df2$SysId==0,df2$AppId,paste0(df2$SysId,df2$AppId)) 
df1$key <- ifelse(df1$AppId %in% df2$AppId[df2$SysId==0],df1$AppId,paste0(df1$SysId,df1$AppId)) 

# merge data frames 
df1 <- merge(x=df1,y=df2,by="key",all.x=TRUE) 

# format results 
df1 <- df1[,c("SysId.x","AppId.x","Flag")] 
colnames(df1) <- c("SysId","AppId","Flag") 
df1 <- df1[order(df1$AppId,df1$SysId),]