Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Assignment is inconsistent with list #4569

Open
ColeMiller1 opened this issue Jun 22, 2020 · 3 comments
Open

Assignment is inconsistent with list #4569

ColeMiller1 opened this issue Jun 22, 2020 · 3 comments
Labels
consistency non-atomic column e.g. list columns, S4 vector columns

Comments

@ColeMiller1
Copy link
Contributor

ColeMiller1 commented Jun 22, 2020

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.

@jangorecki jangorecki added the non-atomic column e.g. list columns, S4 vector columns label Jun 22, 2020
@jangorecki
Copy link
Member

@ColeMiller1
Copy link
Contributor Author

Thanks for the related items.

I see LHS := RHS similar to transform(), within(), or $<-. In each case, the RHS is taken as is. Therefore, I expect V1 := 1L to be an atomic whereas V1 := list(1L) to be a list column.

@mb706
Copy link

mb706 commented Jun 26, 2020

I assume this behaviour comes from b2 := list(3L) being an edge-case of c("b2", "c2", "d2") := list(3L, 4L, 5L)?

If n is set to an integer, then

dt <- data.table()
lettercols <- head(letters, n)
lettervals <- as.list(seq_len(n))
dt[, (lettercols) := lettervals]

should not give a list column in the n == 1 case. The `:=`(col = val) notation does not work like this, therefore there is no need to remove the outermost list().

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
consistency non-atomic column e.g. list columns, S4 vector columns
Projects
None yet
Development

No branches or pull requests

4 participants