Oi Walmes, Obrigado por postar sua solução. Achei bem interessante. Como disse tem um custo computacional alto, comparada a função fuzzyjoin::regex_left_join(): Apliquei ambas soluções em um conjunto de 583872 linhas:
################################################################################ system.time( u <- sapply(patterns, FUN = grepl, x = df$nome) ) + system.time( df$medicamento <- apply(u, MARGIN = 1, FUN = function(x) { # Tá sendo assumido que apenas 1 match ocorre. index <- head(which(x), n = 1) ifelse(length(index), names(index), NA_character_) }) ) usuário sistema decorrido 275.638 0.649 276.237 > system.time( r <- fuzzyjoin::regex_left_join(df, Tabela_Antibiótico, by = "nome", ignore_case = TRUE) ) usuário sistema decorrido 2.579 0.000 2.578 > dim(df) [1] 583872 11 Após aplicar ambas soluções notei que ainda há um problema quando o nome do medicamento é composto. Por exemplo, o Antibiótico de nome *PIPERACILINA-TAZOBACTAM* teve como resultado apenas o primeiro nome, veja a saída abaixo: [image: image.png] Tem alguma sugestão de como fazer o match quando o nome é composto? Em seg., 15 de mar. de 2021 às 11:00, Walmes Zeviani por (R-br) < r-br@listas.c3sl.ufpr.br> escreveu: > Você pode combinar sapply, grepl e apply. > > # Lista de medicamentos que guardei em um objeto chamado patterns. > patterns <- c("Oritavancina", "Oxacilina", "Pefloxacino", "Penicilina", > "Pexiganan", "Piperacilina", "Piperacilina-tazobactam", > "Pirazinamida", "Plazomicina", "Polimixina B", > "Posilozid") > > # Amostra do Data frame em que preciso encontrar os nomes da lista acima. > df <- data.frame(nome = > c("CLORETO DE POTASSIO DRAGEA 600MG", > "CLORETO DE SODIO 0,9% SERINGA PREENCHIDA 5ML", > "CLORETO DE SODIO SOLUCAO INJETAVEL 0,9% 10ML", > "CODEINA FOSFATO SOLUCAO ORAL 3MGML 10ML ISCMPA @", > "CODEINA FOSFATO SOLUCAO ORAL 3MGML 5ML ISCMPA @", > "DipiRONA SOLUCAO INJETAVEL 500MGML 2ML", > "DipiRONA SOLUCAO INJETAVEL 500MGML 2ML", > "FUROSEMIDA SOLUCAO INJETAVEL 10MGML 2ML", > "HIDROCORTISONA SUCCINATO SODICO PO LIOFILO > INJETAVEL 100MG", > "ONDANSETRONA CLORIDRATO SOLUCAO INJETAVEL 2MGML > 4ML", > "ONDANSETRONA CLORIDRATO SOLUCAO INJETAVEL 2MGML > 4ML", > "Penicilina G BENZATINA PO LIOFILO INJETAVEL > 1200000UI", > "Penicilina G BENZATINA PO LIOFILO INJETAVEL > 1200000UI", > "PIPERACILINA SODICA 4G + TAZOBACTAM SODICA 0,5G PO > LIOFILO INJETAVEL")) > > u <- sapply(patterns, FUN = grepl, x = df$nome) > df$medicamento <- > apply(u, > MARGIN = 1, > FUN = function(x) { > # Tá sendo assumido que apenas 1 match ocorre. > index <- head(which(x), n = 1) > ifelse(length(index), > names(index), > NA_character_) > }) > > Atenção! > Se você tiver que fazer isso para muitos itens e muitos medicamentos onde > no máximo um match é esperado, esse código tá caro porque ele avalia o > match de cada produto (p produtos) com cada item (n itens) e retorna uma > matriz n * p de valores lógicos. Você pode escrever a instrução de forma > condicional: quando encontrar o primeiro match, passar para o próximo item. > Vai ter que fazer um benchmark porque as instruções vetorizadas são rápidas > e colocar condicionais em loops é um pouco lento. Tudo vai depender do p e > n do seu problema. > > Outra opção é verificar se não tem como usar um "inner join with > approximate matching". Confere o que tem no {stringdist} e {fuzzyjoin}. > > À disposição. > Walmes. > > _______________________________________________ > R-br mailing list > R-br@listas.c3sl.ufpr.br > https://listas.inf.ufpr.br/cgi-bin/mailman/listinfo/r-br > Leia o guia de postagem (http://www.leg.ufpr.br/r-br-guia) e forneça > código mínimo reproduzível. >
_______________________________________________ R-br mailing list R-br@listas.c3sl.ufpr.br https://listas.inf.ufpr.br/cgi-bin/mailman/listinfo/r-br Leia o guia de postagem (http://www.leg.ufpr.br/r-br-guia) e forneça código mínimo reproduzível.