如何根据另一个数据框中的条件匹配数据框中的列值?
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
我有两个行数不同的数据框,下面是简单的例子:
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