Cleaning text columns (names, codes, free text) is part of almost every data job.
String functions in R are vectorised: they work on whole character vectors at once.
paste("a", "b")joins with a space,paste0with nothing, andcollapse = ", "joins a vector into one string.sprintf("%.2f%%", x)andformat(x, big.mark = ",")format numbers.nchar,toupper,tolower,trimwsandsubstr(x, start, stop)do the basics.strsplit(x, ",")returns a list, one element per input string.
Pattern functions use extended regular expressions (POSIX) by default, or Perl syntax with perl = TRUE; fixed = TRUE matches literally and is faster:
grepl(pattern, x)returns a logical vector, perfect for filtering;grepreturns positions.subreplaces the first match,gsuball matches; refer to groups with\\1.regmatches(x, regexpr(p, x))extracts the matches.
Backslashes must be doubled inside normal strings: the regex \d is written "\\d". Raw strings (r"(\d+)", R 4.0+) avoid the doubling.
The stringr package wraps these with consistent names and argument order (str_detect, str_replace_all, str_extract), data first, which fits pipes well.
Example
names <- c(" ana smith ", "BO JONES", "cy lee")
clean <- tolower(trimws(names))
print(clean) #> [1] "ana smith" "bo jones" "cy lee"
print(gsub("\\s+", " ", clean)) #> [1] "ana smith" "bo jones" "cy lee"
print(paste0("id_", 1:3)) #> [1] "id_1" "id_2" "id_3"
print(paste(c("a", "b"), collapse = "+")) #> [1] "a+b"
print(sprintf("%-4s|%6.1f", "x", 3.14159)) #> [1] "x | 3.1"
codes <- c("AM-2024-17", "FR-2023-02", "bad")
print(grepl("^[A-Z]{2}-\\d{4}", codes)) #> [1] TRUE TRUE FALSE
print(sub("^([A-Z]{2})-(\\d{4}).*", "\\2/\\1", codes[1:2]))
#> [1] "2024/AM" "2023/FR"
print(regmatches(codes, regexpr(r"(\d+$)", codes))) #> [1] "17" "02"
print(strsplit("a,b,c", ",")[[1]]) #> [1] "a" "b" "c"Remember
- String functions are vectorised over character vectors
greplto filter,sub/gsubto replace,\\1for groups- Double backslashes in regex strings, or use raw strings
r"(...)" strsplitreturns a list
Watch out for
- Forgetting that
.in a pattern matches any character; usefixed = TRUEor escape it.