Skip to main content
v2026.11,858 entries · CC-BY 4.0

Lower Case in R: tolower(), casefold() and str_to_lower()

How to convert text to lower case in R with tolower(), casefold() and str_to_lower(), including the locale and encoding behaviour the docs describe.

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

  1. Start with a character vector. The argument x must be a character vector or an object that can be coerced to character with as.character.
    x <- "MiXeD cAsE 123"
  2. Call tolower().
    tolower(x)
    # "mixed case 123"
  3. Apply it to a data frame column by assigning the result back to the column.
    df$label <- tolower(df$label)
  4. Or use stringr. str_to_lower() takes the string and an optional locale, which defaults to "en".
    str_to_lower("The quick brown dog")
    # "the quick brown dog"
  5. Use casefold() if you want one function for both directions. casefold(x, upper = FALSE) converts to lower case (the default) and upper = TRUE converts 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)

Follow CASRAI

Research-administration guidance, standards updates and independent tool reviews.

Ask CASRAI · free to try

Ask about Lower Case in R: tolower(), casefold() and str_to_lower()

Ask your first 2 questions free below. Subscribers get 150 a day for $29 a month.

An AI assistant specialized in research administration. It cites the sources behind every answer, labels web answers and says when it can't answer.

Answers draw on CASRAI's guides and dictionary plus the federal and funder documents we index: Federal Register, Grants.gov, Regulations.gov and UKRI.

Works on this site and inside Claude, Cursor and the AI tools you already use.

Everything CASRAI publishes — this page, the dictionary, the guides and the news — stays free to read, with no account and no card.

Referenced across the research world

University of Cambridge logoColumbia University logoCrossref logoUniversity of Edinburgh logoHarvard University logoUniversity of Oxford logoPrinceton University logoStanford School of Medicine logoUniversity College London logoORCID logoUniversity of Cambridge logoColumbia University logoCrossref logoUniversity of Edinburgh logoHarvard University logoUniversity of Oxford logoPrinceton University logoStanford School of Medicine logoUniversity College London logoORCID logo
  • University of Cambridge logo
  • Columbia University logo
  • Crossref logo
  • University of Edinburgh logo
  • Harvard University logo
  • University of Oxford logo
  • Princeton University logo
  • Stanford School of Medicine logo
  • University College London logo
  • ORCID logo

View CASRAI adoption →

Ask CASRAI · Regulatory Radar

Research-admin question? Get an answer that links its sources.

An AI assistant specialized in research administration. Every answer links its sources to check before you act. 2 questions free, no account. $29/month after.

  • Answers draw on CASRAI's guides and dictionary plus the federal and funder documents we index: Federal Register, Grants.gov, Regulations.gov and UKRI.
  • Every answer numbers its sources and links each one, so you can check the source yourself.