पाठ 19 / 25

Strings with stringr and Dates with lubridate

Clean text and handle dates and times correctly.

Two common sources of messy data

Text columns are often inconsistent: extra spaces, mixed case, typos and embedded codes. stringr offers consistent functions starting with str_: str_trim(), str_squish(), str_to_lower()/str_to_title(), str_detect() (does it match?), str_replace()/str_replace_all(), str_extract() (pull out a match, such as a PIN code), str_split(), str_pad(), str_length() and str_glue() for templating. Patterns are regular expressions: "\\d{6}" matches six digits (backslashes are doubled inside R strings, or use raw strings r"(\d{6})"). Dates and times cause subtle bugs. lubridate parses them with readable functions named after the input order: dmy("03/10/2026"), ymd("2026-10-03"), ymd_hms(...). It extracts parts (year(), month(label = TRUE), wday()), rounds (floor_date(x, "week")) and does arithmetic with periods (months(1), calendar-aware) and durations (exact seconds). Store timestamps in UTC and convert with with_tz(x, "Asia/Kolkata") for display.

Cleaning text and parsing dates

Messy strings and date formats become clean, typed columns.

Left: jumbled text fragments and differently formatted dates. Right: neat aligned columns with consistent formats.
Figure 7.1 — From messy text and dates to typed values.

Cleaning addresses and working with dates

Regex extraction and calendar-aware date arithmetic.

library(stringr)
library(lubridate)
library(dplyr)

addresses <- c("  12 MG Road , PUNE 411001 ", "Sector 18, noida-201301", "Anna Nagar Chennai 600040")

tibble(raw = addresses) |>
  mutate(
    clean = str_squish(raw),
    pin = str_extract(clean, "\\d{6}"),                         # six-digit PIN code
    city = str_to_title(str_extract(clean, "(?i)pune|noida|chennai"))
  )

order_dates <- dmy(c("03/10/2026", "31/01/2026"))
wday(order_dates, label = TRUE)                     # day of week
order_dates + months(1)                             # 2026-11-03 and NA (no 31 Feb)
order_dates %m+% months(1)                          # rolls back to month end: 2026-11-03, 2026-02-28

placed <- ymd_hms("2026-10-03 06:45:00", tz = "UTC")
with_tz(placed, "Asia/Kolkata")                     # 2026-10-03 12:15:00 IST
floor_date(placed, "week", week_start = 1)          # Monday of that week

Month arithmetic is tricky

Adding one month to 31 January has no single right answer. lubridate's + months(1) returns NA for impossible dates, while %m+% rolls back to the last valid day. Choose deliberately for billing dates.

त्वरित जाँच: Which lubridate function parses "03/10/2026" written as day/month/year?

  • dmy
  • ymd
  • mdy
  • ydm
Answer

dmy — The function name follows the order of components in the input.