Lapidando strings

A manipulação eficaz de dados frequentemente envolve lidar com strings, que consistem em letras, símbolos e números representando informações escritas. Descubra como abordar strings utilizando o R.
Data Wrangling
R
Análise de Dados
Programação
Autor

Pedro de Brito Neto

Data de Publicação

1 de julho de 2021

Um desafio muito grande na manipulação de dados é extrair informações de caracteres. Em resumo caracteres são letras, símbolos, sinais, números que representem algo escrito, etc.. Essa sequência de caracteres formam o que chamamos de string. Diversas vezes encontramos variáveis com categorias não padronizadas, como, por exemplo, uma variável contendo “São Paulo”, “sao paulo” e “sp”. Apesar de representarem o mesmo estado, elas são diferentes. Nesse sentido, uma parte muito importante no tratamento de dados é “lapidar” esse conjunto de caracteres para que seja possível usá-los nas análises.

Algumas tarefas relacionadas a string’s podem ser listadas, como:

Uma das principais soluções para isso é fazer o uso de funções e expressões regulares, do inglês regular expressions (Regex). O proprio R possui algumas funções que nos ajudam a trabalhar com string’s. Porém, o pacote stringr pertencente ao universo tidyverse deixa essas (e outras) funções de uma maneira muito mais intuitiva de ser utilizada.

Vamos primeiro mostrar algumas funções básicas do pacote que podem nos auxiliar nessa manipulação de caracteres e depois falaremos sobre as expressões regulares. Com um breve conhecimento em ambas as partes (funções e Regex), podemos juntá-las e com isso tornar nossas análises muito mais fáceis.

Para usar o pacote podemos importá-lo diretamente ou através do tidyverse. Para o post vamos carregar o tidyverse pois iremos utilizar algumas funções de outros pacotes. Vale lembrar que já fizemos um post sobre o tidyverse e você pode acessá-lo clicando aqui.

Código
# carregando o stringr através do tidyverse
library(tidyverse)

str_length

A primeira função que vamos falar é a str_length. Essa é uma função bem simples do stringr que tem como objetivo fornecer o número de caracteres de uma string, ou seja, o comprimento da string (não confunda com o length() de um vetor). Uma observação é que para valores NA ela irá retornar NA, ao invés de contar o número de caracteres na string NA. Vamos a um exemplo

Código
ex_1 <- c("tamanho", "das", "palavras", "com", "str_length", NA, "3")

str_length(ex_1)
[1] 7 3 8 3 10 NA 1

str_sub

É comum você precisar pegar partes fixas de strings, como apenas a parte final das strings ou apenas os 2 primeiros caracteres. Essa função possui 5 argumentos, os quais podem ser obtidos utilizando o help do R (rodar ?str_sub no console). Os três primeiros argumentos são em geral os mais utilizados. O primeiro irá receber um vetor de caracteres, o objeto no qual a função irá fazer as buscas. O segundo start você indica onde irá começar e o argumento end indica até onde ir na busca. Para este exemplo em particular vamos criar uma vetor mais organizado para ficar mais claro.

Código
# vamos criar um vetor de caracteres padronizando "nome-idade"
ex_sub <- c("João-42", "Maria-29", "Pedro-20", "Tereza-50")

Primeiro vamos supor que a gente queira pegar apenas os nomes. Como nesse caso os caracteres possuem tamanhos diferentes para os nomes, mas a idade possui dois dígitos para todos. Uma característica interessante do str_sub() é sua capacidade de trabalhar com índices negativos nas posições start e end. Quando usamos uma posição negativa, str_sub() conta regressivamente a partir do último caracter:

Código
str_sub(ex_sub, end = -4)
[1] “João” “Maria” “Pedro” “Tereza”

Caso a gente queira pegar apenas as idade podemos utilizar o argumento start para indicar onde iremos começar.

Código
# neste caso iremos pegar do penultimo caractere até o último
str_sub(ex_sub, start = -2)
[1] “42” “29” “20” “50”

Também é possível utilizar o start e o end em conjunto.

