Baek-Lok Oh - 1 year ago 61
R Question

# How to mutate multiple variables without repeating codes?

I'm trying to create new variables from existing variables like below:

``````a1+a2=a3, b1+b2=b3, ..., z1+z2=z3
``````

Here is an example data frame

``````df <- data.frame(replicate(10,sample(1:10)))
colnames(df) <- c("a1","a2","b1","b2","c1","c2","d1","d2","e1","e2")
``````

Here's my solution with repeating codes

``````# a solution by base R
df\$a3 <- df\$a1 + df\$a2
df\$b3 <- df\$b1 + df\$b2
df\$c3 <- df\$c1 + df\$c2
df\$d3 <- df\$d1 + df\$d2
df\$e3 <- df\$e1 + df\$e2
``````

Or

``````# a solution by dplyr
library(dplyr)
df <- df %>%
mutate(a3 = a1+a2,
b3 = b1+b2,
c3 = c1+c2,
d3 = d1+d2,
e3 = e1+d2)
``````

Or

``````# a solution by data.table
library(data.table)
DT <- data.table(df)
DT[,a3:=a1+a2][,b3:=b1+b2][,c3:=c1+c2][,d3:=d1+d2][,e3:=e1+e2]
``````

Actually I have more than 100 variables, so I want to find a way to do so without repeating code... Although I tried to use mutate_ with standard evaluation and regular expression, I lost my way because I'm a newbie in R. Can you mutate multiple variables without repeating code?

My `data.table` solution:

``````sapply(c("a", "b", "c", "d", "e"), function(ll)
df[ , paste0(ll, 3) := get(paste0(ll, 1)) + get(paste0(ll, 2))])
df[]
#     a1 a2 b1 b2 c1 c2 d1 d2 e1 e2 a3 b3 c3 d3 e3
#  1:  5  2  2  6  4  1 10  7  3  9  7  8  5 17 12
#  2:  4  8  7  3  3  7  9  6  9  7 12 10 10 15 16
#  3: 10  7  6 10  1  9  4  1  2  4 17 16 10  5  6
#  4:  3  4  1  7  6  4  7  4  7  5  7  8 10 11 12
#  5:  8  3  4  2  2  2  3  3  4 10 11  6  4  6 14
#  6:  6  6  5  1  8 10  1 10  5  3 12  6 18 11  8
#  7:  2 10  8  9  5  6  2  5 10  2 12 17 11  7 12
#  8:  1  1 10  8  9  5  6  9  6  8  2 18 14 15 14
#  9:  9  5  3  5 10  3  5  2  1  6 14  8 13  7  7
# 10:  7  9  9  4  7  8  8  8  8  1 16 13 15 16  9
``````

Or, more extensibly:

``````sapply(c("a", "b", "c", "d", "e"), function(ll)
df[ , paste0(ll, 3) := Reduce(`+`, mget(paste0(ll, 1:2)))])
``````

If all of the variables fit the pattern of ending with `1` or `2`, you might try:

``````stems = unique(gsub("[0-9]", "", names(df)))
``````

Then `sapply(stems, ...)`

Recommended from our users: Dynamic Network Monitoring from WhatsUp Gold from IPSwitch. Free Download