melbez
melbez

Reputation: 1000

Creating multiple new columns conditional on values of previous columns with modified names in R

I have a dataframe that looks like the following, but with more columns and rows.

dog_c  cat_c  cheese_c  hat_c 
3      4      3         2
3      1      2         5
5      2      1         4 

I would like to create a dataframe that looks like the following. I want to square all the values in a given column from the original dataframe and then create a column name that's the same as the original but with a 2 on the end. I would then like to attach it to the original dataframe.

dog_c  cat_c  cheese_c  hat_c  dog_c2  cat_c2  cheese_c2  hat_c2 
3      4      3         2      9       16      9          4
3      1      2         5      9       1       2          5
5      2      1         4      25      4       1          16

I know I could do this in the following way for each new column.

df$dog_c2 <- (df$dog_c)^2

Does anyone have suggestions for how I can do this more efficiently?

Upvotes: 1

Views: 40

Answers (2)

akrun
akrun

Reputation: 886938

We can use mutate with across in the devel version of dplyr

library(dplyr)
df1 %>% 
    mutate(across(everything(), list(~ .x^2), names = "{col}2"))
#  dog_c cat_c cheese_c hat_c dog_c2 cat_c2 cheese_c2 hat_c2
#1     3     4        3     2      9     16         9      4
#2     3     1        2     5      9      1         4     25
#3     5     2        1     4     25      4         1     16

Or for selected columns

nm1 <- c('dog_c','cat_c')
df1 %>% 
    mutate(across(all_of(nm1), list(~ .x^2), names = "{col}2"))
#   dog_c cat_c cheese_c hat_c dog_c2 cat_c2
#1     3     4        3     2      9     16
#2     3     1        2     5      9      1
#3     5     2        1     4     25      4

Or with data.table

library(data.table)
setDT(df1)[, paste0(nm1, 2) := .SD^2, .SDcols = nm1]

data

df1 <- structure(list(dog_c = c(3L, 3L, 5L), cat_c = c(4L, 1L, 2L), 
cheese_c = 3:1, hat_c = c(2L, 5L, 4L)), class = "data.frame", 
row.names = c(NA, -3L))

Upvotes: 1

Ronak Shah
Ronak Shah

Reputation: 388807

You could do the same directly for dataframe as well :

df[paste0(names(df), 2)] <- df^2
df

#  dog_c cat_c cheese_c hat_c dog_c2 cat_c2 cheese_c2 hat_c2
#1     3     4        3     2      9     16         9      4
#2     3     1        2     5      9      1         4     25
#3     5     2        1     4     25      4         1     16

If you want to do this in dplyr, you can use mutate_all

library(dplyr)
df %>% mutate_all(list(`2` = ~. ^2))

If we want to do this only for selected columns, we can do :

cols <- c('dog_c','cat_c') #Use regex if there are lot of columns.
df[paste0(cols, 2)] <- df[cols]^2

#  dog_c cat_c cheese_c hat_c dog_c2 cat_c2
#1     3     4        3     2      9     16
#2     3     1        2     5      9      1
#3     5     2        1     4     25      4

Or use mutate_at with dplyr

df %>% mutate_at(cols, list(`2` = ~.^2))

data

df <- structure(list(dog_c = c(3L, 3L, 5L), cat_c = c(4L, 1L, 2L), 
cheese_c = 3:1, hat_c = c(2L, 5L, 4L)), class = "data.frame", 
row.names = c(NA, -3L))

Upvotes: 2

Related Questions