Código
# estamos pegando valores da posição 3 até a posição 4.
ex_sub2 <- c("__SP__", "__MG__", "__RJ__", "__ES__")
str_sub(ex_sub2, 3, 4)
[1] “SP” “MG” “RJ” “ES”

str_trim

Dentro de um conjunto de dados é comum que a gente encontre textos com espaços a mais ou em lugares que não deveriam ter espaços. Espaços antes e após o texto são especialmente chatos, pois pode ser difícil detectá-los. Isso pode acontecer principalmente quando estamos tratando de dados provenientes de formulários que contém respostas abertas, ou seja, cada usuário pode escrever da forma que preferir. Isso pode gerar alguns problemas, como criar categorias diferentes para valores que deveriam ser iguais. A função str_trim pode nos auxiliar na resolução desse problema removendo os espaços excedentes antes e depois da string. Os argumentos da função são dois: o objeto , e side, onde você indica o lado que deseja tirar os espaços, com as opções side = c("both", "left", "right")).

Código
extrim <- c(" vetor", " para ", "exemplificar", "o uso", "  da função  ")

str_trim(extrim, side = "left") # removendo espaçoes excedentes à esquerda
[1] “vetor” “para” “exemplificar” “o uso” “da função”
Código
str_trim(extrim, side = "right") # removendo espaçoes excedentes à direita
[1] “vetor” ” para” “exemplificar” “o uso” ” da função”
Código
str_trim(extrim, side = "both") # removendo espaçoes excedentes em ambos os lados
[1] “vetor” “para” “exemplificar” “o uso” “da função”

str_detect e str_which

Caso a gente queira detectar alguma característica dentro de um vetor como números, letras ou palavras por exemplo, poderíamos fazer o uso da função str_detect.

Código
# criando um vetor

altura <- c(
    "1.85", "1 metro e 60 centimetros", "191 cm", "167",
    "1,58 metros", "188"
)

Como dito antes, iremos utilizar algumas outras funções e uma delas é o operador pipe (%>%). No post sobre tidyverse ensinamos a usar esse operador.

Código
# Aqui ele retorna um vetor booleano com valores "TRUE"
# caso o caractere contenha o "8" e "FALSO" caso contrário.
altura %>% str_detect("8")
[1] TRUE FALSE FALSE FALSE TRUE TRUE
Código
# Também é possível utilizar operadores lógicos
altura %>% str_detect("cm|centimetro")
[1] FALSE TRUE TRUE FALSE FALSE FALSE

Note que na segunda vez que utilizamos função, escrevemos “centimetro” e o vetor retornou um TRUE na posição dois, entretando ela está no plural (centimetros). É exatamento isso que a função faz: ela não está buscando toda a palavra, ela busca padrões, qualquer string que tiver, nesse caso, “centimetro” ele irá retornar o valor TRUE. Neste mesmo conceito, existe a função str_which que no lugar de retornar um vetor booleano, ela retorna as posições no vetor em que a string buscada foi encontrada.

Código
altura %>% str_which("cm|centimetro")
[1] 2 3

str_subset

Digamos agora que a gente queira não só detectar essas características (números, pontuação, letras), mas utilizá-las. A função str_subset() retorna essas strings compatíveis com as características fornecidas, sendo possível armazenar essas strings em um objeto, por exemplo.

Código
altura %>% str_subset("cm|centimetro")
[1] “1 metro e 60 centimetros” “191 cm”

str_remove e str_remove_all

A função str_remove é usada para remover padrões das strings, por exemplo, você pode desejar tirar alguma letra, algum número ou algum caractere. Essa função (mas não só ela) possui umas variante que é str_remove_all que basicamente funciona da mesma maneira que a primeira, porém ela vai remover TODOS os padrões dentro da mesma string e não somente a primeira possibilidade. Vamos demonstrar em um exemplo.

Código
altura %>% str_remove("8")
[1] “1.5” “1 metro e 60 centimetros”
[3] “191 cm” “167”
[5] “1,5 metros” “18”
Código
altura %>% str_remove_all("8")
[1] “1.5” “1 metro e 60 centimetros”
[3] “191 cm” “167”
[5] “1,5 metros” “1”

