AskOverflow.Dev

AskOverflow.Dev Logo AskOverflow.Dev Logo

AskOverflow.Dev Navigation

  • Início
  • system&network
  • Ubuntu
  • Unix
  • DBA
  • Computer
  • Coding
  • LangChain

Mobile menu

Close
  • Início
  • system&network
    • Recentes
    • Highest score
    • tags
  • Ubuntu
    • Recentes
    • Highest score
    • tags
  • Unix
    • Recentes
    • tags
  • DBA
    • Recentes
    • tags
  • Computer
    • Recentes
    • tags
  • Coding
    • Recentes
    • tags
Início / coding / Perguntas / 79573539
Accepted
Rinke
Rinke
Asked: 2025-04-14 23:46:24 +0800 CST2025-04-14 23:46:24 +0800 CST 2025-04-14 23:46:24 +0800 CST

R: substituir múltiplas ocorrências de strings correspondentes a regex em campos de dataframe, pesquisando-as em outro dataframe

  • 772

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:

  1. "descrição sem correspondência"
  2. "descrição com uma correspondência"
  3. "descrição sem correspondência novamente"
  4. "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.

  • 5 5 respostas
  • 97 Views

5 respostas

  • Voted
  1. Best Answer
    jpsmith
    2025-04-15T00:11:28+08:002025-04-15T00:11:28+08:00

    Uma abordagem básica R pode usar Reduce:

    Reduce(
      \(x, i) gsub(lookup$oldId[i], lookup$newId[i], x),
      seq_along(lookup$oldId),
      init = descr
    )
    

    Saída:

    [1] "description with no match"        "description with one 1 match"    
    [3] "description with again no match"  "description 2 with two 4 matches"
    
    • 5
  2. Ronak Shah
    2025-04-15T00:34:27+08:002025-04-15T00:34:27+08:00

    Uma opção usando gsubfn:

    gsubfn::gsubfn("\\d+", as.list(setNames(lookup$newId, lookup$oldId)), descr)
    
    #[1] "description with no match"        "description with one 1 match"    
    #[3] "description with again no match"  "description 2 with two 4 matches"
    
    • 3
  3. SamR
    2025-04-14T23:54:46+08:002025-04-14T23:54:46+08:00

    Você pode fornecer uma função como replacementargumento para stringr::str_replace_all():

    stringr::str_replace_all(
        descr,
        "([[:digit:]]{3})",
        \(x, old = lookup$oldId, new = lookup$newId) new[old == x]
    )
    # [1] "description with no match"        "description with one 1 match"     "description with again no match"  "description 2 with two 4 matches"
    
    • 2
  4. jay.sf
    2025-04-15T00:35:16+08:002025-04-15T00:35:16+08:00

    Para que sua função funcione, você precisaria matchdo resultado da pesquisa, algo como:

    fx <- \(x) {
      m <- regmatches(x, gregexpr('\\b\\d{3}\\b', x, perl=TRUE))
      mapply(\(a, b) {
        for (i in seq_along(b)) {
          a <- gsub(sprintf('\\b%s\\b', b[i]), lookup$newId[match(b[i], lookup$oldId)], a)
        }
        a
      }, x, m, USE.NAMES=FALSE)
    }
    

    \\bcorresponde aos limites das palavras, garantindo que apenas números completos como 123sejam substituídos, não substrings como 1234ou a123.

    > sapply(descr, fx)
               description with no match       description with one 123 match 
             "description with no match"       "description with one 1 match" 
         description with again no match description 456 with two 789 matches 
       "description with again no match"   "description 2 with two 4 matches" 
    
    • 1
  5. 2025-04-15T01:02:58+08:002025-04-15T01:02:58+08:00

    str_replace_allpode pegar um vetor nomeado como padrão como str_replace_all(c("one" = "1", "two" = "2", "three" = "3")), então você também pode fazer

    stringr::str_replace_all(descr, setNames(as.character(newId),as.character(oldId)))
    [1] "description with no match"        "description with one 1 match"  
    [3] "description with again no match"  "description 2 with two 4 matches"
    
    • 1

