根据两个数据帧之间的部分字符串检索匹配的行

时间:2019-03-17 12:34:48

标签: r dplyr data.table match

我正在寻找一种基于来自另一个数据框的条件来检索来自一个数据框的行的方法。这是我要执行的操作的说明性示例:-

prefix<-c("0141", "0142", "0143", "0144", "0156", "0157", "0158", "0161")
IDnumbers<-c("01416783902", "014138926949", "01444783002", "07862738468", "01618769203", "015728936482", "07728394562","07264783959","02873819364")
IDnames<-c("aaa", "bbb", "ccc", "ddd", "eee", "fff", "ggg", "hhh", "iii")

df1<-cbind(IDnames, IDnumbers)
df2<-cbind(prefix)

基本上,我试图通过将4位数字前缀与“ IDnumbers”变量中的前4位数字匹配来从df中检索行。我应该以:-

结尾
aaa    01416783902
bbb    014138926949
ccc    01444783002
eee    01618769203
fff    015728936482

我尝试的无法正常工作的代码是:-

results<-sapply(df2$prefix, grep, df1$IDnumbers)

那没有返回期望的输出。我想在dplyr和data.table包中有解决方案,但我还没有找到。任何建议将是最欢迎的!干杯:)

2 个答案:

答案 0 :(得分:0)

一种方法是将paste中的prefix df2放在一个字符串中,并将subset中的df1的行匹配到该模式。

subset(df1, grepl(paste0("^",df2$prefix, collapse = "|"), IDnumbers))

#  IDnames    IDnumbers
#1     aaa  01416783902
#2     bbb 014138926949
#3     ccc  01444783002
#5     eee  01618769203
#6     fff 015728936482

作为参考,从paste0语句生成的模式是

paste0("^",df2$prefix, collapse = "|")
#[1] "^0141|^0142|^0143|^0144|^0156|^0157|^0158|^0161"

因此,它过滤了IDnumbers以任何这些数字开头的行。

数据

更改了数据格式,使其成为数据框而不是矩阵。

prefix<-c("0141", "0142", "0143", "0144", "0156", "0157", "0158", "0161")
IDnumbers<-c("01416783902", "014138926949", "01444783002", "07862738468", 
      "01618769203", "015728936482", "07728394562","07264783959","02873819364")
IDnames<-c("aaa", "bbb", "ccc", "ddd", "eee", "fff", "ggg", "hhh", "iii")

df1<-data.frame(IDnames, IDnumbers, stringsAsFactors = FALSE)
df2<-data.frame(prefix, stringsAsFactors = FALSE)

答案 1 :(得分:0)

我们只需在获得%in%的“ IDnumbers”之后,使用完全匹配的substr来获得逻辑矢量

subset(df1, substr(IDnumbers, 1, 4) %in% df2$prefix)
#   IDnames    IDnumbers
#1     aaa  01416783902
#2     bbb 014138926949
#3     ccc  01444783002
#5     eee  01618769203
#6     fff 015728936482

stringr版本1.4.0开始,我们还可以使用str_starts/str_ends

library(dplyr)
library(stringr)
df1 %>% 
    filter(str_starts(IDnumbers, paste(df2$prefix, collapse="|")))
# IDnames    IDnumbers
#1     aaa  01416783902
#2     bbb 014138926949
#3     ccc  01444783002
#4     eee  01618769203
#5     fff 015728936482