Strings and regular expressions

R · Practical · 12 min

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, paste0 with nothing, and collapse = ", " joins a vector into one string.
  • sprintf("%.2f%%", x) and format(x, big.mark = ",") format numbers.
  • nchar, toupper, tolower, trimws and substr(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; grep returns positions.
  • sub replaces the first match, gsub all 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
  • grepl to filter, sub/gsub to replace, \\1 for groups
  • Double backslashes in regex strings, or use raw strings r"(...)"
  • strsplit returns a list

Watch out for

  • Forgetting that . in a pattern matches any character; use fixed = TRUE or escape it.

Check yourself

  1. What does strsplit(c("a,b", "c"), ",") return?

Sign in to answer, see the explanations, and get this lesson back as a quick review later.

Official docs: stat.ethz.ch/R-manual/R-devel/library/base/html/grep.html

Builds on

Unlocks

Nothing builds on this yet.