Observe que ao utilizar o str_remove, ainda ficou um “8” no último objeto. Isso acontece basicamente porque essa função remove o padrão escolhido de todas as strings, entretando apenas o primeiro encontrado. O str_remove_all é uma alternativa caso queira contornar isso.

str_replace e str_replace_all

Agora digamos que a gente não queira remover certos padrões e sim substituir por alguma outra coisa. A função str_replace nos auxilia nisso e assim como a str_remove, ela também possui a variante str_replace_all. Essas funções possuem 3 argumentos. Em resumo, o primeiro argumento string irá receber um vetor de caracteres. O segundo argumento pattern irá receber o padrão a ser procurado. Por fim, o terceiro argumento replacement recebe um vetor de caracteres de substituições e deve ter comprimento um ou o mesmo comprimento que string ou pattern. Vamos a um exemplo simples.

Código
str_replace(altura, "cm|metros|centimetros", "cm.")
[1] “1.85” “1 metro e 60 cm.” “191 cm.” “167”
[5] “1,58 cm.” “188”
Código
# note que no último argumento eu subsitui "metros" por nada.
str_replace_all(altura, c("cm" = "cm1", "centimetros" = "cm2", "metros" = ""))
[1] “1.85” “1 metro e 60 cm2.” “191 cm1.” “167”
[5] “1,58” “188”

Expressões regulares

Agora que já conhecemos algumas das funções do pacote stringr, vamos falar um pouco sobre as expressões regulares (regex). Para trabalhar com textos de uma maneira fácil, é necessário saber um pouco de regex. Elas permitem identificar conjuntos de caracteres, palavras e outros padrões por meio de uma sintaxe concisa. O pacote divide algumas “características” das expressões regulares em subgrupos, como são muitos e normalmente seguem um padrão vamos falar apenas de algumas. Você pode ter acesso a toda parte de regex através do seguinte cheat sheet. Para facilitar o entendimento, após introduzir uma base das expressões regulares, vamos seguir com os exemplos práticos, exemplicando passo a passo o que está acontecendo.

Classes

Suplentes

  • x|y ou
  • [xy] qualquer um de
  • [^xy] qualquer coisa menos
  • x-y entre

Âncoras

  • ^x começo da string
  • x$ fim da string

Olhar em volta

  • x(?=y) seguido por
  • x(?!y) não seguido por
  • (?<=x)y precedido por
  • (?<!x)y não precedido por

Quantificadores

  • x? zero ou um
  • x* zero ou mais
  • x+ um ou mais
  • x{n} exatamente “n”
  • x{n,} “n” ou mais
  • x{n,m} entre “n” e “m”

Alguns operadores interessantes

  • \\s espaço; \\S não espaço

  • \\d qualquer dígito; \\D não dígito

  • \\w qualquer caractere de palavra

  • [:lower:] letra minusculas

  • [:upper:] letras maiusculas

  • [:punct:] pontuação

  • [:graph:] letras, números e pontuações

  • . qualquer coisa (caso queira usar o “.” em sua forma literal, use \\.)

Exemplificando classes e operadores

Mostramos acima algumas classes e operadores interesserantes e que geralmente são muito utilizados. Vamos agora mostrar em alguns exemplos como eles funcionam.

Vamos criar então 2 vetores contendo as mesmas informações (3 modelos de carros), porém o segundo vetor terá espaços excedentes no meio das palavras. Imagino que poderíamos ter um conjunto de dados muito grande, “corrigir” um caractere por vez se tornaria improdutivo. Então, vamos pensar em uma solução para este exemplo usando regex.

Código
carros1 <- c("Ford Mustang", "Chevrolet Camaro", "Cherry Tigo")


carros2 <- c("Ford      Mustang", "Chevrolet    Camaro", "Cherry      Tigo")

identical(carros1, carros2)
[1] FALSE

Usamos a função identical para mostrar que o R reconhece que os vetores não são iguais. Para resolver esse problema, podemos usar a seguinte lógica: sabemos que o correto é haver apenas um espaço entre as palavras. Qualquer quantidade de espaços que for maior que um, iremos corrigir. Podemos fazer isso combinando regex com a função str_replace_all.

