Baek-Lok Oh - 1 year ago 52

R Question

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?

Answer Source

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, ...)`