No R há várias funções para manipular textos (ou strings). No entanto, as funções do base não possuem uma interface consistente e cada uma tem a sua forma de passar os argumentos, dificultando a programação durante a análise.
Problemas: é bastante comum encontrarmos colunas com categorias não padronizadas, como, por exemplo, para a variável estado com “MG”, “mg”, “Minas gerais”, “Minas Gerais”, etc, todas indicando o mesmo estado.
Pensando nisso, Hadley Wickham criou o pacote stringr, que possui uma sintaxe mais consistente, permitindo ao usuário manipular textos com muito mais facilidade.
## O básico do pacote stringr
# install.packages("stringr")
library(stringr)
## Warning: package 'stringr' was built under R version 3.6.1
library(tidyverse)
## Warning: package 'tidyverse' was built under R version 3.6.1
## -- Attaching packages ---------------------------------------------- tidyverse 1.2.1 --
## v ggplot2 3.2.1 v readr 1.3.1
## v tibble 2.1.3 v purrr 0.3.2
## v tidyr 1.0.0 v dplyr 0.8.3
## v ggplot2 3.2.1 v forcats 0.4.0
## Warning: package 'ggplot2' was built under R version 3.6.1
## Warning: package 'tibble' was built under R version 3.6.1
## Warning: package 'tidyr' was built under R version 3.6.1
## Warning: package 'dplyr' was built under R version 3.6.1
## -- Conflicts ------------------------------------------------- tidyverse_conflicts() --
## x dplyr::filter() masks stats::filter()
## x dplyr::lag() masks stats::lag()
vogais<-c("a","e","i","o","u")
str_length(vogais)
## [1] 1 1 1 1 1
palavras<-c("Estatística","Regressão","Modelos Lineares")
str_length(palavras)
## [1] 11 9 16
length(vogais)
## [1] 5
length(palavras)
## [1] 3
# combiando strings
str_c("a","b","c")
## [1] "abc"
str_c("a","b","c", sep = ";")
## [1] "a;b;c"
str_c("x",c("a","b","c"),"y")
## [1] "xay" "xby" "xcy"
# subconjunto de strigs
f<-c("laranja","maça","pera")
str_sub(f,2,4)
## [1] "ara" "aça" "era"
s <- c("__SP__", "__MG__", "__RJ__")
str_sub(s, 3, 4)
## [1] "SP" "MG" "RJ"
# modificar caixa de letras
curso<-c("Este é um curso de Estatística")
str_to_lower(curso)
## [1] "este é um curso de estatística"
str_to_upper(curso)
## [1] "ESTE É UM CURSO DE ESTATÍSTICA"
str_to_title(curso)
## [1] "Este É Um Curso De Estatística"
# concatenar strigs
string1 <- "O valor de x na expressão é: "
string2 <- 1.01
str_c(string1, string2)
## [1] "O valor de x na expressão é: 1.01"
# dividindo uma string em caracteres
str_split("Estatística Aplicada à Análise de Dados","")
## [[1]]
## [1] "E" "s" "t" "a" "t" "í" "s" "t" "i" "c" "a" " " "A" "p" "l" "i" "c"
## [18] "a" "d" "a" " " "à" " " "A" "n" "á" "l" "i" "s" "e" " " "d" "e" " "
## [35] "D" "a" "d" "o" "s"
str_split("Estatística Aplicada à Análise de Dados","a")
## [[1]]
## [1] "Est" "tístic" " Aplic" "d"
## [5] " à Análise de D" "dos"
# contar caracteres
str1<-"Estatística Aplicada à Análise de Dados"
str_count(str1,"E")
## [1] 1
str_count(str1,"e")
## [1] 2
# localizar caracteres
str_locate(str1,"A")
## start end
## [1,] 13 13
str_locate_all(str1,"A")
## [[1]]
## start end
## [1,] 13 13
## [2,] 24 24
# substituir caracteres
str_replace(str1,"A","a")
## [1] "Estatística aplicada à Análise de Dados"
str_replace_all(str1,"A","a")
## [1] "Estatística aplicada à análise de Dados"
É comum encontrar textos que vêm com espaços a mais, principalmente de dados provenientes de formulários em que cada usuário escreve da forma que prefere. Isso é um problema pois cria categorias diferentes para valores que deveriam ser iguais.
s <- c("M", "F", "F", " M", " F ", "M")
as.factor(s)
## [1] M F F M F M
## Levels: F M F M
# A função str_trim() ajuda removendo os espaços excedentes antes e depois da string.
string_certa <- str_trim(s)
string_certa
## [1] "M" "F" "F" "M" "F" "M"
As expressões regulares “ou simplesmente regex” permitem identificar conjuntos de caracteres, palavras e outros padrões por meio de uma sintaxe concisa.
As expressões regulares são úteis, pois, as strings normalmente contêm dados desestruturados ou semiestruturados e as regexs são uma linguagem concisa para descrever tais padrões em strings.
#install.packages("htmlwidgets")
x<-c("banana","maça","morango")
str_view(x,"an")
str_view_all(x,"an")
str_view(x,"^ban") # reconhece apenas o que começa exatamente com "ban"
str_view(x,"b?an") # ‘b?an’ reconhece tudo que tenha "ban", com ou sem espaço entre o "b" e o "a"
str_view(x,"ban")
str_view(x,"BAN")
str_view(x,"ban$") # ‘ban$’ reconhece apenas o que termina exatamente em "ban"
# ^ combina o começo da strig e $ o fim da strig.
str_detect("sao paulo", pattern = "paulo$")
## [1] TRUE
str_detect("sao paulo sp", pattern = "paulo$")
## [1] FALSE
# Outros exemplos
palavras<-c("inocente", "incógnita","inseguro","insignifcate","seguro")
str_view(palavras, pattern = "^in")
str_view(palavras, pattern = "e$")
A regex/pattern “paulo$” indica que o texto deve ser terminado em “paulo”. Existem diversos caracteres auxiliares que auxiliam na manipulação de textos como o “$“.
Importante: o valor passado para o argumento pattern de qualquer função do pacote stringr será entendido como uma regex.
Os caracteres +, * e {x,y} indicam quantas vezes um padrão se repete:
ey+ significa e e depois y “uma vez ou mais”. Por exemplo, reconhece hey, heyy, a eyyy, mas não reconhece e, y nem yy.
ey* significa “nenhuma vez ou mais”. Por exemplo, reconhece hey, heyy, a eyyy e e, mas não reconhece y nem yy.
ey{3} significa “exatamente três vezes”. Por exemplo, reconhece eyyy e eyyyy, mas não reconhece eyy.
ey{1,3} significa “entre uma e três vezes”.
Colocando caracteres dentro de [], reconhecemos quaisquer caracteres desse conjunto.
[Cc]asa para reconhecer “casa” em maiúsculo ou minúsculo.
[0-9] para reconhecer somente números. O mesmo vale para letras [a-z], [A-Z], [a-zA-Z] etc.
[^abc] combina qualquer coisa, exceto a, b ou c.
[^0-9] significa pegar tudo o que não é número.
O símbolo .(ponto) fora do colchete indica “qualquer caractere”, mas dentro do colchete é apenas ponto.
Podemos usar [[:space:]]+ para reconhecer espaços e [[:punct:]]+ para reconhecer pontuações.
{n}: exatamente n
{n,}: n ou mais
{,m}: no máximo m
{n,m}: entre n e m.
#install.packages("abjutils")
library(abjutils)
## Warning: package 'abjutils' was built under R version 3.6.1
a<-"Olá, como vocês estão?"
a<-rm_accent(a)
a
## [1] "Ola, como voces estao?"
# ou da forma:
RemoveAcentos <- function(textoComAcentos) {
if(!is.character(textoComAcentos)){
on.exit()
}
letrasComAcentos <- "áéíóúÁÉÍÓÚýÝàèìòùÀÈÌÒÙâêîôûÂÊÎÔÛãõÃÕñÑäëïöüÄËÏÖÜÿçÇ´`^~¨"
letrasSemAcentos <- "aeiouAEIOUyYaeiouAEIOUaeiouAEIOUaoAOnNaeiouAEIOUycC "
textoSemAcentos <- chartr(
old = letrasComAcentos,
new = letrasSemAcentos,
x = textoComAcentos
)
return(textoSemAcentos)
}
a1<-c("Olá, como vocês estão?")
RemoveAcentos(a1)
## [1] "Ola, como voces estao?"
Podemos usar as funções tolower() e toupper() para mudar o case de uma string.
Um bom lugar para testar o funcionamento das regex é regex101 (https://regex101.com/).
str_detect() - Retorna TRUE se a regex é compatível com a string e FALSE caso contrário.
library(stringr)
str_detect('sao paulo', pattern = 'paulo$')
## [1] TRUE
str_detect('sao paulo', pattern = '^sao')
## [1] TRUE
str_detect('sao paulo', pattern = '^paulo')
## [1] FALSE
# str_replace() e str_replace_all() - Substituem um padrão (ou todos) encontrado para um outro padrão
titulos <- c("o arqueiro", "o andarilho", "o herege")
# remove a primeira vogal de cada string
str_replace(titulos, "[aeiou]", "")
## [1] " arqueiro" " andarilho" " herege"
# substitui todas as vogais por "v"
str_replace_all(titulos, "[aeiou]", "v")
## [1] "v vrqvvvrv" "v vndvrvlhv" "v hvrvgv"
s <- "-- ffffWda, --- unWvers-- e tud- maWs"
# substitui o primeiro f (ou f"s) por "v"
s <- str_replace(s, "f+", "v")
s
## [1] "-- vWda, --- unWvers-- e tud- maWs"
# substitui o primeiro hífen (ou hífens) por "A"
s <- str_replace(s, "-+", "A")
s
## [1] "A vWda, --- unWvers-- e tud- maWs"
# str_extract() - Retorna a primeira ocorrência do padrão especificado
codigo <- c("Esse código", "pega a 1ª", "ocorrência de cada palavra")
str_extract(codigo, pattern = "[a-z]{4}")
## [1] "digo" "pega" "ocor"
str_extract(codigo, pattern = "[a-z]{6}")
## [1] NA NA "palavr"
str_extract(codigo, pattern = "[A-z]{4}")
## [1] "Esse" "pega" "ocor"
str_extract(codigo, pattern = "[A-Z]{4}")
## [1] NA NA NA
str_extract(codigo, pattern = "[a-zA-Z]{4}")
## [1] "Esse" "pega" "ocor"
str_extract(codigo, pattern = "[0-9]")
## [1] NA "1" NA
# str_match() - Verifica se o padrão desejado existe na string de interesse e retorna tal padrão
sequencia<- c("#FFFFFF")
str_match(sequencia, pattern = c("^#[A-Z]{6}$", "FFFFFF"))
## [,1]
## [1,] "#FFFFFF"
## [2,] "FFFFFF"
# eliminar espaços desnecessários
a2<-c("Olá, como vocês estão ?")
a2<-str_squish(a2)
a2
## [1] "Olá, como vocês estão ?"
texto<-c("Durante um longo período de tempo o 'R' foi escrito 'P' como no alfabeto cirílico. O seu nome no alfabeto fenício era 'rech'. Seu significado era o de uma cabeça, representada pela adaptação do hieróglifo egípcio de uma cabeça. Transformou-se no 'rô' dos gregos. Os romanos modificaram o 'rô' acrescentando um pequeno traço para diferenciá-lo do no nosso 'P' string")
cat(str_wrap(texto, width = 50) , "\n")
## Durante um longo período de tempo o 'R' foi
## escrito 'P' como no alfabeto cirílico. O seu nome
## no alfabeto fenício era 'rech'. Seu significado
## era o de uma cabeça, representada pela adaptação
## do hieróglifo egípcio de uma cabeça. Transformou-
## se no 'rô' dos gregos. Os romanos modificaram
## o 'rô' acrescentando um pequeno traço para
## diferenciá-lo do no nosso 'P' string
Q1) O CPF é um número de 11 dígitos, por exemplo: 54491651884. No entanto para facilitar a visualização costumamos mostrá-lo com separadores a cada 3 casas: 544.916.518-84. Crie uma função que transforma um número de 11 dígitos em uma string com as separações, como um CPF.
Q2) Crie uma regex que capture múltiplas versões da palavra ‘casa’. Ela deve funcionar com as palavras ‘Casa’, ‘CASA’, ‘CaSa’, ‘CAsa’. Teste-a usando a função str_detect().
Q3) De acordo com as regras da língua portuguesa, antes de ‘p’ ou ‘b’ devemos usar a letra ‘m’. Em outras palavras, com outras consoantes, usamos a letra ‘N’. Suponha que você tem o seguinte texto com erros gramaticais:
s <- ‘Nós chamamos os bonbeiros quando começou o incêmdio.’
Q4) Proceda a ‘limpeza’ do texto que segue:
“toda_Escolha___quE_você_FizEr_E_toda_DECisão_quE_você_toMar_ tErá_sEu_lado_boM_E_sEu_lado_ruiM.@.@_considErE-os__ coM_cuidado_E_toME_a_dEcisão.@UMa_rEsposta_ MEnos_quE_pErfEita_é_infinitaMEntE_MElhor_do_quE_não_fazEr_nada_.@ Tudo_quE_vocE_sE_dispõE_a_fazEr_EnvolvE_alguns_ riscos_E_dEsafios.@_Para_qualquEr_coisa_quE_você_EMprEEndEr_ ExistEM_ Muitas_razõEs_para_não_fazê-lo.@_PEsE_os_ riscos_E_os_bEnEfícios_E,_Então_assuMa_o_coMproMisso_dE_agir.@_DEcida_o_quE_você_ quEr_fazEr,coM_os_olhos_bEM_abErtos,E lEvE_isso_EM_frEntE_sEM_olhar_para_trás.@ ExistEM_Muitas_dirEçõEs_dEntrE_as_quais você_podE_EscolhEr.@_MEsMo_assiM,você_prEcisa_EscolhEr. @_Suas_possibilidadEs_são_ significativas_apEnas_quando_você_EscolhE alguMas_dElas__E_rEjEita_o_rEsto.@_TEntar_fazEr_tudo_ao_MEsMo_tEMpo_é_ tão_inútil_ quanto_não_tEntar_nada.@ DEfina-sE.@_Escolha_sEu_caMinho_E_coMEcE_ a_andar.@_DEcida_o_quE_quEr_fazEr_E_Mãos_à_obra.@"