13.6 O pacote stringr
library(stringr)
library(dplyr)
library(glue)1. 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.
# Sem regex
formata_CPF <- function(num) {
if(str_count(num) != 11) {
stop("Número inválido!")
}
# Concatemos cada parte do número, interpolando
# com os pontos e o traço.
s <- str_c(
str_sub(num, start = 1, end = 3),
".",
str_sub(num, start = 4, end = 6),
".",
str_sub(num, start = 7, end = 9),
"-",
str_sub(num, start = 10, end = 11)
)
}
# Com regex
formata_CPF <- function(num) {
if(str_count(num) != 11) {
stop("Número inválido!")
}
str_replace(
string = num,
pattern = "([0-9]{3})([0-9]{3})([0-9]{3})",
replacement = "\\1.\\2.\\3-"
)
}A função str_replace() faz o seguinte:
- O
pattern=procurará um padrão de 9 números:- O primeiro
([0-9]{3})pega os três primeiros números. - O segundo
([0-9]{3})pega os três próximos números (quarto ao sexto). - O terceiro
([0-9]{3})pega os três números seguintes (sétimo ao nono).
- O primeiro
- O
replacement=substituirá esses 9 números pela string formada por:\\1, a expressão dada pelo primeiro parêntese dopattern=, isto é, os três primeiros números.., o primeiro ponto.\\2, a expressão dada pelo segundo parêntese dopattern=, isto é, os três próximos números (quarto ao sexto).., o segundo ponto.\\3, a expressão dada pelo terceiro parêntese dopattern=, isto é, os três números seguintes (sétimo ao nono).-, o traço.
2. Transforme o vetor de strings abaixo em "01 - Alto" "02 - Médio" "03 - Baixo".
s <- c('Alto', 'Médio', 'Baixo')
# Usando str_c()
str_c("0", 1:length(s), " - ", s, sep = "")
## [1] "01 - Alto" "02 - Médio" "03 - Baixo"
# Usando o pacote glue
glue("0{1:length(s)} - {s}")
## 01 - Alto
## 02 - Médio
## 03 - BaixoPara mais informações sobre o pacote glue, confira este post.
3. 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().
s <- c('Casa', 'CASA', 'CaSa', 'CAsa')
str_detect(s, "[CcAaSsAa]")
## [1] TRUE TRUE TRUE TRUE
str_detect(s, "[Cc][Aa][Ss][Aa]")
## [1] TRUE TRUE TRUE TRUE4. Imagine que a seguinte string é a parte final de uma URL.
/ac/rio-branco/xpto-xyz-1-0-1fds2396-5
Transforme-a em “AC - Rio Branco” utilizando a função str_split().
url <- c('/ac/rio-branco/xpto-xyz-1-0-1fds2396-5')
UF <- url %>%
str_split("[/]", simplify = TRUE) %>%
.[1,2] %>%
str_to_upper()
cidade <- url %>%
str_split("[/]", simplify = TRUE) %>%
.[1,3] %>%
str_replace("-", " ") %>%
str_to_title()
str_c(UF, " - ", cidade)
## [1] "AC - Rio Branco"5. Crie uma função que retorna TRUE quando a string é um palíndromo e FALSO caso não seja.
# Solução 1: usando a função rev() para inverter uma string fragmentada
testa_palindromo <- function(s) {
s %>%
str_split("", simplify = T) %>%
rev %>%
str_c(collapse = "") %>%
str_detect(s)
}
testa_palindromo("ana")
## [1] TRUE
testa_palindromo("bananas")
## [1] FALSE
testa_palindromo("socorrammesubinoonibusemmarrocos")
## [1] TRUE
# Solução 2: usando a função str_reverse() do pacote stringi,
# que já inverte a string diretamente.
testa_palindromo <- function(s) {
s %>%
stringi::stri_reverse() %>%
str_detect(s)
}
testa_palindromo("ana")
## [1] TRUE
testa_palindromo("bananas")
## [1] FALSE
testa_palindromo("socorrammesubinoonibusemmarrocos")
## [1] TRUE6. 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.'Crie uma função para corrigi-lo.
# Função que funciona para o exemplo
corrige_mn <- function(s) {
s %>%
str_replace("nb", "mb") %>%
str_replace("md", "nd")
}
corrige_mn(s)
## [1] "Nós chamamos os bombeiros quando começou o incêndio."
# Função que funciona no caso geral
corrige_mn <- function(s) {
s %>%
str_replace_all("m([^aeioubp[[:space:]]+])", "n\\1") %>%
str_replace_all("n([pb])", "m\\1")
}
corrige_mn(s)
## [1] "Nós chamamos os bombeiros quando começou o incêndio."O padrão [^aeioubp[[:space:]]+] significa “tudo menos vogais, b, p ou espaços”. O \\1 devolve o padrão encontrado pelo primeiro parêntese do argumento patern=.
7. Considere o seguinte texto
s <- "A função mais importante para leitura de dados no `lubridate` é a `ymd`. Essa função serve para ler qualquer data de uma `string` no formato `YYYY-MM-DD`. Essa função é útil pois funciona com qualquer separador entre os elementos da data e também porque temos uma função para cada formato (`ymd`, `mdy`, `dmy`, `dym`, `myd`, `ydm`)."Extraia todas as combinações da função ymd, sem repetições.
str_extract_all(s, "[ymd]{3}") %>%
unlist() %>%
unique
## [1] "ymd" "mdy" "dmy" "dym" "myd" "ydm"8. Considere as frases abaixo
s <- c(
'O produto é bom.',
'O produto não é bom.',
'O produto não é muito bom.',
'O produto é muito bom',
'O produto não é ruim.',
'O produto não é não ruim.',
'O produto não é não bom.'
)Crie uma regra para identificar se o texto refere-se a um feedback positivo ou negativo sobre o produto (considere não bom = ruim e não ruim = bom). Retorne um vetor lógico que vale TRUE se o feedback for positivo e FALSE caso contrário.
feedback <- function(s) {
s %>%
str_replace("não bom", "ruim") %>%
str_replace("não ruim", "bom") %>%
str_replace("muito ", "") %>%
str_detect("(.*) produto é bom|(.*) não é ruim")
}
feedback(s)
## [1] TRUE FALSE FALSE TRUE TRUE FALSE TRUE