I want to write a shorter version of this code:
ResultsTable <- ResultsTable %>%
mutate(V_a = as.integer(V_a + h2_a),
V_b = as.integer(V_b + h2_b),
V_c = as.integer(V_c + h2_c),
V_d = as.integer(V_d + h2_d),
V_e = as.integer(V_e + h2_e),
V_f = as.integer(V_f + h2_f))
the point it that there are several variable prefixes and suffixes that need to be combined.
also, this should be done only for lines where ResultsTable$cond == 1
, but all lines must be kept.
I tried using across(), but that doesn't seem to work with both prefixes and suffixes.
I don't even know how to approach this. help!
It is easier to help if you provide a reproducible example along with expected output. Here is a simple made up example -
df <- data.frame(cond = c(1, 1, 0, 1, 0),
V_a = 1:5, V_b = 11:15,
h2_a = 26:30, h2_b = 36:40)
df
# cond V_a V_b h2_a h2_b
#1 1 1 11 26 36
#2 1 2 12 27 37
#3 0 3 13 28 38
#4 1 4 14 29 39
#5 0 5 15 30 40
One way to automate this is using across
and pick
. For better visibility of the results I create new columns to store the output (res_V_a
and res_V_b
) using .names
argument in across
. For these results column we check if the cond
column is either 1 or 0 and use ifelse
to apply the condition.
library(dplyr)
df %>%
mutate(across(starts_with("V"), .names = "res_{col}") + pick(starts_with("h2")),
across(starts_with("res"), ~ifelse(cond == 1, .,
get(sub("res_", "", cur_column())))))
# cond V_a V_b h2_a h2_b res_V_a res_V_b
#1 1 1 11 26 36 27 47
#2 1 2 12 27 37 29 49
#3 0 3 13 28 38 3 13
#4 1 4 14 29 39 33 53
#5 0 5 15 30 40 5 15
and if you don't want to create new columns and modify only existing columns.
df %>%
mutate(pick(starts_with("V")) + pick(starts_with("h2")),
across(starts_with("V"), ~ifelse(cond == 1, .,
. - get(sub("V", "h2", cur_column())))))
# cond V_a V_b h2_a h2_b
#1 1 27 47 26 36
#2 1 29 49 27 37
#3 0 3 13 28 38
#4 1 33 53 29 39
#5 0 5 15 30 40