Estou tentando determinar se uma string é um subconjunto de outra string. Por exemplo:
chars <- "test"
value <- "es"
Quero retornar TRUE se "value" aparecer como parte da string "chars". No cenário a seguir, eu gostaria de retornar false:
chars <- "test"
value <- "et"
fixed=TRUE
, caso contrário, você a está tratando como uma expressão regular em vez de uma string. Veja minha resposta de outubro de 2016.fixed=TRUE
ou possui um erro que atrapalha discretamente e sutilmente seus dados.Respostas:
Use a
grepl
funçãoUse
?grepl
para descobrir mais.fonte
vec <- replicate(100000, paste( sample(letters, 10, replace=TRUE), collapse='') )
.system.time(a <- grepl("abc", vec))
esystem.time(a <- grepl("abc", vec, fixed=TRUE))
,fixed=TRUE
ainda assim, se algo ligeiramente mais lento. A diferença não é apreciável com essas seqüências curtas, masfixed=TRUE
ainda não parece ser mais rápida. Obrigado por apontar, porém, que é em longas seqüências quefixed=TRUE
levam o verdadeiro sucesso.Responda
Suspiro, levei 45 minutos para encontrar a resposta para esta pergunta simples. A resposta é:
grepl(needle, haystack, fixed=TRUE)
Interpretação
grep
é nomeado após o executável do Linux, o que em si é um acrônimo de " G lobal R egular E xpression P rint", ele iria ler linhas de entrada e, em seguida, imprimi-los se eles combinavam com os argumentos que você deu. "Global" significou que a correspondência poderia ocorrer em qualquer lugar da linha de entrada, explicarei abaixo "Expressão regular" abaixo, mas a ideia é que é uma maneira mais inteligente de corresponder à string (R chama esse "caractere", por exemploclass("abc")
) e "Print "porque é um programa de linha de comando, emitir saída significa que imprime na sua cadeia de saída.Agora, o
grep
programa é basicamente um filtro, das linhas de entrada às linhas de saída. E parece que agrep
função de R, da mesma forma, terá uma matriz de entradas. Por razões totalmente desconhecidas para mim (eu só comecei a jogar com o R há cerca de uma hora), ele retorna um vetor dos índices correspondentes, em vez de uma lista de correspondências.Mas, voltando à sua pergunta original, o que realmente queremos é saber se encontramos a agulha no palheiro, um valor verdadeiro / falso. Eles aparentemente decidiu nomear esta função
grepl
, como em "grep", mas com um " L valor de retorno ogical" (que eles chamam de valores lógicos verdadeiro e falso, por exemploclass(TRUE)
).Então, agora sabemos de onde o nome veio e o que ele deve fazer. Vamos voltar para expressões regulares. Os argumentos, mesmo que sejam cadeias, são usados para criar expressões regulares (doravante: regex). Um regex é uma maneira de corresponder a uma string (se essa definição o irritar, deixe-o ir). Por exemplo, a regex
a
corresponde ao caractere"a"
, a regexa*
corresponde ao caractere"a"
0 ou mais vezes e a regexa+
corresponde ao caractere"a"
1 ou mais vezes. Portanto, no exemplo acima, a agulha que estamos procurando1+2
, quando tratada como regex, significa "um ou mais 1 seguido de um 2" ... mas o nosso é seguido de um sinal de mais!Portanto, se você usasse a
grepl
configuração semfixed
, suas agulhas seriam acidentalmente palheiros e isso acidentalmente funcionaria com bastante frequência, podemos ver que funciona até para o exemplo do OP. Mas isso é um bug latente! Precisamos dizer que a entrada é uma string, não uma regex, que aparentementefixed
é para isso. Por que consertado? Nenhuma pista, marque esta resposta com um b / c. Você provavelmente terá que procurar mais 5 vezes antes de memorizá-la.Algumas considerações finais
Quanto melhor o seu código, menos histórico você precisa conhecer para entender o código. Todo argumento pode ter pelo menos dois valores interessantes (caso contrário, não precisaria ser um argumento), os documentos listam 9 argumentos aqui, o que significa que há pelo menos 2 ^ 9 = 512 maneiras de invocá-lo, é muito trabalho para escreva, teste e lembre-se ... dissocie essas funções (divida-as, remova dependências umas das outras, as coisas de string são diferentes do que as expressões regulares, as coisas do vetor). Algumas das opções também são mutuamente exclusivas, não fornecem aos usuários maneiras incorretas de usar o código, ou seja, a chamada problemática deve ser estruturalmente sem sentido (como passar uma opção que não existe), não logicamente sem sentido (onde você precisa emitir um aviso para explicá-lo). Coloque metaforicamente: substituir a porta da frente no lado do 10º andar por uma parede é melhor do que pendurar uma placa que adverte contra seu uso, mas também é melhor que nenhuma. Em uma interface, a função define como devem ser os argumentos, e não o chamador (porque o chamador depende da função, inferindo tudo o que todos desejam chamar) faz com que a função dependa também dos chamadores e desse tipo de dependência cíclica entupirá rapidamente um sistema e nunca fornecerá os benefícios que você espera). Desconfie de tipos equivocados, é uma falha de design que coisas como inferir tudo o que todos podem querer chamar também faz com que a função dependa dos chamadores, e esse tipo de dependência cíclica entupirá rapidamente um sistema e nunca fornecerá os benefícios que você espera). Desconfie de tipos equivocados, é uma falha de design que coisas como inferir tudo o que todos podem querer chamar também faz com que a função dependa dos chamadores, e esse tipo de dependência cíclica entupirá rapidamente um sistema e nunca fornecerá os benefícios que você espera). Desconfie de tipos equivocados, é uma falha de design que coisas como
TRUE
e0
e"abc"
são todos vetores.fonte
grep
filtragem de linhas, não de células.Você quer
grepl
:fonte
Use esta função do
stringi
pacote:Alguns benchmarks:
fonte
Além disso, pode ser feito usando a biblioteca "stringr":
fonte
Caso você também queira verificar se uma string (ou um conjunto de strings) contém várias sub-strings, você também pode usar o '|' entre duas substrings.
Você vai ter
já que a 1ª palavra tem substring "as" e a última palavra contém substring "at"
fonte
Use
grep
ougrepl
esteja ciente de que deseja ou não usar expressões regulares .Por padrão,
grep
e relacionados usam uma expressão regular para corresponder, não uma substring literal. Se você não espera isso e tenta corresponder a um regex inválido, ele não funciona:Para fazer um verdadeiro teste de substring, use
fixed = TRUE
.Se você quer regex, ótimo, mas não é isso que o OP parece estar perguntando.
fonte
Você pode usar
grep
fonte
Problema semelhante aqui: dada uma string e uma lista de palavras-chave, detecte quais delas, se houver, estão contidas na string.
Recomendações de esta discussão sugerem
stringr
'sstr_detect
egrepl
. Aqui estão os benchmarks domicrobenchmark
pacote:Usando
e depois
nós achamos
Como você pode ver, mais de 5.000 iterações da pesquisa de palavras-chave usando
str_detect
egrepl
sobre uma sequência prática e um vetor de palavras-chave têm umgrepl
desempenho um pouco melhor questr_detect
.O resultado é o vetor booleano
r
que identifica quais, se houver alguma, das palavras-chave estão contidas na string.Portanto, recomendo usar
grepl
para determinar se alguma palavra-chave está em uma sequência.fonte