Different results for the standard form and functional form data.table assigne-by-reference `: =`

There seems to be a slight difference between assigning data.tabel by reference: = in the standard to the functional form.

The standard form coercites RHS on a vector, the functional form does not. Detail, but not documented, as I suppose.

library(data.table) dt <- data.table(a = c('a','b','c')) v <- c('A','B','C') l <- list(v) all.equal(copy(dt)[, new := v], copy(dt)[, `:=` (new = v)]) # [1] TRUE all.equal(copy(dt)[, new := l], copy(dt)[, `:=` (new = l)]) # [1] "Datasets have different column modes. First 3: new(character!=list)" copy(dt)[, new := l][] # a new # 1: a A # 2: b B # 3: c C copy(dt)[, `:=` (new = l)][] # a new # 1: a A,B,C # 2: b A,B,C # 3: c A,B,C 

This is the main version of how I asked this question initially.

+8
source share
1 answer

This is a very good question regarding a design decision about := operator.

For simple calls using := as an operator, for example, col := val , we decided to automatically include val in the list. This decision was made to make it more convenient for users to assign a single column.

When you use the function call form, ":="(col = val) we no longer add val to the list. This is an extended form already. := behaves like an alias for list but is updated in-place. You can always check what the updated column will be by changing := in list (or . ) Like .(col = val) .

Not even when using := , you should still specify RHS as the operator, since the list creates columns 2+, c("col1","col2") := list(val1, val2) .

+2
source

All Articles