anthr
anthr

Reputation: 1036

Generating new columns in an R dataframe based on applying a function across multiple columns

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

Answers (2)

Bertil Baron
Bertil Baron

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

Scipione Sarlo
Scipione Sarlo

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

Related Questions