Código
carros2 <- carros2 %>%
    str_replace_all("\\s{2,}", " ")

carros2
[1] “Ford Mustang” “Chevrolet Camaro” “Cherry Tigo”
Código
identical(carros1, carros2)
[1] TRUE

Como já vimos, a função str_replace_all nos ajuda a fazer substiuições de caracteres. Nesse caso, a regex \\s significa “espaço”. O {2,} indica que queremos identificar algo se repita duas ou mais vezes. Então a função basicamente irá identificar toda vez que um espaço aparecer seguidamente duas ou mais vezes e vai substituir por apenas um espaço. Note que agora o identical retorna true, ou seja, os vetores são iguais. Lembrando que já falamos da str_trim() que remove espaços no começo e no fim dos caracteres, agora sabemos como tratar qualquer tipo de problema relacionado a espaços excedentes.

Vamos agora voltar para um vetor que já utilizamos acima. Devido a maneira com que os caracteres estão armazenadas nesse vetor, fica complicado transformar esses caracteres em informações. Ao utilizarmos expressões regulares de uma forma bem simples, já conseguimos trabalhar com essas informaçõs.

Código
altura
[1] “1.85” “1 metro e 60 centimetros”
[3] “191 cm” “167”
[5] “1,58 metros” “188”
Código
altura <- altura %>%
    str_remove_all("\\D")

altura
[1] “185” “160” “191” “167” “158” “188”

Observe que ao utilizar o \\D, obtivemos apenas números. Sendo assim já conseguimos uniformizar a maneira com que as informações estão sendo exibidas. A partir daqui já podemos até obter algumas estatísticas descritivas, como a média por exemplo.

Código
altura <- as.numeric(altura)
mean(altura)
[1] 174.8333

Note que para obter a média foi preciso transformar o vetor altura, originalmente da classe character em numeric.

Na prática

Vamos agora colocar em prática tudo o que vimos em um banco de dados fictício que iremos criar. Suponha que uma empresa nacional de aluguel de veículos esteja interessada em obter algumas informações. Para isso ela irá aplicar um questionário tendo como público as pessoas que já alugaram seus veículos. No questionário as pessoas deveriam passar as seguintes informações: “Marca/modelo do veículo”, “Alugaria esse veículo novamente?”, “Grau de satisfação com a empresa”, “Qual sua cidade/estado (sigla)”. Todas as variáveis do questionario foram do tipo resposta aberta, ou seja, os respondentes poderiam escrevem de qualquer maneira suas respostas. Assim gerou-se uma dificuldade em sumarizar e obter informações relevantes desse banco de dados, já nas respostas foram encontradas erros como, espaços excedentes, palavras iguais escritas de formas diferentes, discordância entre letras maiúsculas e minúsculas, entre outros.
Torna-se necessário então realizar um bom tratamento nesses caracteres para que seja possível extrair todas as informações. Vamos então utilizar o queridinho stringr para nos ajudar.

Criando o banco de dados

Existem diferentes formas de criar um banco de dados. Para este exemplo vamos criar 4 vetores e transformá-los em um data.frame.

Código
# veículos da locadora: "Honda Civic", "Toyota Corolla", "Fiat Argo" e "Ford Fusion"
veiculo <- c(
    "Honda  civic", "honda - civic", "  fiat Argo", "FORD FUSION  ",
    "toyota Corolla", "Toyota   COROLLA", "Fiat  / argo",
    " HONDA civic", "ford fusion ", "toyota COROLLa"
)

alugaria_de_novo <- c(
    "SIM", "Sim", "nao", "sim", "não", "NAOOO", "Não",
    "sim", "NÃO", "Nao"
)

grau_de_satisfacao <- c(
    "8.1", "10", "3,23", "6", " 5,3", "0,0000",
    "7.7", "9 ", "5", "6,666"
)

cidade <- c(
    "Vitória - ES", "sao paulo - sp", "Rio de Janeiro /Rj",
    "BELO HORIZONTE MG", " vitoria  Es", "Florianopolis / sc ",
    "TRES CORAÇÕES - mg", "salvador BA", "São Paulo - SP",
    " belo horizonte / mg"
)

dados <- data.frame(
    veiculo,
    alugaria_de_novo,
    grau_de_satisfacao,
    cidade
)
Código
knitr::kable(dados)
veiculo alugaria_de_novo grau_de_satisfacao cidade
Honda civic SIM 8.1 Vitória - ES
honda - civic Sim 10 sao paulo - sp
fiat Argo nao 3,23 Rio de Janeiro /Rj
FORD FUSION sim 6 BELO HORIZONTE MG
toyota Corolla não 5,3 vitoria Es
Toyota COROLLA NAOOO 0,0000 Florianopolis / sc
Fiat / argo Não 7.7 TRES CORAÇÕES - mg
HONDA civic sim 9 salvador BA
ford fusion NÃO 5 São Paulo - SP
toyota COROLLa Nao 6,666 belo horizonte / mg

Assim ficou o nosso data.frame. Note que além dos erros visíveis, ainda temos problemas com espaços a mais antes, depois e no meio das palavras que apesar de não estar visível na apresentação da tabela, eles existem.

Lapidando os caracteres

Vamos fazer o nosso tratamento de dados variável por variável. Iremos mostrar maneiras diferentes de organizar essas informações, lembrando que isso pode ser feito de diversas formas.

Olhando para a variável “veiculo” conseguimos notar um certo padrão. Todas as observações contém a marca do veículo seguida pelo modelo. A partir daqui já podemos pensar em algumas formas de tratamento, como, criar uma variável apenas com a marca e outra com o modelo. Note que a marca e modelo são separados ou por espaço, ou por um “-” ou por “/”. Perceber padrões no seu banco de dados é interessante para o tratamento.

Código
dados <- dados %>%
    mutate(
        marca = veiculo %>%
            str_trim() %>%
            str_remove("\\s.+|\\s\\(.+|/.+") %>%
            str_to_upper(),
        modelo = veiculo %>%
            str_trim() %>%
            str_extract("\\s.+|\\s\\(.+|/.+") %>%
            str_remove("[:punct:]") %>%
            str_trim() %>%
            str_to_upper(),
        marca_modelo = paste(marca, modelo)
    )

dados <- dados %>%
    subset(select = -c(veiculo))

