Reputation: 1036
What I'd like to do is apply a function to multiple columns in a dataframe, recording the output as a new column. To make this clearer, I'd like to take a dataframe of the form:
first_name last_name age
Alice Smith 45
Bob Richards 20
to:
first_name last_name age first_name_lower last_name_lower
Alice Smith 45 alice smith
Bob Richards 20 bob richards
I can do this column-wise with something like:
df$first_name_lower <- apply(df[,c('first_name')], 1, function(x) str_to_lower(x))
df$last_name_lower <- apply(df[,c('last_name')], 1, function(x) str_to_lower(x))
but of course for multiple columns this isn't a particularly elegant solution.
Thanks!
Upvotes: 1
Views: 267
Reputation: 5003
This could work
transmute_if
takes a predicate and performs and action on all columns satisfying the predicate and throws away all the rest - in this case we use is.character as predicate
. Since we want to keep the orignial data we combine both datasets with cbind.
To change the names of the new columns we use select_all
to paste "_lower"
to end of the column names
dta <- read.table(header = TRUE,sep = ",",stringsAsFactors = FALSE,
text = "first_name,last_name,age
Alice,Smith,45
Bob,Richards,20")
library(tidyverse)
cbind(dta,
dta %>%
transmute_if(is.character,tolower) %>%
select_all(funs(paste0(.,"_lower")))))
Hope it helps!
Upvotes: 3
Reputation: 1498
Using tidyverse
solution:
library(tidyverse)
mydf %>%
mutate(first_name_lower=first_name,
last_name_lower=last_name) %>%
mutate_at(vars=first_name_lower,last_name_lower), ~ str_to_lower(.)))
Whether you don't want to preserve original variables:
mydf %>%
mutate_at(vars(first_name_lower, last_name_lower), ~ str_to_lower(.))
Upvotes: 2