2016-07-19 5 views
0

У меня есть 2 dataframes. Если SysId в df2 равен 0, тогда я должен объединиться с df1 в AppId else, мне нужно объединиться в 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),] 
Смежные вопросы