Skip to content

dcast.data.table eval(fun.aggragate) -- cannot pass as an argument #713

@mathematicalcoffee

Description

@mathematicalcoffee

Referred from SO question

Affects 1.9.3 (and not 1.9.2)

TL;DR

If you have a function that calls dcast.data.table, you can't seem to pass fun.aggregate into that call from the function argument.
Because of an eval(fun.aggregate) within dcast.data.table.

Example

I have a table like this:

library(data.table)
t <- data.table(id=rep(1:2, c(3,4)), k=c(rep(letters[1:3], 2), 'c'), v=1:7)
t
   id k v
1:  1 a 1
2:  1 b 2
3:  1 c 3
4:  2 a 4
5:  2 b 5
6:  2 c 6
7:  2 c 7  # note the duplicate (2, c)

I reshape to long format, retaining the last occurence of duplicates

dcast.data.table(t, id ~ k, value.var='v', fun.aggregate=last) # last is in data.table
   id a b c
1:  1 1 2 3
2:  2 4 5 7

However if I wrap my dcast.data.table call into a function:

f <- function (tbl, fun.aggregate) {
    dcast.data.table(tbl, id ~ k, value.var='v', fun.aggregate=fun.aggregate)
}
f(t, last)
Error in `[.data.table`(data, , eval(fun.aggregate), by = c(ff_)) : 
  could not find function "fun.aggregate"

It looks like the symbol fun.aggregate is being evaluated (eval(fun.aggregate)) and not found (since the function "fun.aggregate" does not exist).

Is there a way to "protect" a function argument from the eval() call when I pass it in (i.e. perhaps this behaviour is intended), or perhaps this is a bug. My personal opinion is that it is a bug, because this works for dcast and not dcast.data.table, and the two should be consistent.

Metadata

Metadata

Labels

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions