首页 文章

如何通过匹配每列中的3列将数据从数据框复制到另一个数据框中

提问于
浏览
0

我有2个数据帧,我试图通过将第一个数据帧中的3列与第二个数据帧中的3列相匹配,将一个数据帧中的一列复制到另一个数据帧中 . 我不想完全合并数据帧,因为我的实际数据帧每个都有太多列,我不希望它们全部在一起 .

以下是示例数据框:

DF1

ID_num  Terr_Bred  Dispersal_Dist  Year_Bred
  1         1        BAM             760       1987
  2         2        GRE            1006       1993
  3         3        MEW             999       2000

DF2

Mal_ID    Date_Rec   Year  Terr  Pair_ID  Fem_ID
  1          4   3/22/1987   1987   BAM       87       1
  2          7   2/22/1987   1987   YER       43       1
  3          5   1/17/1993   1993   GRE       22       2
  4          8   2/14/1991   1991   GRE       91       2
  5          6   10/1/2000   2000   MEW       65       3

我要这个:

ID_num  Year_Bred   Terr_Bred   Dispersal_Dist Mate_ID_num
  1         1       1987         BAM              760           4
  2         2       1993         GRE             1006           5
  3         3       2000         MEW              999           6

所以,我正在尝试将df2中的Mal_ID列添加到df1并重命名列Mate_ID_num . 为此,我想匹配df1中的d_n1到Fem_ID列的ID_num列,df2中df1到Year列的Year_Bred列,以及df1中df1到Terr列的Terr_Bred列 . 如上面的示例所示,列的名称在每个数据框中都不同 .

我一直无法找到这样做的方法,我只找到了完全合并数据框的示例,或者基于匹配每个数据框中的单个列而不是多个列添加列的示例 .

2 回答

  • 1

    你也可以使用 dplyr 做同样的事情,这比基础R更具表现力:

    library(dplyr)
    
    df <- df1 %>%
      left_join(df2, c("ID_num" = "Fem_ID", "Year_Bred" = "Year", "Terr_Bred" = "Terr")) %>%
      rename(Mate_ID_num = Mal_ID) %>%
      select(1:5)
    
  • 1

    1) base 这称为左连接:

    by.x <- c("ID_num", "Year_Bred", "Terr_Bred")
    by.y <- c("Fem_ID", "Year", "Terr")
    
    df <- merge(df1[by.x], df2[c(by.y, "Mal_ID")], 
             all.x = TRUE, all.y = FALSE, by.x = by.x, by.y = by.y)
    
    names(df["Mal_ID"]) <- "Mal_ID_num"
    

    赠送:

    > df
      ID_num Year_Bred Terr_Bred Dispersal_Dist Mate_ID_num
    1      1      1987       BAM            760           4
    2      2      1993       GRE           1006           5
    3      3      2000       MEW            999           6
    

    我们使用了名称而不是位置表示法,因为您指出列在实际问题中没有对齐但是对于问题中显示的问题(在问题被更改之前但反映在注释中的可再现输入中)合并将略有这样的位置符号更短:

    df <- merge(df1[1:3], df2[1:4], all.x = TRUE, all.y = FALSE, by = 1:3)
    

    然而,

    2) 可以使用SQL来完成它:

    library(sqldf)
    sqldf("select a.*, b.Mal_ID Ma1_ID_num
           from df1 a left join df2 b on a.ID_num = b.Fem_ID and 
                                         a.Year_Bred = b.Year and 
                                         a.Terr_Bred = b.Terr")
    

    赠送:

    ID_num Year_Bred Terr_Bred Dispersal_Dist Ma1_ID_num
    1      1      1987       BAM            760          4
    2      2      1993       GRE           1006          5
    3      3      2000       MEW            999          6
    >
    

    可再现形式的 Note: df1df2 如下 . 这个问题最初有这些,但后来改变了它们;但是,上面的答案使用下面显示的原始 df1df2 .

    Lines1 <- "
           ID_num  Year_Bred  Terr_Bred  Dispersal_Dist  
      1         1       1987        BAM             760
      2         2       1993        GRE            1006
      3         3       2000        MEW             999"
    df1 <- read.table(text = Lines1, as.is = TRUE)
    
    Lines2 <- "
            Fem_ID   Year  Terr      Mal_ID  Pair_ID    Date_Rec
      1          1   1987   BAM           4       87   3/22/1987
      2          1   1987   YER           7       43   2/22/1987
      3          2   1993   GRE           5       22   1/17/1993
      4          2   1991   GRE           8       91   2/14/1991
      5          3   2000   MEW           6       65   10/1/2000"
    df2 <- read.table(text = Lines2, as.is = TRUE)
    

相关问题