Cole
Cole

Reputation: 11255

data.table assign new columns based on variable

A follow-up on this question, can a data.table refer to a variable inside of the DT to create new columns?

The other question wanted to turn this table:

library(data.table)
dt <- data.table(
  dates = c("2017-01-01", "2017-01-02", "2017-01-03", "2017-01-04", "2017-01-05"),
  yes_no = c(0, 1, 0, 1, 1) 
)
        dates yes_no
1: 2017-01-01      0
2: 2017-01-02      1
3: 2017-01-03      0
4: 2017-01-04      1
5: 2017-01-05      1

Into this:

        dates yes_no 2017-01-02 2017-01-04 2017-01-05
1: 2017-01-01      0          0          0          0
2: 2017-01-02      1          1          0          0
3: 2017-01-03      0          0          0          0
4: 2017-01-04      1          0          1          0
5: 2017-01-05      1          0          0          1

I wanted to update-by-reference but do not know how to make new columns based on what is in the data.table. That is, the LHS of the := operator does not appear to look in the data.table environment which makes this fail:

## tried
dt[yes_no == 1, as.character(dates) := as.data.frame(diag(.N))]

Error in eval(lhs, parent.frame(), parent.frame()) : object 'dates' not found

## used:
ind <- dt[['yes_no']] != 0
cols <- as.character(dt[['dates']])[ind]

dt[, (cols) := 0L]
dt[ind, (cols) := as.data.frame(diag(.N))]
## also valid
# set(d, which(ind), cols, as.data.frame(diag(length(cols))))

Is there a more direct way to make this work?

dt[yes_no == 1, as.character(dates) := as.data.frame(diag(.N))]

Upvotes: 2

Views: 71

Answers (1)

s_baldur
s_baldur

Reputation: 33488

Not pretty but you could do:

dt[yes_no == 1, 
   (dt[yes_no == 1, as.character(dates)]) := as.data.table(diag(.N))]

Upvotes: 3

Related Questions