Rdatatable / data.table

R's data.table package extends data.frame:
http://r-datatable.com
Mozilla Public License 2.0
3.6k stars 983 forks source link

Column type overwrite fails for recycled values #2577

Open MichaelChirico opened 6 years ago

MichaelChirico commented 6 years ago
data.table(a = 1:2)[ , a := 'b']

Warning messages: 1: In [.data.table(data.table(a = 1:2), , :=(a, "b")) : NAs introduced by coercion 2: In [.data.table(data.table(a = 1:2), , :=(a, "b")) : Coerced 'character' RHS to 'integer' to match the column's type. Either change the target column ['a'] to 'character' first (by creating a new 'character' vector length 2 (nrows of entire table) and assign that; i.e. 'replace' column), or coerce RHS to 'integer' (e.g. 1L, NA[real|integer], as.*, etc) to make your intent clear and for speed. Or, set the column type correctly up front when you create the table and stick to it, please.

Not sure if this is intended behavior... it's technically against the rule specified by the warning, but seems like a natural usage

MichaelChirico commented 6 months ago

The problem is a bit more general -- length-1 attempts to plonk are first attempted to coerce to the original type:

data.table(a = rep(TRUE, 2L))[ , a := 0L][]         # a is now FALSE
data.table(a = rep(TRUE, 2L))[ , a := 0][]          # a is now FALSE
data.table(a = rep(TRUE, 2L))[ , a := 0+1i][]       # error (can't coerce complex->logical)
data.table(a = rep(TRUE, 2L))[ , a := "b"][]        # error, like in main issue
data.table(a = rep(TRUE, 2L))[ , a := .(list(0))][] # works with warning, probably not for other list inputs

data.table(a = 1:2)[ , a := TRUE][] # a is 1L,1L
data.table(a = 1:2)[ , a := 1][]    # a is 1L,1L
data.table(a = 1:2)[ , a := 0+1i][] # ...
data.table(a = 1:2)[ , a := "b"][]
data.table(a = 1:2)[ , a := .(list(1))][]

data.table(a = c(1,2))[ , a := TRUE][]
data.table(a = c(1,2))[ , a := 1L][]
data.table(a = c(1,2))[ , a := 0+1i][]
data.table(a = c(1,2))[ , a := "b"][]
data.table(a = c(1,2))[ , a := .(list(1))][]

data.table(a = rep(0+1i, 2L))[ , a := TRUE][]
data.table(a = rep(0+1i, 2L))[ , a := 1L][]
data.table(a =rep( 0+1i, 2L))[ , a := 1][]
data.table(a =rep( 0+1i, 2L))[ , a := "b"][]
data.table(a =rep( 0+1i, 2L))[ , a := .(list(1))][]

data.table(a = rep("b", 2L))[, a := TRUE][]
data.table(a = rep("b", 2L))[, a := 1L][]
data.table(a = rep("b", 2L))[, a := 1][]
data.table(a = rep("b", 2L))[, a := 0+1i][]
data.table(a = rep("b", 2L))[, a := .(list(1))][]

data.table(a = list(1, 2))[ , a := TRUE][]
data.table(a = list(1, 2))[ , a := 1L][]
data.table(a = list(1, 2))[ , a := 1][]
data.table(a = list(1, 2))[ , a := "b"][]
data.table(a = list(1, 2))[ , a := 0+1i][]