diff --git a/R/fcast.R b/R/fcast.R index 3de3fcb8f..18206a106 100644 --- a/R/fcast.R +++ b/R/fcast.R @@ -168,10 +168,18 @@ dcast.data.table = function(data, formula, fun.aggregate = NULL, sep = "_", ..., setDT(dat) m = as.list(match.call()[-1L]) - subset = m[["subset"]][[2L]] + subset = m[["subset"]] if (!is.null(subset)) { + if (is.call(subset) && (subset[[1L]] == quote(.) || subset[[1L]] == quote(list))) { + subset = subset[[2L]] + } if (is.name(subset)) subset = as.call(list(quote(`(`), subset)) - idx = which(eval(subset, data, parent.frame())) # any advantage thro' secondary keys? + idx = eval(subset, data, parent.frame()) + if (is.logical(idx) && length(idx) == 1L) { + idx = if (!is.na(idx) && idx) seq_len(nrow(data)) else integer(0) + } else { + idx = which(idx) # which() returns indices of TRUE, ignores FALSE and NA + } dat = .Call(CsubsetDT, dat, idx, seq_along(dat)) } fun.call = m[["fun.aggregate"]] diff --git a/inst/tests/tests.Rraw b/inst/tests/tests.Rraw index 687bf929e..5e866cc18 100644 --- a/inst/tests/tests.Rraw +++ b/inst/tests/tests.Rraw @@ -21660,3 +21660,13 @@ test(2374.08, key(DT[, .(a, a)]), NULL) test(2374.09, key(subset(DT, select=c(a, a))), NULL) DT = data.table(a=1:2, a.1=3:4, val=10:11) test(2374.10, key(DT[, .(a.1, sum(val)), keyby=.(a, a)]), NULL) + +# dcast() subset supports base-style logical expressions, #4325 +DT = data.table( a = rep(1:5, 3), b = rep(1:3, each = 5), v = 1:15) +y = data.table(a=2:5, `1`=2:5, `2`=7:10, `3`=12:15) +setkey(y, a) +test(2375.1, dcast(DT, a ~ b, value.var="v", subset=a > 1), y) +test(2375.2, dcast(DT, a ~ b, value.var="v", subset=.(a > 1)), y) +test(2375.3, identical( dcast(DT, a ~ b, value.var="v", subset=a > 2 & b != 2), dcast(DT, a ~ b, value.var="v", subset=.(a > 2 & b != 2)) ), TRUE) +test(2375.4, dcast(DT, a ~ b, value.var="v", subset=TRUE), dcast(DT, a ~ b, value.var="v")) +test(2375.5, nrow(dcast(DT, a ~ b, value.var="v", subset=FALSE)), 0L)