Working with Strings: Base R vs stringr
Base R provides string functions like paste(), paste0(), nchar(), substr(), toupper(), and tolower(), but their argument order and behavior are inconsistent across functions; the stringr package (part of the tidyverse) wraps most string operations behind a consistent str_ prefix where the string is always the first argument, for example str_length(), str_sub(), str_to_upper(), and str_detect(), making functions easier to chain with the pipe and to remember.
Cricket analogy: Base R's inconsistent string functions are like a scorecard app where run rate, strike rate, and economy rate each use a different input order, while stringr's str_ prefix is like a redesigned app where every stat function takes the player's name first, consistently.
Pattern Matching with Regular Expressions
Regular expressions describe patterns within text: str_detect(x, '^R') tests whether each string starts with R, str_extract(x, '[0-9]+') pulls out the first run of digits, and str_replace_all(x, '[aeiou]', '*') replaces every vowel; base R's grepl(), grep(), sub(), and gsub() perform the equivalent operations but take the pattern as the first argument instead of the string, matching base R's less consistent convention.
Cricket analogy: str_detect(x, '^Century') flagging every match report that starts with Century is like a scanner searching newspaper archives for headlines announcing a hundred, pulling out only the relevant articles.
library(stringr)
titles <- c('Intro to R Lv3', 'Advanced R Lv12', 'Data Wrangling Lv7')
str_extract(titles, '\\d+')
str_detect(titles, '^Advanced')
str_replace(titles, 'Lv(\\d+)', 'Level \\1')
str_to_lower(titles) |>
str_split(' ')Splitting, Joining, and Case Manipulation
str_split(x, pattern) breaks each string into a list of pieces wherever the pattern matches (e.g. splitting a,b,c on a comma), while str_c() (or base paste0()) joins pieces back together, optionally with a collapse argument to flatten a vector into one string; str_to_upper(), str_to_lower(), and str_to_title() normalize case, which matters because string comparisons and joins in R are case-sensitive by default, so India and india are treated as different values unless case is normalized first.
Cricket analogy: str_split('India,Australia,England', ',') breaking a comma-separated squad list into individual team names is like a scorer separating a combined fixture list into individual matches to log each one.
Trimming, Padding, and Formatting Strings
str_trim() removes leading and trailing whitespace that often creeps in from manual data entry or copy-pasting (a value like ' R ' becomes R), str_pad() adds characters to reach a fixed width (useful for aligning IDs like zero-padding: str_pad('7', width = 3, pad = '0') gives 007), and glue::glue() offers readable string interpolation with {} placeholders as a more legible alternative to paste0() or sprintf() for building formatted messages from variables.
Cricket analogy: str_trim() cleaning up a name entered with stray spaces is like a scorer proofreading a scorecard before publishing, while str_pad('7', width = 3, pad = '0') formatting a jersey number as 007 mirrors squad-list conventions.
The glue package's glue('Player {name} scored {runs} runs') interpolates variables directly inside {} braces, avoiding the awkward quote-and-comma juggling of paste0('Player ', name, ' scored ', runs, ' runs').
Regex metacharacters like the dot, parentheses, brackets, plus sign, and dollar sign have special meaning in pattern strings; to match them literally (e.g. a literal period in a filename), escape them with a double backslash in R string literals, such as str_detect(x, '\\.') to detect an actual dot.
- Base R string functions (paste0, substr, grepl) work but have inconsistent argument order; stringr's str_ prefix functions are more consistent, always taking the string first.
- str_detect(), str_extract(), and str_replace_all() use regular expressions to find, pull out, or replace patterns in text.
- str_split() breaks strings into pieces on a pattern; str_c()/paste0() join pieces back together.
- String comparisons in R are case-sensitive by default, so normalize case with str_to_upper()/str_to_lower() before comparing or joining.
- str_trim() removes stray leading/trailing whitespace; str_pad() pads strings to a fixed width, e.g. for zero-padded IDs.
- glue() offers readable {}-based string interpolation as an alternative to chaining paste0() calls.
- Regex metacharacters need escaping with a double backslash in R string literals to be matched literally.
Practice what you learned
1. Which stringr function tests whether each element of a character vector matches a regex pattern, returning TRUE/FALSE?
2. Why might a join between two data frames silently fail to match rows even though the key values look the same?
3. What does str_pad('7', width = 3, pad = '0') return?
4. In R regex, why must a literal period character be escaped when used inside a pattern string?
5. What is the main advantage of glue('{name} scored {runs} runs') over paste0() for building formatted strings?
Was this page helpful?
You May Also Like
Handling Missing Data in R
Understand how R represents missing values with NA, how to detect and quantify missingness, and strategies for removal versus imputation.
dplyr Basics
Learn the core dplyr verbs—filter, select, mutate, arrange, summarise, and group_by—for fast, readable data manipulation in R.
tidyr and Reshaping Data
Learn how to reshape messy or wide data into tidy form using pivot_longer(), pivot_wider(), separate_wider_delim(), and complete().
Related Reading
Related Study Notes in Programming
Browse all study notesApache Spark Study Notes
Programming · 30 topics
ProgrammingApache Flink Study Notes
Programming · 30 topics
ProgrammingHadoop Study Notes
Programming · 30 topics
ProgrammingSnowflake Study Notes
Programming · 30 topics
ProgrammingApache Airflow Study Notes
Programming · 30 topics
Programmingdbt (Data Build Tool) Study Notes
Programming · 30 topics