5

I want to do a simple loop using data.table. I have 20 dichotomous (0,1) variables (from var_1 to var_20) and I would like to do a loop for this:

dat[var_1==1, newvar:=1]
dat[var_2==1, newvar:=2]
dat[var_3==1, newvar:=3]
...
dat[var_20==1, newvar:=21]

My main problem is I don't know how specify i (i.e. var_1==1, var_2==2...) using a loop. Below a short example:

var_1  <- c(1, rep(0,9))
var_2  <- c(0,1, rep(0,8))
var_3  <- c(0,0,1, rep(0,7))
dat  <- data.table(var_1, var_2, var_3)

dat[var_1==1, newvar:=1]
dat[var_2==1, newvar:=2]
dat[var_3==1, newvar:=3]

Any ideas about how to do this with a loop? Thanks!

2 Answers 2

4

To take advantage of data.table class it is better to set key.

dat[ ,newvar:= NA_integer_]
for(i in ncol(dat)) {
 setkeyv(dat, names(dat)[i])
 dat[J(1), newvar:=i]
}
Sign up to request clarification or add additional context in comments.

3 Comments

Thank you. Do you know how to do that newvar:=1L increases from 1 to the number of variables (e.g., newvar should be equal to 2 for var_2, 3 for var_3, and so on). It is also possible that some variables have a value 1 simultaneously, in that case, I would like to impute just the bigger value (e.g., a case has var_1=1 and var_3=1, I would like to get newvar=3).
The code above should do this. I would be interested in the performance of repeatedly setting keys compared to sequential but single vector scans on large data.tables
@WojciechSobala Usually it is better to setkey but setkey has to read every value in the column (scan) in the process of sorting it. So in the special case of a single scan for a single value on a single column, a vector scan should be faster than setkey+join. Worth testing though, I haven't tested that myself.
4

Something like this will work.

nams <- names(dat)
for(n in seq_along(nams)){
  nam <- nams[n] 
  char <- sprintf('%s==1',nam)
  dat[eval(parse(text=char)), newvar := n]
}
dat
var_1 var_2 var_3 newvar
1:     1     0     0      1
2:     0     1     0      2
3:     0     0     1      3
4:     0     0     0     NA
5:     0     0     0     NA
6:     0     0     0     NA
7:     0     0     0     NA
8:     0     0     0     NA
9:     0     0     0     NA
10:    0     0     0     NA

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.