3

I am trying to use conditional statements to obtain some variables in a data table. Here's some simplified data, the code and the results:

> dt
   id trial  bet outcome
1: 11     1    1       6
2: 11     2  456       2
3: 11     3 3456       3
4: 11     4  456       6
5: 12     1   34       6
6: 12     2 3456       2
7: 12     3   12       4
8: 12     4  123       2

dt1=dt[,list(
nbet=nchar(bet),
if (nchar(bet)>2.5) riskybet=1 else riskybet=0,
if (grepl(outcome,bet)==TRUE) win=1 else win=0),
by='id,trial']

> dt1
   id trial nbet V2 V3
1: 11     1    1  0  0
2: 11     2    3  1  0
3: 11     3    4  1  1
4: 11     4    3  1  1
5: 12     1    2  0  0
6: 12     2    4  1  0
7: 12     3    2  0  0
8: 12     4    3  1  1

The conditional statements are working as they should but without the assigned variable names 'riskybet' and 'win', i.e. they appear as V2 and V3. What am I doing wrong?

AlexR
  • 791
  • 2
  • 8
  • 22
  • 1
    A side comment: `1 * (nchar(bet) > 2.5)` is a shorter way of expressing your first if statement and `1 * grepl(outcome, bet)` is an equivalent way to do the second. – Dennis Jun 10 '13 at 15:03
  • 1
    I guess that the if statement works only because id and trial determine a unique row. Also, you can avoid calculating nchar twice... `{nbet=nchar(bet);list(nbet=nbet,riskybet=1*(nbet>2),win=1*grepl(outcome,bet))}` – Frank Jun 10 '13 at 15:49

1 Answers1

8

You are assigning values to variables "inside" the if/else-statement. Try this:

dt1=dt[,list(
 nbet=nchar(bet),
 riskybet = if (nchar(bet)>2.5) 1 else 0,
 win = if (grepl(outcome, bet)) 1 else 0),
    by='id,trial']

   id trial nbet riskybet win
1: 11     1    1        0   0
2: 11     2    3        1   0
3: 11     3    4        1   1
4: 11     4    3        1   1
5: 12     1    2        0   0
6: 12     2    4        1   0
7: 12     3    2        0   0
8: 12     4    3        1   1

Alternatively you could also use ifelse instead of the traditional if-else.

Arun
  • 116,683
  • 26
  • 284
  • 387
  • 2
    @AlexR I like using `0 + (nchar(bet)>2.5)` or `as.numeric(nchar(bet)>2.5)` better than `if/else` in this particular case; or better yet, just leave it as a boolean and any numeric operation you do will automatically convert to the desired 0/1 later on – eddi Jun 10 '13 at 15:39