【问题标题】:Merging dataframes in R based on different join conditions?根据不同的连接条件合并R中的数据框?
【发布时间】:2016-07-19 20:52:26
【问题描述】:

我有 2 个数据框。 如果 df2 中的 SysId 为 0,那么我必须通过 AppId 合并到 df1 否则我必须将 SysId 和 AppId 合并在一起并获得标志。

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

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>

【问题讨论】:

  • 这是一个复杂的规则。我不知道合并逻辑中的条件通配符规范。也许SQL会有这样的?
  • 我认为您的解决方案很好。现在只需执行df1$Flag &lt;- ifelse(is.na(df1$Flag.x), df1$Flag.y, df1$Flag.x)。如果您在 Flag.x 和 Flag.y 中获得不同的标志会发生什么取决于您...
  • 感谢 42 和 dash2 的快速解答。

标签: r


【解决方案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),]

【讨论】:

    猜你喜欢
    • 2023-01-08
    • 2018-11-25
    • 2020-11-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-05-10
    • 2015-07-19
    相关资源
    最近更新 更多