在 R 中匹配而不考虑顺序

Match in R while disregarding order

无论列的顺序如何,我都试图在 R 中进行匹配。

基本上我要解决的问题是,如果 df2 的列中从第 2 列到末尾的所有值都在 df1 中找到(在 Partner 之后),则匹配 df1 .

这里有一个要点:在进行此匹配时忽略每行中最后一个非 NA 值,但将其包含在最终输出中。 所以不要取最后一个非 NA 值匹配时考虑 NA 值但包括它。

匹配后,确定最后一个非 na 值是否存在于相应行的任何列中。

df1

Partner    Col1  Col2  Col3  Col4  
      A      A1    A2    NA    NA  
      B      A2    B9    NA    NA  
      C      B7    V9    C1    N9    
      D      Q1    Q3    Q4    NA    

df2

lift  rule1  rule2  rule3  
  11     A2     A1     A9  
  10     A1     A3     NA  
  11     B9     A2     D7  
  10     Q4     Q1     NA
  11     A2     B9     B1

如何将 df1 与 df2 匹配,以便发生以下情况:

1) 忽略在两个数据框中找到的列的顺序。

2) 然后判断当前行中是否存在最后一个非na值。

最终输出:

df3

Partner    Col1  Col2  Col3  Col4  lift   rule1   rule2   rule3   EXIST?
      A      A1    A2    NA    NA    11      A2      A1      A9     YES
      A      A1    A2    NA    NA    10      A1      A3      NA    NOPE
      B      A2    B9    NA    NA    11      B9      A2      D7     YES
      B      A2    B9    NA    NA    11      A2      B9      B1     YES        
      D      Q1    Q3    Q4    NA    10      Q4      Q1      NA     YES

我比你多了一个B匹配,但是这个方案已经很接近你想要的了。您首先必须添加一个 id 列,因为我们使用它来重建数据。然后要执行匹配,首先需要用 tidyr 中的 gather 融化它,并使用 dplyr 中的 inner_join。然后我们 cbind 使用 ids 和原来的 data.frames.

    library(tidyr);library(dplyr)

df1 <- read.table(text="Partner    Col1  Col2  Col3  Col4
A      A1    A2    NA    NA
B      A2    B9    NA    NA
C      B7    V9    C1    N9
D      Q1    Q3    Q4    NA",header=TRUE, stringsAsFactors=FALSE)


df2 <- read.table(text="lift  rule1  rule2  rule3
  11     A2     A1     A9
  10     A1     A3     NA
  11     B9     A2     D7
  10     Q4     Q1     NA
  11     A2     B9     B1",header=TRUE, stringsAsFactors=FALSE)

df1 <- cbind(df1_id=1:nrow(df1),df1)
df2 <- cbind(df2_id=1:nrow(df2),df2)

#melt with gather
d11  <- df1 %>% gather(Col, Value,starts_with("C"))           #Long
d11 <- d11 %>% na.omit() %>%group_by(df1_id) %>% slice(-n()) #remove last non NA

d22  <- df2 %>%  gather(Rule, Value,starts_with("r"))         #Long

res <- inner_join(d11,d22)

cbind(df1[res$df1_id,],df2[res$df2_id,])

    df1_id Partner Col1 Col2 Col3 Col4 df2_id lift rule1 rule2 rule3
1        1       A   A1   A2 <NA> <NA>      2   10    A1    A3  <NA>
1.1      1       A   A1   A2 <NA> <NA>      1   11    A2    A1    A9
2        2       B   A2   B9 <NA> <NA>      1   11    A2    A1    A9
2.1      2       B   A2   B9 <NA> <NA>      5   11    A2    B9    B1
2.2      2       B   A2   B9 <NA> <NA>      3   11    B9    A2    D7
4        4       D   Q1   Q3   Q4 <NA>      4   10    Q4    Q1  <NA>