Acabamos de utilizar a função mutate para criar 3 novas variáveis a partir da variável original (veiculos), sendo elas: marca, modelo e marca_modelo. Basicamente utilizamos as funções já mostradas ateriormente como a str_trim para remover os espaços antes e depois do characteres, também utilizamos o str_remove e str_extract, ambos combinados com as mesmas expressões regulares (\\s.+|\\s\\(.+|/.+). Em resumo essa regex detecta todo “espaço” seguido por qualquer coisa ou “espaço” seguido por um parênteses aberto seguido por qualquer coisa ou uma “/” seguida por qualquer coisa. Também utilizamos o str_remove("[:punct:]") e str_to_upper para deixar todas as letras sem acentos, maiúsculas e padronizadas. Retiramos do banco de dados a variável original veiculos já que se tornou inutilizável.

A variável alugaria_de_novo é do tipo binária que contém, ou pelo menos deveria conter, dois tipo de respostas: “SIM” e “NÃO”. De fato todas as respostas estão representando SIM ou NAO, entretanto, devido às diferentes maneiras com que elas foram escritas, fica difícil extrair informações. Vamos então tratar essa variável.

Código
dados$alugaria_de_novo <- dados$alugaria_de_novo %>%
    str_replace("^S|s[Ii]", "SIM") %>%
    str_sub(end = 3)

dados$alugaria_de_novo <- dados$alugaria_de_novo %>%
    str_replace("^N|n[Aaãâ]", "NAO") %>%
    str_sub(end = 3)

dados$alugaria_de_novo
[1] “SIM” “SIM” “NAO” “SIM” “NAO” “NAO” “NAO” “SIM” “NAO” “NAO”

Para este caso usamos o str_replace junto com expressões regulares para substituir palavras que representam “sim” e “não” por “SIM” e o “NAO”, respectivamente. As regex usadas para esse caso foram "^S|s[Ii]", que representa “todo S ou s seguido por I ou i observado no início da string” e ^N|n[Aaãâ] que representa “todo n ou N seguido por A, a, ã ou â”. Após isso, usamos o str_sub para pegar apenas as três primeiras letras. Vale ressaltar que caso outras palavras apareçam na resposta, ela não vai funcionar, nesse caso será preciso utilizar outras funções ou apenas “aprimorar” as expressões regulares utilizadas.

Para o grau de satisfação as pessoas deram notas de 0 a 10. Notamos que algumas pessoas separaram os números utilizando “.” e outras utilizando “,”. O R entende essa variável como character e pode ser interessante transformar essa variável em numérica (igual fizemos anteriormente) para realizar algumas análises quantitativas. O R não irá reconhecer como número uma variável com duas formas diferentes de separação para o dígito (“.” e “,”), por exemplo, para um vetor do tipo c("3.1", "3,1") é necessário padronizar essa variável utilizando o mesmo separador.

Código
dados$grau_de_satisfacao <-
    str_replace(grau_de_satisfacao, "\\,", "\\.") %>%
    str_trim() %>%
    as.numeric() %>%
    round(1)

dados$grau_de_satisfacao
[1] 8.1 10.0 3.2 6.0 5.3 0.0 7.7 9.0 5.0 6.7

Substituímos todas as vírgulas por pontos por meio da função str_replace, depois foi necessário transformar a variável em númerica, fizemos isso por meio da função as.numeric. Logo após, utilizamos a função round para arredondar os números para uma casa decimal. A parte de arredondar números pode ser interessante em diversar análises e o R possui algumas funções como floor e ceiling, além da round. Logo, quando estiver trabalhando com arrendondamentos pode ser interessente pesquisar sobre elas.

A última variável para ser tratada é a que contém as informações de cidade/estado dos respondentes. Observe que as observações tem estruturas parecidas com as da variável veiculos, logo um tratamento similar poderia ser útil, mas vamos fazer um pouco diferente.

Código
dados$cidade <- dados$cidade %>%
    str_trim() %>%
    str_to_upper() %>%
    str_remove_all("[:punct:]") %>%
    abjutils::rm_accent() %>%
    str_replace("\\s(?=([:alpha:]){2}$)", " - ") %>%
    str_replace_all("\\s{2,}", " ")

dados$cidade
[1] “VITORIA - ES” “SAO PAULO - SP” “RIO DE JANEIRO - RJ”
[4] “BELO HORIZONTE - MG” “VITORIA - ES” “FLORIANOPOLIS - SC”
[7] “TRES CORACOES - MG” “SALVADOR - BA” “SAO PAULO - SP””
[10] “BELO HORIZONTE - MG”

Aqui queremos padronizar as observações para que fiquem no padrão “CIDADE - UF” então começamos removendo espaços excedentes, depois deixamos todas as letras maiúsculas e então usamos o str_remove_all("[:punct:]"), mesmo assim ainda restou restou alguns acentos como em VITÓRIA. Para corrigir isso utilizamos a função rm_accent do pacote abjutils. O último passo seria substituir os espaços que separam a cidade do UF por um “-”. Uma maneira de fazer isso seria utilizando o str_replace, entretanto algumas cidade possuem mais de um nome, ou seja, ao fazer essa substituição todos os espaços seriam afetados e teriamos resultados como “SAO - PAULO - SP”. Uma maneira de contornar isso (nesse caso) é usar a expressão regular "\\s(?=([:alpha:]){2}$)". Essa expressão basicamente está pegando, no final da string, todo espaço seguido por exatamente 2 letras quaisquer "([:alpha:])". O ?= faz com que seja alterada apenas a entrada, nesse caso ele vai alterar apenas o espaço. Consideramos que todos os UF’s tem exatamente duas letras. Em alguns casos pode ser interessante separar em colunas diferentes o município e a cidade. Fizemos algo parecido quando tratamos a primeira variável.

Vamos dar uma olhada em como ficou o nosso banco de dados final

Código
dados <- dados %>%
    select(marca_modelo, marca, modelo, alugaria_de_novo, cidade, grau_de_satisfacao)

knitr::kable(dados)
marca_modelo marca modelo alugaria_de_novo cidade grau_de_satisfacao
HONDA CIVIC HONDA CIVIC SIM VITORIA - ES 8.1
HONDA CIVIC HONDA CIVIC SIM SAO PAULO - SP 10.0
FIAT ARGO FIAT ARGO NAO RIO DE JANEIRO - RJ 3.2
FORD FUSION FORD FUSION SIM BELO HORIZONTE - MG 6.0
TOYOTA COROLLA TOYOTA COROLLA NAO VITORIA - ES 5.3
TOYOTA COROLLA TOYOTA COROLLA NAO FLORIANOPOLIS - SC 0.0
FIAT ARGO FIAT ARGO NAO TRES CORACOES - MG 7.7
HONDA CIVIC HONDA CIVIC SIM SALVADOR - BA 9.0
FORD FUSION FORD FUSION NAO SAO PAULO - SP 5.0
TOYOTA COROLLA TOYOTA COROLLA NAO BELO HORIZONTE - MG 6.7

Para finalizar é interessente ver que nosso tratamento de dados funcionou. Queremos saber se nossas observações estão corretamentes estruturadas, se por exemplo todas as respostas que representam a mesma coisa estão de fato iguais. Uma maneira legal de fazer isso é criar tabelas de frequência para as variáveis qualitativas e apresentar medidas resumo para as variáveis quantitativas.

Código
questionr::freq(
    dados$marca_modelo,
    cum = FALSE,
    total = TRUE,
    na.last = FALSE,
    valid = FALSE,
    sort = "inc"
) %>%
    knitr::kable(caption = "Tabela de frequências para marca/modelo", digits = 2)
n %
FIAT ARGO 2 20
FORD FUSION 2 20
HONDA CIVIC 3 30
TOYOTA COROLLA 3 30
Total 10 100

Tabela de frequências para marca/modelo

Código
questionr::freq(
    dados$cidade,
    cum = FALSE,
    total = TRUE,
    na.last = FALSE,
    valid = FALSE,
    sort = "inc"
) %>%
    knitr::kable(caption = "Tabela de frequências para cidade/estado", digits = 2)
n %
FLORIANOPOLIS - SC 1 10
RIO DE JANEIRO - RJ 1 10
SALVADOR - BA 1 10
TRES CORACOES - MG 1 10
BELO HORIZONTE - MG 2 20
SAO PAULO - SP 2 20
VITORIA - ES 2 20
Total 10 100

Tabela de frequências para cidade/estado

Código
questionr::freq(
    dados$alugaria_de_novo,
    cum = FALSE,
    total = TRUE,
    na.last = FALSE,
    valid = FALSE,
    sort = "inc"
) %>%
    knitr::kable(caption = "Tabela de frequências para 'alugaria de novo'", digits = 2)
n %
SIM 4 40
NAO 6 60
Total 10 100

Tabela de frequências para ‘alugaria de novo’

Código
summary(dados$grau_de_satisfacao)
Min. 1st Qu. Median Mean 3rd Qu. Max.
0.000 5.075 6.350 6.100 8.000 10.000

Com o banco de dados prontos já é possível realizar inúmeras análises e conseguir apresentar os resultados/informações. Muitas dessas informações são passadas atráves de gráficos. O pacote ggplot2 é um grande aliado nesse ramo, mas isso é assunto para um outro post (spoiler).

Esperamos que com esse post você possa entender um pouco mais de como tratar string’s utilizando (mas não só) o pacote stringr e expressões regulares. Vale ressaltar que realizar um tratamento de caracteres, inúmeros obstaculos podem surgir no caminho. É importante ter em mente que cada caso é um caso e muitas das vezes você precisará encontrar uma expressão regular que resolva aquele seu problema específico.

Referências

https://livro.curso-r.com/7-4-o-pacote-stringr.html

https://bookdown.org/davi_moreira/txt4cs/stringR.html

https://www.youtube.com/watch?v=ii4Pfox-3s8&t=3274s