Skip to content

Assignment is inconsistent with list #4569

@ColeMiller1

Description

@ColeMiller1

Updating a data.table by reference provides inconsistent results for single-row data.tables:

library(data.table) ##1.12.8 - same results in master
dt = data.table(a = 3L)
dt[, b:= 3L]
dt[, b2 := .(3L)]
dt[, `:=`( b3 = 3L)]
dt[, `:=`(b4 = .(3L))]
dt
#>        a     b    b2    b3     b4
#>    <int> <int> <int> <int> <list>
#> 1:     3     3     3     3      3

Basically, the var := .(...) version seems to coerce the RHS to an atomic if ... evaluates to an atomic and is the same number of rows as the data.table. This differs from `:=`(var = .(...)) which appears to always make var a list column

dt = data.table(a = c(1L,3L))
dt[, b2 := .(c(2L, 3L))]
dt[, `:=`(b4 = .(c(2L, 3L)))]
dt

##       a    b2     b4
##   <int> <int> <list>
##1:     1     2    2,3
##2:     3     3    2,3

##non-equal lengths
dt = data.table(a = c(1L, 3L, 5))
dt[, b2 := .(c(2L, 3L))]
dt

##       a     b2
##   <num> <list>
##1:     1    2,3
##2:     3    2,3
##3:     5    2,3

I have not had a chance to dig deep, but this line from [.data.table may help explain why `:=`(var = .(...)) results in a list.

data.table/R/data.table.R

Lines 1047 to 1053 in ad7b67c

} else {
# `:=`(c2=1L,c3=2L,...)
lhs = names(jsub)[-1L]
if (any(lhs=="")) stop("In `:=`(col1=val1, col2=val2, ...) form, all arguments must be named.")
names(jsub)=""
jsub[[1L]]=as.name("list")
}

This was observed while investigating #4568 although I am not sure how related they are.

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions