Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Use dynamic names for CJ in data.table

I want to use CJ with a flexible number of columns with flexible names, for example

J = 3
temp = CJ(paste0('Q', 1) = 0:100)
if(J > 1){
  for(j in 2:J){
    temp = CJ(temp,paste0('Q', j) = 0:100))
  }
}

For arbitrary J.

Where the output is:

CJ(Q1 = 0:100, Q2 = 0:100, Q3 = 0:100)


          Q1  Q2  Q3
      1:   0   0   0
      2:   0   0   1
      3:   0   0   2
      4:   0   0   3
      5:   0   0   4
     ---            
1030297: 100 100  96
1030298: 100 100  97
1030299: 100 100  98
1030300: 100 100  99
1030301: 100 100 100
like image 488
wolfsatthedoor Avatar asked Feb 03 '26 10:02

wolfsatthedoor


1 Answers

This is a classic case for do.call:

temp = do.call(CJ, replicate(J, 0:100, simplify = FALSE))
setnames(temp, paste0('Q', 1:J))
temp
#           Q1  Q2  Q3
#       1:   0   0   0
#       2:   0   0   1
#       3:   0   0   2
#       4:   0   0   3
#       5:   0   0   4
#      ---            
# 1030297: 100 100  96
# 1030298: 100 100  97
# 1030299: 100 100  98
# 1030300: 100 100  99
# 1030301: 100 100 100

It's possible to construct this in one line using setNames and lapply instead of replicate, but much less readable IMO. setnames is almost instantaneous so there's no efficiency concern.

like image 132
MichaelChirico Avatar answered Feb 05 '26 00:02

MichaelChirico



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!