Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions NEWS.md
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,8 @@ unit = "s")

8. Compiler support for OpenMP is now detected during installation, which allows data.table to compile from source (in single threaded mode) on macOS which, frustratingly, does not include OpenMP support by default, [#2161](https://github.com/Rdatatable/data.table/issues/2161), unlike Windows and Linux. A helpful message is emitted during installation from source, and on package startup as before. Many thanks to @jimhester for the PR. This was typically a problem just after release to CRAN in the few days before macOS binaries (which do support OpenMP) are made available by CRAN.

9. `rbindlist` now supports columns of type `expression`, [#546](https://github.com/Rdatatable/data.table/issues/546). Thanks @jangorecki for the report.

## BUG FIXES

1. A NULL timezone on POSIXct was interpreted by `as.IDate` and `as.ITime` as UTC rather than the session's default timezone (`tz=""`) , [#4085](https://github.com/Rdatatable/data.table/issues/4085).
Expand Down
11 changes: 8 additions & 3 deletions inst/tests/tests.Rraw
Original file line number Diff line number Diff line change
Expand Up @@ -16673,7 +16673,12 @@ test(2128.3, DT[, .SD, .SDcols=function(x) x==1], error='conditions were not met
test(2128.4, DT[, .SD, .SDcols=function(x) 2L], error='conditions were not met for: [a, b, c]')
test(2128.5, DT[, .SD, .SDcols=function(x) NA], error='conditions were not met for: [a, b, c]')

# expression columns in rbindlist, #546
A = data.table(c1 = 1, c2 = 'asd', c3 = expression(as.character(Sys.time())))
B = data.table(c1 = 3, c2 = 'qwe', c3 = expression(as.character(Sys.time()+5)))
test(2129, rbind(A,B)$c3, expression(as.character(Sys.time()), as.character(Sys.time()+5)))

###################################
# Add new tests above this line #
###################################

########################
# Add new tests here #
########################
3 changes: 2 additions & 1 deletion src/assign.c
Original file line number Diff line number Diff line change
Expand Up @@ -1061,7 +1061,8 @@ const char *memrecycle(SEXP target, SEXP where, int start, int len, SEXP source,
BODY(SEXP, STRING_PTR, SEXP, val, SET_STRING_ELT(target, off+i, cval))
}
case VECSXP :
if (TYPEOF(source)!=VECSXP)
case EXPRSXP : // #546
if (TYPEOF(source)!=VECSXP && TYPEOF(source)!=EXPRSXP)
BODY(SEXP, &, SEXP, val, SET_VECTOR_ELT(target, off+i, cval))
else
BODY(SEXP, VECTOR_PTR, SEXP, val, SET_VECTOR_ELT(target, off+i, cval))
Expand Down
7 changes: 4 additions & 3 deletions src/rbindlist.c
Original file line number Diff line number Diff line change
Expand Up @@ -292,7 +292,8 @@ SEXP rbindlist(SEXP l, SEXP usenamesArg, SEXP fillArg, SEXP idcolArg)
}
SEXP thisCol = VECTOR_ELT(li, w);
int thisType = TYPEOF(thisCol);
if (TYPEORDER(thisType)>TYPEORDER(maxType)) maxType=thisType;
// Use >= for #546 -- TYPEORDER=0 for both LGLSXP and EXPRSXP (but also NULL)
if (TYPEORDER(thisType)>=TYPEORDER(maxType) && !isNull(thisCol)) maxType=thisType;
if (isFactor(thisCol)) {
if (isNull(getAttrib(thisCol,R_LevelsSymbol))) error("Column %d of item %d has type 'factor' but has no levels; i.e. malformed.", w+1, i+1);
factor = true;
Expand Down Expand Up @@ -513,9 +514,9 @@ SEXP rbindlist(SEXP l, SEXP usenamesArg, SEXP fillArg, SEXP idcolArg)
if (w==-1 || !length(thisCol=VECTOR_ELT(li, w))) { // !length for zeroCol warning above; #1871
writeNA(target, ansloc, thisnrow); // writeNA is integer64 aware and writes INT64_MIN
} else {
if (TYPEOF(target)==VECSXP && TYPEOF(thisCol)!=VECSXP) {
if ((TYPEOF(target)==VECSXP || TYPEOF(target)==EXPRSXP) && TYPEOF(thisCol)!=TYPEOF(target)) {
// do an as.list() on the atomic column; #3528
thisCol = PROTECT(coerceVector(thisCol, VECSXP)); nprotect++;
thisCol = PROTECT(coerceVector(thisCol, TYPEOF(target))); nprotect++;
}
// else coerces if needed within memrecycle; with a no-alloc direct coerce from 1.12.4 (PR #3909)
const char *ret = memrecycle(target, R_NilValue, ansloc, thisnrow, thisCol, idcol+j+1, foundName);
Expand Down