Skip to content

Commit

Permalink
Closes #893. dcast handles factor levels correctly on drop=FALSE.
Browse files Browse the repository at this point in the history
  • Loading branch information
arunsrinivasan committed Dec 13, 2014
1 parent 25368a2 commit a14cef5
Show file tree
Hide file tree
Showing 3 changed files with 26 additions and 5 deletions.
2 changes: 2 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,8 @@

24. `X[Y, .N]` returned the same result as `X[Y, .N, nomatch=0L]`) when `Y` contained rows that has no matches in `X`. Fixed now. Closes [#963](https:/Rdatatable/data.table/issues/963). Thanks to [this SO post](http://stackoverflow.com/q/27004002/559784) from @Alex which helped discover the bug.

25. `data.table::dcast` handles levels in factor columns properly when `drop = FALSE`. Closes [#893](https:/Rdatatable/data.table/issues/893). Thanks to @matthieugomez for the great minimal example.

#### NOTES

1. Clearer explanation of what `duplicated()` does (borrowed from base). Thanks to @matthieugomez for pointing out. Closes [#872](https:/Rdatatable/data.table/issues/872).
Expand Down
11 changes: 11 additions & 0 deletions inst/tests/tests.Rraw
Original file line number Diff line number Diff line change
Expand Up @@ -5623,6 +5623,17 @@ test(1456.1, chmatch2(x1, table), as.integer(c(3,1,NA,2,5,NA)))
test(1456.2, chmatch2(x2, table), as.integer(c(1,2,NA)))
test(1456.3, chmatch2(x3, table), as.integer(c(NA,1,2,NA,NA)))

# Fix for #893
if ("package:reshape2" %in% search()) {
dt <- data.table(
x = factor("a", levels = c("a", "b")),
y = factor("b", levels = c("a", "b")),
z = 1
)
test(1449.1, dcast(dt, y ~ x, drop = FALSE, value.var="z"),
data.table(dcast(as.data.frame(dt), y ~ x, drop = FALSE, value.var="z"), key="y"))
}

##########################


Expand Down
18 changes: 13 additions & 5 deletions src/fcast.c
Original file line number Diff line number Diff line change
Expand Up @@ -401,11 +401,19 @@ SEXP fcast(SEXP DT, SEXP inames, SEXP mnames, SEXP vnames, SEXP fill, SEXP fill_
for (i=0; i<mlen; i++) {
cpy = PROTECT(allocVector(VECSXP, 1));
SET_VECTOR_ELT(cpy, 0, VECTOR_ELT(rdt, i));
dorder = PROTECT(cast_order(cpy, env));
ddup = PROTECT(uniqlist(cpy, dorder));
ddup = PROTECT(subsetVector(dorder, ddup));
dtmp = PROTECT(subsetVector(VECTOR_ELT(cpy, 0), ddup));
UNPROTECT(5);
if (isFactor(VECTOR_ELT(rdt, i))) {
lvls = PROTECT(getAttrib(VECTOR_ELT(rdt, i), R_LevelsSymbol));
dtmp = PROTECT(seq_int(length(lvls), 1));
setAttrib(dtmp, R_ClassSymbol, mkString("factor"));
setAttrib(dtmp, R_LevelsSymbol, lvls);
UNPROTECT(3);
} else {
dorder = PROTECT(cast_order(cpy, env));
ddup = PROTECT(uniqlist(cpy, dorder));
ddup = PROTECT(subsetVector(dorder, ddup));
dtmp = PROTECT(subsetVector(VECTOR_ELT(cpy, 0), ddup));
UNPROTECT(5);
}
SET_VECTOR_ELT(rcj, i, dtmp);
}
rcj = PROTECT(cross_join(rcj, env)); protecti++;
Expand Down

0 comments on commit a14cef5

Please sign in to comment.