Tenho dois dataframes:
pesquisa df:
oldId <- c(123, 456, 567, 789)
newId <- c(1, 2, 3, 4)
lookup <- data.frame(oldId, newId)
dados df:
descr <- c("description with no match",
+ "description with one 123 match",
+ "description with again no match",
+ "description 456 with two 789 matches")
Meta:
Quero um novo dataframe:
- mesma estrutura que os dados df
- mesmos valores de campo, exceto que todas as instâncias de números (ou seja, 123, 456, 789) são pesquisadas no outro dataframe e substituídas por lookup$newId.
O dataframe resultante ficará assim:
- "descrição sem correspondência"
- "descrição com uma correspondência"
- "descrição sem correspondência novamente"
- "descrição 2 com duas 4 correspondências"
Portanto, cada texto na coluna descr pode conter uma grande quantidade de números que precisam ser substituídos. Claro, este é um exemplo simplificado; meus dataframes da vida real são muito maiores.
Eu corrigi a parte regex:
fx <- function(x) {gsub("([[:digit:]]{3})", "TESTTEST", x)}
data$descr <- lapply(data$descr, fx)
Mas não tenho ideia de como deixar a função percorrer todas as correspondências em uma linha e, então, procurar o número e substituí-lo.
Uma abordagem básica R pode usar
Reduce
:Saída:
Uma opção usando
gsubfn
:Você pode fornecer uma função como
replacement
argumento parastringr::str_replace_all()
:Para que sua função funcione, você precisaria
match
do resultado da pesquisa, algo como:\\b
corresponde aos limites das palavras, garantindo que apenas números completos como123
sejam substituídos, não substrings como1234
oua123
.str_replace_all
pode pegar um vetor nomeado como padrão comostr_replace_all(c("one" = "1", "two" = "2", "three" = "3"))
, então você também pode fazer