User2321
User2321

Reputation: 3062

R data.table assign two columns by reference using ifelse

I have the following data.table

library(data.table)
x <- data.table(a = 1:3, b = 1:6) 

And I would like to assign at the same time two columns by reference since both columns use the same type of check. Normally I would do: (Assign multiple columns using := in data.table, by group)

x[, c("col1", "col2") := list("Yes", b)]

But I need an ifelse construction for it. So I tried:

x[, c("col1", "col2") := ifelse(a > 2, list("Yes", b), list("No", a))]

But this does not work, I get an error:

Supplied 2 columns to be assigned 6 items

How can I work around it?

Upvotes: 4

Views: 544

Answers (2)

s_baldur
s_baldur

Reputation: 33753

You could:

x[, c("col1", "col2") := .("No", a)] # Default value
x[a > 2, c("col1", "col2") := .("Yes", b)] # .() is short for list()

Another option that would generalise better to more complicated cases:

x[, test_a := a > 2]
update_table <- data.table(
  test_a = c(TRUE, FALSE),
  col1 = c('Yes', 'No'),
  col2 = c('a', 'b')
)
cols <- c('col1', 'col2')
x[, (cols) := update_table[.SD, on = 'test_a', .SD, .SDcols = cols]]

Upvotes: 4

ThomasIsCoding
ThomasIsCoding

Reputation: 102920

You can try the code below using if ... else ..., instead of ifelse()

x <- data.table(a = 1:3, b = 1:6)
x[,
  c("col1", "col2") :={
    if (a > 2) list("Yes", b) else list("No", a)
  },
  by = 1:nrow(x)
][]

which gives

   a b col1 col2
1: 1 1   No    1
2: 2 2   No    2
3: 3 3  Yes    3
4: 1 4   No    1
5: 2 5   No    2
6: 3 6  Yes    6

Upvotes: 1

Related Questions