R语言 match()的子集友好版本

gupuwyp2  于 2023-04-27  发布在  其他
关注(0)|答案(2)|浏览(89)

我不喜欢(或者说不理解)match()函数,因为如果它没有找到值,它会输出NA,而且它只返回第一次匹配的结果。
让数据成为

df1 <- data.frame(id=c(1:3,3:4), val= 11:15)
df2 <- data.frame(id= c(2,0,3,1), val=91:94)

我想用df2的id子集df1

df_expected <- data.frame(id= c(2,3,3,1), val= c(12,13,14,11))

但是如果我尝试使用df1[match(df2$id, df1$id), ]来子集化df1,我得到的不是我所期望的,首先,因为match返回一个NA,因为它不能t在df1中找到id 0,这会添加一行,其中只包含NA s,其次,因为它只返回id 3df1中的第一次出现,但我希望所有一场比赛的发生。
如何调整匹配函数,使其按上述方式运行?

py49o6xq

py49o6xq1#

您可以使用%in%which的组合。不过,输出不是按照您发布的顺序。

df1 <- data.frame(id=c(1:3,3:4), val= 11:15)
df2 <- data.frame(id= c(2,0,3,1), val=91:94)

i <- which(df1$id %in% df2$id)
df1[i, ]
#>   id val
#> 1  1  11
#> 2  2  12
#> 3  3  13
#> 4  3  14

创建于2023-04-22使用reprex v2.0.2

编辑

以下将给予已发布的订单。

df1 <- data.frame(id=c(1:3,3:4), val= 11:15)
df2 <- data.frame(id= c(2,0,3,1), val=91:94)

i <- df1$id[df1$id %in% df2$id]
j <- df2$id[df2$id %in% df1$id]
df1[order(match(i, j)), ]
#>   id val
#> 2  2  12
#> 3  3  13
#> 4  3  14
#> 1  1  11

创建于2023-04-22带有reprex v2.0.2

编辑2

在阅读了Ingo Pingo和TarJae的评论后,我将上述解决方案更改为

1

i <- which(df1$id %in% df2$id)
df1[order(match(df1$id[i], df2$id)),]
#>   id val
#> 2  2  12
#> 3  3  13
#> 4  3  14
#> 1  1  11

创建于2023-04-22使用reprex v2.0.2

j <- df1$id[df1$id %in% df2$id]
df1[order(match(j, df2$id)), ]
#>   id val
#> 2  2  12
#> 3  3  13
#> 4  3  14
#> 1  1  11

创建于2023-04-22使用reprex v2.0.2

gcmastyq

gcmastyq2#

这将给予预期的输出:

library(dplyr)

df1 %>%
  filter(id %in% df2$id) %>%
  arrange(match(id, df2$id)) 

  id val
1  2  12
2  3  13
3  3  14
4  1  11

或在碱R中:

df_subset <- df1[df1$id %in% df2$id, ]
df_subset[order(match(df_subset$id, df2$id)), ]

  id val
2  2  12
3  3  13
4  3  14
1  1  11

相关问题