There are a couple wrinkles here. First, I'm interpreting title case as meaning each word starts with a capital letter, and underscores are replaced by spaces. Second, some solutions will work on the data frame's names but not on the precinct column, because tools::toTitleCase
, which underlies some other functions including the snakecase
that I initially suggested, assumes that a single letter shouldn't be capitalized.
snakecase::to_title_case(names(df))
#> [1] "Precinct" "Steve Alpha" "Mike Bravo" "Allan Charlie"
snakecase::to_title_case(df$precinct, sep_out = " ", sep_in = "_")
#> [1] "A b c" "B c d" "E f g"
That seems like not the correct outcome for precincts. Knowing that every precinct has only single-letter words, you could just replace the underscores and then convert to all caps, but that won't hold for any other words. Alternatively, stringr::str_to_title
doesn't keep single-letter words lowercase, so do the replacement and then pass to that.
stringr::str_to_title(stringr::str_replace_all(df$precinct, "_", " "))
#> [1] "A B C" "B C D" "E F G"
I mentioned in a comment having made a similar function for a package at work, which handles a variety of cases and which people should feel free to copy. This is a greatly pared down version that replaces underscores, then converts any lowercase letter at the start of a word with its uppercase counterpart, so it will work on both instances.
clean_titles <- function(x) {
x <- gsub("_", " ", x)
x <- gsub("\\b([a-z])", "\\U\\1", x, perl = TRUE)
x
}
clean_titles(names(df))
#> [1] "Precinct" "Steve Alpha" "Mike Bravo" "Allan Charlie"
clean_titles(df$precinct)
#> [1] "A B C" "B C D" "E F G"
Finally, because you have a function that does this, you can use it in both dplyr::mutate
to change that one column, and in dplyr::rename_with
to change all column names.
library(dplyr)
df %>%
mutate(precinct = clean_titles(precinct)) %>%
rename_with(clean_titles)
#> Precinct Steve Alpha Mike Bravo Allan Charlie
#> 1 A B C 309 120 379
#> 2 B C D 337 151 442
#> 3 E F G 294 240 597