【问题标题】:How to join 2 dataframes based on paired values如何基于配对值连接 2 个数据帧
【发布时间】:2023-03-09 16:13:01
【问题描述】:

我正在寻找一个函数,它可以根据两个 df 是否具有相同的配对变量来将一个列从一个 df 连接到另一个。例如,Var1 Var2Var2 Var1 相同。

这是一个模拟示例:

Var1 <- c(1,2,6,5,5)
Var2 <- c(4,3,1,5,6)
f <- c("blue","green","red","orange2","grey")
df1 <- data.frame(Var1,Var2,f)

Var1 <- c(1,3,4,2,5,5)
Var2 <- c(4,2,2,2,5,1)
g <- c("house","car","bridge","stuff","book","other")
df2 <- data.frame(Var1,Var2,g)

给予:

> df1
  Var1 Var2       f
1    1    4    blue
2    2    3   green
3    6    1     red
4    5    5  orange
5    5    6    grey
> df2
  Var1 Var2      g
1    1    4  house
2    3    2    car
3    4    2 bridge
4    2    2  stuff
5    5    5   book
6    5    1  other

我希望 new_df 看起来像:

> new_df
  Var1 Var2       f     g
1    1    4    blue house
2    5    5  orange  book
3    2    3   green   car

我可以通过以下方式获取 new_df:

df3 <- inner_join(df1, df2, by = c("Var1", "Var2"))
df4 <- inner_join(df1, df2, by = c("Var1" = "Var2", "Var2" = "Var1"))
new_df <- rbind(df3,df4) %>% unique()

但我想知道是否有一个函数可以做到这一点? 谢谢!!

【问题讨论】:

  • 我不认为你会找到一个知道迭代所有可能的连接变量组合以获得你想要的东西的函数。我认为你这样做的方式可能是最简单的(最易读,最具声明性)。 (除了@jay.sf 的巧妙技巧。)
  • 好的,谢谢!我对 sql 不是很熟悉,所以我会坚持我所拥有的:)

标签: r dataframe merge


【解决方案1】:

您可以将逻辑放入一个小函数中并使用merge,但我不确定您是否要这样做。

f <- function(x, c1=1, c2=2, vc=3) {
  o <- data.frame(pmin(x[,c1], x[,c2]), pmax(x[,c1], x[,c2]), x[,vc])
  setNames(o, names(x))
}
merge(f(df1), f(df2))
#   Var1 Var2       f     g
# 1    1    4    blue house
# 2    2    3   green   car
# 3    5    5 orange2  book

【讨论】:

    【解决方案2】:

    可以在一条 SQL 语句中完成:

    library(sqldf)
    
    sqldf("select distinct a.*, b.g 
     from df1 a
     inner join df2 b on min(a.Var1, a.Var2) = min(b.Var1, b.Var2) and
                         max(a.Var1, a.Var2) = max(b.Var1, b.Var2)")
    ##   Var1 Var2       f     g
    ## 1    1    4    blue house
    ## 2    2    3   green   car
    ## 3    5    5 orange2  book
    

    如果要在管道中执行此操作,请将管道的 LHS 称为点:

    library(magrittr)
    library(sqldf)
    
    df1 %>% 
     { sqldf("select distinct a.*, b.g 
         from [.] a
         inner join df2 b on min(a.Var1, a.Var2) = min(b.Var1, b.Var2) and
                             max(a.Var1, a.Var2) = max(b.Var1, b.Var2)") }
    ##   Var1 Var2       f     g
    ## 1    1    4    blue house
    ## 2    2    3   green   car
    ## 3    5    5 orange2  book
    

    【讨论】:

    • 真的喜欢 sqldf 如何将 SQL 查询的强大功能带入 R 框架!虽然我不是每天都使用这个包,但当我有一些奇怪的数据时(即,不是简单的等式连接,而不是data.table 的范围连接),它通常是我必须路由的最好和最快的方法快速拿出我需要的东西。谢谢你的包裹!
    猜你喜欢
    • 2021-03-17
    • 2022-11-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-12-15
    • 1970-01-01
    • 2018-02-23
    • 1970-01-01
    相关资源
    最近更新 更多