I have a data frame that looks like this :
cond1 | cond2 | a | b | c | d |
---|---|---|---|---|---|
1 | 0 | 98 | 89 | 78 | 89 |
1 | 0 | 45 | 54 | 34 | 56 |
0 | 0 | 34 | 233 | 56 | 67 |
0 | 0 | 21 | 12 | 4 | 78 |
1 | 1 | 1 | 1 | 2 | 89 |
1 | 1 | 34 | 4 | 123 | 2 |
If the values of cond1 and cond2 columns is 0 then 0 must be the columns a and b and then 1 for columns c and d.
Ideally I want a resulted data frame like this :
cond1 | cond2 | a | b | c | d |
---|---|---|---|---|---|
1 | 0 | 98 | 89 | 78 | 89 |
1 | 0 | 45 | 54 | 34 | 56 |
0 | 0 | 0 | 0 | 1 | 1 |
0 | 0 | 0 | 0 | 1 | 1 |
1 | 1 | 1 | 1 | 2 | 89 |
1 | 1 | 34 | 4 | 123 | 2 |
How I can do this in R using dplyr package ?
library(tidyverse)
cond1 = c(1,1,0,0,1,1)
cond2 = c(0,0,0,0,1,1)
a = c(98,45,34,21,1,34)
b = c(89,54,233,12,1,4)
c = c(78,34,56,4,2,123)
d = c(89,56,67,78,89,2)
data = tibble(cond1,cond2,a,b,c,d);data
CodePudding user response:
With dplyr
, if there are separate values to be replaced for blocks of columns, call the across
with those subset of columns and replace
library(dplyr)
data <- data %>%
mutate(across(c(a,b), ~ .x * !(cond1==0 & cond2==0)),
across(c(c, d), ~ replace(.x,(cond1 == 0 & cond2 == 0), 1)))
-output
data
# A tibble: 6 × 6
cond1 cond2 a b c d
<dbl> <dbl> <dbl> <dbl> <dbl> <dbl>
1 1 0 98 89 78 89
2 1 0 45 54 34 56
3 0 0 0 0 1 1
4 0 0 0 0 1 1
5 1 1 1 1 2 89
6 1 1 34 4 123 2
Or use a single across
and create a condition with case_when
data %>%
mutate(across(a:d, ~ case_when(cond1 == 0 & cond2 == 0 ~ c(0, 1)[
1 any(c('c', 'd') %in% cur_column())], TRUE ~ .x)))
-output
# A tibble: 6 × 6
cond1 cond2 a b c d
<dbl> <dbl> <dbl> <dbl> <dbl> <dbl>
1 1 0 98 89 78 89
2 1 0 45 54 34 56
3 0 0 0 0 1 1
4 0 0 0 0 1 1
5 1 1 1 1 2 89
6 1 1 34 4 123 2