jagex
jagex

Reputation: 23

Creating multiple new columns within a DF depending on the the order of logical columns

I am trying to create three new columns with values depending on a particular order of three logical type columns.

eg I have this:

     a     b    c 
1 TRUE  TRUE TRUE
2 TRUE FALSE TRUE
3 TRUE FALSE TRUE

And depending if going across the row the values are TRUE, TRUE, TRUE as in row 1, then create three new columns with the values 1,1,1 but if the order is TRUE,FALSE,TRUE as in row 2 and 3 then the values would be 2,3,3. Just to note, a value of TRUE does not = 1 but rather a value I define depending on all three logical values (A total of 8 possible combinations each defined by three separate numbers). So I get something like this:

     a     b    c d e f
1 TRUE  TRUE TRUE 5 5 2
2 TRUE FALSE TRUE 2 3 3
3 TRUE FALSE TRUE 2 3 3

If someone could point me in the right direction to do this as efficiently as possible it would be greatly appreciated as I am relatively new to R.

Upvotes: 2

Views: 44

Answers (2)

Matt
Matt

Reputation: 7413

Here's a dplyr solution using case_when. On the left side of the ~ you define your conditions, and on the right side of the ~ you assign a value for when those conditions are met. If a condition is not met (i.e. all FALSE values), you will return NA.

df %>% 
  mutate(d = 
           case_when(
             a == TRUE & b == TRUE & c == TRUE ~ 5,
             a == TRUE & b == FALSE & c == TRUE ~ 2
           ),
         e = 
           case_when(
             a == TRUE & b == TRUE & c == TRUE ~ 5,
             a == TRUE & b == FALSE & c == TRUE ~ 3
           ),
         f = 
           case_when(
             a == TRUE & b == TRUE & c == TRUE ~ 2,
             a == TRUE & b == FALSE & c == TRUE ~ 3
           ))

Which gives you:

  a     b     c         d     e     f
  <lgl> <lgl> <lgl> <dbl> <dbl> <dbl>
1 TRUE  TRUE  TRUE      5     5     2
2 TRUE  FALSE TRUE      2     3     3
3 TRUE  FALSE TRUE      2     3     3

Data:

df <- tribble(
  ~a, ~b, ~c,
  TRUE, TRUE, TRUE,
  TRUE, FALSE, TRUE,
  TRUE, FALSE, TRUE
)

Upvotes: 1

Ronak Shah
Ronak Shah

Reputation: 389265

If there is no logic in getting values for the columns and you need to add conditions individually for each combination you can use if/else.

df[c('d', 'e', 'f')] <- t(apply(df, 1, function(x) {
                          if (x[1] && x[2] && x[3]) c(5, 5, 2)
                          else if (x[1] && !x[2] && x[3]) c(2, 3, 3)
                          #add more conditions
                          #....
                          }))

df
#     a     b    c d e f
#1 TRUE  TRUE TRUE 5 5 2
#2 TRUE FALSE TRUE 2 3 3
#3 TRUE FALSE TRUE 2 3 3

Upvotes: 2

Related Questions