relate perguntas

  • Adicionar número de série para atividade de cópia ao blob

  • A fonte dinâmica do empacotador duplica artefatos

  • Selecione linhas por grupo com 1s consecutivos

  • Lista de chamada de API de gráfico subscritoSkus estados Privilégios insuficientes enquanto os privilégios são concedidos

  • Função para criar DFs separados com base no valor da coluna

Sidebar

Stats

  • Perguntas 205573
  • respostas 270741
  • best respostas 135370
  • utilizador 68524
  • Highest score
  • respostas
  • Marko Smith

    Reformatar números, inserindo separadores em posições fixas

    • 6 respostas
  • Marko Smith

    Por que os conceitos do C++20 causam erros de restrição cíclica, enquanto o SFINAE antigo não?

    • 2 respostas
  • Marko Smith

    Problema com extensão desinstalada automaticamente do VScode (tema Material)

    • 2 respostas
  • Marko Smith

    Vue 3: Erro na criação "Identificador esperado, mas encontrado 'import'" [duplicado]

    • 1 respostas
  • Marko Smith

    Qual é o propósito de `enum class` com um tipo subjacente especificado, mas sem enumeradores?

    • 1 respostas
  • Marko Smith

    Como faço para corrigir um erro MODULE_NOT_FOUND para um módulo que não importei manualmente?

    • 6 respostas
  • Marko Smith

    `(expression, lvalue) = rvalue` é uma atribuição válida em C ou C++? Por que alguns compiladores aceitam/rejeitam isso?

    • 3 respostas
  • Marko Smith

    Um programa vazio que não faz nada em C++ precisa de um heap de 204 KB, mas não em C

    • 1 respostas
  • Marko Smith

    PowerBI atualmente quebrado com BigQuery: problema de driver Simba com atualização do Windows

    • 2 respostas
  • Marko Smith

    AdMob: MobileAds.initialize() - "java.lang.Integer não pode ser convertido em java.lang.String" para alguns dispositivos

    • 1 respostas
  • Martin Hope
    Fantastic Mr Fox Somente o tipo copiável não é aceito na implementação std::vector do MSVC 2025-04-23 06:40:49 +0800 CST
  • Martin Hope
    Howard Hinnant Encontre o próximo dia da semana usando o cronógrafo 2025-04-21 08:30:25 +0800 CST
  • Martin Hope
    Fedor O inicializador de membro do construtor pode incluir a inicialização de outro membro? 2025-04-15 01:01:44 +0800 CST
  • Martin Hope
    Petr Filipský Por que os conceitos do C++20 causam erros de restrição cíclica, enquanto o SFINAE antigo não? 2025-03-23 21:39:40 +0800 CST
  • Martin Hope
    Catskul O C++20 mudou para permitir a conversão de `type(&)[N]` de matriz de limites conhecidos para `type(&)[]` de matriz de limites desconhecidos? 2025-03-04 06:57:53 +0800 CST
  • Martin Hope
    Stefan Pochmann Como/por que {2,3,10} e {x,3,10} com x=2 são ordenados de forma diferente? 2025-01-13 23:24:07 +0800 CST
  • Martin Hope
    Chad Feller O ponto e vírgula agora é opcional em condicionais bash com [[ .. ]] na versão 5.2? 2024-10-21 05:50:33 +0800 CST
  • Martin Hope
    Wrench Por que um traço duplo (--) faz com que esta cláusula MariaDB seja avaliada como verdadeira? 2024-05-05 13:37:20 +0800 CST
  • Martin Hope
    Waket Zheng Por que `dict(id=1, **{'id': 2})` às vezes gera `KeyError: 'id'` em vez de um TypeError? 2024-05-04 14:19:19 +0800 CST
  • Martin Hope
    user924 AdMob: MobileAds.initialize() - "java.lang.Integer não pode ser convertido em java.lang.String" para alguns dispositivos 2024-03-20 03:12:31 +0800 CST

Hot tag

python javascript c++ c# java typescript sql reactjs html

Explore

  • Início
  • Perguntas
    • Recentes
    • Highest score
  • tag
  • help

Footer

AskOverflow.Dev

About Us

  • About Us
  • Contact Us

Legal Stuff

  • Privacy Policy

Language

  • Pt
  • Server
  • Unix

© 2023 AskOverflow.DEV All Rights Reserve