Uma string é um pedaço de texto entre aspas. Qualquer versão do R com suporte atualmente codifica strings em UTF-8, então a maioria dos idiomas do mundo pode ser usada.
mystring <- "some text"
mystring
#> [1] "some text"
typeof(mystring)
#> [1] "character"
Infelizmente, a terminologia pode confundir quem já programa em outras linguagens.
Embora o type seja character, o R não faz distinção entre uma única letra (chamada char em várias outras linguagens, mas não no R) e uma string longa.
Ambas são um único item e podem estar entre aspas simples ' ' ou duplas " " de forma intercambiável.
O guia de estilo recomenda usar aspas duplas, exceto quando você quer usar aspas duplas dentro da string sem escapá-las.
str2 <- 'String with "quotes"' # convenience format
str2
#> [1] "String with \"quotes\"" # standard format
Um character vector é, portanto, um vetor de strings, com cada string como um único elemento.
s <- c("some", "strings")
s
#> [1] "some" "strings"
length(s)
#> [1] 2
length(s[1]) # the number of vector elements, not the string length
#> [1] 1
nchar(s[1]) # the number of characters in the string "some"
#> [1] 4
No exemplo acima, length(s[1]) é equivalente a length("some"): o número de elementos do vetor, não o comprimento da string.
Manipular uma string individual é obviamente possível, como com nchar() no exemplo acima, mas exige funções específicas que serão discutidas abaixo.
Quase tudo é possível no R base, mas muitos programadores acham o suporte à manipulação de strings bastante limitado e confuso.
Felizmente, existem pacotes do tidyverse que são muito mais intuitivos, flexíveis e coerentes.
Ainda existe muito código legado usando funções de string do estilo antigo. Isso inclui a maioria das soluções da comunidade no Exercism.
Além disso, para tarefas pequenas pode ser útil usar funções nativas em vez de importar uma biblioteca grande. Os mantenedores da trilha de R tendem a adotar essa abordagem ao escrever soluções exemplares para validar os exercícios.
Portanto, ainda vale a pena aprender um pouco sobre as abordagens antigas.
ncharRetorna o número de caracteres em uma string.
nchar("string")
#> [1] 6
nchar("Hrōðgār") # a person in Beowulf, written in Old English
#> [1] 7
O tópico (complicado!) do que "caractere" significa está além do nosso escopo. Apenas observe alguns pontos nos exemplos acima:
\0 (o que adicionaria 1 ao comprimento).paste e paste0
Combina um número arbitrário de strings em uma única string.
Opcionalmente, um separador pode ser especificado para paste: o padrão é um espaço.
paste0(v) é equivalente a paste(v, sep = "").
paste("bits", "of", "a", "string")
#> [1] "bits of a string"
paste0("bits", "of", "a", "string")
#> [1] "bitsofastring"
sprintfPara um controle mais fino sobre a montagem de strings, o R copia a função sprintf do C (e de várias linguagens posteriores: a Wikipedia lista cerca de 30).
r <- 5.3
pi <- 3.14159
sprintf("A circle of radius %.1f has area %.2f", r, pi * r^2)
#> [1] "A circle of radius 5.3 has area 88.25"
trimwsEspaços em branco no início e/ou no fim podem ser removidos com trimws():
s <- " messy string "
trimws(s)
#> [1] "messy string"
Existe um parâmetro which = "left" (ou "right") para evitar remover as duas pontas.
substrOpera sobre uma única string e retorna uma substring entre dois limites (inclusive).
substr("Exercism", 5, 7)
#> [1] "cis"
strsplitDivide uma string em uma lista do R, com base em uma string separadora. O separador é obrigatório (sem valor padrão), mas pode ser uma string vazia.
strsplit("R, Python, Julia", ", ")
[[1]]
#> [1] "R" "Python" "Julia"
strsplit("Exercism", "")
[[1]]
#> [1] "E" "x" "e" "r" "c" "i" "s" "m"
Listas serão abordadas em um conceito separado.
Se você ainda não chegou a essa parte do programa, saiba por enquanto que a função unlist() vai (neste caso) converter uma lista em um vetor.
unlist(strsplit("Exercism", ""))
#> [1] "E" "x" "e" "r" "c" "i" "s" "m"
Sendo generosos, poderíamos dizer que as funções de string do estilo antigo não são o melhor que o R tem a oferecer (visões menos generosas são possíveis).
Para melhorar a situação, a biblioteca stringr está em desenvolvimento desde 2009 e agora é uma parte fundamental da coleção Tidyverse.
Importe-a para o seu namespace com library(stringr) ou library(tidyverse).
Alguns recursos principais incluem:
str_ e tentam deixar o propósito claro.Como todos os pacotes do Tidyverse, o stringr tem boa documentação, normalmente escrita pelo(s) autor(es) do pacote.
O uso de pipes |> para conectar funções será discutido com mais detalhes em outras partes do programa.
Por enquanto, é útil saber que:
O exemplo abaixo ilustra a sintaxe. As funções individuais serão discutidas mais adiante.
library(stringr)
"Monday-25-February" |>
str_split("-") |>
unlist() |> # [1] "Monday" "25" "February"
str_sub(1, 3) |> # [1] "Mon" "25" "Feb"
str_to_upper() |> # [1] "MON" "25" "FEB"
str_flatten(collapse = ", ")
#> [1] "MON, 25, FEB"
str_length conta pontos de código (semelhante a nchars).
Várias outras funções manipulam espaços em branco, incluindo str_trim() e str_squish().
Muitas vezes essa é uma tarefa de limpeza essencial no início de qualquer projeto de ciência de dados.
# The first 3 kernels in JuPyteR notebooks:
str_length(c("Julia", "Python", "R")) #> [1] 1 6 5
#> [1] 5 6 1
str_pad(c("Julia", "Python", "R"), 8, "right") # add spaces if necessary
#> [1] "Julia " "Python " "R "
str_trim("Julia Python R ") # remove leading & trailing whitespace
#> [1] "Julia Python R"
str_squish("Julia Python R ") # trim, collapse multiple spaces
#> [1] "Julia Python R"
A função str_sub(string, start, end) retorna a substring de start até end (inclusive), enquanto str_sub_all() pode operar sobre várias strings.
Há muita flexibilidade.
start e end têm como padrão o primeiro e o último caractere, respectivamente.
Eles podem ser vetores de índices.
Em um contraste bem-vindo com a indexação de vetores, valores negativos contam a partir do fim da string, no estilo do Python.
s <- "abcdefgh"
str_sub(s, 2, 4)
#> [1] "bcd"
str_sub(s, 5)
#> [1] "efgh"
str_sub(s, -3, -2)
#> [1] "fg"
str_sub(s, c(1, 4), c(2, 5))
#> [1] "ab" "de"
str_sub(s, c(1, 4, 6), c(2, 5, -1))
#> [1] "ab" "de" "fgh"
s |> str_sub(2, 4) # these functions are designed for pipes
#> [1] "bcd"
str_flatten converte um vetor de caracteres em uma única string.
O argumento collapse é inserido entre cada elemento e tem como padrão "".
c("R", "Julia", "Python") |> str_flatten()
#> [1] "RJuliaPython"
c("R", "Julia", "Python") |> str_flatten(collapse = " - ")
#> [1] "R - Julia - Python"
str_c converte vários vetores de caracteres em um único vetor de caracteres, com reciclagem conforme necessário.
str_c(LETTERS[1:8], 1:8, sep = ":")
#> [1] "A:1" "B:2" "C:3" "D:4" "E:5" "F:6" "G:7" "H:8"
str_glue traz interpolação de strings simples para o R.
Expressões dentro das chaves { } são interpretadas e a representação em texto é substituída.
r <- 5.3
pi <- 3.14159
str_glue("A circle of radius {r} has area {pi * r^2}")
A circle of radius 5.3 has area 88.2472631
Um uso muito comum do R é transformar dados bagunçados em um formato consistente para análise. Para ajudar nisso, existem várias maneiras de dividir texto em substrings. A maioria está além do escopo atual.
str_split_1 é a mais simples, convertendo uma única string em um vetor de partes, divididas em algum padrão especificado (não há padrão predefinido).
s <- "R Julia Python"
str_split_1(s, " ")
#> [1] "R" "Julia" "Python"
Algumas linguagens (principalmente europeias) distinguem entre letras MAIÚSCULAS e minúsculas.
Há um conjunto de funções do stringr para converter entre elas, de formas adequadas ao locale:
str_to_lower()str_to_upper()str_to_title() : primeira letra de cada palavra em maiúsculastr_to_sentence() : primeira letra da frase em maiúsculastr_to_upper("elixir") # defaults to locale = "en"
#> [1] "ELIXIR"
str_to_upper("ελληνικά") # infers Greek
#> [1] "ΕΛΛΗΝΙΚΆ"
str_to_title("the cat sat on the mat")
#> [1] "The Cat Sat On The Mat"
str_to_sentence("the cat sat on the mat")
#> [1] "The cat sat on the mat"
Para substituição de substring com base em correspondência de padrões, str_replace() altera a primeira ocorrência do padrão e str_replace_all() altera todas as ocorrências.
Para substituição de substring com base na indexação por caractere, existe uma forma de atribuição de str_sub().
s <- "abcde"
str_sub(s, 3, 4) <- "yz"
s
#> [1] "abyze"
Neste exercício você vai processar linhas de log.
Cada linha de log é uma string formatada assim: "[<LEVEL>]: <MESSAGE>".
Existem três níveis de log diferentes:
INFOWARNINGERRORVocê tem três tarefas, e cada uma recebe uma linha de log e pede que você faça algo com ela.
Fique à vontade para usar tanto funções legadas do R base quanto a biblioteca stringr, e as duas permitem soluções curtas e viáveis.
Implemente a função message para retornar a mensagem de uma linha de log:
message("[ERROR]: Invalid operation")
#> "Invalid operation"
Qualquer espaço em branco no início ou no fim deve ser removido:
message("[WARNING]: Disk almost full\r\n")
#> "Disk almost full"
Implemente a função log_level para retornar o nível de log de uma linha de log, que deve ser retornado em letras minúsculas:
log_level("[ERROR]: Invalid operation")
#> "error"
Implemente a função reformat, que reformata a linha de log, colocando a mensagem primeiro e o nível de log depois dela, entre parênteses:
reformat("[INFO]: Operation completed")
#> "Operation completed (info)"
Crie sua conta no Exercism para aprender e dominar R com 21 conceitos111 exercícios e mentoria humana de verdade, tudo de graça.