Reverse the content of certain rows of specific columns based on a 3rd column in R

Viewed 43

My data frame looks like this:

library(tidyverse)
df <- tibble(col1=c(1,10,100,40,1000), col2=c(15,20,50,80,2000), 
             direction=c("+","+","-","+","+"), score=c(50,100,300,10,300))
df 
#> # A tibble: 5 × 4
#>    col1  col2 direction score
#>   <dbl> <dbl> <chr>     <dbl>
#> 1     1    15 +            50
#> 2    10    20 +           100
#> 3   100    50 -           300
#> 4    40    80 +            10
#> 5  1000  2000 +           300

Created on 2022-07-29 by the reprex package (v2.0.1)

I want when the direction is " - " to reverse the content of the col1 and col2,
so my data looks like this.

#>    col1  col2 direction score
#>   <dbl> <dbl> <chr>     <dbl>
#> 1     1    15 +            50
#> 2    10    20 +           100
#> 3    50   100 +           300
#> 4    40    80 +            10
#> 5  1000  2000 +           300

or

#>    col1  col2 direction score new_col1 new_col2 new_direction 
#>   <dbl> <dbl> <chr>     <dbl>
#> 1     1    15 +            50    1         15          +
#> 2    10    20 +           100    10        20          +
#> 3    100   50 -           300    50        100         +
#> 4    40    80 +            10    40        80          +
#> 5  1000  2000 +           300   1000       2000        +
1 Answers

For both, you could use transform:

df |>
  transform(col1 = ifelse(direction == "-", col2, col1),
            col2 = ifelse(direction == "-", col1, col2),
            direction = "+")

df |>
  transform(col1_new = ifelse(direction == "-", col2, col1),
            col2_new = ifelse(direction == "-", col1, col2),
            direction_new = "+")

The second can easily be done with mutate in a similar fashion:

library(dplyr)

df |> 
  mutate(col1_new = if_else(direction == "-", col2, col1),
         col2_new = if_else(direction == "-", col1, col2),
         direction_new = "+")

But in order to do the first in dplyr it won't be as elegant as transform. You'll probably need an intermediate variable.

Output:

  col1 col2 direction score
1    1   15         +    50
2   10   20         +   100
3   50  100         +   300
4   40   80         +    10
5 1000 2000         +   300

  col1 col2 direction score col1_new col2_new direction_new
1    1   15         +    50        1       15             +
2   10   20         +   100       10       20             +
3  100   50         -   300       50      100             +
4   40   80         +    10       40       80             +
5 1000 2000         +   300     1000     2000             +
Related