I have a dataframe with a factor variable identifying my groups (here y
), and multiple numerical variables (to simplify, here I only show two x
and z
):
df = tribble(
~x, ~y, ~z,
1, "a", 5,
2, "b", 6,
3, "a", 7,
4, "b", 8,
5, "a", 9,
6, "b", 10
)
I want to add new columns to my dataframe in which I apply different mathematical functions on those numerical variables (x and z), based on the values of the factor variable (y). For the example dataframe above: all observations with y == "a"
are added with 1, and the ones with y == "b"
are added with 2.
This is my code to do it:
df %>% mutate(x_new = case_when(grepl("a", y) ~ x + 1,
grepl("b", y) ~ x + 2))
### Output
# A tibble: 6 × 4
x y z x_new
<dbl> <chr> <dbl> <dbl>
1 1 a 5 2
2 2 b 6 4
3 3 a 7 4
4 4 b 8 6
5 5 a 9 6
6 6 b 10 8
My code works OK for adding one variable, but I want to apply the same functions for ALL the numerical variables, so in the example I want to apply the functions to the "z" variable as well and store the values in another new column. Since I have many numerical columns I don't want to manually mutate them one by one with the approach above. Any advice on how to do this? (specially tidyverse solutions but any help is very appreciated)
Make a lookup to match a, b with 1,2. Then add to df excluding y column. Finally, suffix with "_new"
and column bind back to original dataframe:
ll <- setNames(c(1, 2), c("a", "b"))
x <- df[, -2 ] + ll[ df$y ]
colnames(x) <- paste0(colnames(x), "_new")
cbind(df, x)
# x y z x_new z_new
# 1 2 a 6 3 7
# 2 4 b 8 6 10
# 3 4 a 8 5 9
# 4 6 b 10 8 12
# 5 6 a 10 7 11
# 6 8 b 12 10 14