2017-01-04 13 views
2

У меня есть несколько баз данных для закупки, в которых мне нужно запустить список «ключевых слов», которые я создал для идентификации определенных продуктов, и если есть совпадение, я хотел бы пометить продуктов в хирургическую категорию.R частичное соответствие строк и возвращаемое значение (в R)

Вот пример.

базы данных закупок (на самом деле у меня есть более чем 2,000,000 линии перейти):

d<-data.frame(prod_desc=c("BANDELETTE TVTO-OBTRYX HALO", "BANDELETTE MINI ARC PRECISES", "BANDELETTE D'ANALYSE POUR GLYCEMIE", "DIACH. BANDELETTE STER 19MM X 72MM","SLING MALE SYSTEM","DIACHILON","AIGUILLE","GANT","LABEL","CRAYON"),label=1:10) 

Список ключевых слов и возвращаемого значения (фактический список гораздо больше):

kw<-data.frame(kw=c("bandelette","tvt","bande transvaginale","sling system","argus"),category="ss_bandelette") 

Я хотел бы чтобы найти продукты prod_desc, содержащие строку ключевых слов kw, и если есть совпадение, я хотел бы добавить столбец в фрейм данных d, который вернет category, связанный с kw, в kw dataframe.

Пока я был в состоянии достичь желаемого результата, используя следующий код:

d$match <- ifelse(d$cat <- grepl(paste(kw$kw,collapse="|"), d$name,ignore.case = TRUE) == "TRUE","SS_Bandelette","-") 

Но этот код не очень эффективен, так как у меня есть около 350 ключевых слов, которые сопоставляются с около 30 различных категорий. Какой код я могу использовать для автоматического возврата категории в фреймворк d, если срабатывает одно из ключевых слов?

Большое спасибо за помощь.

Phil

+1

@DarshanBaral Я думаю, этот вопрос по-другому. даже я думал то же самое раньше. Я отправил ответ –

ответ

1
# made all to lowercase 
d$prod_desc <- tolower(d$prod_desc) 
# create a logical matrix that specifies which keywords are present on each row of 'd' 
m = data.frame(sapply(kw$kw, grepl, d$prod_desc)) 
colnames(m) = kw$kw 

# create a column in 'd' with the corresponding keyword  
d$kw <- apply(m, 1, function(x) names(x)[which(x)[1]]) 
# simple merge 
merge(d, kw, by = "kw", all.x = T) 

#   kw       prod_desc label  category 
#1 bandelette bandelette d'analyse pour glycemie  3 ss_bandelette 
#2 bandelette diach. bandelette ster 19mm x 72mm  4 ss_bandelette 
#3 bandelette  bandelette tvto-obtryx halo  1 ss_bandelette 
#4 bandelette  bandelette mini arc precises  2 ss_bandelette 
#5  <NA>     sling male system  5   <NA> 
#6  <NA>       diachilon  6   <NA> 
#7  <NA>       aiguille  7   <NA> 
#8  <NA>        gant  8   <NA> 
#9  <NA>        label  9   <NA> 
#10  <NA>        crayon 10   <NA> 
+0

@PhilippeLachapelle Я не уверен, правильно ли я понял. Холодно, вы проверяете это на своих реальных данных и дайте мне знать –

+0

Джоэл, спасибо вам большое. Он работает красиво. Спасибо за быстрый ответ. Я изучу ваш код сейчас! С уважением. PL –

+0

@PhilippeLachapelle ум через этот http://stackoverflow.com/help/someone-answers –

0
# Create dataframe as per original question 
d<-data.frame(prod_desc=c("BANDELETTE TVTO-OBTRYX HALO", "BANDELETTE MINI ARC PRECISES", "BANDELETTE D'ANALYSE POUR GLYCEMIE", "DIACH. BANDELETTE STER 19MM X 72MM","SLING MALE SYSTEM","DIACHILON","AIGUILLE","GANT","LABEL","CRAYON"),label=1:10) 
# Create keywords as per origianl question 
kw<-data.frame(kw=c("bandelette","tvt","bande transvaginale","sling system","argus"),category="ss_bandelette") 
# Assume you want match/tag string on word boundaries? If not; "BANDELETTE TVTO-OBTRYX HALO" would match to "tvt" for instance. 
kw$kw <- paste0("\\b",kw$kw,"\\b") 

x <- sapply(kw$kw, function(x) grepl(tolower(x), tolower(d$prod_desc))) 
d$Match <- apply(x, 1, function(i) paste0(names(i)[i])) 
d$Match <- kw$category[match(d$Match,kw$kw)] 
d 
#        prod_desc label   Match 
# 1   BANDELETTE TVTO-OBTRYX HALO  1 ss_bandelette 
# 2  BANDELETTE MINI ARC PRECISES  2 ss_bandelette 
# 3 BANDELETTE D'ANALYSE POUR GLYCEMIE  3 ss_bandelette 
# 4 DIACH. BANDELETTE STER 19MM X 72MM  4 ss_bandelette 
# 5     SLING MALE SYSTEM  5   <NA> 
# 6       DIACHILON  6   <NA> 
# 7       AIGUILLE  7   <NA> 
# 8        GANT  8   <NA> 
# 9        LABEL  9   <NA> 
# 10        CRAYON 10   <NA> 
Смежные вопросы