【问题标题】:Join 2 dataframes together if two columns match如果两列匹配,则将 2 个数据框连接在一起
【发布时间】:2018-05-09 09:26:25
【问题描述】:

我有 2 个数据框:

CountryPoints

From.country  To.Country points
Belgium       Finland    4
Belgium       Germany    5
Malta         Italy      12
Malta         UK         1

和另一个具有邻国/接壤国家的数据框:

From.country    To.Country 
    Belgium       Finland   
    Belgium       Germany   
    Malta         Italy   

我想在 CountryPoints 中添加另一列,称为邻居 (Y/N),具体取决于是否在邻国/接壤国家数据框中找到键值对。这是否可能 - 所以它是一种连接,但结果应该是一个布尔列。

结果应该是:

From.country  To.Country points  Neighbour
    Belgium       Finland    4    Y
    Belgium       Germany    5    Y
    Malta         Italy      12   Y
    Malta         UK         1    N

在下面的问题中,它显示了如何合并,但没有显示如何添加额外的布尔列

【问题讨论】:

  • 另外,相关帖子:stackoverflow.com/questions/1169248/…
  • 要获得布尔值,你可以这样做df1$From.country %in% df2$From.country & df1$To.Country %in% df2$To.Country
  • 如果它们在 df2 的同一行中,这将给我一个真正的无关紧要
  • 你需要逐行匹配吗?所以 Belgium Finland 在另一行会导致 N
  • 如果我在邻国/邻国找到比利时芬兰,我希望在 CountryPoints 的 Neighbor 列中写入 Y。否则将写入 N

标签: r dataframe join


【解决方案1】:

两种替代方法:

1) 以 R 为基数:

idx <- match(df1$From.country, df2$From.country, nomatch = 0) &
  match(df1$To.Country, df2$To.Country, nomatch = 0)
df1$Neighbour <- c('N','Y')[1 + idx]

2) 与data.table:

library(data.table)
setDT(df1)
setDT(df2)

df1[, Neighbour := 'N'][df2, on = .(From.country, To.Country), Neighbour := 'Y'][]

两者都给出(data.table-output 显示):

   From.country To.Country points Neighbour
1:      Belgium    Finland      4         Y
2:      Belgium    Germany      5         Y
3:        Malta      Italy     12         Y
4:        Malta         UK      1         N

【讨论】:

    【解决方案2】:

    借鉴this post的思路:

    df1$Neighbour  <- duplicated(rbind(df2[, 1:2], df1[, 1:2]))[ -seq_len(nrow(df2)) ]
    
    df1
    #   From.country To.Country points Neighbour
    # 1      Belgium    Finland      4      TRUE
    # 2      Belgium    Germany      5      TRUE
    # 3        Malta      Italy     12      TRUE
    # 4        Malta         UK      1     FALSE
    

    【讨论】:

      【解决方案3】:

      这样的事情呢?

      sortpaste <- function(x) paste0(sort(x), collapse = "_");
      df1$Neighbour <- apply(df1[, 1:2], 1, sortpaste) %in% apply(df2[, 1:2], 1, sortpaste)
      #  From.country To.Country points Neighbour
      #1      Belgium    Finland      4      TRUE
      #2      Belgium    Germany      5      TRUE
      #3        Malta      Italy     12      TRUE
      #4        Malta         UK      1     FALSE
      

      样本数据

      df1 <- read.table(text =
          "From.country  To.Country points
      Belgium       Finland    4
      Belgium       Germany    5
      Malta         Italy      12
      Malta         UK         1", header = T)
      
      df2 <- read.table(text =
          "From.country    To.Country
          Belgium       Finland
          Belgium       Germany
          Malta         Italy", header = T)
      

      【讨论】:

        猜你喜欢
        • 2022-11-04
        • 2022-01-26
        • 2018-04-24
        • 2023-03-22
        • 2021-10-22
        • 1970-01-01
        • 2016-08-05
        • 2016-05-22
        相关资源
        最近更新 更多