I was wondering how I could split many columns by their sign in a data.table. To be concrete, suppose that we have:
library(data.table)
DT = data.table(x = c(-1,-2,1,3),
z = c(-1,-1,-1,-1))
I am looking to create a new data.table called DT_new
such that it looks like:
DT_new
x z x_pos x_neg z_pos z_neg
1: -1 -1 0 1 0 1
2: -2 -1 0 2 0 1
3: 1 -1 1 0 0 1
4: 3 -1 3 0 0 1
The reason I am doing this is that I want to separate out the positive and negative variables in a regression. Doing a few of these manually is easy enough. But I have hundreds of variables that I want to apply this technique to. So I am hoping that there is a "SDcols" solutions.
Thanks!
No need to use .SDcols ;-) Please find below a reprex:
DT[,`:=` (x_pos = fifelse(x>0, x, 0),
x_neg = fifelse(x<0, abs(x), 0),
z_pos = fifelse(z>0, z, 0),
z_neg = fifelse(z<0, abs(z), 0))][]
x z x_pos x_neg z_pos z_neg
1: -1 -1 0 1 0 1
2: -2 -1 0 2 0 1
3: 1 -1 1 0 0 1
4: 3 -1 3 0 0 1
AS A FOLLOW-UP TO YOUR COMMENT
Please find the reprex below.
vars <- c("x","z")
suffix <- c("_pos", "_neg")
DT[, CJ(vars, suffix, sorted = FALSE)[, paste0(vars, suffix)] := .(fifelse(x>0, x, 0),
fifelse(x<0, abs(x), 0),
fifelse(z>0, z, 0),
fifelse(z<0, abs(z), 0))][]
#> x z x_pos x_neg z_pos z_neg
#> 1: -1 -1 0 1 0 1
#> 2: -2 -1 0 2 0 1
#> 3: 1 -1 1 0 0 1
#> 4: 3 -1 3 0 0 1
Created on 2021-11-28 by the reprex package (v2.0.1)