根据不同的连接条件合并R中的数据帧?

时间:2016-07-19 20:52:27

标签: r

我有2个数据帧。 如果df2中的SysId为0,那么我必须通过AppId合并到df1,否则我必须在SysId和AppId上合并并获得Flag。

我已经在两个步骤中完成了它,并且在合并之后基于两个标志列创建了一个新的列。我需要根据不同的连接条件进行合并,并将其放在同一列中。我创造的方式也是如此,有更好的方法吗?提前致谢

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>

1 个答案:

答案 0 :(得分: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),]