Written and maintained by CASRAI Editorial Board
Last updated
To put text in lower case in R, call tolower(x) on a character vector. It returns a new vector of the same length with every alphabetic character converted to lower case; digits, spaces and punctuation are left unchanged. The stringr equivalent is str_to_lower(string). The less obvious part is what R’s own documentation says about locales and encodings, which decides whether the result is the same on every machine.
What it is used for in research
Lower-casing is a cleaning step, not an analysis. Typical uses are making free-text labels, journal names, keywords or participant-entered categories comparable before you count, merge or match them, so that “Control”, “CONTROL” and “control” are treated as one value. If you need the reverse conversion, see R uppercase with toupper() and stringr. Consistent text conventions also belong in a wider data-handling plan, such as the one described in file naming and folder conventions for research data.
Install or access (official source only)
tolower(), toupper(), casefold() and chartr() are part of base R, so they need no installation once R is installed from the Comprehensive R Archive Network (CRAN). str_to_lower() belongs to the stringr package, which is also available as part of the tidyverse. Install it from CRAN with:
install.packages("stringr")
library(stringr)
Step-by-step: convert text to lower case
- Start with a character vector. The argument
xmust be a character vector or an object that can be coerced to character withas.character.x <- "MiXeD cAsE 123" - Call
tolower().tolower(x) # "mixed case 123" - Apply it to a data frame column by assigning the result back to the column.
df$label <- tolower(df$label) - Or use stringr.
str_to_lower()takes the string and an optionallocale, which defaults to"en".str_to_lower("The quick brown dog") # "the quick brown dog" - Use
casefold()if you want one function for both directions.casefold(x, upper = FALSE)converts to lower case (the default) andupper = TRUEconverts to upper case.
Output and how to read it
The R documentation for these functions states that the value has the same length and attributes as the input (after coercion to character). Non-alphabetic characters are unchanged, so “MiXeD cAsE 123” keeps its digits and spaces. The stringr documentation likewise describes the result of str_to_lower() as a character vector the same length as string. On encoding, the documentation says elements with a declared encoding get the current locale’s declared encoding when that locale is Latin-1 or UTF-8, and that the result is in the current locale’s encoding unless the input was UTF-8 or Latin-1, in which case it is UTF-8.
Which function should you use?
All four are free and documented, but they do different jobs.
| Function | Package | What the documentation says it does |
|---|---|---|
tolower(x) |
base R | Converts alphabetic characters in a character vector to lower case. |
casefold(x, upper = FALSE) |
base R | Wrapper around tolower and toupper; upper = FALSE (the default) gives lower case. Exists for S-PLUS compatibility. |
str_to_lower(string, locale = "en") |
stringr | Lower-cases a string using the stated locale; the English default keeps behaviour consistent across platforms. |
chartr(old, new, x) |
base R | Translates the characters you specify in old into those in new; documented on the same page as tolower. |
Troubleshooting
Accented or non-English letters do not convert as expected
The base R documentation notes that these functions are platform-dependent and often use operating-system services. In some 8-bit locales only ASCII letters are handled, and what counts as “alphabetic” depends on the platform and may change as Unicode tables change. If results must be identical on every machine, str_to_lower() with an explicit locale argument is the documented way to make the behaviour consistent. Run stringi::stri_locale_list() to see the available locale values.
The input is not a character vector
The argument must be a character vector or something coercible with as.character. Check your column with class(df$label) and convert it deliberately with as.character() if needed.
Free alternatives
| Task | Option |
|---|---|
| Lower case without installing anything | tolower() in base R |
| Same result across platforms | str_to_lower() in stringr |
| One function for either direction | casefold() in base R |
Related R how-tos on CASRAI include ifelse() in R for conditional recoding and bootstrapping in R.
FAQ
How do I convert a string to lower case in R?
Use tolower("TEXT"), which returns “text”. With stringr, use str_to_lower("TEXT").
What is the difference between tolower() and casefold()?
According to the R documentation, casefold() is a wrapper around tolower() and toupper() kept for S-PLUS compatibility. casefold(x, upper = FALSE) gives lower case.
Does tolower() change numbers or punctuation?
No. Non-alphabetic characters are unchanged.
How do I make the result the same on every computer?
Use str_to_lower() with its locale argument, which defaults to English. The base R functions depend on the platform and locale.
Sources (official docs)
- R Documentation, “Character Translation and Case Folding” (chartr, tolower, toupper, casefold): https://stat.ethz.ch/R-manual/R-devel/library/base/html/chartr.html, checked 2026-10-29.
- stringr reference, “Convert string to upper/lower/title/sentence case” (str_to_lower): https://stringr.tidyverse.org/reference/case.html, checked 2026-10-29.








