Skip to content
Open
2 changes: 2 additions & 0 deletions NEWS.md
Original file line number Diff line number Diff line change
Expand Up @@ -197,6 +197,8 @@

19. Ellipsis elements like `..1` are correctly excluded when searching for variables in "up-a-level" syntax inside `[`, [#5460](https://github.com/Rdatatable/data.table/issues/5460). Thanks @ggrothendieck for the report and @MichaelChirico for the fix.

20. `rowwiseDT()` now provides a helpful error message when a complex object that is not a list (e.g., a function) is provided as a cell value, instructing the user to wrap it in `list()`. [#7219](https://github.com/Rdatatable/data.table/issues/7219). Thanks @kylebutts for the report and @venom1204 for the fix.

### NOTES

1. The following in-progress deprecations have proceeded:
Expand Down
15 changes: 15 additions & 0 deletions R/rowwiseDT.R
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,21 @@ rowwiseDT = function(...) {
nrows = length(body) %/% ncols
if (length(body) != nrows * ncols)
stopf("There are %d columns but the number of cells is %d, which is not an integer multiple of the columns", ncols, length(body))
is_problematic = vapply_1b(
body,
function(v) !(is.atomic(v) || is.null(v) || typeof(v) == "list")
)
if (any(is_problematic)) {
first_problem_idx = which(is_problematic)[1L]
col_idx = (first_problem_idx - 1L) %% ncols + 1L
col_name = header[col_idx]
obj_type = class1(body[[first_problem_idx]])
stopf(
"In column '%s', received an object of type '%s'.\nComplex objects (like functions, formulas, or calls) must be wrapped in list() to be stored in a data.table column.\nPlease use `list(...)` for this value.",
col_name,
obj_type
)
}
# make all the non-scalar elements to a list
needs_list = lengths(body) != 1L
body[needs_list] = lapply(body[needs_list], list)
Expand Down
13 changes: 13 additions & 0 deletions inst/tests/tests.Rraw
Original file line number Diff line number Diff line change
Expand Up @@ -21655,3 +21655,16 @@ local({
...123 = 'a'
test(2339.11, DT[, .....123], DT)
})

# rowwiseDT() valid and invalid handling of complex objects #7219
test(2340.1, rowwiseDT(x =, y =, 1, 2, 3, 4), data.table(x = c(1, 3), y = c(2, 4)))
test(2340.2, rowwiseDT(x =, func =,
1, list(\(x) x + 1),
2, list(function(z) z * 2)),
data.table(x = c(1, 2), func = list(\(x) x + 1, function(z) z * 2)))
test(2340.3, rowwiseDT(x =, func =, 1, \(x) x + 1),
error = "In column 'func', received an object of type 'function'.*wrap.*list")
test(2340.4, rowwiseDT(x =, expr =, 1, quote(a + b)),
error = "In column 'expr', received an object of type 'call'.*wrap.*list")
test(2340.5, rowwiseDT(x =, plist =, 1, as.pairlist(list(123))),
error = "In column 'plist', received an object of type 'pairlist'.*wrap.*list")
Loading