[R-br] Identificando e criando nova variável por uma expressão regular

Felipe Barletta felipe.e.barletta em gmail.com
Seg Mar 15 15:42:39 -03 2021


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 em 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 em 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.
>
-------------- Próxima Parte ----------
Um anexo em HTML foi limpo...
URL: <http://listas.inf.ufpr.br/pipermail/r-br/attachments/20210315/d31c881a/attachment.html>
-------------- Próxima Parte ----------
Um anexo não-texto foi limpo...
Nome: image.png
Tipo: image/png
Tamanho: 40501 bytes
Descrição: não disponível
URL: <http://listas.inf.ufpr.br/pipermail/r-br/attachments/20210315/d31c881a/attachment.png>


Mais detalhes sobre a lista de discussão R-br