如何根据另一个数据框中的条件匹配数据框中的列值?

How to match column value in a dataframe based on condition in another dataframe?

我有两个行数不同的数据框,下面是简单的例子:

df= data.frame(Xmin=c(10,15),Xmax=c(20,20),Ymin=c(10,20),Ymax=c(20,25),ID=c(1,2))
df
  Xmin Xmax Ymin Ymax ID
1   10   20   10   20  1
2   15   20   20   25  2
df2=data.frame(Xmin=c(13,15,17),Xmax=c(17,17,19),Ymin=c(12,21,20),Ymax=c(18,25,22),ID=c(NA,NA,NA))

df2
  Xmin Xmax   Ymin Ymax ID
1   13   17     12   18 NA
2   15   17     21   25 NA
3   17   19     20   22 NA

我想将 df2 的列 ID 替换为 df ID 列中符合条件的行的相应值。

df2$Xmin >= df$Xmin & df2$Xmax<=df$Xmax & df2$Ymin >= df$Ymin & df2$Ymax<=df$Ymax

期望的输出是

  Xmin Xmax   Ymin Ymax ID
1   13   17     12   18  1
2   15   17     21   25  2
3   17   19     20   22  2

有没有简单的方法可以做到这一点?

类似于 ifelse():

df= data.frame(Xmin=c(10,20),Xmax=c(20,20),Ymin=c(10,20),Ymax=c(20,25),ID=c(1,2))
df2=data.frame(Xmin=c(13,15,17),Xmax=c(17,17,19),Ymin=c(12,21,20),Ymax=c(18,25,22),ID=c(NA,NA,NA))

df2$ID = ifelse(df2$Xmin >= df$Xmin & df2$Xmax<=df$Xmax & df2$Ymin >= df$Ymin & df2$Ymax<=df$Ymax, df$ID, NA)

df2
#>   Xmin Xmax Ymin Ymax ID
#> 1   13   17   12   18  1
#> 2   15   17   21   25 NA
#> 3   17   19   20   22 NA

reprex package (v2.0.1)

创建于 2022-03-07

另一种可能的解决方案,基于tidyverse

library(tidyverse)

df2 %>% 
  rowwise() %>% 
  mutate(ID = df[Xmax <= df$Xmax & Xmin >= df$Xmin & Ymax <= df$Ymax & Ymin >= df$Ymin,"ID"][1]) %>% 
  ungroup

#> # A tibble: 3 x 5
#>    Xmin  Xmax  Ymin  Ymax    ID
#>   <dbl> <dbl> <dbl> <dbl> <dbl>
#> 1    13    17    12    18     1
#> 2    15    17    21    25     2
#> 3    17    19    20    22     2

我们可以使用 non-equi 加入此处

library(data.table)
df2$ID <- NULL
setDT(df2)[df, ID := i.ID, 
 on = .(Xmin >= Xmin, Xmax <= Xmax, Ymin >= Ymin, Ymax <= Ymax)]

-输出

> df2
    Xmin  Xmax  Ymin  Ymax    ID
   <num> <num> <num> <num> <num>
1:    13    17    12    18     1
2:    15    17    21    25     2
3:    17    19    20    22     2