You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardexpand all lines: NEWS.md
+20-2
Original file line number
Diff line number
Diff line change
@@ -92,6 +92,8 @@
92
92
93
93
15. `DT[order(col)[1:5], ...]` (i.e.where`i`isacompoundexpressioninvolving`order()`) isnowoptimizedtouse`data.table`'s multithreaded `forder`, [#1921](https://github.com/Rdatatable/data.table/issues/1921). This example is not a fully optimal top-N query since the full ordering is still computed. The improvement is that the call to `order()` is computed faster for any `i` expression using `order`.
94
94
95
+
16. `as.data.table` now unpacks columns in a `data.frame` which are themselves a `data.frame`. This need arises when parsing JSON, a corollary in [#3369](https://github.com/Rdatatable/data.table/issues/3369#issuecomment-462662752). `data.table` does not allow columns to be objects which themselves have columns (such as `matrix` and `data.frame`), unlike `data.frame` which does. Bug fix 19 in v1.12.2 (see below) added a helpful error (rather than segfault) to detect such invalid `data.table`, and promised that `as.data.table()` would unpack these columns in the next release (i.e. this release) so that the invalid `data.table` is not created in the first place.
96
+
95
97
#### BUG FIXES
96
98
97
99
1. `first`, `last`, `head` and `tail` by group no longer error in some cases, [#2030](https://github.com/Rdatatable/data.table/issues/2030) [#3462](https://github.com/Rdatatable/data.table/issues/3462). Thanks to @franknarf1 for reporting.
@@ -134,7 +136,23 @@
134
136
135
137
20. `c`, `seq` and `mean` of `ITime` objects now retain the `ITime` class via new `ITime` methods, [#3628](https://github.com/Rdatatable/data.table/issues/3628). Thanks @UweBlock for reporting. The `cut` and `split` methods for `ITime` have been removed since the default methods work, [#3630](https://github.com/Rdatatable/data.table/pull/3630).
136
138
137
-
20. `as.data.table.array` now handles the case when some of the array'sdimensionnamesare`NULL`, [#3636](https://github.com/Rdatatable/data.table/issues/3636).
139
+
21. `as.data.table.array` now handles the case when some of the array'sdimensionnamesare`NULL`, [#3636](https://github.com/Rdatatable/data.table/issues/3636).
140
+
141
+
22.Addinga`list`columnusing`cbind`, `as.data.table`, or`data.table`nowworksratherthantreatingthe`list`asifitwereasetofcolumns, [#3471](https://github.com/Rdatatable/data.table/pull/3471). However, please note that using `:=` to add columns is preferred.
142
+
143
+
```R
144
+
# cbind( data.table(1:2), list(c("a","b"),"a") )
145
+
# V1 V2 NA # v1.12.2 and before
146
+
# <int> <char> <char> # introduced invalid NA column name too
147
+
# 1: 1 a a
148
+
# 2: 2 b a
149
+
#
150
+
# V1 V2 # v1.12.4+
151
+
# <int> <list>
152
+
# 1: 1 a,b
153
+
# 2: 2 a
154
+
```
155
+
138
156
139
157
#### NOTES
140
158
@@ -231,7 +249,7 @@
231
249
232
250
18. `cbind` with a null (0-column) `data.table` now works as expected, [#3445](https://github.com/Rdatatable/data.table/issues/3445). Thanks to @mb706 for reporting.
233
251
234
-
19. Subsetting does a better job of catching a malformed `data.table` with error rather than segfault. A column may not be NULL, nor may a column be an object such as a data.frame or matrix which have columns. Thanks to a comment and reproducible example in [#3369](https://github.com/Rdatatable/data.table/issues/3369) from Drew Abbot which demonstrated the issue which arose from parsing JSON. The next release will enable `as.data.table` to unpack columns which are data.frame to support this use case.
252
+
19. Subsetting does a better job of catching a malformed `data.table` with error rather than segfault. A column may not be NULL, nor may a column be an object which has columns (such as a `data.frame` or `matrix`). Thanks to a comment and reproducible example in [#3369](https://github.com/Rdatatable/data.table/issues/3369) from Drew Abbot which demonstrated the issue which arose from parsing JSON. The next release will enable `as.data.table` to unpack columns which are `data.frame` to support this use case.
eachnrow= integer(n) # vector of lengths of each column. may not be equal if silent repetition is required.
121
+
eachncol= integer(n)
122
+
missing.check.names= missing(check.names)
123
+
for (iin seq_len(n)) {
124
+
xi=x[[i]]
125
+
if (is.null(xi)) next# eachncol already initialized to 0 by integer() above
126
+
if (!is.null(dim(xi)) &&missing.check.names) check.names=TRUE
127
+
if ("POSIXlt" %chin% class(xi)) {
128
+
warning("POSIXlt column type detected and converted to POSIXct. We do not recommend use of POSIXlt at all because it uses 40 bytes to store one date.")
129
+
xi=x[[i]] = as.POSIXct(xi)
130
+
} elseif (is.matrix(xi) || is.data.frame(xi)) {
131
+
if (!is.data.table(xi)) {
132
+
xi=x[[i]] = as.data.table(xi, keep.rownames=keep.rownames) # we will never allow a matrix to be a column; always unpack the columns
133
+
}
134
+
# else avoid dispatching to as.data.table.data.table (which exists and copies)
eachnrow[i] = NROW(xi) # for a vector (including list() columns) returns the length
141
+
eachncol[i] = NCOL(xi) # for a vector returns 1
131
142
}
132
-
n= vapply(x, length, 0L)
133
-
mn= max(n)
134
-
x= copy(x)
135
-
idx= which(n<mn)
136
-
if (length(idx)) {
137
-
for (iinidx) {
138
-
# any is.null(x[[i]]) were removed above, otherwise warning when a list element is NULL
139
-
if (inherits(x[[i]], "POSIXlt")) {
140
-
warning("POSIXlt column type detected and converted to POSIXct. We do not recommend use of POSIXlt at all because it uses 40 bytes to store one date.")
141
-
x[[i]] = as.POSIXct(x[[i]])
142
-
}
143
-
# Implementing FR #4813 - recycle with warning when nr %% nrows[i] != 0L
144
-
if (!n[i] &&mn)
145
-
warning("Item ", i, " is of size 0 but maximum size is ", mn, ", therefore recycled with 'NA'")
146
-
elseif (n[i] &&mn%%n[i] !=0L)
147
-
warning("Item ", i, " is of size ", n[i], " but maximum size is ", mn, " (recycled leaving a remainder of ", mn%%n[i], " items)")
148
-
x[[i]] = rep(x[[i]], length.out=mn)
143
+
ncol= sum(eachncol) # hence removes NULL items silently (no error or warning), #842.
144
+
if (ncol==0L) return(null.data.table())
145
+
nrow= max(eachnrow)
146
+
ans= vector("list",ncol) # always return a new VECSXP
147
+
recycle=function(x, nrow) {
148
+
if (length(x)==nrow) {
149
+
return(copy(x))
150
+
# This copy used to be achieved via .Call(CcopyNamedInList,x) at the top of data.table(). It maintains pre-Rv3.1.0
151
+
# behavior, for now. See test 548.2. The copy() calls duplicate() at C level which (importantly) also expands ALTREP objects.
152
+
# TODO: port this as.data.table.list() to C and use MAYBE_REFERENCED(x) || ALTREP(x) to save some copies.
153
+
# That saving used to be done by CcopyNamedInList but the copies happened again as well, so removing CcopyNamedInList is
154
+
# not worse than before, and gets us in a better centralized place to port as.data.table.list to C and use MAYBE_REFERENCED
155
+
# again in future.
149
156
}
157
+
if (identical(x,list())) vector("list", nrow) else rep(x, length.out=nrow) # new objects don't need copy
0 commit comments