#r #dplyr #data.table #match
#r #dplyr #данные.таблица #сопоставление
Вопрос:
Я ищу способ извлекать строки из одного фрейма данных на основе критериев из другого фрейма данных. Вот наглядный пример того, что я пытаюсь сделать:-
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)
По сути, я пытаюсь извлечь строки из моего df, сопоставляя 4-значные префиксы с первыми 4 цифрами в переменной «IDnumbers». В итоге я должен получить:-
aaa 01416783902
bbb 014138926949
ccc 01444783002
eee 01618769203
fff 015728936482
Код, который я пробовал, но который не сработал должным образом, заключается в следующем:-
results<-sapply(df2$prefix, grep, df1$IDnumbers)
Это не вернуло желаемый результат. Я полагаю, что в пакете dplyr и data.table есть решения, но я их не нашел. Любые предложения будут приветствоваться! Приветствия 🙂
Ответ №1:
Одним из способов является 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)
Ответ №2:
Мы можем просто использовать %in%
с точным совпадением, чтобы получить логический вектор после получения substr
ввода ‘IDnumbers’
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
Комментарии:
1. Это решение сработало действительно хорошо, особенно
stringr
решение. Большое вам спасибо !! 🙂