diff --git a/NEWS.md b/NEWS.md index 9b179489ce..8cbe8b2f7b 100644 --- a/NEWS.md +++ b/NEWS.md @@ -63,6 +63,8 @@ 8. `rbind()` and `rbindlist()` of length-0 ordered factors failed with `Internal error: savetl_init checks failed`, [#4795](https://github.com/Rdatatable/data.table/issues/4795) [#4823](https://github.com/Rdatatable/data.table/issues/4823). Thanks to @shrektan and @dbart79 for reporting, and @shrektan for fixing. +9. `data.table(NULL)[, firstCol:=1L]` created `data.table(firstCol=1L)` ok but did not update the internal `row.names` attribute, causing `Error in '$<-.data.frame'(x, name, value) : replacement has 1 row, data has 0` when passed to packages like `ggplot` which use `DT` as if it is a `data.frame`, [#4597](https://github.com/Rdatatable/data.table/issues/4597). Thanks to Matthew Son for reporting, and Cole Miller for the PR. + ## NOTES 1. New feature 29 in v1.12.4 (Oct 2019) introduced zero-copy coercion. Our thinking is that requiring you to get the type right in the case of `0` (type double) vs `0L` (type integer) is too inconvenient for you the user. So such coercions happen in `data.table` automatically without warning. Thanks to zero-copy coercion there is no speed penalty, even when calling `set()` many times in a loop, so there's no speed penalty to warn you about either. However, we believe that assigning a character value such as `"2"` into an integer column is more likely to be a user mistake that you would like to be warned about. The type difference (character vs integer) may be the only clue that you have selected the wrong column, or typed the wrong variable to be assigned to that column. For this reason we view character to numeric-like coercion differently and will warn about it. If it is correct, then the warning is intended to nudge you to wrap the RHS with `as.()` so that it is clear to readers of your code that a coercion from character to that type is intended. For example : diff --git a/inst/tests/tests.Rraw b/inst/tests/tests.Rraw index ff1647bea8..bcdd90f6af 100644 --- a/inst/tests/tests.Rraw +++ b/inst/tests/tests.Rraw @@ -17381,3 +17381,13 @@ test(2173, as.data.table(x), data.table(a=1:5, b.V1=6:10, b.V2=11:15)) # rbind two length-0 ordered factors, #4795 DT = data.table(A = ordered(character())) test(2174, rbind(DT, DT), DT) + +## set row.names when a null data.table has a column assigned for the first time, #4597 +DT = data.table() +test(2175.1, attr(DT[, x:=1:5], "row.names"), 1:5) +DT = data.table() +set(DT, j=c("v1","v2"), value=list(1:6, 2:7)) +test(2175.2, attr(DT, "row.names"), 1:6) +DT = data.table(x=integer()) +test(2175.3, DT[, y:=3L], data.table(x=integer(), y=integer())) # in keeping with recent #4262, view as recycling the length-1 3L to match the length-0 data + diff --git a/src/assign.c b/src/assign.c index 27fbccbd0e..e811276610 100644 --- a/src/assign.c +++ b/src/assign.c @@ -473,6 +473,14 @@ SEXP assign(SEXP dt, SEXP rows, SEXP cols, SEXP newcolnames, SEXP values) for (i=0; i