Reputation: 3062
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
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
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